Skip to content

Commit

Permalink
MusicTrack#initialize can also set track properties.
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeremy Voorhis committed Mar 3, 2009
1 parent 9223521 commit d78c776
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 15 deletions.
44 changes: 37 additions & 7 deletions ext/music_player.c
Expand Up @@ -37,13 +37,17 @@ static VALUE rb_sChannel = Qnil;
static VALUE rb_sData1 = Qnil;
static VALUE rb_sData2 = Qnil;
static VALUE rb_sDuration = Qnil;
static VALUE rb_sLength = Qnil;
static VALUE rb_sLoopInfo = Qnil;
static VALUE rb_sMute = Qnil;
static VALUE rb_sNote = Qnil;
static VALUE rb_sNumber = Qnil;
static VALUE rb_sPressure = Qnil;
static VALUE rb_sProgram = Qnil;
static VALUE rb_sReleaseVelocity = Qnil;
static VALUE rb_sSamp = Qnil;
static VALUE rb_sSecs = Qnil;
static VALUE rb_sSolo = Qnil;
static VALUE rb_sStatus = Qnil;
static VALUE rb_sValue = Qnil;
static VALUE rb_sVelocity = Qnil;
Expand Down Expand Up @@ -405,9 +409,28 @@ track_free (MusicTrack *track)
}

static VALUE
track_init (VALUE self, VALUE rb_seq)
track_init (int argc, VALUE *argv, VALUE self)
{
VALUE rb_seq, rb_options;
rb_scan_args(argc, argv, "11", &rb_seq, &rb_options);

rb_iv_set(self, "@sequence", rb_seq);

if (T_HASH == TYPE(rb_options)) {
VALUE loop_info = rb_hash_aref(rb_options, rb_sLoopInfo),
mute = rb_hash_aref(rb_options, rb_sMute),
solo = rb_hash_aref(rb_options, rb_sSolo),
length = rb_hash_aref(rb_options, rb_sLength);
if (!NIL_P(loop_info))
rb_funcall(self, rb_intern("loop_info="), 1, loop_info);
if (!NIL_P(mute))
rb_funcall(self, rb_intern("mute="), 1, mute);
if (!NIL_P(solo))
rb_funcall(self, rb_intern("solo="), 1, solo);
if (!NIL_P(length))
rb_funcall(self, rb_intern("length="), 1, length);
}

return self;
}

Expand All @@ -422,18 +445,21 @@ track_internal_new (VALUE rb_seq, MusicTrack *track)
}

static VALUE
track_new (VALUE class, VALUE rb_seq)
track_new (int argc, VALUE *argv, VALUE class)
{
VALUE rb_seq, rb_options, rb_track, init_argv[2];
MusicSequence *seq;
MusicTrack *track;
OSStatus err;
VALUE rb_track, argv[1];

rb_scan_args(argc, argv, "11", &rb_seq, &rb_options);
Data_Get_Struct(rb_seq, MusicSequence, seq);

rb_track = Data_Make_Struct(rb_cMusicTrack, MusicTrack, 0, track_free, track);
require_noerr( err = MusicSequenceNewTrack(*seq, track), fail );
argv[0] = rb_seq;
rb_obj_call_init(rb_track, 1, argv);
init_argv[0] = rb_seq;
init_argv[1] = rb_options;
rb_obj_call_init(rb_track, 2, init_argv);
return rb_track;

fail:
Expand Down Expand Up @@ -1297,8 +1323,8 @@ Init_music_player ()

/* AudioToolbox::MusicTrack */
rb_cMusicTrack = rb_define_class_under(rb_mAudioToolbox, "MusicTrack", rb_cObject);
rb_define_singleton_method(rb_cMusicTrack, "new", track_new, 1);
rb_define_method(rb_cMusicTrack, "initialize", track_init, 1);
rb_define_singleton_method(rb_cMusicTrack, "new", track_new, -1);
rb_define_method(rb_cMusicTrack, "initialize", track_init, -1);
rb_define_method(rb_cMusicTrack, "add_midi_note_message", track_add_midi_note_message, 2);
rb_define_method(rb_cMusicTrack, "add_midi_channel_message", track_add_midi_channel_message, 2);
rb_define_method(rb_cMusicTrack, "add_extended_tempo_event", track_add_extended_tempo_event, 2);
Expand Down Expand Up @@ -1372,12 +1398,16 @@ Init_music_player ()
rb_sData2 = CSTR2SYM("data2");
rb_sDuration = CSTR2SYM("duration");
rb_sNote = CSTR2SYM("note");
rb_sLength = CSTR2SYM("length");
rb_sLoopInfo = CSTR2SYM("loop_info");
rb_sMute = CSTR2SYM("mute");
rb_sNumber = CSTR2SYM("number");
rb_sPressure = CSTR2SYM("pressure");
rb_sProgram = CSTR2SYM("program");
rb_sReleaseVelocity = CSTR2SYM("release_velocity");
rb_sSamp = CSTR2SYM("samp");
rb_sSecs = CSTR2SYM("secs");
rb_sSolo = CSTR2SYM("solo");
rb_sStatus = CSTR2SYM("status");
rb_sValue = CSTR2SYM("value");
rb_sVelocity = CSTR2SYM("velocity");
Expand Down
4 changes: 2 additions & 2 deletions lib/music_player.rb
Expand Up @@ -28,9 +28,9 @@ def each
0.upto(size-1) { |i| yield self[i] }
end

def new
def new(options=nil)
@lock.synchronize do
track = MusicTrack.send(:new, @sequence)
track = MusicTrack.send(:new, @sequence, options)
@tracks << track
track
end
Expand Down
24 changes: 18 additions & 6 deletions test/music_track_test.rb
Expand Up @@ -5,31 +5,31 @@ def setup
@sequence = MusicSequence.new
@track = @sequence.tracks.new
end

def test_iterator
assert_kind_of MusicEventIterator, @track.iterator
end

def test_enumerable
@track.add 0, ev1=MIDINoteMessage.new(:note => 60)
@track.add 1, ev2=MIDINoteMessage.new(:note => 64)
@track.add 2, ev3=MIDINoteMessage.new(:note => 67)

assert_equal [ev1, ev2, ev3], @track.map { |x| x }
end

def test_loop_info
assert_equal({ :duration => 0.0, :number => 1 }, @track.loop_info)
@track.loop_info = { :duration => 100.0, :number => 42 }
assert_equal({ :duration => 100.0, :number => 42 }, @track.loop_info)
end

def test_offset
assert_equal 0.0, @track.offset
@track.offset = 1.0
assert_equal 1.0, @track.offset
end

def test_mute
assert_equal false, @track.mute
@track.mute = true
Expand All @@ -41,7 +41,7 @@ def test_solo
@track.solo = true
assert_equal true, @track.solo
end

def test_length
assert_equal 0, @track.length

Expand All @@ -65,4 +65,16 @@ def test_resolution
assert_equal 480, @sequence.tracks.tempo.resolution
assert_raise(ArgumentError) { @track.resolution }
end

def test_initialize
track = @sequence.tracks.new(:loop_info => { :duration => 10,
:number => 3},
:mute => true,
:solo => true,
:length => 10)
assert_equal({:duration => 10, :number => 3}, track.loop_info)
assert track.mute
assert track.solo
assert_equal 10, track.length
end
end

0 comments on commit d78c776

Please sign in to comment.