wavefile 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +15 -0
  2. data/LICENSE +1 -1
  3. data/README.markdown +71 -18
  4. data/lib/wavefile/buffer.rb +63 -39
  5. data/lib/wavefile/duration.rb +34 -0
  6. data/lib/wavefile/format.rb +42 -16
  7. data/lib/wavefile/info.rb +5 -38
  8. data/lib/wavefile/reader.rb +88 -61
  9. data/lib/wavefile/writer.rb +57 -25
  10. data/lib/wavefile.rb +6 -4
  11. data/test/buffer_test.rb +227 -37
  12. data/test/duration_test.rb +73 -0
  13. data/test/fixtures/actual_output/{valid_mono_8_44100_with_padding_byte.wav → valid_mono_pcm_8_44100_with_padding_byte.wav} +0 -0
  14. data/test/fixtures/{expected_output → valid}/no_samples.wav +0 -0
  15. data/test/fixtures/valid/valid_mono_float_32_44100.wav +0 -0
  16. data/test/fixtures/valid/valid_mono_float_64_44100.wav +0 -0
  17. data/test/fixtures/{expected_output/valid_mono_16_44100.wav → valid/valid_mono_pcm_16_44100.wav} +0 -0
  18. data/test/fixtures/{expected_output/valid_mono_32_44100.wav → valid/valid_mono_pcm_32_44100.wav} +0 -0
  19. data/test/fixtures/{expected_output/valid_mono_8_44100.wav → valid/valid_mono_pcm_8_44100.wav} +0 -0
  20. data/test/fixtures/{expected_output/valid_mono_8_44100_with_padding_byte.wav → valid/valid_mono_pcm_8_44100_with_padding_byte.wav} +0 -0
  21. data/test/fixtures/valid/valid_stereo_float_32_44100.wav +0 -0
  22. data/test/fixtures/valid/valid_stereo_float_64_44100.wav +0 -0
  23. data/test/fixtures/{expected_output/valid_stereo_16_44100.wav → valid/valid_stereo_pcm_16_44100.wav} +0 -0
  24. data/test/fixtures/{expected_output/valid_stereo_32_44100.wav → valid/valid_stereo_pcm_32_44100.wav} +0 -0
  25. data/test/fixtures/{expected_output/valid_stereo_8_44100.wav → valid/valid_stereo_pcm_8_44100.wav} +0 -0
  26. data/test/fixtures/valid/valid_tri_float_32_44100.wav +0 -0
  27. data/test/fixtures/valid/valid_tri_float_64_44100.wav +0 -0
  28. data/test/fixtures/{expected_output/valid_tri_16_44100.wav → valid/valid_tri_pcm_16_44100.wav} +0 -0
  29. data/test/fixtures/{expected_output/valid_tri_32_44100.wav → valid/valid_tri_pcm_32_44100.wav} +0 -0
  30. data/test/fixtures/{expected_output/valid_tri_8_44100.wav → valid/valid_tri_pcm_8_44100.wav} +0 -0
  31. data/test/format_test.rb +88 -58
  32. data/test/info_test.rb +9 -37
  33. data/test/reader_test.rb +160 -63
  34. data/test/wavefile_io_test_helper.rb +40 -30
  35. data/test/writer_test.rb +124 -37
  36. metadata +29 -31
  37. data/test/fixtures/valid/valid_mono_16_44100.wav +0 -0
  38. data/test/fixtures/valid/valid_mono_32_44100.wav +0 -0
  39. data/test/fixtures/valid/valid_mono_8_44100.wav +0 -0
  40. data/test/fixtures/valid/valid_mono_8_44100_with_padding_byte.wav +0 -0
  41. data/test/fixtures/valid/valid_stereo_16_44100.wav +0 -0
  42. data/test/fixtures/valid/valid_stereo_32_44100.wav +0 -0
  43. data/test/fixtures/valid/valid_stereo_8_44100.wav +0 -0
  44. data/test/fixtures/valid/valid_tri_16_44100.wav +0 -0
  45. data/test/fixtures/valid/valid_tri_32_44100.wav +0 -0
  46. data/test/fixtures/valid/valid_tri_8_44100.wav +0 -0
data/test/info_test.rb CHANGED
@@ -12,7 +12,7 @@ class InfoTest < Test::Unit::TestCase
12
12
  format_chunk = { :audio_format => 1, :channels => 2, :sample_rate => 44100,
13
13
  :byte_rate => 176400, :block_align => 4, :bits_per_sample => 16 }
14
14
  info = Info.new(FILE_NAME, format_chunk, 44100)
15
-
15
+
16
16
  assert_equal(FILE_NAME, info.file_name)
