wavefile 0.8.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. checksums.yaml +5 -5
  2. data/LICENSE +1 -1
  3. data/README.markdown +33 -28
  4. data/Rakefile +2 -2
  5. data/lib/wavefile.rb +5 -5
  6. data/lib/wavefile/chunk_readers/format_chunk_reader.rb +1 -1
  7. data/lib/wavefile/duration.rb +1 -1
  8. data/lib/wavefile/format.rb +120 -29
  9. data/lib/wavefile/reader.rb +18 -16
  10. data/lib/wavefile/unvalidated_format.rb +51 -3
  11. data/lib/wavefile/writer.rb +74 -21
  12. data/test/buffer_test.rb +13 -10
  13. data/test/chunk_readers/format_chunk_reader_test.rb +40 -40
  14. data/test/fixtures/{invalid → wave/invalid}/bad_riff_header.wav +0 -0
  15. data/test/fixtures/{invalid → wave/invalid}/bad_wavefile_format.wav +0 -0
  16. data/test/fixtures/{invalid → wave/invalid}/empty.wav +0 -0
  17. data/test/fixtures/{invalid → wave/invalid}/empty_format_chunk.wav +0 -0
  18. data/test/fixtures/{invalid → wave/invalid}/incomplete_riff_header.wav +0 -0
  19. data/test/fixtures/{invalid → wave/invalid}/insufficient_format_chunk.wav +0 -0
  20. data/test/fixtures/{invalid → wave/invalid}/no_data_chunk.wav +0 -0
  21. data/test/fixtures/{invalid → wave/invalid}/no_format_chunk.wav +0 -0
  22. data/test/fixtures/{unsupported → wave/unsupported}/bad_audio_format.wav +0 -0
  23. data/test/fixtures/{unsupported → wave/unsupported}/bad_channel_count.wav +0 -0
  24. data/test/fixtures/{unsupported → wave/unsupported}/bad_sample_rate.wav +0 -0
  25. data/test/fixtures/{unsupported → wave/unsupported}/extensible_container_size_bigger_than_sample_size.wav +0 -0
  26. data/test/fixtures/wave/unsupported/extensible_unsupported_subformat_guid.wav +0 -0
  27. data/test/fixtures/{unsupported → wave/unsupported}/unsupported_audio_format.wav +0 -0
  28. data/test/fixtures/{unsupported → wave/unsupported}/unsupported_bits_per_sample.wav +0 -0
  29. data/test/fixtures/{valid → wave/valid}/no_samples.wav +0 -0
  30. data/test/fixtures/wave/valid/valid_extensible_20_pcm_16_44100_speaker_mapping_overflow.wav +0 -0
  31. data/test/fixtures/{valid → wave/valid}/valid_extensible_mono_float_32_44100.wav +0 -0
  32. data/test/fixtures/{valid → wave/valid}/valid_extensible_mono_float_64_44100.wav +0 -0
  33. data/test/fixtures/wave/valid/valid_extensible_mono_pcm_16_44100.wav +0 -0
  34. data/test/fixtures/wave/valid/valid_extensible_mono_pcm_16_44100_non_default_speaker_mapping.wav +0 -0
  35. data/test/fixtures/wave/valid/valid_extensible_mono_pcm_24_44100.wav +0 -0
  36. data/test/fixtures/wave/valid/valid_extensible_mono_pcm_32_44100.wav +0 -0
  37. data/test/fixtures/wave/valid/valid_extensible_mono_pcm_8_44100.wav +0 -0
  38. data/test/fixtures/{valid → wave/valid}/valid_extensible_stereo_float_32_44100.wav +0 -0
  39. data/test/fixtures/{valid → wave/valid}/valid_extensible_stereo_float_64_44100.wav +0 -0
  40. data/test/fixtures/wave/valid/valid_extensible_stereo_pcm_16_44100.wav +0 -0
  41. data/test/fixtures/wave/valid/valid_extensible_stereo_pcm_16_44100_center_right_speakers.wav +0 -0
  42. data/test/fixtures/wave/valid/valid_extensible_stereo_pcm_16_44100_more_speakers_than_channels.wav +0 -0
  43. data/test/fixtures/wave/valid/valid_extensible_stereo_pcm_16_44100_more_speakers_than_defined_by_spec.wav +0 -0
  44. data/test/fixtures/wave/valid/valid_extensible_stereo_pcm_16_44100_only_undefined_high_bit_speakers.wav +0 -0
  45. data/test/fixtures/wave/valid/valid_extensible_stereo_pcm_24_44100.wav +0 -0
  46. data/test/fixtures/wave/valid/valid_extensible_stereo_pcm_24_44100_incomplete_speaker_mapping.wav +0 -0
  47. data/test/fixtures/wave/valid/valid_extensible_stereo_pcm_24_44100_no_speaker_mapping.wav +0 -0
  48. data/test/fixtures/wave/valid/valid_extensible_stereo_pcm_32_44100.wav +0 -0
  49. data/test/fixtures/wave/valid/valid_extensible_stereo_pcm_8_44100.wav +0 -0
  50. data/test/fixtures/{valid → wave/valid}/valid_extensible_tri_float_32_44100.wav +0 -0
  51. data/test/fixtures/{valid → wave/valid}/valid_extensible_tri_float_64_44100.wav +0 -0
  52. data/test/fixtures/wave/valid/valid_extensible_tri_pcm_16_44100.wav +0 -0
  53. data/test/fixtures/wave/valid/valid_extensible_tri_pcm_16_44100_custom_speaker_mapping.wav +0 -0
  54. data/test/fixtures/wave/valid/valid_extensible_tri_pcm_24_44100.wav +0 -0
  55. data/test/fixtures/wave/valid/valid_extensible_tri_pcm_32_44100.wav +0 -0
  56. data/test/fixtures/wave/valid/valid_extensible_tri_pcm_8_44100.wav +0 -0
  57. data/test/fixtures/{valid → wave/valid}/valid_mono_float_32_44100.wav +0 -0
  58. data/test/fixtures/{valid → wave/valid}/valid_mono_float_64_44100.wav +0 -0
  59. data/test/fixtures/{valid → wave/valid}/valid_mono_pcm_16_44100.wav +0 -0
  60. data/test/fixtures/{valid → wave/valid}/valid_mono_pcm_16_44100_junk_chunk_with_padding_byte.wav +0 -0
  61. data/test/fixtures/wave/valid/valid_mono_pcm_16_44100_with_extension.wav +0 -0
  62. data/test/fixtures/{valid → wave/valid}/valid_mono_pcm_24_44100.wav +0 -0
  63. data/test/fixtures/{valid → wave/valid}/valid_mono_pcm_32_44100.wav +0 -0
  64. data/test/fixtures/{valid → wave/valid}/valid_mono_pcm_8_44100.wav +0 -0
  65. data/test/fixtures/{valid → wave/valid}/valid_mono_pcm_8_44100_with_padding_byte.wav +0 -0
  66. data/test/fixtures/{valid → wave/valid}/valid_stereo_float_32_44100.wav +0 -0
  67. data/test/fixtures/{valid → wave/valid}/valid_stereo_float_64_44100.wav +0 -0
  68. data/test/fixtures/{valid → wave/valid}/valid_stereo_pcm_16_44100.wav +0 -0
  69. data/test/fixtures/{valid → wave/valid}/valid_stereo_pcm_24_44100.wav +0 -0
  70. data/test/fixtures/{valid → wave/valid}/valid_stereo_pcm_32_44100.wav +0 -0
  71. data/test/fixtures/{valid → wave/valid}/valid_stereo_pcm_8_44100.wav +0 -0
  72. data/test/fixtures/{valid → wave/valid}/valid_tri_float_32_44100.wav +0 -0
  73. data/test/fixtures/{valid → wave/valid}/valid_tri_float_64_44100.wav +0 -0
  74. data/test/fixtures/{valid → wave/valid}/valid_tri_pcm_16_44100.wav +0 -0
  75. data/test/fixtures/{valid → wave/valid}/valid_tri_pcm_24_44100.wav +0 -0
  76. data/test/fixtures/{valid → wave/valid}/valid_tri_pcm_32_44100.wav +0 -0
  77. data/test/fixtures/{valid → wave/valid}/valid_tri_pcm_8_44100.wav +0 -0
  78. data/test/format_test.rb +189 -3
  79. data/test/reader_test.rb +179 -4
  80. data/test/unvalidated_format_test.rb +181 -6
  81. data/test/wavefile_io_test_helper.rb +11 -1
  82. data/test/writer_test.rb +246 -25
  83. metadata +70 -80
  84. data/test/fixtures/actual_output/total_duration_mono_float_32_44100.wav +0 -0
  85. data/test/fixtures/actual_output/total_duration_mono_float_64_44100.wav +0 -0
  86. data/test/fixtures/actual_output/total_duration_mono_pcm_16_44100.wav +0 -0
  87. data/test/fixtures/actual_output/total_duration_mono_pcm_24_44100.wav +0 -0
  88. data/test/fixtures/actual_output/total_duration_mono_pcm_32_44100.wav +0 -0
  89. data/test/fixtures/actual_output/total_duration_mono_pcm_8_44100.wav +0 -0
  90. data/test/fixtures/actual_output/total_duration_stereo_float_32_44100.wav +0 -0
  91. data/test/fixtures/actual_output/total_duration_stereo_float_64_44100.wav +0 -0
  92. data/test/fixtures/actual_output/total_duration_stereo_pcm_16_44100.wav +0 -0
  93. data/test/fixtures/actual_output/total_duration_stereo_pcm_24_44100.wav +0 -0
  94. data/test/fixtures/actual_output/total_duration_stereo_pcm_32_44100.wav +0 -0
  95. data/test/fixtures/actual_output/total_duration_stereo_pcm_8_44100.wav +0 -0
  96. data/test/fixtures/actual_output/total_duration_tri_float_32_44100.wav +0 -0
  97. data/test/fixtures/actual_output/total_duration_tri_float_64_44100.wav +0 -0
  98. data/test/fixtures/actual_output/total_duration_tri_pcm_16_44100.wav +0 -0
  99. data/test/fixtures/actual_output/total_duration_tri_pcm_24_44100.wav +0 -0
  100. data/test/fixtures/actual_output/total_duration_tri_pcm_32_44100.wav +0 -0
  101. data/test/fixtures/actual_output/total_duration_tri_pcm_8_44100.wav +0 -0
  102. data/test/fixtures/invalid/README.markdown +0 -10
  103. data/test/fixtures/unsupported/README.markdown +0 -6
  104. data/test/fixtures/unsupported/extensible_unsupported_subformat_guid.wav +0 -0
  105. data/test/fixtures/valid/README.markdown +0 -3
  106. data/test/fixtures/valid/valid_extensible_mono_pcm_16_44100.wav +0 -0
  107. data/test/fixtures/valid/valid_extensible_mono_pcm_24_44100.wav +0 -0
  108. data/test/fixtures/valid/valid_extensible_mono_pcm_32_44100.wav +0 -0
  109. data/test/fixtures/valid/valid_extensible_mono_pcm_8_44100.wav +0 -0
  110. data/test/fixtures/valid/valid_extensible_stereo_pcm_16_44100.wav +0 -0
  111. data/test/fixtures/valid/valid_extensible_stereo_pcm_24_44100.wav +0 -0
  112. data/test/fixtures/valid/valid_extensible_stereo_pcm_32_44100.wav +0 -0
  113. data/test/fixtures/valid/valid_extensible_stereo_pcm_8_44100.wav +0 -0
  114. data/test/fixtures/valid/valid_extensible_tri_pcm_16_44100.wav +0 -0
  115. data/test/fixtures/valid/valid_extensible_tri_pcm_24_44100.wav +0 -0
  116. data/test/fixtures/valid/valid_extensible_tri_pcm_32_44100.wav +0 -0
  117. data/test/fixtures/valid/valid_extensible_tri_pcm_8_44100.wav +0 -0
@@ -14,7 +14,7 @@ class FormatTest < Minitest::Test
14
14
  end
15
15
 
16
16
  def test_invalid_channels
17
- ["dsfsfsdf", :foo, 0, -1, 65536].each do |invalid_channels|
17
+ ["dsfsfsdf", :foo, 0, -1, 65536, 2.5, 2.0].each do |invalid_channels|
18
18
  assert_raises(InvalidFormatError) { Format.new(invalid_channels, :pcm_16, 44100) }
19
19
  end
20
20
  end
@@ -52,11 +52,197 @@ class FormatTest < Minitest::Test
52
52
  end
53
53
 
54
54
  def test_invalid_sample_rate
55
- ["dsfsfsdf", :foo, 0, -1, 4294967297].each do |invalid_sample_rate|
55
+ ["dsfsfsdf", :foo, 0, -1, 4294967297, 44100.5, 44100.0].each do |invalid_sample_rate|
56
56
  assert_raises(InvalidFormatError) { Format.new(:mono, :pcm_16, invalid_sample_rate) }
57
57
  end
58
58
  end
59
59
 
60
+ def test_no_speaker_mapping_set_in_constructor_mono
61
+ assert_equal([:front_center], Format.new(:mono, :pcm_8, 44100).speaker_mapping)
62
+ end
63
+
64
+ def test_no_speaker_mapping_set_in_constructor__stereo
65
+ assert_equal([:front_left, :front_right], Format.new(:stereo, :pcm_8, 44100).speaker_mapping)
66
+ end
67
+
68
+ def test_no_speaker_mapping_set_in_constructor_3_channel
69
+ assert_equal([:front_left, :front_right, :front_center], Format.new(3, :pcm_8, 44100).speaker_mapping)
70
+ end
71
+
72
+ def test_no_speaker_mapping_set_in_constructor_4_channel
73
+ assert_equal([:front_left, :front_right, :back_left, :back_right], Format.new(4, :pcm_8, 44100).speaker_mapping)
74
+ end
75
+
76
+ def test_no_speaker_mapping_set_in_constructor_5_channel
77
+ expected_speaker_mapping = [:front_left, :front_right, :front_center, :back_left, :back_right]
78
+
79
+ assert_equal(expected_speaker_mapping, Format.new(5, :pcm_8, 44100).speaker_mapping)
80
+ end
81
+
82
+ def test_no_speaker_mapping_set_in_constructor_6_channel
83
+ expected_speaker_mapping = [:front_left,
84
+ :front_right,
85
+ :front_center,
86
+ :low_frequency,
87
+ :back_left,
88
+ :back_right]
89
+
90
+ assert_equal(expected_speaker_mapping, Format.new(6, :pcm_8, 44100).speaker_mapping)
91
+ end
92
+
93
+ def test_no_speaker_mapping_set_in_constructor_7_channel
94
+ expected_speaker_mapping = [:front_left,
95
+ :front_right,
96
+ :front_center,
97
+ :low_frequency,
98
+ :back_center,
99
+ :side_left,
100
+ :side_right]
101
+
102
+ assert_equal(expected_speaker_mapping, Format.new(7, :pcm_8, 44100).speaker_mapping)
103
+ end
104
+
105
+ def test_no_speaker_mapping_set_in_constructor_8_channel
106
+ expected_speaker_mapping = [:front_left,
107
+ :front_right,
108
+ :front_center,
109
+ :low_frequency,
110
+ :back_left,
111
+ :back_right,
112
+ :front_left_of_center,
113
+ :front_right_of_center]
114
+
115
+ assert_equal(expected_speaker_mapping, Format.new(8, :pcm_8, 44100).speaker_mapping)
116
+ end
117
+
118
+ def test_no_speaker_mapping_set_in_constructor_9_channel
119
+ expected_speaker_mapping = [:front_left,
120
+ :front_right,
121
+ :front_center,
122
+ :low_frequency,
123
+ :back_left,
124
+ :back_right,
125
+ :front_left_of_center,
126
+ :front_right_of_center,
127
+ :back_center]
128
+
129
+ assert_equal(expected_speaker_mapping, Format.new(9, :pcm_8, 44100).speaker_mapping)
130
+ end
131
+
132
+ def test_no_speaker_mapping_set_in_constructor_18_channel
133
+ expected_speaker_mapping = [
134
+ :front_left,
135
+ :front_right,
136
+ :front_center,
137
+ :low_frequency,
138
+ :back_left,
139
+ :back_right,
140
+ :front_left_of_center,
141
+ :front_right_of_center,
142
+ :back_center,
143
+ :side_left,
144
+ :side_right,
145
+ :top_center,
146
+ :top_front_left,
147
+ :top_front_center,
148
+ :top_front_right,
149
+ :top_back_left,
150
+ :top_back_center,
151
+ :top_back_right,
152
+ ]
153
+
154
+ assert_equal(expected_speaker_mapping, Format.new(18, :pcm_8, 44100).speaker_mapping)
155
+ end
156
+
157
+ def test_no_speaker_mapping_set_in_constructor_20_channel
158
+ expected_speaker_mapping = [
159
+ :front_left,
160
+ :front_right,
161
+ :front_center,
162
+ :low_frequency,
163
+ :back_left,
164
+ :back_right,
165
+ :front_left_of_center,
166
+ :front_right_of_center,
167
+ :back_center,
168
+ :side_left,
169
+ :side_right,
170
+ :top_center,
171
+ :top_front_left,
172
+ :top_front_center,
173
+ :top_front_right,
174
+ :top_back_left,
175
+ :top_back_center,
176
+ :top_back_right,
177
+ :undefined,
178
+ :undefined,
179
+ ]
180
+
181
+ assert_equal(expected_speaker_mapping, Format.new(20, :pcm_8, 44100).speaker_mapping)
182
+ end
183
+
184
+ def test_defined_speaker_mapping_in_constructor
185
+ assert_equal([:front_left, :front_right], Format.new(:stereo, :pcm_8, 44100, speaker_mapping: [:front_left, :front_right]).speaker_mapping)
186
+ end
187
+
188
+ def test_defined_speaker_mapping_with_explicitly_undefined_channels_in_constructor
189
+ assert_equal([:front_left, :undefined, :undefined], Format.new(3, :pcm_8, 44100, speaker_mapping: [:front_left, :undefined, :undefined]).speaker_mapping)
190
+ end
191
+
192
+ def test_defined_speaker_mapping_with_implicitly_undefined_channels_in_constructor
193
+ assert_equal([:front_left, :undefined, :undefined], Format.new(3, :pcm_8, 44100, speaker_mapping: [:front_left]).speaker_mapping)
194
+ end
195
+
196
+ def test_extra_valid_speaker_mapping_fields_in_constructor
197
+ assert_raises(InvalidFormatError) do
198
+ Format.new(2, :pcm_8, 44100, speaker_mapping: [:front_left, :front_right, :front_center, :low_frequency])
199
+ end
200
+ end
201
+
202
+ def test_extra_undefined_speaker_mapping_fields_in_constructor
203
+ assert_raises(InvalidFormatError) do
204
+ Format.new(2, :pcm_8, 44100, speaker_mapping: [:front_left, :front_right, :undefined, :undefined])
205
+ end
206
+ end
207
+
208
+ def test_extra_invalid_speaker_mapping_fields_in_constructor
209
+ assert_raises(InvalidFormatError) do
210
+ Format.new(2, :pcm_8, 44100, speaker_mapping: [:front_left, :front_right, :gibberish, :what_is_this])
211
+ end
212
+ end
213
+
214
+ def test_speaker_mapping_is_frozen_copy
215
+ original_speaker_mapping = [:front_left, :front_right]
216
+
217
+ format = Format.new(:stereo, :pcm_16, 44100, speaker_mapping: original_speaker_mapping)
218
+
219
+ # Changing the original input array after constructing the `Format` doesn't change the `Format` speaker mapping
220
+ assert_equal([:front_left, :front_right], format.speaker_mapping)
221
+ original_speaker_mapping.push(:front_center)
222
+ assert_equal([:front_left, :front_right], format.speaker_mapping)
223
+
224
+ # Changing the underlaying Array should raise an error, since the Array should be frozen
225
+ assert_raises(RuntimeError) { format.speaker_mapping.push(:front_center) }
226
+ end
227
+
228
+ def test_invalid_speaker_mapping
229
+ mapping_with_invalid_speaker = [:front_left, :bad_speaker]
230
+ mapping_with_duplicate_speaker = [:front_left, :front_right, :front_left]
231
+ mapping_with_out_of_order_speakers = [:front_center, :front_left, :front_right]
232
+ mapping_with_out_of_order_speakers_2 = [:undefined, :front_left, :front_right]
233
+ mapping_with_out_of_order_speakers_3 = [:front_left, :undefined, :front_right]
234
+
235
+ assert_raises(InvalidFormatError) { Format.new(:stereo, :pcm_16, 44100, speaker_mapping: mapping_with_invalid_speaker) }
236
+ assert_raises(InvalidFormatError) { Format.new(3, :pcm_16, 44100, speaker_mapping: mapping_with_duplicate_speaker) }
237
+ assert_raises(InvalidFormatError) { Format.new(3, :pcm_16, 44100, speaker_mapping: mapping_with_out_of_order_speakers) }
238
+ assert_raises(InvalidFormatError) { Format.new(3, :pcm_16, 44100, speaker_mapping: mapping_with_out_of_order_speakers_2) }
239
+ assert_raises(InvalidFormatError) { Format.new(3, :pcm_16, 44100, speaker_mapping: mapping_with_out_of_order_speakers_3) }
240
+
241
+ ["dsfsfsdf", :foo, 5].each do |invalid_speaker_mapping|
242
+ assert_raises(InvalidFormatError) { Format.new(:mono, :pcm_16, 44100, speaker_mapping: invalid_speaker_mapping) }
243
+ end
244
+ end
245
+
60
246
  def test_byte_and_block_align
61
247
  [1, :mono].each do |one_channel|
62
248
  format = Format.new(one_channel, :pcm_8, 44100)
@@ -79,7 +265,7 @@ class FormatTest < Minitest::Test
79
265
 
80
266
  format = Format.new(one_channel, :float_64, 44100)
81
267
  assert_equal(352800, format.byte_rate)
82
- assert_equal(8, format.block_align)
268
+ assert_equal(8, format.block_align)
83
269
  end
84
270
 
85
271
  [2, :stereo].each do |two_channels|
@@ -7,7 +7,7 @@ include WaveFile
7
7
  class ReaderTest < Minitest::Test
8
8
  include WaveFileIOTestHelper
9
9
 
10
- FIXTURE_ROOT_PATH = "test/fixtures"
10
+ FIXTURE_ROOT_PATH = "test/fixtures/wave"
11
11
 
12
12
 
13
13
  def test_nonexistent_file
@@ -59,9 +59,11 @@ class ReaderTest < Minitest::Test
59
59
  assert_equal(2, reader.native_format.channels)
60
60
  assert_equal(20, reader.native_format.bits_per_sample)
61
61
  assert_equal(44100, reader.native_format.sample_rate)
62
+ assert_nil(reader.format.speaker_mapping)
62
63
  assert_equal(2, reader.format.channels)
63
64
  assert_equal(20, reader.format.bits_per_sample)
64
65
  assert_equal(44100, reader.format.sample_rate)
66
+ assert_nil(reader.format.speaker_mapping)
65
67
  assert_equal(false, reader.closed?)
66
68
  assert_equal(0, reader.current_sample_frame)
67
69
  assert_equal(2240, reader.total_sample_frames)
@@ -75,9 +77,11 @@ class ReaderTest < Minitest::Test
75
77
  assert_equal(2, reader.native_format.channels)
76
78
  assert_equal(20, reader.native_format.bits_per_sample)
77
79
  assert_equal(44100, reader.native_format.sample_rate)
80
+ assert_nil(reader.native_format.speaker_mapping)
78
81
  assert_equal(1, reader.format.channels)
79
82
  assert_equal(16, reader.format.bits_per_sample)
80
83
  assert_equal(22050, reader.format.sample_rate)
84
+ assert_equal([:front_center], reader.format.speaker_mapping)
81
85
  assert_equal(false, reader.closed?)
82
86
  assert_equal(0, reader.current_sample_frame)
83
87
  assert_equal(2240, reader.total_sample_frames)
@@ -198,9 +202,11 @@ class ReaderTest < Minitest::Test
198
202
  assert_equal(2, reader.native_format.channels)
