wavefile 0.5.0 → 0.6.0
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.
- checksums.yaml +6 -14
- data/README.markdown +8 -17
- data/lib/wavefile.rb +9 -9
- data/lib/wavefile/buffer.rb +61 -15
- data/lib/wavefile/duration.rb +34 -3
- data/lib/wavefile/format.rb +54 -8
- data/lib/wavefile/info.rb +34 -4
- data/lib/wavefile/reader.rb +57 -42
- data/lib/wavefile/writer.rb +39 -18
- data/test/buffer_test.rb +141 -0
- data/test/buffer_test.rbc +19560 -0
- data/test/duration_test.rbc +1536 -0
- data/test/fixtures/unsupported/unsupported_bits_per_sample.wav +0 -0
- data/test/fixtures/valid/valid_mono_pcm_16_44100_junk_chunk_with_padding_byte.wav +0 -0
- data/test/fixtures/valid/valid_mono_pcm_24_44100.wav +0 -0
- data/test/fixtures/valid/valid_stereo_pcm_24_44100.wav +0 -0
- data/test/fixtures/valid/valid_tri_pcm_24_44100.wav +0 -0
- data/test/format_test.rb +16 -0
- data/test/format_test.rbc +5325 -0
- data/test/info_test.rbc +759 -0
- data/test/reader_test.rb +12 -1
- data/test/reader_test.rbc +7927 -0
- data/test/wavefile_io_test_helper.rb +7 -0
- data/test/wavefile_io_test_helper.rbc +2013 -0
- data/test/writer_test.rbc +6105 -0
- metadata +16 -5
data/lib/wavefile/reader.rb
CHANGED
@@ -1,20 +1,33 @@
|
|
1
1
|
module WaveFile
|
2
|
-
# Error that is raised when trying to read from a file that is either not a wave file,
|
2
|
+
# Error that is raised when trying to read from a file that is either not a wave file,
|
3
3
|
# or that is not valid according to the wave file spec.
|
4
4
|
class InvalidFormatError < StandardError; end
|
5
5
|
|
6
|
-
# Error that is raised when trying to read from a valid wave file that has its sample data
|
6
|
+
# Error that is raised when trying to read from a valid wave file that has its sample data
|
7
7
|
# stored in a format that Reader doesn't understand.
|
8
8
|
class UnsupportedFormatError < StandardError; end
|
9
9
|
|
10
10
|
|
11
|
-
# Provides the ability to read sample data out of a wave file, as well as query a
|
11
|
+
# Provides the ability to read sample data out of a wave file, as well as query a
|
12
12
|
# wave file about its metadata (e.g. number of channels, sample rate, etc).
|
13
|
+
#
|
14
|
+
# When constructing a Reader a block can be given. All data should be read inside this
|
15
|
+
# block, and when the block exits the Reader will automatically be closed.
|
16
|
+
#
|
17
|
+
# Reader.new("my_file.wav") do |reader|
|
18
|
+
# # Read sample data here
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# Alternately, if a block isn't given you should make sure to call close when finished reading.
|
22
|
+
#
|
23
|
+
# reader = Reader.new("my_file.wav")
|
24
|
+
# # Read sample data here
|
25
|
+
# reader.close
|
13
26
|
class Reader
|
14
|
-
# Returns a Reader object that is ready to start reading the specified file's sample data.
|
27
|
+
# Returns a Reader object that is ready to start reading the specified file's sample data.
|
15
28
|
#
|
16
29
|
# file_name - The name of the wave file to read from.
|
17
|
-
# format - The format that read sample data should be returned in
|
30
|
+
# format - The format that read sample data should be returned in
|
18
31
|
# (default: the wave file's internal format).
|
19
32
|
#
|
20
33
|
# Returns a Reader object that is ready to start reading the specified file's sample data.
|
@@ -50,9 +63,9 @@ module WaveFile
|
|
50
63
|
end
|
51
64
|
|
52
65
|
|
53
|
-
# Reads metadata from the specified wave file and returns an Info object with the results.
|
54
|
-
# Metadata includes things like the number of channels, bits per sample, number of sample
|
55
|
-
# frames, sample encoding format (i.e. PCM, IEEE float, uLaw etc). See the Info object for
|
66
|
+
# Reads metadata from the specified wave file and returns an Info object with the results.
|
67
|
+
# Metadata includes things like the number of channels, bits per sample, number of sample
|
68
|
+
# frames, sample encoding format (i.e. PCM, IEEE float, uLaw etc). See the Info object for
|
56
69
|
# more detail on exactly what metadata is available.
|
57
70
|
#
|
58
71
|
# file_name - The name of the wave file to read from
|
@@ -74,17 +87,17 @@ module WaveFile
|
|
74
87
|
end
|
75
88
|
|
76
89
|
|
77
|
-
# Reads sample data of the into successive Buffers of the specified size, until there is no more
|
78
|
-
# sample data to be read. When all sample data has been read, the Reader is automatically closed.
|
90
|
+
# Reads sample data of the into successive Buffers of the specified size, until there is no more
|
91
|
+
# sample data to be read. When all sample data has been read, the Reader is automatically closed.
|
79
92
|
# Each Buffer is passed to the given block.
|
80
93
|
#
|
81
|
-
# Note that sample_frame_count indicates the number of sample frames to read, not number of samples.
|
82
|
-
# A sample frame include one sample for each channel. For example, if sample_frame_count is 1024, then
|
83
|
-
# for a stereo file 1024 samples will be read from the left channel, and 1024 samples will be read from
|
94
|
+
# Note that sample_frame_count indicates the number of sample frames to read, not number of samples.
|
95
|
+
# A sample frame include one sample for each channel. For example, if sample_frame_count is 1024, then
|
96
|
+
# for a stereo file 1024 samples will be read from the left channel, and 1024 samples will be read from
|
84
97
|
# the right channel.
|
85
98
|
#
|
86
|
-
# sample_frame_count - The number of sample frames to read into each Buffer from each channel. The number
|
87
|
-
# of sample frames read into the final Buffer could be less than this size, if there
|
99
|
+
# sample_frame_count - The number of sample frames to read into each Buffer from each channel. The number
|
100
|
+
# of sample frames read into the final Buffer could be less than this size, if there
|
88
101
|
# are not enough remaining.
|
89
102
|
#
|
90
103
|
# Returns nothing.
|
@@ -99,10 +112,10 @@ module WaveFile
|
|
99
112
|
end
|
100
113
|
|
101
114
|
|
102
|
-
# Reads the specified number of sample frames from the wave file into a Buffer. Note that the Buffer will have
|
115
|
+
# Reads the specified number of sample frames from the wave file into a Buffer. Note that the Buffer will have
|
103
116
|
# at most sample_frame_count sample frames, but could have less if the file doesn't have enough remaining.
|
104
117
|
#
|
105
|
-
# sample_frame_count - The number of sample frames to read. Note that each sample frame includes a sample for
|
118
|
+
# sample_frame_count - The number of sample frames to read. Note that each sample frame includes a sample for
|
106
119
|
# each channel.
|
107
120
|
#
|
108
121
|
# Returns a Buffer containing sample_frame_count sample frames
|
@@ -118,24 +131,18 @@ module WaveFile
|
|
118
131
|
samples = @file.sysread(sample_frame_count * @native_format.block_align).unpack(@pack_code)
|
119
132
|
@current_sample_frame += sample_frame_count
|
120
133
|
|
121
|
-
if @native_format.
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
# General algorithm that works for any number of channels, 2 or greater.
|
131
|
-
num_multichannel_samples.times do |i|
|
132
|
-
sample = Array.new(@native_format.channels)
|
133
|
-
@native_format.channels.times {|j| sample[j] = samples.pop }
|
134
|
-
multichannel_data[i] = sample.reverse!
|
135
|
-
end
|
136
|
-
end
|
134
|
+
if @native_format.bits_per_sample == 24
|
135
|
+
# Since the sample data is little endian, the 3 bytes will go from least->most significant
|
136
|
+
samples = samples.each_slice(3).map {|least_significant_byte, middle_byte, most_significant_byte|
|
137
|
+
# Convert the byte read as "C" to one read as "c"
|
138
|
+
most_significant_byte = [most_significant_byte].pack("c").unpack("c").first
|
139
|
+
|
140
|
+
(most_significant_byte << 16) | (middle_byte << 8) | least_significant_byte
|
141
|
+
}
|
142
|
+
end
|
137
143
|
|
138
|
-
|
144
|
+
if @native_format.channels > 1
|
145
|
+
samples = samples.each_slice(@native_format.channels).to_a
|
139
146
|
end
|
140
147
|
|
141
148
|
buffer = Buffer.new(samples, @native_format)
|
@@ -165,19 +172,19 @@ module WaveFile
|
|
165
172
|
# Returns the name of the Wave file that is being read
|
166
173
|
attr_reader :file_name
|
167
174
|
|
168
|
-
# Returns a Format object describing how sample data is being read from the Wave file (number of
|
169
|
-
# channels, sample format and bits per sample, etc). Note that this might be different from the
|
175
|
+
# Returns a Format object describing how sample data is being read from the Wave file (number of
|
176
|
+
# channels, sample format and bits per sample, etc). Note that this might be different from the
|
170
177
|
# underlying format of the Wave file on disk.
|
171
178
|
attr_reader :format
|
172
179
|
|
173
|
-
# Returns the index of the sample frame which is "cued up" for reading. I.e., the index
|
174
|
-
# of the next sample frame that will be read. A sample frame contains a single sample
|
175
|
-
# for each channel. So if there are 1,000 sample frames in a stereo file, this means
|
180
|
+
# Returns the index of the sample frame which is "cued up" for reading. I.e., the index
|
181
|
+
# of the next sample frame that will be read. A sample frame contains a single sample
|
182
|
+
# for each channel. So if there are 1,000 sample frames in a stereo file, this means
|
176
183
|
# there are 1,000 left-channel samples and 1,000 right-channel samples.
|
177
184
|
attr_reader :current_sample_frame
|
178
185
|
|
179
|
-
# Returns the total number of sample frames in the file. A sample frame contains a single
|
180
|
-
# sample for each channel. So if there are 1,000 sample frames in a stereo file, this means
|
186
|
+
# Returns the total number of sample frames in the file. A sample frame contains a single
|
187
|
+
# sample for each channel. So if there are 1,000 sample frames in a stereo file, this means
|
181
188
|
# there are 1,000 left-channel samples and 1,000 right-channel samples.
|
182
189
|
attr_reader :total_sample_frames
|
183
190
|
|
@@ -218,7 +225,7 @@ module WaveFile
|
|
218
225
|
# Used to read the RIFF chunks in a wave file up until the data chunk. Thus is can be used
|
219
226
|
# to open a wave file and "queue it up" to the start of the actual sample data, as well as
|
220
227
|
# extract information out of pre-data chunks, such as the format chunk.
|
221
|
-
class HeaderReader
|
228
|
+
class HeaderReader # :nodoc:
|
222
229
|
RIFF_CHUNK_HEADER_SIZE = 12
|
223
230
|
FORMAT_CHUNK_MINIMUM_SIZE = 16
|
224
231
|
|
@@ -237,6 +244,14 @@ module WaveFile
|
|
237
244
|
if chunk_id == CHUNK_IDS[:format]
|
238
245
|
format_chunk = read_format_chunk(chunk_id, chunk_size)
|
239
246
|
else
|
247
|
+
# The RIFF specification requires that each chunk be aligned to an even number of bytes,
|
248
|
+
# even if the byte count is an odd number.
|
249
|
+
#
|
250
|
+
# See http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Docs/riffmci.pdf, page 11.
|
251
|
+
if chunk_size.odd?
|
252
|
+
chunk_size += 1
|
253
|
+
end
|
254
|
+
|
240
255
|
# Other chunk types besides the format chunk are ignored. This may change in the future.
|
241
256
|
@file.sysread(chunk_size)
|
242
257
|
end
|
data/lib/wavefile/writer.rb
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
module WaveFile
|
2
2
|
# Provides the ability to write data to a wave file.
|
3
|
+
#
|
4
|
+
# When a Writer is constructed it can be given a block. All samples should be written inside this
|
5
|
+
# block, and when the block exits the file will automatically be closed:
|
6
|
+
#
|
7
|
+
# Writer.new("my_file.wav", Format.new(:mono, :pcm_16, 44100)) do |writer|
|
8
|
+
# # Write sample data here
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# If no block is given, you'll need to manually close the Writer when done. The underlaying
|
12
|
+
# file will not be valid or playable until close is called.
|
13
|
+
#
|
14
|
+
# writer = Writer.new("my_file.wav", Format.new(:mono, :pcm_16, 44100))
|
15
|
+
# # Write sample data here
|
16
|
+
# writer.close
|
3
17
|
class Writer
|
4
18
|
|
5
|
-
# Padding value written to the end of chunks whose payload is an odd number of bytes. The RIFF
|
6
|
-
# specification requires that each chunk be aligned to an even number of bytes, even if the byte
|
19
|
+
# Padding value written to the end of chunks whose payload is an odd number of bytes. The RIFF
|
20
|
+
# specification requires that each chunk be aligned to an even number of bytes, even if the byte
|
7
21
|
# count is an odd number.
|
8
22
|
#
|
9
23
|
# See http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Docs/riffmci.pdf, page 11.
|
10
|
-
EMPTY_BYTE = "\000"
|
24
|
+
EMPTY_BYTE = "\000" # :nodoc:
|
11
25
|
|
12
|
-
# The number of bytes at the beginning of a wave file before the sample data in the data chunk
|
26
|
+
# The number of bytes at the beginning of a wave file before the sample data in the data chunk
|
13
27
|
# starts, assuming this canonical format:
|
14
28
|
#
|
15
29
|
# RIFF Chunk Header (12 bytes)
|
@@ -18,16 +32,16 @@ module WaveFile
|
|
18
32
|
# Data Chunk Header (8 bytes)
|
19
33
|
#
|
20
34
|
# All wave files written by Writer use this canonical format.
|
21
|
-
CANONICAL_HEADER_BYTE_LENGTH = {:pcm => 36, :float => 50}
|
35
|
+
CANONICAL_HEADER_BYTE_LENGTH = {:pcm => 36, :float => 50} # :nodoc:
|
22
36
|
|
23
37
|
|
24
|
-
# Returns a constructed Writer object which is available for writing sample data to the specified
|
25
|
-
# file (via the write method). When all sample data has been written, the Writer should be closed.
|
26
|
-
# Note that the wave file being written to will NOT be valid (and playable in other programs) until
|
38
|
+
# Returns a constructed Writer object which is available for writing sample data to the specified
|
39
|
+
# file (via the write method). When all sample data has been written, the Writer should be closed.
|
40
|
+
# Note that the wave file being written to will NOT be valid (and playable in other programs) until
|
27
41
|
# the Writer has been closed.
|
28
42
|
#
|
29
|
-
# If a block is given to this method, sample data can be written inside the given block. When the
|
30
|
-
# block terminates, the Writer will be automatically closed (and no more sample data can be written).
|
43
|
+
# If a block is given to this method, sample data can be written inside the given block. When the
|
44
|
+
# block terminates, the Writer will be automatically closed (and no more sample data can be written).
|
31
45
|
#
|
32
46
|
# If no block is given, then sample data can be written until the close method is called.
|
33
47
|
def initialize(file_name, format)
|
@@ -60,7 +74,14 @@ module WaveFile
|
|
60
74
|
def write(buffer)
|
61
75
|
samples = buffer.convert(@format).samples
|
62
76
|
|
63
|
-
@
|
77
|
+
if @format.bits_per_sample == 24 && @format.sample_format == :pcm
|
78
|
+
samples.flatten.each do |sample|
|
79
|
+
@file.syswrite([sample].pack("lX"))
|
80
|
+
end
|
81
|
+
else
|
82
|
+
@file.syswrite(samples.flatten.pack(@pack_code))
|
83
|
+
end
|
84
|
+
|
64
85
|
@total_sample_frames += samples.length
|
65
86
|
end
|
66
87
|
|
@@ -73,10 +94,10 @@ module WaveFile
|
|
73
94
|
|
74
95
|
# Closes the Writer. After a Writer is closed, no more sample data can be written to it.
|
75
96
|
#
|
76
|
-
# Note that the wave file will NOT be valid until this method is called. The wave file
|
77
|
-
# format requires certain information about the amount of sample data, and this can't be
|
78
|
-
# determined until all samples have been written. (This method doesn't need to be called
|
79
|
-
# when passing a block to Writer.new, as this method will automatically be called when
|
97
|
+
# Note that the wave file will NOT be valid until this method is called. The wave file
|
98
|
+
# format requires certain information about the amount of sample data, and this can't be
|
99
|
+
# determined until all samples have been written. (This method doesn't need to be called
|
100
|
+
# when passing a block to Writer.new, as this method will automatically be called when
|
80
101
|
# the block exits).
|
81
102
|
#
|
82
103
|
# Returns nothing.
|
@@ -109,12 +130,12 @@ module WaveFile
|
|
109
130
|
# Returns the name of the Wave file that is being written to
|
110
131
|
attr_reader :file_name
|
111
132
|
|
112
|
-
# Returns a Format object describing the Wave file being written (number of channels, sample
|
133
|
+
# Returns a Format object describing the Wave file being written (number of channels, sample
|
113
134
|
# format and bits per sample, sample rate, etc.)
|
114
135
|
attr_reader :format
|
115
136
|
|
116
|
-
# Returns the number of samples (per channel) that have been written to the file so far.
|
117
|
-
# For example, if 1000 "left" samples and 1000 "right" samples have been written to a stereo file,
|
137
|
+
# Returns the number of samples (per channel) that have been written to the file so far.
|
138
|
+
# For example, if 1000 "left" samples and 1000 "right" samples have been written to a stereo file,
|
118
139
|
# this will return 1000.
|
119
140
|
attr_reader :total_sample_frames
|
120
141
|
|
data/test/buffer_test.rb
CHANGED
@@ -106,6 +106,22 @@ class BufferTest < Test::Unit::TestCase
|
|
106
106
|
b.samples)
|
107
107
|
end
|
108
108
|
|
109
|
+
def test_convert_buffer_bits_per_sample_8_to_24
|
110
|
+
# Mono
|
111
|
+
b = Buffer.new([0, 32, 64, 96, 128, 160, 192, 223, 255], Format.new(:mono, :pcm_8, 44100))
|
112
|
+
b.convert!(Format.new(:mono, :pcm_24, 44100))
|
113
|
+
assert_equal([-8388608, -6291456, -4194304, -2097152, 0, 2097152, 4194304, 6225920, 8323072], b.samples)
|
114
|
+
|
115
|
+
# Stereo
|
116
|
+
b = Buffer.new([[0, 255], [32, 223], [64, 192], [96, 160], [128, 128],
|
117
|
+
[160, 96], [192, 64], [223, 32], [255, 0]],
|
118
|
+
Format.new(:stereo, :pcm_8, 44100))
|
119
|
+
b.convert!(Format.new(:stereo, :pcm_24, 44100))
|
120
|
+
assert_equal([[-8388608, 8323072], [-6291456, 6225920], [-4194304, 4194304], [-2097152, 2097152], [0, 0],
|
121
|
+
[2097152, -2097152], [4194304, -4194304], [6225920, -6291456], [8323072, -8388608]],
|
122
|
+
b.samples)
|
123
|
+
end
|
124
|
+
|
109
125
|
def test_convert_buffer_bits_per_sample_8_to_32
|
110
126
|
# Mono
|
111
127
|
b = Buffer.new([0, 32, 64, 96, 128, 160, 192, 223, 255], Format.new(:mono, :pcm_8, 44100))
|
@@ -158,6 +174,22 @@ class BufferTest < Test::Unit::TestCase
|
|
158
174
|
b.samples)
|
159
175
|
end
|
160
176
|
|
177
|
+
def test_convert_buffer_bits_per_sample_16_to_24
|
178
|
+
# Mono
|
179
|
+
b = Buffer.new([-32768, -24576, -16384, -8192, 0, 8192, 16384, 24575, 32767], Format.new(:mono, :pcm_16, 44100))
|
180
|
+
b.convert!(Format.new(:mono, :pcm_24, 44100))
|
181
|
+
assert_equal([-8388608, -6291456, -4194304, -2097152, 0, 2097152, 4194304, 6291200, 8388352], b.samples)
|
182
|
+
|
183
|
+
# Stereo
|
184
|
+
b = Buffer.new([[-32768, 32767], [-24576, 24575], [-16384, 16384], [-8192, 8192], [0, 0],
|
185
|
+
[8192, -8192], [16384, -16384], [24575, -24576], [32767, -32768]],
|
186
|
+
Format.new(:stereo, :pcm_16, 44100))
|
187
|
+
b.convert!(Format.new(:stereo, :pcm_24, 44100))
|
188
|
+
assert_equal([[-8388608, 8388352], [-6291456, 6291200], [-4194304, 4194304], [-2097152, 2097152], [0, 0],
|
189
|
+
[2097152, -2097152], [4194304, -4194304], [6291200, -6291456], [8388352, -8388608]],
|
190
|
+
b.samples)
|
191
|
+
end
|
192
|
+
|
161
193
|
def test_convert_buffer_bits_per_sample_16_to_32
|
162
194
|
# Mono
|
163
195
|
b = Buffer.new([-32768, -24576, -16384, -8192, 0, 8192, 16384, 24575, 32767], Format.new(:mono, :pcm_16, 44100))
|
@@ -194,6 +226,78 @@ class BufferTest < Test::Unit::TestCase
|
|
194
226
|
end
|
195
227
|
end
|
196
228
|
|
229
|
+
def test_convert_buffer_bits_per_sample_24_to_8
|
230
|
+
# Mono
|
231
|
+
b = Buffer.new([-8388608, -6291456, -4194304, -2097152, 0, 2097152, 4194304, 6291455, 8388607],
|
232
|
+
Format.new(:mono, :pcm_24, 44100))
|
233
|
+
b.convert!(Format.new(:mono, :pcm_8, 44100))
|
234
|
+
assert_equal([0, 32, 64, 96, 128, 160, 192, 223, 255], b.samples)
|
235
|
+
|
236
|
+
# Stereo
|
237
|
+
b = Buffer.new([[-8388608, 8388607], [-6291456, 6291455], [-4194304, 4194304], [-2097152, 2097152], [0, 0],
|
238
|
+
[2097152, -2097152], [4194304, -4194304], [6291455, -6291456], [8388607, -8388608]],
|
239
|
+
Format.new(:stereo, :pcm_24, 44100))
|
240
|
+
b.convert!(Format.new(:stereo, :pcm_8, 44100))
|
241
|
+
assert_equal([[0, 255], [32, 223], [64, 192], [96, 160], [128, 128],
|
242
|
+
[160, 96], [192, 64], [223, 32], [255, 0]],
|
243
|
+
b.samples)
|
244
|
+
end
|
245
|
+
|
246
|
+
def test_convert_buffer_bits_per_sample_24_to_16
|
247
|
+
# Mono
|
248
|
+
b = Buffer.new([-8388608, -6291456, -4194304, -2097152, 0, 2097152, 4194304, 6291455, 8388607],
|
249
|
+
Format.new(:mono, :pcm_24, 44100))
|
250
|
+
b.convert!(Format.new(:mono, :pcm_16, 44100))
|
251
|
+
assert_equal([-32768, -24576, -16384, -8192, 0, 8192, 16384, 24575, 32767], b.samples)
|
252
|
+
|
253
|
+
# Stereo
|
254
|
+
b = Buffer.new([[-8388608, 8388607], [-6291456, 6291455], [-4194304, 4194304], [-2097152, 2097152], [0, 0],
|
255
|
+
[2097152, -2097152], [4194304, -4194304], [6291455, -6291456], [8388607, -8388608]],
|
256
|
+
Format.new(:stereo, :pcm_24, 44100))
|
257
|
+
b.convert!(Format.new(:stereo, :pcm_16, 44100))
|
258
|
+
assert_equal([[-32768, 32767], [-24576, 24575], [-16384, 16384], [-8192, 8192], [0, 0],
|
259
|
+
[8192, -8192], [16384, -16384], [24575, -24576], [32767, -32768]],
|
260
|
+
b.samples)
|
261
|
+
end
|
262
|
+
|
263
|
+
def test_convert_buffer_bits_per_sample_24_to_32
|
264
|
+
# Mono
|
265
|
+
b = Buffer.new([-8388608, -6291456, -4194304, -2097152, 0, 2097152, 4194304, 6291455, 8388607],
|
266
|
+
Format.new(:mono, :pcm_24, 44100))
|
267
|
+
b.convert!(Format.new(:mono, :pcm_32, 44100))
|
268
|
+
assert_equal([-2147483648, -1610612736, -1073741824, -536870912, 0, 536870912, 1073741824, 1610612480, 2147483392], b.samples)
|
269
|
+
|
270
|
+
# Stereo
|
271
|
+
b = Buffer.new([[-8388608, 8388607], [-6291456, 6291455], [-4194304, 4194304], [-2097152, 2097152], [0, 0],
|
272
|
+
[2097152, -2097152], [4194304, -4194304], [6291455, -6291456], [8388607, -8388608]],
|
273
|
+
Format.new(:stereo, :pcm_24, 44100))
|
274
|
+
b.convert!(Format.new(:stereo, :pcm_32, 44100))
|
275
|
+
assert_equal([[-2147483648, 2147483392], [-1610612736, 1610612480], [-1073741824, 1073741824], [-536870912, 536870912], [0, 0],
|
276
|
+
[536870912, -536870912], [1073741824, -1073741824], [1610612480, -1610612736], [2147483392, -2147483648]],
|
277
|
+
b.samples)
|
278
|
+
end
|
279
|
+
|
280
|
+
def test_convert_buffer_bits_per_sample_24_to_float
|
281
|
+
Format::SUPPORTED_BITS_PER_SAMPLE[:float].each do |bits_per_sample|
|
282
|
+
float_format = "float_#{bits_per_sample}".to_sym
|
283
|
+
|
284
|
+
# Mono
|
285
|
+
b = Buffer.new([-8388608, -6291456, -4194304, -2097152, 0, 2097152, 4194304, 6291455, 8388607],
|
286
|
+
Format.new(:mono, :pcm_24, 44100))
|
287
|
+
b.convert!(Format.new(:mono, float_format, 44100))
|
288
|
+
assert_equal([-1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.7499998807907104, 0.9999998807907104], b.samples)
|
289
|
+
|
290
|
+
# Stereo
|
291
|
+
b = Buffer.new([[-8388608, 8388607], [-6291456, 6291455], [-4194304, 4194304], [-2097152, 2097152], [0, 0],
|
292
|
+
[2097152, -2097152], [4194304, -4194304], [6291455, -6291456], [8388607, -8388608]],
|
293
|
+
Format.new(:stereo, :pcm_24, 44100))
|
294
|
+
b.convert!(Format.new(:stereo, float_format, 44100))
|
295
|
+
assert_equal([[-1.0, 0.9999998807907104], [-0.75, 0.7499998807907104 ], [-0.5, 0.5], [-0.25, 0.25], [0.0, 0.0],
|
296
|
+
[0.25, -0.25], [0.5, -0.5], [0.7499998807907104 , -0.75], [0.9999998807907104, -1.0]],
|
297
|
+
b.samples)
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
197
301
|
def test_convert_buffer_bits_per_sample_32_to_8
|
198
302
|
# Mono
|
199
303
|
b = Buffer.new([-2147483648, -1610612736, -1073741824, -536870912, 0, 536870912, 1073741824, 1610612735, 2147483647],
|
@@ -228,6 +332,23 @@ class BufferTest < Test::Unit::TestCase
|
|
228
332
|
b.samples)
|
229
333
|
end
|
230
334
|
|
335
|
+
def test_convert_buffer_bits_per_sample_32_to_24
|
336
|
+
# Mono
|
337
|
+
b = Buffer.new([-2147483648, -1610612736, -1073741824, -536870912, 0, 536870912, 1073741824, 1610612735, 2147483647],
|
338
|
+
Format.new(:mono, :pcm_32, 44100))
|
339
|
+
b.convert!(Format.new(:mono, :pcm_24, 44100))
|
340
|
+
assert_equal([-8388608, -6291456, -4194304, -2097152, 0, 2097152, 4194304, 6291455, 8388607], b.samples)
|
341
|
+
|
342
|
+
# Stereo
|
343
|
+
b = Buffer.new([[-2147483648, 2147483647], [-1610612736, 1610612735], [-1073741824, 1073741824], [-536870912, 536870912], [0, 0],
|
344
|
+
[536870912, -536870912], [1073741824, -1073741824], [1610612735, -1610612736], [2147483647, -2147483648]],
|
345
|
+
Format.new(:stereo, :pcm_32, 44100))
|
346
|
+
b.convert!(Format.new(:stereo, :pcm_24, 44100))
|
347
|
+
assert_equal([[-8388608, 8388607], [-6291456, 6291455], [-4194304, 4194304], [-2097152, 2097152], [0, 0],
|
348
|
+
[2097152, -2097152], [4194304, -4194304], [6291455, -6291456], [8388607, -8388608]],
|
349
|
+
b.samples)
|
350
|
+
end
|
351
|
+
|
231
352
|
def test_convert_buffer_bits_per_sample_32_to_float
|
232
353
|
Format::SUPPORTED_BITS_PER_SAMPLE[:float].each do |bits_per_sample|
|
233
354
|
float_format = "float_#{bits_per_sample}".to_sym
|
@@ -289,6 +410,26 @@ class BufferTest < Test::Unit::TestCase
|
|
289
410
|
end
|
290
411
|
end
|
291
412
|
|
413
|
+
def test_convert_buffer_bits_per_sample_float_to_24
|
414
|
+
Format::SUPPORTED_BITS_PER_SAMPLE[:float].each do |bits_per_sample|
|
415
|
+
float_format = "float_#{bits_per_sample}".to_sym
|
416
|
+
|
417
|
+
# Mono
|
418
|
+
b = Buffer.new([-1.0, -0.75, -0.5, -0.25, 0.0, 0.25, 0.5, 0.75, 1.0], Format.new(:mono, float_format, 44100))
|
419
|
+
b.convert!(Format.new(:mono, :pcm_24, 44100))
|
420
|
+
assert_equal([-8388607, -6291455, -4194304, -2097152, 0, 2097152, 4194304, 6291455, 8388607], b.samples)
|
421
|
+
|
422
|
+
# Stereo
|
423
|
+
b = Buffer.new([[-1.0, 1.0], [-0.75, 0.75], [-0.5, 0.5], [-0.25, 0.25], [0.0, 0.0],
|
424
|
+
[0.25, -0.25], [0.5, -0.5], [0.75, -0.75], [1.0, -1.0]],
|
425
|
+
Format.new(:stereo, float_format, 44100))
|
426
|
+
b.convert!(Format.new(:stereo, :pcm_24, 44100))
|
427
|
+
assert_equal([[-8388607, 8388607], [-6291455, 6291455], [-4194304, 4194304], [-2097152, 2097152], [0, 0],
|
428
|
+
[2097152, -2097152], [4194304, -4194304], [6291455, -6291455], [8388607, -8388607]],
|
429
|
+
b.samples)
|
430
|
+
end
|
431
|
+
end
|
432
|
+
|
292
433
|
def test_convert_buffer_bits_per_sample_float_to_32
|
293
434
|
Format::SUPPORTED_BITS_PER_SAMPLE[:float].each do |bits_per_sample|
|
294
435
|
float_format = "float_#{bits_per_sample}".to_sym
|