17
17
  assert_equal(1, info.audio_format)
18
18
  assert_equal(2, info.channels)
@@ -20,41 +20,13 @@ class InfoTest < Test::Unit::TestCase
20
20
  assert_equal(176400, info.byte_rate)
21
21
  assert_equal(4, info.block_align)
22
22
  assert_equal(16, info.bits_per_sample)
23
- assert_equal(44100, info.sample_count)
24
- assert_equal({:hours => 0, :minutes => 0, :seconds => 1, :milliseconds => 0}, info.duration)
25
- end
26
-
27
- def test_duration
28
- format_chunk = { :audio_format => 1, :channels => 2, :byte_rate => 176400, :block_align => 4, :bits_per_sample => 16 }
29
-
30
- # Test common sample rates (22050 and 44100), and some crazy arbitrary sample rate (12346)
31
- [22050, 44100, 12346].each do |sample_rate|
32
- format_chunk[:sample_rate] = sample_rate
33
-
34
- info = Info.new(FILE_NAME, format_chunk, 0)
35
- assert_equal({:hours => 0, :minutes => 0, :seconds => 0, :milliseconds => 0}, info.duration)
36
-
37
- info = Info.new(FILE_NAME, format_chunk, sample_rate / 2)
38
- assert_equal({:hours => 0, :minutes => 0, :seconds => 0, :milliseconds => 500}, info.duration)
39
-
40
- info = Info.new(FILE_NAME, format_chunk, sample_rate)
41
- assert_equal({:hours => 0, :minutes => 0, :seconds => 1, :milliseconds => 0}, info.duration)
42
-
43
- info = Info.new(FILE_NAME, format_chunk, sample_rate * SECONDS_IN_MINUTE)
44
- assert_equal({:hours => 0, :minutes => 1, :seconds => 0, :milliseconds => 0}, info.duration)
45
-
46
- info = Info.new(FILE_NAME, format_chunk, sample_rate * SECONDS_IN_HOUR)
47
- assert_equal({:hours => 1, :minutes => 0, :seconds => 0, :milliseconds => 0}, info.duration)
48
-
49
- info = Info.new(FILE_NAME, format_chunk, (sample_rate * SECONDS_IN_MINUTE) + sample_rate + (sample_rate / 2))
50
- assert_equal({:hours => 0, :minutes => 1, :seconds => 1, :milliseconds => 500}, info.duration)
51
- end
52
-
53
- # Test for when the number of hours is more than a day.
54
- format_chunk[:sample_rate] = 44100
55
- samples_per_hour = 44100 * 60 * 60
56
- info = Info.new(FILE_NAME, format_chunk, samples_per_hour * 25)
57
- assert_equal({:hours => 25, :minutes => 0, :seconds => 0, :milliseconds => 0}, info.duration)
23
+ assert_equal(44100, info.sample_frame_count)
24
+
25
+ assert_equal(0, info.duration.hours)
26
+ assert_equal(0, info.duration.minutes)
27
+ assert_equal(1, info.duration.seconds)
28
+ assert_equal(0, info.duration.milliseconds)
29
+ assert_equal(44100, info.duration.sample_frame_count)
30
+ assert_equal(44100, info.duration.sample_rate)
58
31
  end
59
32
  end
60
-
data/test/reader_test.rb CHANGED
@@ -9,7 +9,7 @@ class ReaderTest < Test::Unit::TestCase
9
9
 
10
10
  FIXTURE_ROOT_PATH = "test/fixtures"
11
11
 
12
-
12
+
13
13
  def test_nonexistent_file
14
14
  assert_raise(Errno::ENOENT) { Reader.new(fixture("i_do_not_exist.wav")) }
15
15
 
@@ -17,63 +17,77 @@ class ReaderTest < Test::Unit::TestCase
17
17
  end
18
18
 
19
19
  def test_invalid_formats
