beats 1.2.2 → 1.2.3

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.
@@ -35,16 +35,16 @@ And [here's what it sounds like](http://beatsdrummachine.com/beat.mp3) after get
35
35
  Current Status
36
36
  --------------
37
37
 
38
- The latest stable version of BEATS is 1.2.2, released on June 12, 2011. This is a minor release which includes two bug fixes:
38
+ The latest stable version of BEATS is 1.2.3, released on December 31, 2011. This is a minor release which includes two improvements:
39
39
 
40
- * Bug fix: Compatibility issues with Windows
41
- * Bug fix: Return the correct status code when BEATS terminates, to improve scriptability.
40
+ * Bug fix: You can now use `~` in sound file paths, and it will correctly expand to your home folder. (At least on UNIX OSes, I'm not sure if that works on Windows).
41
+ * The new `--path` option allows setting the base path from which relative sound file paths are searched for.
42
42
 
43
43
 
44
44
  Installation
45
45
  ------------
46
46
 
47
- To install the latest stable version (1.2.2) from [rubygems.org](http://rubygems.org/gems/beats), run the following from the command line:
47
+ To install the latest stable version (1.2.3) from [rubygems.org](http://rubygems.org/gems/beats), run the following from the command line:
48
48
 
49
49
  gem install beats
50
50
 
data/bin/beats CHANGED
@@ -20,7 +20,7 @@ require "lib/track"
20
20
  USAGE_INSTRUCTIONS = ""
21
21
 
22
22
  def parse_options()
23
- options = {:split => false, :pattern => nil}
23
+ options = {:split => false}
24
24
 
25
25
  optparse = OptionParser.new do |opts|
26
26
  opts.banner = "usage: beats [options] input_file [output_file]"
@@ -32,12 +32,16 @@ def parse_options()
32
32
  opts.on('-p', '--pattern PATTERN_NAME', "Output a single pattern instead of the whole song" ) do |p|
33
33
  options[:pattern] = p
34
34
  end
35
-
35
+
36
+ opts.on('--path BASE_PATH', "The base path used to load sound files with relative paths.") do |base_path|
37
+ options[:base_path] = base_path
38
+ end
39
+
36
40
  opts.on('-v', '--version', "Display version number and exit") do
37
41
  puts "BEATS v#{Beats::BEATS_VERSION}"
38
42
  exit
39
43
  end
40
-
44
+
41
45
  opts.on( '-h', '--help', "Display this screen and exit" ) do
42
46
  puts opts
43
47
  exit
Binary file
@@ -1,5 +1,5 @@
1
1
  class Beats
2
- BEATS_VERSION = "1.2.2"
2
+ BEATS_VERSION = "1.2.3"
3
3
 
4
4
  # Each pattern in the song will be split up into sub patterns that have at most this many steps.
5
5
  # In general, audio for several shorter patterns can be generated more quickly than for one long
@@ -18,7 +18,8 @@ class Beats
18
18
  end
19
19
 
20
20
  def run
21
- song, kit = SongParser.new().parse(File.dirname(@input_file_name), File.read(@input_file_name))
21
+ base_path = @options[:base_path] || File.dirname(@input_file_name)
22
+ song, kit = SongParser.new().parse(base_path, File.read(@input_file_name))
22
23
 
23
24
  song = normalize_for_pattern_option(song)
24
25
  songs_to_generate = normalize_for_split_option(song)
data/lib/kit.rb CHANGED
@@ -137,18 +137,15 @@ private
137
137
  end
138
138
  end
139
139
 
140
- def get_absolute_path(base_path, sound_file_name)
141
- path_is_absolute = sound_file_name.start_with?(File::SEPARATOR)
142
- return path_is_absolute ? sound_file_name : (base_path + File::SEPARATOR + sound_file_name)
143
- end
144
-
140
+ # Converts relative paths into absolute paths. Note that this will also handle
141
+ # expanding ~ on platforms that support that.
145
142
  def make_file_names_absolute(kit_items)
146
143
  kit_items.each do |label, sound_file_names|
147
144
  unless sound_file_names.class == Array
148
145
  sound_file_names = [sound_file_names]
149
146
  end
150
147
 
151
- sound_file_names.map! {|sound_file_name| get_absolute_path(base_path, sound_file_name)}
148
+ sound_file_names.map! {|sound_file_name| File.expand_path(sound_file_name, base_path) }
152
149
  kit_items[label] = sound_file_names
153
150
  end
154
151
 
@@ -1,5 +1,3 @@
1
- $:.unshift File.join(File.dirname(__FILE__),'..','lib')
2
-
3
1
  require 'includes'
4
2
 
5
3
  # Make private methods public for testing
@@ -1,5 +1,3 @@
1
- $:.unshift File.join(File.dirname(__FILE__),'..','lib')
2
-
3
1
  require 'includes'
4
2
 
5
3
  class AudioUtilsTest < Test::Unit::TestCase
@@ -0,0 +1,33 @@
1
+ # An example song using mono 16-bit sounds
2
+ # The sound files in this example do not exist in the given
3
+ # location relative to this file, so this is intended for testing
4
+ # when a custom base path is given.
5
+
6
+ Song:
7
+ Tempo: 120
8
+ Flow:
9
+ - Verse: x2
10
+ - Chorus: x4
11
+ - Verse: x2
12
+ - Chorus: x4
13
+ Kit:
14
+ - bass: bass_mono_16.wav
15
+ - snare: snare_mono_16.wav
16
+ - hh_closed: hh_closed_mono_16.wav
17
+ - agogo: agogo_high_mono_16.wav
18
+
19
+ Verse:
20
+ - bass: X...X...X...X...
21
+ - snare: ..............X.
22
+ - hh_closed: X.XXX.XX........
23
+ - hh_closed: ........X.X.X.X.
24
+ - agogo: ..............XX
25
+
26
+ # Also including non-Kit sounds to test that they work as well:
27
+ Chorus:
28
+ - bass: X...X...XX..X...
29
+ - snare: ....X.......X...
30
+ - hh_closed: X.XXX.XX........
31
+ - hh_closed: ........X.XX..X.
32
+ - tom4_mono_16.wav: ...........X....
33
+ - tom2_mono_16.wav: ..............X.
@@ -1,11 +1,14 @@
1
- $:.unshift File.join(File.dirname(__FILE__),'..','lib')
2
-
3
1
  require 'includes'
4
2
 
5
3
  class IntegrationTest < Test::Unit::TestCase
6
4
  TRACK_NAMES = ["bass", "snare", "hh_closed", "hh_closed2", "agogo", "tom4", "tom2"]
7
5
  OUTPUT_FOLDER = "test/integration_output"
8
6
 
7
+ def setup
8
+ # Make sure no output from previous tests is still around
9
+ clean_output_folder()
10
+ end
11
+
9
12
  def test_bad_song_errors
10
13
  invalid_fixtures = ["bad_tempo.txt",
11
14
  "bad_repeat_count.txt",
@@ -17,7 +20,7 @@ class IntegrationTest < Test::Unit::TestCase
17
20
 
18
21
  invalid_fixtures.each do |fixture_name|
19
22
  assert_raise(SongParseError) do
20
- beats = Beats.new("test/fixtures/invalid/#{fixture_name}", "doesn't matter", {:split => false, :pattern => nil})
23
+ beats = Beats.new("test/fixtures/invalid/#{fixture_name}", "doesn't matter", {:split => false})
21
24
  beats.run()
22
25
  end
23
26
  end
@@ -27,25 +30,32 @@ class IntegrationTest < Test::Unit::TestCase
27
30
  # TODO: Add tests for the -p option
28
31
  # TODO: Add test verify that song generated with and without SongOptimizer are identical.
29
32
 
33
+ def test_base_path
34
+ run_combined_test("mono", 16, "_base_path", "test/sounds")
35
+ run_split_test("mono", 16, "_base_path", "test/sounds")
36
+ end
37
+
30
38
  def test_generate_combined
31
- # Make sure no output from previous tests is still around
32
- clean_output_folder()
33
-
34
39
  run_combined_test("mono", 8)
35
40
  run_combined_test("mono", 16)
36
41
  run_combined_test("stereo", 8)
37
42
  run_combined_test("stereo", 16)
38
43
  end
39
44
 
40
- def run_combined_test(num_channels, bits_per_sample)
45
+ def run_combined_test(num_channels, bits_per_sample, suffix="", base_path=nil)
41
46
  # Make sure no output from previous tests is still around
42
47
  assert_equal([".", ".."], Dir.new(OUTPUT_FOLDER).entries)
43
48
 
44
- song_fixture = "test/fixtures/valid/example_#{num_channels}_#{bits_per_sample}.txt"
45
- actual_output_file = "#{OUTPUT_FOLDER}/example_combined_#{num_channels}_#{bits_per_sample}.wav"
49
+ song_fixture = "test/fixtures/valid/example_#{num_channels}_#{bits_per_sample}#{suffix}.txt"
50
+ actual_output_file = "#{OUTPUT_FOLDER}/example_combined_#{num_channels}_#{bits_per_sample}#{suffix}.wav"
46
51
  expected_output_file = "test/fixtures/expected_output/example_combined_#{num_channels}_#{bits_per_sample}.wav"
47
52
 
48
- beats = Beats.new(song_fixture, actual_output_file, {:split => false, :pattern => nil})
53
+ options = {:split => false}
54
+ unless base_path == nil
55
+ options[:base_path] = base_path
56
+ end
57
+
58
+ beats = Beats.new(song_fixture, actual_output_file, options)
49
59
  beats.run()
50
60
  assert(File.exists?(actual_output_file), "Expected file '#{actual_output_file}' to exist, but it doesn't.")
51
61
 
@@ -59,24 +69,26 @@ class IntegrationTest < Test::Unit::TestCase
59
69
  end
60
70
 
61
71
  def test_generate_split
62
- # Make sure no output from previous tests is still around
63
- clean_output_folder()
64
-
65
72
  run_split_test("mono", 8)
66
73
  run_split_test("mono", 16)
67
74
  run_split_test("stereo", 8)
68
75
  run_split_test("stereo", 16)
69
76
  end
70
77
 
71
- def run_split_test(num_channels, bits_per_sample)
78
+ def run_split_test(num_channels, bits_per_sample, suffix="", base_path=nil)
72
79
  # Make sure no output from previous tests is still around
73
80
  assert_equal([".", ".."], Dir.new(OUTPUT_FOLDER).entries)
74
81
 
75
- song_fixture = "test/fixtures/valid/example_#{num_channels}_#{bits_per_sample}.txt"
76
- actual_output_prefix = "#{OUTPUT_FOLDER}/example_split_#{num_channels}_#{bits_per_sample}"
82
+ song_fixture = "test/fixtures/valid/example_#{num_channels}_#{bits_per_sample}#{suffix}.txt"
83
+ actual_output_prefix = "#{OUTPUT_FOLDER}/example_split_#{num_channels}_#{bits_per_sample}#{suffix}"
77
84
  expected_output_prefix = "test/fixtures/expected_output/example_split_#{num_channels}_#{bits_per_sample}"
78
85
 
79
- beats = Beats.new(song_fixture, actual_output_prefix + ".wav", {:split => true, :pattern => nil})
86
+ options = {:split => true}
87
+ unless base_path == nil
88
+ options[:base_path] = base_path
89
+ end
90
+
91
+ beats = Beats.new(song_fixture, actual_output_prefix + ".wav", options)
80
92
  beats.run()
81
93
  TRACK_NAMES.each do |track_name|
82
94
  if(track_name.start_with?("tom"))
@@ -1,5 +1,3 @@
1
- $:.unshift File.join(File.dirname(__FILE__),'..','lib')
2
-
3
1
  require 'includes'
4
2
 
5
3
  # Kit which allows directly changing the sound bank after initialization, to allows tests
@@ -1,5 +1,3 @@
1
- $:.unshift File.join(File.dirname(__FILE__),'..','lib')
2
-
3
1
  require 'includes'
4
2
 
5
3
  class PatternTest < Test::Unit::TestCase
@@ -1,5 +1,3 @@
1
- $:.unshift File.join(File.dirname(__FILE__),'..','lib')
2
-
3
1
  require 'includes'
4
2
 
5
3
  class PatternExpanderTest < Test::Unit::TestCase
@@ -1,5 +1,3 @@
1
- $:.unshift File.join(File.dirname(__FILE__),'..','lib')
2
-
3
1
  require 'includes'
4
2
 
5
3
  class SongTest < Test::Unit::TestCase
@@ -1,5 +1,3 @@
1
- $:.unshift File.join(File.dirname(__FILE__),'..','lib')
2
-
3
1
  require 'includes'
4
2
 
5
3
  class MockSongOptimizer < SongOptimizer
@@ -1,5 +1,3 @@
1
- $:.unshift File.join(File.dirname(__FILE__),'..','lib')
2
-
3
1
  require 'includes'
4
2
 
5
3
  class SongParserTest < Test::Unit::TestCase
@@ -1,5 +1,3 @@
1
- $:.unshift File.join(File.dirname(__FILE__),'..','lib')
2
-
3
1
  require 'includes'
4
2
 
5
3
  class TrackTest < Test::Unit::TestCase
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: beats
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 1.2.2
5
+ version: 1.2.3
6
6
  platform: ruby
7
7
  authors:
8
8
  - Joel Strait
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-06-13 00:00:00 Z
13
+ date: 2012-01-01 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: wavefile
@@ -47,6 +47,7 @@ files:
47
47
  - lib/songparser.rb
48
48
  - lib/track.rb
49
49
  - bin/beats
50
+ - bin/example_song.wav
50
51
  - test/audioengine_test.rb
51
52
  - test/audioutils_test.rb
52
53
  - test/fixtures/expected_output/example_combined_mono_16.wav
@@ -94,6 +95,7 @@ files:
94
95
  - test/fixtures/invalid/sound_in_track_wrong_format.txt
95
96
  - test/fixtures/invalid/template.txt
96
97
  - test/fixtures/valid/example_mono_16.txt
98
+ - test/fixtures/valid/example_mono_16_base_path.txt
97
99
  - test/fixtures/valid/example_mono_8.txt
98
100
  - test/fixtures/valid/example_no_kit.txt
99
101
  - test/fixtures/valid/example_stereo_16.txt
@@ -225,7 +227,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
225
227
  requirements: []
226
228
 
227
229
  rubyforge_project:
228
- rubygems_version: 1.8.5
230
+ rubygems_version: 1.8.13
229
231
  signing_key:
230
232
  specification_version: 3
231
233
  summary: A command-line drum machine. Feed it a song notated in YAML, and it will produce a precision-milled Wave file of impeccable timing and feel.
@@ -277,6 +279,7 @@ test_files:
277
279
  - test/fixtures/invalid/sound_in_track_wrong_format.txt
278
280
  - test/fixtures/invalid/template.txt
279
281
  - test/fixtures/valid/example_mono_16.txt
282
+ - test/fixtures/valid/example_mono_16_base_path.txt
280
283
  - test/fixtures/valid/example_mono_8.txt
281
284
  - test/fixtures/valid/example_no_kit.txt
282
285
  - test/fixtures/valid/example_stereo_16.txt
@@ -385,3 +388,4 @@ test_files:
385
388
  - test/sounds/tom4_stereo_8.wav
386
389
  - test/sounds/tone.wav
387
390
  - test/track_test.rb
391
+ has_rdoc: