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.
- data/README.markdown +4 -4
- data/bin/beats +7 -3
- data/bin/example_song.wav +0 -0
- data/lib/beats.rb +3 -2
- data/lib/kit.rb +3 -6
- data/test/audioengine_test.rb +0 -2
- data/test/audioutils_test.rb +0 -2
- data/test/fixtures/valid/example_mono_16_base_path.txt +33 -0
- data/test/integration_test.rb +29 -17
- data/test/kit_test.rb +0 -2
- data/test/pattern_test.rb +0 -2
- data/test/patternexpander_test.rb +0 -2
- data/test/song_test.rb +0 -2
- data/test/songoptimizer_test.rb +0 -2
- data/test/songparser_test.rb +0 -2
- data/test/track_test.rb +0 -2
- metadata +7 -3
    
        data/README.markdown
    CHANGED
    
    | @@ -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. | 
| 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:  | 
| 41 | 
            -
            *  | 
| 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. | 
| 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 | 
| 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 | 
    
        data/lib/beats.rb
    CHANGED
    
    | @@ -1,5 +1,5 @@ | |
| 1 1 | 
             
            class Beats
         | 
| 2 | 
            -
              BEATS_VERSION = "1.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 | 
            -
                 | 
| 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 | 
            -
               | 
| 141 | 
            -
             | 
| 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|  | 
| 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 |  | 
    
        data/test/audioengine_test.rb
    CHANGED
    
    
    
        data/test/audioutils_test.rb
    CHANGED
    
    
| @@ -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.
         | 
    
        data/test/integration_test.rb
    CHANGED
    
    | @@ -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 | 
| 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 | 
            -
                 | 
| 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 | 
            -
                 | 
| 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"))
         | 
    
        data/test/kit_test.rb
    CHANGED
    
    
    
        data/test/pattern_test.rb
    CHANGED
    
    
    
        data/test/song_test.rb
    CHANGED
    
    
    
        data/test/songoptimizer_test.rb
    CHANGED
    
    
    
        data/test/songparser_test.rb
    CHANGED
    
    
    
        data/test/track_test.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -2,7 +2,7 @@ | |
| 2 2 | 
             
            name: beats
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version 
         | 
| 4 4 | 
             
              prerelease: 
         | 
| 5 | 
            -
              version: 1.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:  | 
| 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. | 
| 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: 
         |