199
203
  assert_equal(16, reader.native_format.bits_per_sample)
200
204
  assert_equal(44100, reader.native_format.sample_rate)
205
+ assert_equal([:front_left, :front_right], reader.native_format.speaker_mapping)
201
206
  assert_equal(2, reader.format.channels)
202
207
  assert_equal(16, reader.format.bits_per_sample)
203
208
  assert_equal(44100, reader.format.sample_rate)
209
+ assert_equal([:front_left, :front_right], reader.format.speaker_mapping)
204
210
  assert_equal(false, reader.closed?)
205
211
  assert_equal(0, reader.current_sample_frame)
206
212
  assert_equal(2240, reader.total_sample_frames)
@@ -216,6 +222,157 @@ class ReaderTest < Minitest::Test
216
222
  assert_equal(SQUARE_WAVE_CYCLE[channels][sample_format] * 24, buffers[2].samples)
217
223
  end
218
224
 
225
+ def test_read_extensible_no_speaker_mapping
226
+ reader = Reader.new(fixture("valid/valid_extensible_stereo_pcm_24_44100_no_speaker_mapping.wav"))
227
+
228
+ assert_equal(2, reader.native_format.channels)
229
+ assert_equal(24, reader.native_format.bits_per_sample)
230
+ assert_equal(44100, reader.native_format.sample_rate)
231
+ assert_equal([:undefined, :undefined], reader.native_format.speaker_mapping)
232
+ assert_equal(2, reader.format.channels)
233
+ assert_equal(24, reader.format.bits_per_sample)
234
+ assert_equal(44100, reader.format.sample_rate)
235
+ assert_equal([:undefined, :undefined], reader.format.speaker_mapping)
236
+ assert_equal(false, reader.closed?)
237
+ assert_equal(0, reader.current_sample_frame)
238
+ assert_equal(2240, reader.total_sample_frames)
239
+ assert_equal(true, reader.readable_format?)
240
+ reader.close
241
+
242
+ buffers = read_file("valid/valid_extensible_stereo_pcm_24_44100_no_speaker_mapping.wav", 1024)
243
+
244
+ assert_equal(3, buffers.length)
245
+ assert_equal([1024, 1024, 192], buffers.map {|buffer| buffer.samples.length })
246
+ assert_equal(SQUARE_WAVE_CYCLE[:stereo][:pcm_24] * 128, buffers[0].samples)
247
+ assert_equal(SQUARE_WAVE_CYCLE[:stereo][:pcm_24] * 128, buffers[1].samples)
248
+ assert_equal(SQUARE_WAVE_CYCLE[:stereo][:pcm_24] * 24, buffers[2].samples)
249
+ end
250
+
251
+ def test_read_extensible_more_speakers_than_channels
252
+ reader = Reader.new(fixture("valid/valid_extensible_stereo_pcm_16_44100_more_speakers_than_channels.wav"))
253
+
254
+ assert_equal(2, reader.native_format.channels)
255
+ assert_equal(16, reader.native_format.bits_per_sample)
256
+ assert_equal(44100, reader.native_format.sample_rate)
257
+ assert_equal([:front_left, :front_right, :front_center, :low_frequency], reader.native_format.speaker_mapping)
258
+ assert_equal(2, reader.format.channels)
259
+ assert_equal(16, reader.format.bits_per_sample)
260
+ assert_equal(44100, reader.format.sample_rate)
261
+ assert_equal([:front_left, :front_right], reader.format.speaker_mapping)
262
+ assert_equal(false, reader.closed?)
263
+ assert_equal(0, reader.current_sample_frame)
264
+ assert_equal(2240, reader.total_sample_frames)
265
+ assert_equal(true, reader.readable_format?)
266
+ reader.close
267
+
268
+ buffers = read_file("valid/valid_extensible_stereo_pcm_16_44100_more_speakers_than_channels.wav", 1024)
269
+
270
+ assert_equal(3, buffers.length)
271
+ assert_equal([1024, 1024, 192], buffers.map {|buffer| buffer.samples.length })
272
+ assert_equal(SQUARE_WAVE_CYCLE[:stereo][:pcm_16] * 128, buffers[0].samples)
273
+ assert_equal(SQUARE_WAVE_CYCLE[:stereo][:pcm_16] * 128, buffers[1].samples)
274
+ assert_equal(SQUARE_WAVE_CYCLE[:stereo][:pcm_16] * 24, buffers[2].samples)
275
+ end
276
+
277
+ def test_read_extensible_more_speakers_than_defined_by_spec
278
+ reader = Reader.new(fixture("valid/valid_extensible_stereo_pcm_16_44100_more_speakers_than_defined_by_spec.wav"))
279
+
280
+ assert_equal(2, reader.native_format.channels)
281
+ assert_equal(16, reader.native_format.bits_per_sample)
282
+ assert_equal(44100, reader.native_format.sample_rate)
283
+ # Extra bits for speakers beyond the first 18 are set in the file, but these bits should be ignored
284
+ assert_equal([:front_left,
285
+ :front_right,
286
+ :front_center,
287
+ :low_frequency,
288
+ :back_left,
289
+ :back_right,
290
+ :front_left_of_center,
291
+ :front_right_of_center,
292
+ :back_center,
293
+ :side_left,
294
+ :side_right,
295
+ :top_center,
296
+ :top_front_left,
297
+ :top_front_center,
298
+ :top_front_right,
299
+ :top_back_left,
300
+ :top_back_center,
301
+ :top_back_right], reader.native_format.speaker_mapping)
302
+ assert_equal(2, reader.format.channels)
303
+ assert_equal(16, reader.format.bits_per_sample)
304
+ assert_equal(44100, reader.format.sample_rate)
305
+ assert_equal([:front_left, :front_right], reader.format.speaker_mapping)
306
+ assert_equal(false, reader.closed?)
307
+ assert_equal(0, reader.current_sample_frame)
308
+ assert_equal(2240, reader.total_sample_frames)
309
+ assert_equal(true, reader.readable_format?)
310
+ reader.close
311
+
312
+ buffers = read_file("valid/valid_extensible_stereo_pcm_16_44100_more_speakers_than_defined_by_spec.wav", 1024)
313
+
314
+ assert_equal(3, buffers.length)
315
+ assert_equal([1024, 1024, 192], buffers.map {|buffer| buffer.samples.length })
316
+ assert_equal(SQUARE_WAVE_CYCLE[:stereo][:pcm_16] * 128, buffers[0].samples)
317
+ assert_equal(SQUARE_WAVE_CYCLE[:stereo][:pcm_16] * 128, buffers[1].samples)
318
+ assert_equal(SQUARE_WAVE_CYCLE[:stereo][:pcm_16] * 24, buffers[2].samples)
319
+ end
320
+
321
+ def test_read_extensible_only_undefined_high_bit_speakers
322
+ reader = Reader.new(fixture("valid/valid_extensible_stereo_pcm_16_44100_only_undefined_high_bit_speakers.wav"))
323
+
324
+ assert_equal(2, reader.native_format.channels)
325
+ assert_equal(16, reader.native_format.bits_per_sample)
326
+ assert_equal(44100, reader.native_format.sample_rate)
327
+ assert_equal([:undefined, :undefined], reader.native_format.speaker_mapping)
328
+ assert_equal(2, reader.format.channels)
329
+ assert_equal(16, reader.format.bits_per_sample)
330
+ assert_equal(44100, reader.format.sample_rate)
331
+ assert_equal([:undefined, :undefined], reader.format.speaker_mapping)
332
+ assert_equal(false, reader.closed?)
333
+ assert_equal(0, reader.current_sample_frame)
334
+ assert_equal(2240, reader.total_sample_frames)
335
+ assert_equal(true, reader.readable_format?)
336
+ reader.close
337
+
338
+ buffers = read_file("valid/valid_extensible_stereo_pcm_16_44100_only_undefined_high_bit_speakers.wav", 1024)
339
+
340
+ assert_equal(3, buffers.length)
341
+ assert_equal([1024, 1024, 192], buffers.map {|buffer| buffer.samples.length })
342
+ assert_equal(SQUARE_WAVE_CYCLE[:stereo][:pcm_16] * 128, buffers[0].samples)
343
+ assert_equal(SQUARE_WAVE_CYCLE[:stereo][:pcm_16] * 128, buffers[1].samples)
344
+ assert_equal(SQUARE_WAVE_CYCLE[:stereo][:pcm_16] * 24, buffers[2].samples)
345
+ end
346
+
347
+ def test_read_non_extensible_that_has_extension
348
+ reader = Reader.new(fixture("valid/valid_mono_pcm_16_44100_with_extension.wav"))
349
+
350
+ assert_equal(1, reader.native_format.audio_format)
351
+ assert_equal(1, reader.native_format.channels)
352
+ assert_equal(16, reader.native_format.bits_per_sample)
353
+ assert_equal(44100, reader.native_format.sample_rate)
354
+ assert_nil(reader.native_format.speaker_mapping)
355
+ assert_nil(reader.native_format.sub_audio_format_guid)
356
+ assert_nil(reader.native_format.valid_bits_per_sample)
357
+ assert_equal(1, reader.format.channels)
358
+ assert_equal(16, reader.format.bits_per_sample)
359
+ assert_equal(44100, reader.format.sample_rate)
360
+ assert_equal([:front_center], reader.format.speaker_mapping)
361
+ assert_equal(false, reader.closed?)
362
+ assert_equal(0, reader.current_sample_frame)
363
+ assert_equal(2240, reader.total_sample_frames)
364
+ assert_equal(true, reader.readable_format?)
365
+ reader.close
366
+
367
+ buffers = read_file("valid/valid_mono_pcm_16_44100_with_extension.wav", 1024)
368
+
369
+ assert_equal(3, buffers.length)
370
+ assert_equal([1024, 1024, 192], buffers.map {|buffer| buffer.samples.length })
371
+ assert_equal(SQUARE_WAVE_CYCLE[:mono][:pcm_16] * 128, buffers[0].samples)
372
+ assert_equal(SQUARE_WAVE_CYCLE[:mono][:pcm_16] * 128, buffers[1].samples)
373
+ assert_equal(SQUARE_WAVE_CYCLE[:mono][:pcm_16] * 24, buffers[2].samples)
374
+ end
375
+
219
376
  def test_read_with_format_conversion
