Class: WaveFile::Buffer

Inherits:
Object
  • Object
show all
Defined in:
lib/wavefile/buffer.rb

Overview

Public: Represents a collection of samples in a certain format (e.g. 16-bit mono Integer PCM). Reader returns sample data contained in Buffers, and Writer expects incoming sample data to be contained in a Buffer as well.

Contains methods to convert the sample data in the buffer to a different format.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(samples, format) ⇒ Buffer

Public: Creates a new Buffer.

samples - An array of samples. If the Format has 1 channel (i.e. is mono), this

should be a flat array of samples such as <code>[0.5, 0.4, -0.3, ...]</code>.
If the Format has 2 or more channels the array should include a sub-array for
each sample frame. For example, <code>[[0.5, 0.2], [0.1, 0.6], [-0.2, 0.4], ...]</code>
for a stereo file.

The individual samples should match the given format:

:pcm_8    - Integer between 0 and 255
:pcm_16   - Integer between -32_768 and 32_767
:pcm_24   - Integer between -8_388_608 and 8_388_607
:pcm_32   - Integer between 2_147_483_648 and 2_147_483_647
:float    - Float between -1.0 and 1.0
:float_32 - Float between -1.0 and 1.0
:float_64 - Float between -1.0 and 1.0

format - A Format instance which describes the sample format of the sample array.

Note that the sample array is not compared with the format to make sure
they match - you are on the honor system to make sure they do. If they
don't match, unexpected things will happen.

Examples

samples = ([0.5] * 50) + ([-0.5] * 50)   # A floating point 440Hz mono square wave
buffer = Buffer.new(samples, Format.new(:mono, :float, 44100)

samples = ([0.5, 0.5] * 50) + ([-0.5, -0.5] * 50)   # A 440Hz stereo square wave
buffer = Buffer.new(samples, Format.new(2, :float, 44100)

samples = ([16000] * 50) + ([-16000] * 50)   # A 16-bit PCM 440Hz mono square wave
buffer = Buffer.new(samples, Format.new(1, :pcm_16, 44100)

Returns a constructed Buffer.



51
52
53
54
# File 'lib/wavefile/buffer.rb', line 51

def initialize(samples, format)
  @samples = samples
  @format = format
end

Instance Attribute Details

#samplesObject (readonly)

Public: Returns the sample data contained in the Buffer as an Array. If the Format has 1 channel, the Array will be a flat list of samples. If the Format has 2 or more channels, the Array will include sub arrays for each sample frame, with a sample for each channel.

Examples

samples = mono_buffer.samples
# => [-0.5, 0.3, 0.2, -0.9, ...]

samples = stereo_buffer.samples
# => [[-0.2, 0.5], [0.1, 0.2], [-0.4, 0.7], [0.1, 0.2], ...]

samples = three_channel_buffer.samples
# => [[0.3, 0.5, 0.2], [-0.1, 0.2, -0.9], [0.2, 0.3, -0.4], [0.1, 0.2, -0.8], ...]


140
141
142
# File 'lib/wavefile/buffer.rb', line 140

def samples
  @samples
end

Instance Method Details

#bits_per_sampleObject

Public: Returns the bits per sample of the buffer’s sample data



115
116
117
# File 'lib/wavefile/buffer.rb', line 115

def bits_per_sample
  @format.bits_per_sample
end

#channelsObject

Public: Returns the number of channels the buffer’s sample data has



109
110
111
# File 'lib/wavefile/buffer.rb', line 109

def channels
  @format.channels
end

#convert(new_format) ⇒ Object

Public: Creates a new Buffer containing the sample data of this Buffer, but converted to a different format.

new_format - The format that the sample data should be converted to. If the new format

has a different number of channels than the original buffer format, the sample data
will be converted in the following way:

1 -> n: Each mono sample will be duplicated into the new number of channels.

n -> 1: Each sample in each sample frame will be averaged into a single sample.

(n > 2) -> 2: The first two channels will be kept, all other channels discarded.

other: Unsupported, will cause BufferConversionError to be raised.

Examples

new_format = Format.new(:mono, :pcm_16, 44100)
new_buffer = old_buffer.convert(new_format)

Returns a new Buffer; the existing Buffer is unmodified.

Raises BufferConversionError if the Buffer can’t be converted to the given format



80
81
82
83
# File 'lib/wavefile/buffer.rb', line 80

def convert(new_format)
  new_samples = convert_buffer(@samples.dup, @format, new_format)
  Buffer.new(new_samples, new_format)
end

#convert!(new_format) ⇒ Object

Public: Converts the sample data contained in the Buffer to a new format. The sample data is converted in place, so the existing Buffer is modified.

new_format - The format that the sample data should be converted to. See Buffer#create

for how samples will be mapped if the new number of channels differs from
the original number of channels.

Examples

new_format = Format.new(:mono, :pcm_16, 44100)
old_buffer.convert!(new_format)

Returns self.

Raises BufferConversionError if the Buffer can’t be converted to the given format



101
102
103
104
105
# File 'lib/wavefile/buffer.rb', line 101

def convert!(new_format)
  @samples = convert_buffer(@samples, @format, new_format)
  @format = new_format
  self
end

#sample_rateObject

Public: Returns the sample rate of the buffer’s sample data



121
122
123
# File 'lib/wavefile/buffer.rb', line 121

def sample_rate
  @format.sample_rate
end