music_player 0.9.0-universal-darwin-9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +22 -0
- data/Rakefile +36 -0
- data/examples/drum_machine.rb +64 -0
- data/ext/music_player/extconf.rb +9 -0
- data/ext/music_player/music_player.c +1440 -0
- data/ext/music_player/util.h +25 -0
- data/lib/music_player.rb +216 -0
- data/test/example.mid +0 -0
- data/test/extended_tempo_event_test.rb +15 -0
- data/test/midi_channel_message_test.rb +93 -0
- data/test/midi_note_message_test.rb +50 -0
- data/test/music_event_iterator_test.rb +160 -0
- data/test/music_player_test.rb +40 -0
- data/test/music_sequence_test.rb +52 -0
- data/test/music_track_collection_test.rb +53 -0
- data/test/music_track_test.rb +92 -0
- data/test/test_helper.rb +4 -0
- metadata +77 -0
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper.rb')
|
2
|
+
|
3
|
+
class MusicPlayerTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@player = MusicPlayer.new
|
6
|
+
@sequence = MusicSequence.new
|
7
|
+
@track = @sequence.tracks.new
|
8
|
+
@track.add 0.0,
|
9
|
+
MIDIProgramChangeMessage.new(:channel => 0, :program => 1)
|
10
|
+
@track.add 0.0, MIDINoteMessage.new(:note => 60)
|
11
|
+
@track.add 1.0, MIDINoteMessage.new(:note => 64)
|
12
|
+
@track.add 2.0, MIDINoteMessage.new(:note => 67)
|
13
|
+
@player.sequence = @sequence
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_playback
|
17
|
+
assert_nothing_raised { assert_nil @player.start }
|
18
|
+
assert @player.playing?
|
19
|
+
assert_nothing_raised { assert_nil @player.stop }
|
20
|
+
assert !@player.playing?
|
21
|
+
|
22
|
+
assert_raise(NoSequence) { MusicPlayer.new.start }
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_time
|
26
|
+
assert_nothing_raised do
|
27
|
+
assert_equal 0.0, @player.time
|
28
|
+
@player.time = 1.0
|
29
|
+
assert_equal 1.0, @player.time
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_play_rate_scalar
|
34
|
+
assert_nothing_raised do
|
35
|
+
assert_equal 1.0, @player.play_rate_scalar
|
36
|
+
@player.play_rate_scalar = 1.6
|
37
|
+
assert_equal 1.6, @player.play_rate_scalar
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper.rb')
|
2
|
+
require 'pathname'
|
3
|
+
require 'tempfile'
|
4
|
+
|
5
|
+
class MusicSequenceTest < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@sequence = MusicSequence.new
|
8
|
+
|
9
|
+
@tempo = @sequence.tracks.tempo
|
10
|
+
@tempo.add 0.0, ExtendedTempoEvent.new(:bpm => 120)
|
11
|
+
|
12
|
+
@track = @sequence.tracks.new
|
13
|
+
@track.add 0.0, MIDIProgramChangeMessage.new(:channel => 0, :program => 1)
|
14
|
+
@track.add 0.0, MIDINoteMessage.new(:note => 60)
|
15
|
+
@track.add 1.0, MIDINoteMessage.new(:note => 64)
|
16
|
+
@track.add 2.0, MIDINoteMessage.new(:note => 67)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_type
|
20
|
+
assert_equal :beat, @sequence.type, "Expected default type of :beat."
|
21
|
+
seq = MusicSequence.new
|
22
|
+
seq.type = :samp
|
23
|
+
assert_equal :samp, seq.type
|
24
|
+
seq.type = :secs
|
25
|
+
assert_equal :secs, seq.type
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_tracks
|
29
|
+
assert_kind_of MusicTrackCollection, @sequence.tracks
|
30
|
+
assert_equal @sequence.tracks, @sequence.tracks,
|
31
|
+
"Expected only one instance of the track collection."
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_save_with_pathname
|
35
|
+
tmp = Tempfile.new('music_sequence_test.mid')
|
36
|
+
assert_nothing_raised { @sequence.save(tmp.path) }
|
37
|
+
# Or more literally, a Pathname. Should support anything with #to_str.
|
38
|
+
assert_nothing_raised { @sequence.save(Pathname(tmp.path)) }
|
39
|
+
assert File.exists?(tmp.path)
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_load
|
43
|
+
dir = File.dirname(__FILE__)
|
44
|
+
smf = File.join(dir, 'example.mid')
|
45
|
+
sz = @sequence.tracks.size
|
46
|
+
assert_nothing_raised { @sequence.load(smf) }
|
47
|
+
# Basically, show that new tracks are appended to the end of the collection.
|
48
|
+
assert_equal 2, @sequence.tracks.size
|
49
|
+
assert_equal @track, @sequence.tracks[0]
|
50
|
+
assert_not_equal @track, @sequence.tracks[1]
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
class MusicSequenceTracksEnumerableTest < Test::Unit::TestCase
|
2
|
+
def setup
|
3
|
+
@sequence = MusicSequence.new
|
4
|
+
@track1 = @sequence.tracks.new
|
5
|
+
@track2 = @sequence.tracks.new
|
6
|
+
@track3 = @sequence.tracks.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_size
|
10
|
+
assert_equal 3, @sequence.tracks.size
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_at_index
|
14
|
+
assert @sequence.tracks[0]
|
15
|
+
assert_nil @sequence.tracks[42]
|
16
|
+
|
17
|
+
assert_equal @sequence.tracks[0].object_id,
|
18
|
+
@sequence.tracks[0].object_id
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_each
|
22
|
+
trks = []
|
23
|
+
@sequence.tracks.each do |trk|
|
24
|
+
trks << trk
|
25
|
+
end
|
26
|
+
# Separate references can be modified independently.
|
27
|
+
# trks.first.add(0.0, MIDINoteMessage.new(:note => 60))
|
28
|
+
# @track1.add(1.0, MIDINoteMessage.new(:note => 72))
|
29
|
+
assert_equal [@track1, @track2, @track3], trks
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_index
|
33
|
+
assert_equal 0, @sequence.tracks.index(@track1)
|
34
|
+
assert_raise(ArgumentError) { @sequence.tracks.index(0) }
|
35
|
+
|
36
|
+
seq = MusicSequence.new
|
37
|
+
track = seq.tracks.new
|
38
|
+
assert_raise(TrackNotFound) { @sequence.tracks.index(track) }
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_delete
|
42
|
+
assert_equal 3, @sequence.tracks.size
|
43
|
+
trk = @sequence.tracks[0]
|
44
|
+
@sequence.tracks.delete(trk)
|
45
|
+
assert_equal 2, @sequence.tracks.size
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_tempo
|
49
|
+
assert_kind_of MusicTrack, @sequence.tracks.tempo
|
50
|
+
assert_equal @sequence.tracks.tempo, @sequence.tracks.tempo,
|
51
|
+
"Expected only one instance of the tempo track."
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper.rb')
|
2
|
+
|
3
|
+
class MusicTrackTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@sequence = MusicSequence.new
|
6
|
+
@track = @sequence.tracks.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_add
|
10
|
+
assert_nothing_raised do
|
11
|
+
@track.add 0, MIDINoteMessage.new(:note => 60)
|
12
|
+
# a representative channel message
|
13
|
+
@track.add 0, MIDIControlChangeMessage.new(:channel => 0, :number => 0, :value => 0)
|
14
|
+
end
|
15
|
+
|
16
|
+
assert_raise(IllegalTrackDestination) do
|
17
|
+
@track.add 0, ExtendedTempoEvent.new(:bpm => 120)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_iterator
|
22
|
+
assert_kind_of MusicEventIterator, @track.iterator
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_enumerable
|
26
|
+
@track.add 0, ev1=MIDINoteMessage.new(:note => 60)
|
27
|
+
@track.add 1, ev2=MIDINoteMessage.new(:note => 64)
|
28
|
+
@track.add 2, ev3=MIDINoteMessage.new(:note => 67)
|
29
|
+
|
30
|
+
assert_equal [ev1, ev2, ev3], @track.map { |x| x }
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_loop_info
|
34
|
+
assert_equal({ :duration => 0.0, :number => 1 }, @track.loop_info)
|
35
|
+
@track.loop_info = { :duration => 100.0, :number => 42 }
|
36
|
+
assert_equal({ :duration => 100.0, :number => 42 }, @track.loop_info)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_offset
|
40
|
+
assert_equal 0.0, @track.offset
|
41
|
+
@track.offset = 1.0
|
42
|
+
assert_equal 1.0, @track.offset
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_mute
|
46
|
+
assert_equal false, @track.mute
|
47
|
+
@track.mute = true
|
48
|
+
assert_equal true, @track.mute
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_solo
|
52
|
+
assert_equal false, @track.solo
|
53
|
+
@track.solo = true
|
54
|
+
assert_equal true, @track.solo
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_length
|
58
|
+
assert_equal 0, @track.length
|
59
|
+
|
60
|
+
@track.add 0, MIDINoteMessage.new(:note => 60, :duration => 1)
|
61
|
+
assert_equal 1, @track.length
|
62
|
+
|
63
|
+
# Length is maximum of the user-set length and the timestamp of the
|
64
|
+
# release of the final event.
|
65
|
+
@track.length = 0.5
|
66
|
+
assert_equal 1, @track.length
|
67
|
+
|
68
|
+
@track.length = 10
|
69
|
+
assert_equal 10, @track.length
|
70
|
+
|
71
|
+
@track.add 42, MIDINoteMessage.new(:note => 60, :duration => 1)
|
72
|
+
assert_equal 43, @track.length
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_resolution
|
76
|
+
# 480 is the default resolution. 960 is also common.
|
77
|
+
assert_equal 480, @sequence.tracks.tempo.resolution
|
78
|
+
assert_raise(ArgumentError) { @track.resolution }
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_initialize
|
82
|
+
track = @sequence.tracks.new(:loop_info => { :duration => 10,
|
83
|
+
:number => 3 },
|
84
|
+
:mute => true,
|
85
|
+
:solo => true,
|
86
|
+
:length => 10)
|
87
|
+
assert_equal({:duration => 10, :number => 3}, track.loop_info)
|
88
|
+
assert track.mute
|
89
|
+
assert track.solo
|
90
|
+
assert_equal 10, track.length
|
91
|
+
end
|
92
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: music_player
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.0
|
5
|
+
platform: universal-darwin-9
|
6
|
+
authors:
|
7
|
+
- Jeremy Voorhis
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-03-18 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Ruby bindings for OS X's high-quality music sequencing API
|
17
|
+
email: jvoorhis@gmail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions:
|
21
|
+
- ext/music_player/extconf.rb
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- LICENSE
|
26
|
+
- Rakefile
|
27
|
+
- examples/drum_machine.rb
|
28
|
+
- ext/music_player/music_player.c
|
29
|
+
- ext/music_player/util.h
|
30
|
+
- ext/music_player/extconf.rb
|
31
|
+
- lib/music_player.rb
|
32
|
+
- test/example.mid
|
33
|
+
- test/extended_tempo_event_test.rb
|
34
|
+
- test/midi_channel_message_test.rb
|
35
|
+
- test/midi_note_message_test.rb
|
36
|
+
- test/music_event_iterator_test.rb
|
37
|
+
- test/music_player_test.rb
|
38
|
+
- test/music_sequence_test.rb
|
39
|
+
- test/music_track_collection_test.rb
|
40
|
+
- test/music_track_test.rb
|
41
|
+
- test/test_helper.rb
|
42
|
+
has_rdoc: false
|
43
|
+
homepage: http://github.com/jvoorhis/music_player
|
44
|
+
post_install_message:
|
45
|
+
rdoc_options: []
|
46
|
+
|
47
|
+
require_paths:
|
48
|
+
- lib
|
49
|
+
- ext
|
50
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: "0"
|
55
|
+
version:
|
56
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: "0"
|
61
|
+
version:
|
62
|
+
requirements: []
|
63
|
+
|
64
|
+
rubyforge_project:
|
65
|
+
rubygems_version: 1.2.0
|
66
|
+
signing_key:
|
67
|
+
specification_version: 2
|
68
|
+
summary: Ruby bindings for OS X's high-quality music sequencing API
|
69
|
+
test_files:
|
70
|
+
- test/extended_tempo_event_test.rb
|
71
|
+
- test/midi_channel_message_test.rb
|
72
|
+
- test/midi_note_message_test.rb
|
73
|
+
- test/music_event_iterator_test.rb
|
74
|
+
- test/music_player_test.rb
|
75
|
+
- test/music_sequence_test.rb
|
76
|
+
- test/music_track_collection_test.rb
|
77
|
+
- test/music_track_test.rb
|