20
- # Reader.new() and Reader.info() should raise the same errors for invalid files,
21
- # so run the tests for both methods.
22
- [:new, :info].each do |method_name|
20
+ invalid_fixtures = [
23
21
  # File contains 0 bytes
24
- assert_raise(InvalidFormatError) { Reader.send(method_name, fixture("invalid/empty.wav")) }
22
+ "invalid/empty.wav",
25
23
 
26
24
  # File consists of "RIFF" and nothing else
27
- assert_raise(InvalidFormatError) { Reader.send(method_name, fixture("invalid/incomplete_riff_header.wav")) }
25
+ "invalid/incomplete_riff_header.wav",
28
26
 
29
27
  # First 4 bytes in the file are not "RIFF"
30
- assert_raise(InvalidFormatError) { Reader.send(method_name, fixture("invalid/bad_riff_header.wav")) }
28
+ "invalid/bad_riff_header.wav",
31
29
 
32
30
  # The format code in the RIFF header is not "WAVE"
33
- assert_raise(InvalidFormatError) { Reader.new(fixture("invalid/bad_wavefile_format.wav")) }
31
+ "invalid/bad_wavefile_format.wav",
34
32
 
35
33
  # The file consists of just a valid RIFF header
36
- assert_raise(InvalidFormatError) { Reader.new(fixture("invalid/no_format_chunk.wav")) }
34
+ "invalid/no_format_chunk.wav",
37
35
 
38
36
  # The format chunk has 0 bytes in it (despite the chunk size being 16)
39
- assert_raise(InvalidFormatError) { Reader.new(fixture("invalid/empty_format_chunk.wav")) }
37
+ "invalid/empty_format_chunk.wav",
40
38
 
41
39
  # The format chunk has some data, but not all of the minimum required.
42
- assert_raise(InvalidFormatError) { Reader.new(fixture("invalid/insufficient_format_chunk.wav")) }
40
+ "invalid/insufficient_format_chunk.wav",
43
41
 
44
42
  # The RIFF header and format chunk are OK, but there is no data chunk
45
- assert_raise(InvalidFormatError) { Reader.new(fixture("invalid/no_data_chunk.wav")) }
43
+ "invalid/no_data_chunk.wav",
44
+ ]
45
+
46
+ # Reader.new and Reader.info should raise the same errors for invalid files,
47
+ # so run the tests for both methods.
48
+ [:new, :info].each do |method_name|
49
+ invalid_fixtures.each do |fixture_name|
50
+ assert_raise(InvalidFormatError) { Reader.send(method_name, fixture(fixture_name)) }
51
+ end
46
52
  end
47
53
  end
48
54
 
49
55
  def test_unsupported_formats
50
- # Audio format is 2, which is not supported
51
- assert_raise(UnsupportedFormatError) { Reader.new(fixture("unsupported/unsupported_audio_format.wav")) }
56
+ unsupported_fixtures = [
57
+ # Audio format is 2, which is not supported
58
+ "unsupported/unsupported_audio_format.wav",
52
59
 
53
- # Bits per sample is 24, which is not supported
54
- assert_raise(UnsupportedFormatError) { Reader.new(fixture("unsupported/unsupported_bits_per_sample.wav")) }
60
+ # Bits per sample is 24, which is not supported
61
+ "unsupported/unsupported_bits_per_sample.wav",
55
62
 
56
- # Channel count is 0
57
- assert_raise(UnsupportedFormatError) { Reader.new(fixture("unsupported/bad_channel_count.wav")) }
63
+ # Channel count is 0
64
+ "unsupported/bad_channel_count.wav",
58
65
 
59
- # Sample rate is 0
60
- assert_raise(UnsupportedFormatError) { Reader.new(fixture("unsupported/bad_sample_rate.wav")) }
66
+ # Sample rate is 0
67
+ "unsupported/bad_sample_rate.wav",
68
+ ]
69
+
70
+ unsupported_fixtures.each do |fixture_name|
71
+ assert_raise(UnsupportedFormatError) { Reader.new(fixture(fixture_name)) }
72
+ end
61
73
  end
62
74
 
63
75
  def test_initialize
64
- format = Format.new(:stereo, 16, 22050)
76
+ format = Format.new(:stereo, :pcm_16, 22050)
65
77
 
66
- exhaustively_test do |channels, bits_per_sample|
67
- file_name = fixture("valid/valid_#{channels}_#{bits_per_sample}_44100.wav")
78
+ exhaustively_test do |channels, sample_format|
79
+ file_name = fixture("valid/valid_#{channels}_#{sample_format}_44100.wav")
68
80
 
69
81
  # Read native format
70
82
  reader = Reader.new(file_name)
71
83
  assert_equal(CHANNEL_ALIAS[channels], reader.format.channels)
72
- assert_equal(bits_per_sample, reader.format.bits_per_sample)
84
+ assert_equal(extract_bits_per_sample(sample_format), reader.format.bits_per_sample)
73
85
  assert_equal(44100, reader.format.sample_rate)
74
86
  assert_equal(false, reader.closed?)
75
87
  assert_equal(file_name, reader.file_name)
76
- reader.close()
88
+ assert_equal(0, reader.current_sample_frame)
89
+ assert_equal(2240, reader.total_sample_frames)
90
+ reader.close
77
91
 
78
92
  # Read a non-native format
79
93
  reader = Reader.new(file_name, format)