220
377
  buffers = read_file("valid/valid_mono_pcm_16_44100.wav", 1024, Format.new(:stereo, :pcm_8, 22100))
221
378
 
@@ -309,6 +466,21 @@ class ReaderTest < Minitest::Test
309
466
  assert_equal(2239, reader.total_sample_frames)
310
467
  end
311
468
 
469
+ def test_each_buffer_inside_reader_block
470
+ buffers = []
471
+
472
+ # This should not raise a ReaderClosedError
473
+ Reader.new(fixture("valid/valid_mono_pcm_16_44100.wav")) do |reader|
474
+ reader.each_buffer(1024) {|buffer| buffers << buffer }
475
+ end
476
+
477
+ assert_equal(3, buffers.length)
478
+ assert_equal([1024, 1024, 192], buffers.map {|buffer| buffer.samples.length })
479
+ assert_equal(SQUARE_WAVE_CYCLE[:mono][:pcm_16] * 128, buffers[0].samples)
480
+ assert_equal(SQUARE_WAVE_CYCLE[:mono][:pcm_16] * 128, buffers[1].samples)
481
+ assert_equal(SQUARE_WAVE_CYCLE[:mono][:pcm_16] * 24, buffers[2].samples)
482
+ end
483
+
312
484
  def test_read_non_data_chunk_with_padding_byte
