wavefile 0.4.0 → 0.5.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.
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