class Beats::KitBuilder

Constants

BITS_PER_SAMPLE
SAMPLE_FORMAT
SAMPLE_RATE

Attributes

composite_replacements[R]

Public Class Methods

new(base_path) click to toggle source
# File lib/beats/kit_builder.rb, line 14
def initialize(base_path)
  @base_path = base_path
  @labels_to_filenames = {}
  @composite_replacements = {}
end

Public Instance Methods

add_item(label, filenames) click to toggle source
# File lib/beats/kit_builder.rb, line 20
def add_item(label, filenames)
  if filenames.is_a?(Array)
    if filenames.empty?
      raise SoundFileNotFoundError, "Kit sound '#{label}' is an empty composite sound (i.e. \"[]\"), which is not valid."
    end

    @composite_replacements[label] = []

    filenames.each do |filename|
      unless filename.is_a?(String)
        raise SoundFileNotFoundError, "Kit sound '#{label}' contains an invalid filename: '#{filename}'. It must be a value that will be parsed from YAML as a String."
      end
      composite_replacement = "#{label}-#{File.basename(filename, ".*")}"
      @labels_to_filenames[composite_replacement] = absolute_file_name(filename)
      @composite_replacements[label] << composite_replacement
    end
  else
    unless filenames.is_a?(String)
      raise SoundFileNotFoundError, "Kit sound '#{label}' has an invalid filename: '#{filenames}'. It must be a value that will be parsed from YAML as a String."
    end

    @labels_to_filenames[label] = absolute_file_name(filenames)
    @composite_replacements.delete(label)
  end
end
build_kit() click to toggle source
# File lib/beats/kit_builder.rb, line 50
def build_kit
  # Load each sample buffer
  filenames_to_buffers = {}
  @labels_to_filenames.values.uniq.each do |filename|
    filenames_to_buffers[filename] = load_sample_buffer(filename)
  end

  # Convert each buffer to the same sample format
  num_channels = filenames_to_buffers.values.map(&:channels).max || 1
  canonical_format = WaveFile::Format.new(num_channels, SAMPLE_FORMAT, SAMPLE_RATE)
  filenames_to_buffers.values.each {|buffer| buffer.convert!(canonical_format) }

  labels_to_buffers = {}
  @labels_to_filenames.each do |label, filename|
    labels_to_buffers[label] = filenames_to_buffers[filename].samples
  end
  labels_to_buffers[Kit::PLACEHOLDER_TRACK_NAME] = []

  Kit.new(labels_to_buffers, num_channels, BITS_PER_SAMPLE)
end
has_label?(label) click to toggle source
# File lib/beats/kit_builder.rb, line 46
def has_label?(label)
  @labels_to_filenames.keys.include?(label)
end

Private Instance Methods

absolute_file_name(filename) click to toggle source

Converts relative path into absolute path. Note that this will also handle expanding ~ on platforms that support that.

# File lib/beats/kit_builder.rb, line 77
def absolute_file_name(filename)
  File.expand_path(filename, @base_path)
end
load_sample_buffer(filename) click to toggle source
# File lib/beats/kit_builder.rb, line 81
def load_sample_buffer(filename)
  sample_buffer = nil

  begin
    reader = WaveFile::Reader.new(filename)
    reader.each_buffer(reader.total_sample_frames) do |buffer|
      sample_buffer = buffer
    end
  rescue Errno::ENOENT
    raise SoundFileNotFoundError, "Sound file `#{filename}` not found."
  rescue WaveFile::UnsupportedFormatError
    raise InvalidSoundFormatError, "Sound file `#{filename}` is not a supported *.wav format. Beats can use *.wav files with a sample format of 8/16/24/32 PCM or floating point."
  rescue WaveFile::InvalidFormatError
    raise InvalidSoundFormatError, "Sound file `#{filename}` is either not a sound file, or is in an unsupported format. Beats can use *.wav files with a sample format of 8/16/24/32 PCM or floating point."
  end

  sample_buffer
end