313
485
  # This fixture file contains a JUNK chunk with an odd size, aligned to an even number of
314
486
  # bytes via an appended padding byte. If the padding byte is not taken into account, this
@@ -325,6 +497,9 @@ class ReaderTest < Minitest::Test
325
497
  assert_equal(false, reader.closed?)
326
498
  reader.close
327
499
  assert(reader.closed?)
500
+ # Closing an already closed Reader should be a no-op
501
+ reader.close
502
+ assert(reader.closed?)
328
503
 
329
504
  # For Reader.each_buffer
330
505
  reader = Reader.new(fixture("valid/valid_mono_pcm_16_44100.wav"))
@@ -367,7 +542,7 @@ class ReaderTest < Minitest::Test
367
542
  def test_sample_counts_manual_reads
368
543
  exhaustively_test do |format_chunk_format, channels, sample_format|
369
544
  reader = Reader.new(fixture("valid/valid_#{format_chunk_format}#{channels}_#{sample_format}_44100.wav"))
370
-
545
+
371
546
  assert_equal(0, reader.current_sample_frame)
372
547
  assert_equal(2240, reader.total_sample_frames)
373
548
  test_duration({:hours => 0, :minutes => 0, :seconds => 0, :milliseconds => 50, :sample_count => 2240},
@@ -393,7 +568,7 @@ class ReaderTest < Minitest::Test
393
568
  assert_equal(2240, reader.total_sample_frames)
394
569
  test_duration({:hours => 0, :minutes => 0, :seconds => 0, :milliseconds => 50, :sample_count => 2240},
395
570
  reader.total_duration)
396
-
571
+
397
572
 
398
573
  reader.close
399
574
  assert_equal(2240, reader.current_sample_frame)
@@ -419,7 +594,7 @@ class ReaderTest < Minitest::Test
419
594
  assert_equal(expected_result, reader.current_sample_frame)
420
595
  assert_equal(2240, reader.total_sample_frames)
421
596
  end
422
-
597
+
423
598
  assert_equal(2240, reader.current_sample_frame)
424
599
  assert_equal(2240, reader.total_sample_frames)
425
600
  end