@@ -82,109 +96,119 @@ class ReaderTest < Test::Unit::TestCase
82
96
  assert_equal(22050, reader.format.sample_rate)
83
97
  assert_equal(false, reader.closed?)
84
98
  assert_equal(file_name, reader.file_name)
85
- reader.close()
99
+ assert_equal(0, reader.current_sample_frame)
100
+ assert_equal(2240, reader.total_sample_frames)
101
+ reader.close
86
102
 
87
103
  # Block is given.
88
104
  reader = Reader.new(file_name) {|reader| reader.read(1024) }
89
105
  assert_equal(CHANNEL_ALIAS[channels], reader.format.channels)
90
- assert_equal(bits_per_sample, reader.format.bits_per_sample)
106
+ assert_equal(extract_bits_per_sample(sample_format), reader.format.bits_per_sample)
91
107
  assert_equal(44100, reader.format.sample_rate)
92
108
  assert(reader.closed?)
93
109
  assert_equal(file_name, reader.file_name)
110
+ assert_equal(1024, reader.current_sample_frame)
111
+ assert_equal(2240, reader.total_sample_frames)
94
112
  end
95
113
  end
96
114
 
97
115
  def test_read_native_format
98
- exhaustively_test do |channels, bits_per_sample|
99
- buffers = read_file("valid/valid_#{channels}_#{bits_per_sample}_44100.wav", 1024)
116
+ exhaustively_test do |channels, sample_format|
117
+ buffers = read_file("valid/valid_#{channels}_#{sample_format}_44100.wav", 1024)
100
118
 
101
119
  assert_equal(3, buffers.length)
102
120
  assert_equal([1024, 1024, 192], buffers.map {|buffer| buffer.samples.length })
103
- assert_equal(SQUARE_WAVE_CYCLE[channels][bits_per_sample] * 128, buffers[0].samples)
104
- assert_equal(SQUARE_WAVE_CYCLE[channels][bits_per_sample] * 128, buffers[1].samples)
105
- assert_equal(SQUARE_WAVE_CYCLE[channels][bits_per_sample] * 24, buffers[2].samples)
121
+ assert_equal(SQUARE_WAVE_CYCLE[channels][sample_format] * 128, buffers[0].samples)
122
+ assert_equal(SQUARE_WAVE_CYCLE[channels][sample_format] * 128, buffers[1].samples)
123
+ assert_equal(SQUARE_WAVE_CYCLE[channels][sample_format] * 24, buffers[2].samples)
106
124
  end
107
125
  end
108
126
 
109
127
  def test_read_with_format_conversion
110
- buffers = read_file("valid/valid_mono_16_44100.wav", 1024, Format.new(:stereo, 8, 22100))
128
+ buffers = read_file("valid/valid_mono_pcm_16_44100.wav", 1024, Format.new(:stereo, :pcm_8, 22100))
111
129
 
112
130
  assert_equal(3, buffers.length)
113
131
  assert_equal([1024, 1024, 192], buffers.map {|buffer| buffer.samples.length })
114
- assert_equal(SQUARE_WAVE_CYCLE[:stereo][8] * 128, buffers[0].samples)
115
- assert_equal(SQUARE_WAVE_CYCLE[:stereo][8] * 128, buffers[1].samples)
116
- assert_equal(SQUARE_WAVE_CYCLE[:stereo][8] * 24, buffers[2].samples)
132
+ assert_equal(SQUARE_WAVE_CYCLE[:stereo][:pcm_8] * 128, buffers[0].samples)
133
+ assert_equal(SQUARE_WAVE_CYCLE[:stereo][:pcm_8] * 128, buffers[1].samples)
134
+ assert_equal(SQUARE_WAVE_CYCLE[:stereo][:pcm_8] * 24, buffers[2].samples)
117
135
  end
118
136
 
119
137
  def test_read_with_padding_byte
120
- buffers = read_file("valid/valid_mono_8_44100_with_padding_byte.wav", 1024)
138
+ buffers = read_file("valid/valid_mono_pcm_8_44100_with_padding_byte.wav", 1024)
121
139
 
122
140
  assert_equal(3, buffers.length)
123
141
  assert_equal([1024, 1024, 191], buffers.map {|buffer| buffer.samples.length })
