wavefile 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|