124
- assert_equal(SQUARE_WAVE_CYCLE[:mono][8] * 128, buffers[0].samples)
125
- assert_equal(SQUARE_WAVE_CYCLE[:mono][8] * 128, buffers[1].samples)
126
- assert_equal((SQUARE_WAVE_CYCLE[:mono][8] * 23) + [88, 88, 88, 88, 167, 167, 167],
142
+ assert_equal(SQUARE_WAVE_CYCLE[:mono][:pcm_8] * 128, buffers[0].samples)
143
+ assert_equal(SQUARE_WAVE_CYCLE[:mono][:pcm_8] * 128, buffers[1].samples)
144
+ assert_equal((SQUARE_WAVE_CYCLE[:mono][:pcm_8] * 23) + [88, 88, 88, 88, 167, 167, 167],
127
145
  buffers[2].samples)
128
146
  end
129
147
 
130
148
  def test_each_buffer_no_block_given
131
- reader = Reader.new(fixture("valid/valid_mono_16_44100.wav"))
149
+ reader = Reader.new(fixture("valid/valid_mono_pcm_16_44100.wav"))
132
150
  assert_raise(LocalJumpError) { reader.each_buffer(1024) }
133
151
  end
134
152
 
135
153
  def test_each_buffer_native_format
136
- exhaustively_test do |channels, bits_per_sample|
137
- reader = Reader.new(fixture("valid/valid_#{channels}_#{bits_per_sample}_44100.wav"))
154
+ exhaustively_test do |channels, sample_format|
155
+ reader = Reader.new(fixture("valid/valid_#{channels}_#{sample_format}_44100.wav"))
138
156
 
139
157
  buffers = []
140
158
  reader.each_buffer(1024) {|buffer| buffers << buffer }
141
-
159
+
142
160
  assert(reader.closed?)
143
161
  assert_equal(3, buffers.length)
144
162
  assert_equal([1024, 1024, 192], buffers.map {|buffer| buffer.samples.length })
145
- assert_equal(SQUARE_WAVE_CYCLE[channels][bits_per_sample] * 128, buffers[0].samples)
146
- assert_equal(SQUARE_WAVE_CYCLE[channels][bits_per_sample] * 128, buffers[1].samples)
147
- assert_equal(SQUARE_WAVE_CYCLE[channels][bits_per_sample] * 24, buffers[2].samples)
163
+ assert_equal(SQUARE_WAVE_CYCLE[channels][sample_format] * 128, buffers[0].samples)
164
+ assert_equal(SQUARE_WAVE_CYCLE[channels][sample_format] * 128, buffers[1].samples)
165
+ assert_equal(SQUARE_WAVE_CYCLE[channels][sample_format] * 24, buffers[2].samples)
166
+ assert_equal(2240, reader.current_sample_frame)
167
+ assert_equal(2240, reader.total_sample_frames)
148
168
  end
149
169
  end
150
170
 
151
171
  def test_each_buffer_with_format_conversion
152
- reader = Reader.new(fixture("valid/valid_mono_16_44100.wav"), Format.new(:stereo, 8, 22050))
172
+ reader = Reader.new(fixture("valid/valid_mono_pcm_16_44100.wav"), Format.new(:stereo, :pcm_8, 22050))
153
173
  assert_equal(2, reader.format.channels)
154
174
  assert_equal(8, reader.format.bits_per_sample)
155
175
  assert_equal(22050, reader.format.sample_rate)
156
176
 
157
177
  buffers = []
158
178
  reader.each_buffer(1024) {|buffer| buffers << buffer }
159
-
179
+
160
180
  assert_equal(3, buffers.length)
161
181
  assert_equal([1024, 1024, 192], buffers.map {|buffer| buffer.samples.length })
162
- assert_equal(SQUARE_WAVE_CYCLE[:stereo][8] * 128, buffers[0].samples)
163
- assert_equal(SQUARE_WAVE_CYCLE[:stereo][8] * 128, buffers[1].samples)
164
- assert_equal(SQUARE_WAVE_CYCLE[:stereo][8] * 24, buffers[2].samples)
182
+ assert_equal(SQUARE_WAVE_CYCLE[:stereo][:pcm_8] * 128, buffers[0].samples)
183
+ assert_equal(SQUARE_WAVE_CYCLE[:stereo][:pcm_8] * 128, buffers[1].samples)
184
+ assert_equal(SQUARE_WAVE_CYCLE[:stereo][:pcm_8] * 24, buffers[2].samples)
185
+ assert_equal(2240, reader.current_sample_frame)
186
+ assert_equal(2240, reader.total_sample_frames)
165
187
  end
166
188
 
167
189
  def test_each_buffer_with_padding_byte
168
190
  buffers = []
169
- reader = Reader.new(fixture("valid/valid_mono_8_44100_with_padding_byte.wav"))
191
+ reader = Reader.new(fixture("valid/valid_mono_pcm_8_44100_with_padding_byte.wav"))
170
192
  reader.each_buffer(1024) {|buffer| buffers << buffer }
171
193
 
172
194
  assert_equal(3, buffers.length)
173
195
  assert_equal([1024, 1024, 191], buffers.map {|buffer| buffer.samples.length })
174
- assert_equal(SQUARE_WAVE_CYCLE[:mono][8] * 128, buffers[0].samples)
175
- assert_equal(SQUARE_WAVE_CYCLE[:mono][8] * 128, buffers[1].samples)
176
- assert_equal((SQUARE_WAVE_CYCLE[:mono][8] * 23) + [88, 88, 88, 88, 167, 167, 167],
196
+ assert_equal(SQUARE_WAVE_CYCLE[:mono][:pcm_8] * 128, buffers[0].samples)
197
+ assert_equal(SQUARE_WAVE_CYCLE[:mono][:pcm_8] * 128, buffers[1].samples)
198
+ assert_equal((SQUARE_WAVE_CYCLE[:mono][:pcm_8] * 23) + [88, 88, 88, 88, 167, 167, 167],
177
199
  buffers[2].samples)
200
+ assert_equal(2239, reader.current_sample_frame)
201
+ assert_equal(2239, reader.total_sample_frames)
178
202
  end
179
203
 
180
204
  def test_closed?
181
- reader = Reader.new(fixture("valid/valid_mono_16_44100.wav"))
205
+ reader = Reader.new(fixture("valid/valid_mono_pcm_16_44100.wav"))
182
206
  assert_equal(false, reader.closed?)
183
- reader.close()
207
+ reader.close
184
208
  assert(reader.closed?)
185
209
 
186
- # For Reader.each_buffer()
187
- reader = Reader.new(fixture("valid/valid_mono_16_44100.wav"))
210
+ # For Reader.each_buffer
211
+ reader = Reader.new(fixture("valid/valid_mono_pcm_16_44100.wav"))
188
212
  assert_equal(false, reader.closed?)
189
213
  reader.each_buffer(1024) do |buffer|
190
214
  # No-op
@@ -193,12 +217,73 @@ class ReaderTest < Test::Unit::TestCase
193
217
  end
194
218
 
195
219
  def test_read_after_close
196
- reader = Reader.new(fixture("valid/valid_mono_16_44100.wav"))
220
+ reader = Reader.new(fixture("valid/valid_mono_pcm_16_44100.wav"))
197
221
  buffer = reader.read(1024)
198
- reader.close()
222
+ reader.close
199
223
  assert_raise(IOError) { reader.read(1024) }
200
224
  end
201
225
 
226
+ def test_sample_counts_manual_reads
227
+ exhaustively_test do |channels, sample_format|
228
+ reader = Reader.new(fixture("valid/valid_#{channels}_#{sample_format}_44100.wav"))
229
+
230
+ assert_equal(0, reader.current_sample_frame)
231
+ assert_equal(2240, reader.total_sample_frames)
232
+ test_duration({:hours => 0, :minutes => 0, :seconds => 0, :milliseconds => 50, :sample_count => 2240},
233
+ reader.total_duration)
234
+
235
+
236
+ reader.read(1024)
237
+ assert_equal(1024, reader.current_sample_frame)
238
+ assert_equal(2240, reader.total_sample_frames)
239
+ test_duration({:hours => 0, :minutes => 0, :seconds => 0, :milliseconds => 50, :sample_count => 2240},
240
+ reader.total_duration)
241
+
242
+
243
+ reader.read(1024)
244
+ assert_equal(2048, reader.current_sample_frame)
245
+ assert_equal(2240, reader.total_sample_frames)
246
+ test_duration({:hours => 0, :minutes => 0, :seconds => 0, :milliseconds => 50, :sample_count => 2240},
247
+ reader.total_duration)
248
+
249
+
250
+ reader.read(192)
251
+ assert_equal(2240, reader.current_sample_frame)
252
+ assert_equal(2240, reader.total_sample_frames)
253
+ test_duration({:hours => 0, :minutes => 0, :seconds => 0, :milliseconds => 50, :sample_count => 2240},
254
+ reader.total_duration)
255
+
256
+
257
+ reader.close
258
+ assert_equal(2240, reader.current_sample_frame)
259
+ assert_equal(2240, reader.total_sample_frames)
260
+ test_duration({:hours => 0, :minutes => 0, :seconds => 0, :milliseconds => 50, :sample_count => 2240},
261
+ reader.total_duration)
262
+ end
263
+ end
264
+
265
+ def test_sample_counts_each_buffer
266
+ exhaustively_test do |channels, sample_format|
267
+ expected_results = [ 1024, 2048, 2240 ]
268
+
269
+ file_name = fixture("valid/valid_#{channels}_#{sample_format}_44100.wav")
270
+ reader = Reader.new(file_name)
271
+
272
+ assert_equal(0, reader.current_sample_frame)
273
+ assert_equal(2240, reader.total_sample_frames)
274
+
275
+ reader.each_buffer(1024) do |buffer|
276
+ expected_result = expected_results.slice!(0)
277
+
278
+ assert_equal(expected_result, reader.current_sample_frame)
279
+ assert_equal(2240, reader.total_sample_frames)
280
+ end
281
+
282
+ assert_equal(2240, reader.current_sample_frame)
283
+ assert_equal(2240, reader.total_sample_frames)
284
+ end
285
+ end
286
+
202
287
  private
203
288
 
204
289
  def read_file(file_name, buffer_size, format=nil)
@@ -210,7 +295,7 @@ private
210
295
  buffers << reader.read(buffer_size)
211
296
  end
212
297
  rescue EOFError
213
- reader.close()
298
+ reader.close
214
299
  end
215
300
 
216
301
  return buffers
@@ -219,4 +304,16 @@ private
219
304
  def fixture(fixture_name)
220
305
  return "#{FIXTURE_ROOT_PATH}/#{fixture_name}"
221
306
  end
307
+
308
+ def extract_bits_per_sample(sample_format)
309
+ sample_format.to_s.split("_").last.to_i
310
+ end
311
+
312
+ def test_duration(expected_hash, duration)
313
+ assert_equal(expected_hash[:hours], duration.hours)
314
+ assert_equal(expected_hash[:minutes], duration.minutes)
315
+ assert_equal(expected_hash[:seconds], duration.seconds)
316
+ assert_equal(expected_hash[:milliseconds], duration.milliseconds)
317
+ assert_equal(expected_hash[:sample_count], duration.sample_frame_count)
318
+ end
222
319
  end
@@ -4,43 +4,53 @@ module WaveFileIOTestHelper
4
4
  SQUARE_WAVE_CYCLE = {}
5
5
  SQUARE_WAVE_CYCLE[:mono] = {}
6
6
 
7
- SQUARE_WAVE_CYCLE[:mono][8] = [88, 88, 88, 88, 167, 167, 167, 167]
8
- SQUARE_WAVE_CYCLE[:mono][16] = [-10000, -10000, -10000, -10000, 10000, 10000, 10000, 10000]
9
- SQUARE_WAVE_CYCLE[:mono][32] = [-1000000000, -1000000000, -1000000000, -1000000000,
10
- 1000000000, 1000000000, 1000000000, 1000000000]
7
+ SQUARE_WAVE_CYCLE[:mono][:pcm_8] = [88, 88, 88, 88, 167, 167, 167, 167]
8
+ SQUARE_WAVE_CYCLE[:mono][:pcm_16] = [-10000, -10000, -10000, -10000, 10000, 10000, 10000, 10000]
9
+ SQUARE_WAVE_CYCLE[:mono][:pcm_32] = [-1000000000, -1000000000, -1000000000, -1000000000,
10
+ 1000000000, 1000000000, 1000000000, 1000000000]
11
+ SQUARE_WAVE_CYCLE[:mono][:float_32] = [-0.5, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5]
12
+ SQUARE_WAVE_CYCLE[:mono][:float_64] = SQUARE_WAVE_CYCLE[:mono][:float_32]
11
13
 
12
14
  SQUARE_WAVE_CYCLE[:stereo] = {}
13
- SQUARE_WAVE_CYCLE[:stereo][8] = [[88, 88], [88, 88], [88, 88], [88, 88],
14
- [167, 167], [167, 167], [167, 167], [167, 167]]
15
- SQUARE_WAVE_CYCLE[:stereo][16] = [[-10000, -10000], [-10000, -10000], [-10000, -10000], [-10000, -10000],
16
- [10000, 10000], [10000, 10000], [10000, 10000], [10000, 10000]]
17
- SQUARE_WAVE_CYCLE[:stereo][32] = [[-1000000000, -1000000000], [-1000000000, -1000000000],
18
- [-1000000000, -1000000000], [-1000000000, -1000000000],
19
- [ 1000000000, 1000000000], [ 1000000000, 1000000000],
20
- [ 1000000000, 1000000000], [ 1000000000, 1000000000]]
15
+ SQUARE_WAVE_CYCLE[:stereo][:pcm_8] = [[88, 88], [88, 88], [88, 88], [88, 88],
16
+ [167, 167], [167, 167], [167, 167], [167, 167]]
17
+ SQUARE_WAVE_CYCLE[:stereo][:pcm_16] = [[-10000, -10000], [-10000, -10000], [-10000, -10000], [-10000, -10000],
18
+ [10000, 10000], [10000, 10000], [10000, 10000], [10000, 10000]]
19
+ SQUARE_WAVE_CYCLE[:stereo][:pcm_32] = [[-1000000000, -1000000000], [-1000000000, -1000000000],
20
+ [-1000000000, -1000000000], [-1000000000, -1000000000],
21
+ [ 1000000000, 1000000000], [ 1000000000, 1000000000],
22
+ [ 1000000000, 1000000000], [ 1000000000, 1000000000]]
23
+ SQUARE_WAVE_CYCLE[:stereo][:float_32] = [[-0.5, -0.5], [-0.5, -0.5], [-0.5, -0.5], [-0.5, -0.5],
24
+ [0.5, 0.5], [0.5, 0.5], [0.5, 0.5], [0.5, 0.5]]
25
+ SQUARE_WAVE_CYCLE[:stereo][:float_64] = SQUARE_WAVE_CYCLE[:stereo][:float_32]
21
26
 
22
27
  SQUARE_WAVE_CYCLE[:tri] = {}
23
- SQUARE_WAVE_CYCLE[:tri][8] = [[88, 88, 88], [88, 88, 88], [88, 88, 88], [88, 88, 88],
28
+ SQUARE_WAVE_CYCLE[:tri][:pcm_8] = [[88, 88, 88], [88, 88, 88], [88, 88, 88], [88, 88, 88],
24
29
  [167, 167, 167], [167, 167, 167], [167, 167, 167], [167, 167, 167]]
25
- SQUARE_WAVE_CYCLE[:tri][16] = [[-10000, -10000, -10000], [-10000, -10000, -10000],
26
- [-10000, -10000, -10000], [-10000, -10000, -10000],
27
- [ 10000, 10000, 10000], [ 10000, 10000, 10000],
28
- [ 10000, 10000, 10000], [ 10000, 10000, 10000]]
29
- SQUARE_WAVE_CYCLE[:tri][32] = [[-1000000000, -1000000000, -1000000000],
30
- [-1000000000, -1000000000, -1000000000],
31
- [-1000000000, -1000000000, -1000000000],
32
- [-1000000000, -1000000000, -1000000000],
33
- [ 1000000000, 1000000000, 1000000000],
34
- [ 1000000000, 1000000000, 1000000000],
35
- [ 1000000000, 1000000000, 1000000000],
36
- [ 1000000000, 1000000000, 1000000000]]
37
-
38
-
39
- # Executes the given block against different combinations of number of channels and bits per sample.
30
+ SQUARE_WAVE_CYCLE[:tri][:pcm_16] = [[-10000, -10000, -10000], [-10000, -10000, -10000],
31
+ [-10000, -10000, -10000], [-10000, -10000, -10000],
32
+ [ 10000, 10000, 10000], [ 10000, 10000, 10000],
33
+ [ 10000, 10000, 10000], [ 10000, 10000, 10000]]
34
+ SQUARE_WAVE_CYCLE[:tri][:pcm_32] = [[-1000000000, -1000000000, -1000000000],
35
+ [-1000000000, -1000000000, -1000000000],
36
+ [-1000000000, -1000000000, -1000000000],
37
+ [-1000000000, -1000000000, -1000000000],
38
+ [ 1000000000, 1000000000, 1000000000],
39
+ [ 1000000000, 1000000000, 1000000000],
40
+ [ 1000000000, 1000000000, 1000000000],
41
+ [ 1000000000, 1000000000, 1000000000]]
42
+ SQUARE_WAVE_CYCLE[:tri][:float_32] = [[-0.5, -0.5, -0.5], [-0.5, -0.5, -0.5], [-0.5, -0.5, -0.5], [-0.5, -0.5, -0.5],
43
+ [0.5, 0.5, 0.5], [0.5, 0.5, 0.5], [0.5, 0.5, 0.5], [0.5, 0.5, 0.5]]
44
+ SQUARE_WAVE_CYCLE[:tri][:float_64] = SQUARE_WAVE_CYCLE[:tri][:float_32]
45
+
46
+
47
+ # Executes the given block against different combinations of number of channels and sample_format
40
48
  def exhaustively_test
41
49
  [:mono, :stereo, :tri].each do |channels|
42
- Format::SUPPORTED_BITS_PER_SAMPLE.each do |bits_per_sample|
43
- yield(channels, bits_per_sample)
50
+ [:pcm, :float].each do |sample_format|
51
+ Format::SUPPORTED_BITS_PER_SAMPLE[sample_format].each do |bits_per_sample|
52
+ yield(channels, "#{sample_format}_#{bits_per_sample}".to_sym)
53
+ end
44
54
  end
45
55
  end
46
56
  end