wavefile 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +2 -2
- data/README.markdown +67 -47
- data/Rakefile +23 -0
- data/lib/wavefile.rb +4 -2
- data/lib/wavefile/buffer.rb +40 -25
- data/lib/wavefile/chunk_readers.rb +7 -1
- data/lib/wavefile/chunk_readers/base_chunk_reader.rb +10 -0
- data/lib/wavefile/chunk_readers/data_chunk_reader.rb +77 -0
- data/lib/wavefile/chunk_readers/format_chunk_reader.rb +59 -0
- data/lib/wavefile/chunk_readers/generic_chunk_reader.rb +15 -0
- data/lib/wavefile/chunk_readers/riff_chunk_reader.rb +19 -0
- data/lib/wavefile/chunk_readers/riff_reader.rb +67 -0
- data/lib/wavefile/duration.rb +47 -12
- data/lib/wavefile/format.rb +44 -23
- data/lib/wavefile/reader.rb +101 -111
- data/lib/wavefile/unvalidated_format.rb +36 -6
- data/lib/wavefile/writer.rb +138 -40
- data/test/buffer_test.rb +21 -17
- data/test/chunk_readers/format_chunk_reader_test.rb +130 -0
- data/test/duration_test.rb +42 -1
- data/test/fixtures/actual_output/total_duration_mono_float_32_44100.wav +0 -0
- data/test/fixtures/actual_output/total_duration_mono_float_64_44100.wav +0 -0
- data/test/fixtures/actual_output/total_duration_mono_pcm_16_44100.wav +0 -0
- data/test/fixtures/actual_output/total_duration_mono_pcm_24_44100.wav +0 -0
- data/test/fixtures/actual_output/total_duration_mono_pcm_32_44100.wav +0 -0
- data/test/fixtures/actual_output/total_duration_mono_pcm_8_44100.wav +0 -0
- data/test/fixtures/actual_output/total_duration_stereo_float_32_44100.wav +0 -0
- data/test/fixtures/actual_output/total_duration_stereo_float_64_44100.wav +0 -0
- data/test/fixtures/actual_output/total_duration_stereo_pcm_16_44100.wav +0 -0
- data/test/fixtures/actual_output/total_duration_stereo_pcm_24_44100.wav +0 -0
- data/test/fixtures/actual_output/total_duration_stereo_pcm_32_44100.wav +0 -0
- data/test/fixtures/actual_output/total_duration_stereo_pcm_8_44100.wav +0 -0
- data/test/fixtures/actual_output/total_duration_tri_float_32_44100.wav +0 -0
- data/test/fixtures/actual_output/total_duration_tri_float_64_44100.wav +0 -0
- data/test/fixtures/actual_output/total_duration_tri_pcm_16_44100.wav +0 -0
- data/test/fixtures/actual_output/total_duration_tri_pcm_24_44100.wav +0 -0
- data/test/fixtures/actual_output/total_duration_tri_pcm_32_44100.wav +0 -0
- data/test/fixtures/actual_output/total_duration_tri_pcm_8_44100.wav +0 -0
- data/test/fixtures/unsupported/README.markdown +1 -1
- data/test/fixtures/unsupported/bad_channel_count.wav +0 -0
- data/test/fixtures/unsupported/extensible_container_size_bigger_than_sample_size.wav +0 -0
- data/test/fixtures/unsupported/extensible_unsupported_subformat_guid.wav +0 -0
- data/test/fixtures/valid/valid_extensible_mono_float_32_44100.wav +0 -0
- data/test/fixtures/valid/valid_extensible_mono_float_64_44100.wav +0 -0
- data/test/fixtures/valid/valid_extensible_mono_pcm_16_44100.wav +0 -0
- data/test/fixtures/valid/valid_extensible_mono_pcm_24_44100.wav +0 -0
- data/test/fixtures/valid/valid_extensible_mono_pcm_32_44100.wav +0 -0
- data/test/fixtures/valid/valid_extensible_mono_pcm_8_44100.wav +0 -0
- data/test/fixtures/valid/valid_extensible_stereo_float_32_44100.wav +0 -0
- data/test/fixtures/valid/valid_extensible_stereo_float_64_44100.wav +0 -0
- data/test/fixtures/valid/valid_extensible_stereo_pcm_16_44100.wav +0 -0
- data/test/fixtures/valid/valid_extensible_stereo_pcm_24_44100.wav +0 -0
- data/test/fixtures/valid/valid_extensible_stereo_pcm_32_44100.wav +0 -0
- data/test/fixtures/valid/valid_extensible_stereo_pcm_8_44100.wav +0 -0
- data/test/fixtures/valid/valid_extensible_tri_float_32_44100.wav +0 -0
- data/test/fixtures/valid/valid_extensible_tri_float_64_44100.wav +0 -0
- data/test/fixtures/valid/valid_extensible_tri_pcm_16_44100.wav +0 -0
- data/test/fixtures/valid/valid_extensible_tri_pcm_24_44100.wav +0 -0
- data/test/fixtures/valid/valid_extensible_tri_pcm_32_44100.wav +0 -0
- data/test/fixtures/valid/valid_extensible_tri_pcm_8_44100.wav +0 -0
- data/test/format_test.rb +22 -48
- data/test/reader_test.rb +188 -93
- data/test/unvalidated_format_test.rb +130 -4
- data/test/wavefile_io_test_helper.rb +6 -4
- data/test/writer_test.rb +118 -95
- metadata +47 -4
- data/lib/wavefile/chunk_readers/header_reader.rb +0 -163
- data/test/fixtures/actual_output/no_samples.wav +0 -0
data/test/duration_test.rb
CHANGED
@@ -3,7 +3,7 @@ require 'wavefile.rb'
|
|
3
3
|
|
4
4
|
include WaveFile
|
5
5
|
|
6
|
-
class DurationTest <
|
6
|
+
class DurationTest < Minitest::Test
|
7
7
|
SECONDS_IN_MINUTE = 60
|
8
8
|
SECONDS_IN_HOUR = SECONDS_IN_MINUTE * 60
|
9
9
|
|
@@ -70,4 +70,45 @@ class DurationTest < MiniTest::Unit::TestCase
|
|
70
70
|
assert_equal(samples_per_hour * 25, duration.sample_frame_count)
|
71
71
|
assert_equal(44100, duration.sample_rate)
|
72
72
|
end
|
73
|
+
|
74
|
+
def test_equality_exact_same_values
|
75
|
+
duration_1 = Duration.new(44100, 1234)
|
76
|
+
duration_2 = Duration.new(44100, 1234)
|
77
|
+
|
78
|
+
assert_equal(duration_1, duration_2)
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_equality_different_values_but_same_duration
|
82
|
+
# Durations have different numbers of sample frames and sample rates,
|
83
|
+
# but both correspond to the same amount of time (1 second)
|
84
|
+
duration_1 = Duration.new(22050, 22050)
|
85
|
+
duration_2 = Duration.new(44100, 44100)
|
86
|
+
|
87
|
+
assert_equal(duration_1, duration_2)
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_equality_different_number_of_sample_frames
|
91
|
+
duration_1 = Duration.new(100, 44100)
|
92
|
+
duration_2 = Duration.new(200, 44100)
|
93
|
+
|
94
|
+
assert_equal(false, duration_1 == duration_2)
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_equality_different_sample_rates
|
98
|
+
duration_1 = Duration.new(500, 22050)
|
99
|
+
duration_2 = Duration.new(500, 44100)
|
100
|
+
|
101
|
+
assert_equal(false, duration_1 == duration_2)
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_equality_less_than_millisecond_difference
|
105
|
+
# Although each represents a different amount of time,
|
106
|
+
# the difference is less than 1 millisecond, which is
|
107
|
+
# the maximum resolution of a Duration. Therefore, they
|
108
|
+
# are considered equal.
|
109
|
+
duration_1 = Duration.new(500, 44100)
|
110
|
+
duration_2 = Duration.new(501, 44100)
|
111
|
+
|
112
|
+
assert_equal(duration_1, duration_2)
|
113
|
+
end
|
73
114
|
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -1,6 +1,6 @@
|
|
1
1
|
The files in this folder are wave files that do not violate the wave file spec, but can not be read by the WaveFile gem.
|
2
2
|
|
3
3
|
* **unsupported_audio_format.wav** - The audio format defined in the format chunk is 2, or ADPCM. While a valid format, this gem only supports 1 (PCM).
|
4
|
-
* **unsupported_bits_per_sample.wav** - The bits per sample is
|
4
|
+
* **unsupported_bits_per_sample.wav** - The bits per sample is 20, which is not supported by this gem.
|
5
5
|
* **bad_channel_count.wav** - The channel count defined in the format chunk is 0.
|
6
6
|
* **bad_sample_rate.wav** - The sample rate defined in the format chunk is 0.
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/test/format_test.rb
CHANGED
@@ -3,7 +3,7 @@ require 'wavefile.rb'
|
|
3
3
|
|
4
4
|
include WaveFile
|
5
5
|
|
6
|
-
class FormatTest <
|
6
|
+
class FormatTest < Minitest::Test
|
7
7
|
def test_valid_channels
|
8
8
|
[1, 2, 3, 4, 65535].each do |valid_channels|
|
9
9
|
assert_equal(valid_channels, Format.new(valid_channels, :pcm_16, 44100).channels)
|
@@ -20,10 +20,6 @@ class FormatTest < MiniTest::Unit::TestCase
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def test_valid_sample_format
|
23
|
-
assert_equal(:pcm, Format.new(:mono, 8, 44100).sample_format)
|
24
|
-
assert_equal(:pcm, Format.new(:mono, 16, 44100).sample_format)
|
25
|
-
assert_equal(:pcm, Format.new(:mono, 24, 44100).sample_format)
|
26
|
-
assert_equal(:pcm, Format.new(:mono, 32, 44100).sample_format)
|
27
23
|
assert_equal(:pcm, Format.new(:mono, :pcm_8, 44100).sample_format)
|
28
24
|
assert_equal(:pcm, Format.new(:mono, :pcm_16, 44100).sample_format)
|
29
25
|
assert_equal(:pcm, Format.new(:mono, :pcm_24, 44100).sample_format)
|
@@ -34,16 +30,12 @@ class FormatTest < MiniTest::Unit::TestCase
|
|
34
30
|
end
|
35
31
|
|
36
32
|
def test_invalid_sample_format
|
37
|
-
["dsfsfsdf", :foo, 12, :pcm_14, :
|
33
|
+
["dsfsfsdf", :foo, :pcm, 0, 12, :pcm_14, :pcm_abc, :float_40].each do |invalid_sample_format|
|
38
34
|
assert_raises(InvalidFormatError) { Format.new(:mono, invalid_sample_format, 44100) }
|
39
35
|
end
|
40
36
|
end
|
41
37
|
|
42
38
|
def test_valid_bits_per_sample
|
43
|
-
assert_equal(8, Format.new(:mono, 8, 44100).bits_per_sample)
|
44
|
-
assert_equal(16, Format.new(:mono, 16, 44100).bits_per_sample)
|
45
|
-
assert_equal(24, Format.new(:mono, 24, 44100).bits_per_sample)
|
46
|
-
assert_equal(32, Format.new(:mono, 32, 44100).bits_per_sample)
|
47
39
|
assert_equal(8, Format.new(:mono, :pcm_8, 44100).bits_per_sample)
|
48
40
|
assert_equal(16, Format.new(:mono, :pcm_16, 44100).bits_per_sample)
|
49
41
|
assert_equal(24, Format.new(:mono, :pcm_24, 44100).bits_per_sample)
|
@@ -53,12 +45,6 @@ class FormatTest < MiniTest::Unit::TestCase
|
|
53
45
|
assert_equal(64, Format.new(:mono, :float_64, 44100).bits_per_sample)
|
54
46
|
end
|
55
47
|
|
56
|
-
def test_invalid_bits_per_sample
|
57
|
-
["dsfsfsdf", :foo, :pcm, 0, 12, :pcm_14, :pcm_abc, :float_40].each do |invalid_sample_format|
|
58
|
-
assert_raises(InvalidFormatError) { Format.new(:mono, invalid_sample_format, 44100) }
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
48
|
def test_valid_sample_rate
|
63
49
|
[1, 44100, 4294967296].each do |valid_sample_rate|
|
64
50
|
assert_equal(valid_sample_rate, Format.new(:mono, :pcm_16, valid_sample_rate).sample_rate)
|
@@ -73,25 +59,19 @@ class FormatTest < MiniTest::Unit::TestCase
|
|
73
59
|
|
74
60
|
def test_byte_and_block_align
|
75
61
|
[1, :mono].each do |one_channel|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
assert_equal(1, format.block_align)
|
80
|
-
end
|
62
|
+
format = Format.new(one_channel, :pcm_8, 44100)
|
63
|
+
assert_equal(44100, format.byte_rate)
|
64
|
+
assert_equal(1, format.block_align)
|
81
65
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
assert_equal(2, format.block_align)
|
86
|
-
end
|
66
|
+
format = Format.new(one_channel, :pcm_16, 44100)
|
67
|
+
assert_equal(88200, format.byte_rate)
|
68
|
+
assert_equal(2, format.block_align)
|
87
69
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
assert_equal(3, format.block_align)
|
92
|
-
end
|
70
|
+
format = Format.new(one_channel, :pcm_24, 44100)
|
71
|
+
assert_equal(132300, format.byte_rate)
|
72
|
+
assert_equal(3, format.block_align)
|
93
73
|
|
94
|
-
[:pcm_32,
|
74
|
+
[:pcm_32, :float, :float_32].each do |format_code|
|
95
75
|
format = Format.new(one_channel, format_code, 44100)
|
96
76
|
assert_equal(176400, format.byte_rate)
|
97
77
|
assert_equal(4, format.block_align)
|
@@ -103,25 +83,19 @@ class FormatTest < MiniTest::Unit::TestCase
|
|
103
83
|
end
|
104
84
|
|
105
85
|
[2, :stereo].each do |two_channels|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
assert_equal(2, format.block_align)
|
110
|
-
end
|
86
|
+
format = Format.new(two_channels, :pcm_8, 44100)
|
87
|
+
assert_equal(88200, format.byte_rate)
|
88
|
+
assert_equal(2, format.block_align)
|
111
89
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
assert_equal(4, format.block_align)
|
116
|
-
end
|
90
|
+
format = Format.new(two_channels, :pcm_16, 44100)
|
91
|
+
assert_equal(176400, format.byte_rate)
|
92
|
+
assert_equal(4, format.block_align)
|
117
93
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
assert_equal(6, format.block_align)
|
122
|
-
end
|
94
|
+
format = Format.new(two_channels, :pcm_24, 44100)
|
95
|
+
assert_equal(264600, format.byte_rate)
|
96
|
+
assert_equal(6, format.block_align)
|
123
97
|
|
124
|
-
[:pcm_32,
|
98
|
+
[:pcm_32, :float, :float_32].each do |format_code|
|
125
99
|
format = Format.new(two_channels, format_code, 44100)
|
126
100
|
assert_equal(352800, format.byte_rate)
|
127
101
|
assert_equal(8, format.block_align)
|
data/test/reader_test.rb
CHANGED
@@ -4,7 +4,7 @@ require 'wavefile_io_test_helper.rb'
|
|
4
4
|
|
5
5
|
include WaveFile
|
6
6
|
|
7
|
-
class ReaderTest <
|
7
|
+
class ReaderTest < Minitest::Test
|
8
8
|
include WaveFileIOTestHelper
|
9
9
|
|
10
10
|
FIXTURE_ROOT_PATH = "test/fixtures"
|
@@ -14,7 +14,7 @@ class ReaderTest < MiniTest::Unit::TestCase
|
|
14
14
|
assert_raises(Errno::ENOENT) { Reader.new(fixture("i_do_not_exist.wav")) }
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
17
|
+
def test_initialize_invalid_formats
|
18
18
|
invalid_fixtures = [
|
19
19
|
# File contains 0 bytes
|
20
20
|
"invalid/empty.wav",
|
@@ -41,14 +41,52 @@ class ReaderTest < MiniTest::Unit::TestCase
|
|
41
41
|
"invalid/no_data_chunk.wav",
|
42
42
|
]
|
43
43
|
|
44
|
-
# Reader.new and Reader.info should raise the same errors for invalid files,
|
45
|
-
# so run the tests for both methods.
|
46
44
|
invalid_fixtures.each do |fixture_name|
|
47
|
-
|
45
|
+
file_name = fixture(fixture_name)
|
46
|
+
|
47
|
+
[file_name, string_io_from_file(file_name)].each do |io_or_file_name|
|
48
|
+
assert_raises(InvalidFormatError) { Reader.new(io_or_file_name) }
|
49
|
+
end
|
48
50
|
end
|
49
51
|
end
|
50
52
|
|
51
|
-
def
|
53
|
+
def test_initialize_unsupported_format
|
54
|
+
file_name = fixture("unsupported/unsupported_bits_per_sample.wav")
|
55
|
+
|
56
|
+
# Unsupported format, no read format given
|
57
|
+
[file_name, string_io_from_file(file_name)].each do |io_or_file_name|
|
58
|
+
reader = Reader.new(io_or_file_name)
|
59
|
+
assert_equal(2, reader.native_format.channels)
|
60
|
+
assert_equal(20, reader.native_format.bits_per_sample)
|
61
|
+
assert_equal(44100, reader.native_format.sample_rate)
|
62
|
+
assert_equal(2, reader.format.channels)
|
63
|
+
assert_equal(20, reader.format.bits_per_sample)
|
64
|
+
assert_equal(44100, reader.format.sample_rate)
|
65
|
+
assert_equal(false, reader.closed?)
|
66
|
+
assert_equal(0, reader.current_sample_frame)
|
67
|
+
assert_equal(2240, reader.total_sample_frames)
|
68
|
+
assert_equal(false, reader.readable_format?)
|
69
|
+
reader.close
|
70
|
+
end
|
71
|
+
|
72
|
+
# Unsupported format, different read format given
|
73
|
+
[file_name, string_io_from_file(file_name)].each do |io_or_file_name|
|
74
|
+
reader = Reader.new(io_or_file_name, Format.new(:mono, :pcm_16, 22050))
|
75
|
+
assert_equal(2, reader.native_format.channels)
|
76
|
+
assert_equal(20, reader.native_format.bits_per_sample)
|
77
|
+
assert_equal(44100, reader.native_format.sample_rate)
|
78
|
+
assert_equal(1, reader.format.channels)
|
79
|
+
assert_equal(16, reader.format.bits_per_sample)
|
80
|
+
assert_equal(22050, reader.format.sample_rate)
|
81
|
+
assert_equal(false, reader.closed?)
|
82
|
+
assert_equal(0, reader.current_sample_frame)
|
83
|
+
assert_equal(2240, reader.total_sample_frames)
|
84
|
+
assert_equal(false, reader.readable_format?)
|
85
|
+
reader.close
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_read_from_unsupported_format
|
52
90
|
unsupported_fixtures = [
|
53
91
|
# Audio format is 2, which is not supported
|
54
92
|
"unsupported/unsupported_audio_format.wav",
|
@@ -61,105 +99,88 @@ class ReaderTest < MiniTest::Unit::TestCase
|
|
61
99
|
|
62
100
|
# Sample rate is 0
|
63
101
|
"unsupported/bad_sample_rate.wav",
|
102
|
+
|
103
|
+
# WAVEFORMATEXTENSIBLE, container size doesn't match sample size
|
104
|
+
# Although this is valid, this is not currently supported by this gem
|
105
|
+
"unsupported/extensible_container_size_bigger_than_sample_size.wav",
|
106
|
+
|
107
|
+
# WAVEFORMATEXTENSIBLE, the subformat GUID is not a valid format
|
108
|
+
# supported by this gem.
|
109
|
+
"unsupported/extensible_unsupported_subformat_guid.wav",
|
64
110
|
]
|
65
111
|
|
66
112
|
unsupported_fixtures.each do |fixture_name|
|
67
|
-
|
68
|
-
assert_equal(false, reader.readable_format?)
|
69
|
-
assert_raises(UnsupportedFormatError) { reader.read(1024) }
|
70
|
-
assert_raises(UnsupportedFormatError) { reader.each_buffer(1024) {|buffer| buffer } }
|
71
|
-
end
|
72
|
-
end
|
113
|
+
file_name = fixture(fixture_name)
|
73
114
|
|
74
|
-
|
75
|
-
|
115
|
+
[file_name, string_io_from_file(file_name)].each do |io_or_file_name|
|
116
|
+
reader = Reader.new(io_or_file_name)
|
117
|
+
assert_equal(false, reader.readable_format?)
|
118
|
+
assert_raises(UnsupportedFormatError) { reader.read(1024) }
|
119
|
+
assert_raises(UnsupportedFormatError) { reader.each_buffer(1024) {|buffer| buffer } }
|
76
120
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
assert_equal(20, reader.native_format.bits_per_sample)
|
81
|
-
assert_equal(44100, reader.native_format.sample_rate)
|
82
|
-
assert_equal(2, reader.format.channels)
|
83
|
-
assert_equal(20, reader.format.bits_per_sample)
|
84
|
-
assert_equal(44100, reader.format.sample_rate)
|
85
|
-
assert_equal(false, reader.closed?)
|
86
|
-
assert_equal(file_name, reader.file_name)
|
87
|
-
assert_equal(0, reader.current_sample_frame)
|
88
|
-
assert_equal(2240, reader.total_sample_frames)
|
89
|
-
assert_equal(false, reader.readable_format?)
|
90
|
-
reader.close
|
91
|
-
|
92
|
-
# Unsupported format, different read format given
|
93
|
-
reader = Reader.new(file_name, Format.new(:mono, :pcm_16, 22050))
|
94
|
-
assert_equal(2, reader.native_format.channels)
|
95
|
-
assert_equal(20, reader.native_format.bits_per_sample)
|
96
|
-
assert_equal(44100, reader.native_format.sample_rate)
|
97
|
-
assert_equal(1, reader.format.channels)
|
98
|
-
assert_equal(16, reader.format.bits_per_sample)
|
99
|
-
assert_equal(22050, reader.format.sample_rate)
|
100
|
-
assert_equal(false, reader.closed?)
|
101
|
-
assert_equal(file_name, reader.file_name)
|
102
|
-
assert_equal(0, reader.current_sample_frame)
|
103
|
-
assert_equal(2240, reader.total_sample_frames)
|
104
|
-
assert_equal(false, reader.readable_format?)
|
105
|
-
reader.close
|
121
|
+
reader.close
|
122
|
+
end
|
123
|
+
end
|
106
124
|
end
|
107
125
|
|
108
126
|
def test_initialize
|
109
127
|
format = Format.new(:stereo, :pcm_16, 22050)
|
110
128
|
|
111
|
-
exhaustively_test do |channels, sample_format|
|
112
|
-
file_name = fixture("valid/valid_#{channels}_#{sample_format}_44100.wav")
|
129
|
+
exhaustively_test do |format_chunk_format, channels, sample_format|
|
130
|
+
file_name = fixture("valid/valid_#{format_chunk_format}#{channels}_#{sample_format}_44100.wav")
|
113
131
|
|
114
132
|
# Native format
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
133
|
+
[file_name, string_io_from_file(file_name)].each do |io_or_file_name|
|
134
|
+
reader = Reader.new(io_or_file_name)
|
135
|
+
assert_equal(CHANNEL_ALIAS[channels], reader.native_format.channels)
|
136
|
+
assert_equal(extract_bits_per_sample(sample_format), reader.native_format.bits_per_sample)
|
137
|
+
assert_equal(44100, reader.native_format.sample_rate)
|
138
|
+
assert_equal(CHANNEL_ALIAS[channels], reader.format.channels)
|
139
|
+
assert_equal(extract_bits_per_sample(sample_format), reader.format.bits_per_sample)
|
140
|
+
assert_equal(44100, reader.format.sample_rate)
|
141
|
+
assert_equal(false, reader.closed?)
|
142
|
+
assert_equal(0, reader.current_sample_frame)
|
143
|
+
assert_equal(2240, reader.total_sample_frames)
|
144
|
+
assert_equal(true, reader.readable_format?)
|
145
|
+
reader.close
|
146
|
+
end
|
128
147
|
|
129
148
|
# Non-native format
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
149
|
+
[file_name, string_io_from_file(file_name)].each do |io_or_file_name|
|
150
|
+
reader = Reader.new(io_or_file_name, format)
|
151
|
+
assert_equal(CHANNEL_ALIAS[channels], reader.native_format.channels)
|
152
|
+
assert_equal(extract_bits_per_sample(sample_format), reader.native_format.bits_per_sample)
|
153
|
+
assert_equal(44100, reader.native_format.sample_rate)
|
154
|
+
assert_equal(2, reader.format.channels)
|
155
|
+
assert_equal(16, reader.format.bits_per_sample)
|
156
|
+
assert_equal(22050, reader.format.sample_rate)
|
157
|
+
assert_equal(false, reader.closed?)
|
158
|
+
assert_equal(0, reader.current_sample_frame)
|
159
|
+
assert_equal(2240, reader.total_sample_frames)
|
160
|
+
assert_equal(true, reader.readable_format?)
|
161
|
+
reader.close
|
162
|
+
end
|
143
163
|
|
144
164
|
# Block is given.
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
165
|
+
[file_name, string_io_from_file(file_name)].each do |io_or_file_name|
|
166
|
+
reader = Reader.new(io_or_file_name) {|r| r.read(1024) }
|
167
|
+
assert_equal(CHANNEL_ALIAS[channels], reader.native_format.channels)
|
168
|
+
assert_equal(extract_bits_per_sample(sample_format), reader.native_format.bits_per_sample)
|
169
|
+
assert_equal(44100, reader.native_format.sample_rate)
|
170
|
+
assert_equal(CHANNEL_ALIAS[channels], reader.format.channels)
|
171
|
+
assert_equal(extract_bits_per_sample(sample_format), reader.format.bits_per_sample)
|
172
|
+
assert_equal(44100, reader.format.sample_rate)
|
173
|
+
assert(reader.closed?)
|
174
|
+
assert_equal(1024, reader.current_sample_frame)
|
175
|
+
assert_equal(2240, reader.total_sample_frames)
|
176
|
+
assert_equal(true, reader.readable_format?)
|
177
|
+
end
|
157
178
|
end
|
158
179
|
end
|
159
180
|
|
160
181
|
def test_read_native_format
|
161
|
-
exhaustively_test do |channels, sample_format|
|
162
|
-
buffers = read_file("valid/valid_#{channels}_#{sample_format}_44100.wav", 1024)
|
182
|
+
exhaustively_test do |format_chunk_format, channels, sample_format|
|
183
|
+
buffers = read_file("valid/valid_#{format_chunk_format}#{channels}_#{sample_format}_44100.wav", 1024)
|
163
184
|
|
164
185
|
assert_equal(3, buffers.length)
|
165
186
|
assert_equal([1024, 1024, 192], buffers.map {|buffer| buffer.samples.length })
|
@@ -169,6 +190,32 @@ class ReaderTest < MiniTest::Unit::TestCase
|
|
169
190
|
end
|
170
191
|
end
|
171
192
|
|
193
|
+
def test_read_native_extensible_format
|
194
|
+
channels = :stereo
|
195
|
+
sample_format = :pcm_16
|
196
|
+
|
197
|
+
reader = Reader.new(fixture("valid/valid_extensible_stereo_pcm_16_44100.wav"))
|
198
|
+
assert_equal(2, reader.native_format.channels)
|
199
|
+
assert_equal(16, reader.native_format.bits_per_sample)
|
200
|
+
assert_equal(44100, reader.native_format.sample_rate)
|
201
|
+
assert_equal(2, reader.format.channels)
|
202
|
+
assert_equal(16, reader.format.bits_per_sample)
|
203
|
+
assert_equal(44100, reader.format.sample_rate)
|
204
|
+
assert_equal(false, reader.closed?)
|
205
|
+
assert_equal(0, reader.current_sample_frame)
|
206
|
+
assert_equal(2240, reader.total_sample_frames)
|
207
|
+
assert_equal(true, reader.readable_format?)
|
208
|
+
reader.close
|
209
|
+
|
210
|
+
buffers = read_file("valid/valid_extensible_stereo_pcm_16_44100.wav", 1024)
|
211
|
+
|
212
|
+
assert_equal(3, buffers.length)
|
213
|
+
assert_equal([1024, 1024, 192], buffers.map {|buffer| buffer.samples.length })
|
214
|
+
assert_equal(SQUARE_WAVE_CYCLE[channels][sample_format] * 128, buffers[0].samples)
|
215
|
+
assert_equal(SQUARE_WAVE_CYCLE[channels][sample_format] * 128, buffers[1].samples)
|
216
|
+
assert_equal(SQUARE_WAVE_CYCLE[channels][sample_format] * 24, buffers[2].samples)
|
217
|
+
end
|
218
|
+
|
172
219
|
def test_read_with_format_conversion
|
173
220
|
buffers = read_file("valid/valid_mono_pcm_16_44100.wav", 1024, Format.new(:stereo, :pcm_8, 22100))
|
174
221
|
|
@@ -195,9 +242,25 @@ class ReaderTest < MiniTest::Unit::TestCase
|
|
195
242
|
assert_raises(LocalJumpError) { reader.each_buffer(1024) }
|
196
243
|
end
|
197
244
|
|
245
|
+
def test_each_buffer_no_buffer_size_given
|
246
|
+
exhaustively_test do |format_chunk_format, channels, sample_format|
|
247
|
+
reader = Reader.new(fixture("valid/valid_#{format_chunk_format}#{channels}_#{sample_format}_44100.wav"))
|
248
|
+
|
249
|
+
buffers = []
|
250
|
+
reader.each_buffer {|buffer| buffers << buffer }
|
251
|
+
|
252
|
+
assert(reader.closed?)
|
253
|
+
assert_equal(1, buffers.length)
|
254
|
+
assert_equal([2240], buffers.map {|buffer| buffer.samples.length })
|
255
|
+
assert_equal(SQUARE_WAVE_CYCLE[channels][sample_format] * 280, buffers[0].samples)
|
256
|
+
assert_equal(2240, reader.current_sample_frame)
|
257
|
+
assert_equal(2240, reader.total_sample_frames)
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
198
261
|
def test_each_buffer_native_format
|
199
|
-
exhaustively_test do |channels, sample_format|
|
200
|
-
reader = Reader.new(fixture("valid/valid_#{channels}_#{sample_format}_44100.wav"))
|
262
|
+
exhaustively_test do |format_chunk_format, channels, sample_format|
|
263
|
+
reader = Reader.new(fixture("valid/valid_#{format_chunk_format}#{channels}_#{sample_format}_44100.wav"))
|
201
264
|
|
202
265
|
buffers = []
|
203
266
|
reader.each_buffer(1024) {|buffer| buffers << buffer }
|
@@ -270,18 +333,40 @@ class ReaderTest < MiniTest::Unit::TestCase
|
|
270
333
|
# No-op
|
271
334
|
end
|
272
335
|
assert_equal(true, reader.closed?)
|
336
|
+
|
337
|
+
# Constructed from an File IO instance
|
338
|
+
io = File.open(fixture("valid/valid_mono_pcm_16_44100.wav"), "rb")
|
339
|
+
reader = Reader.new(io)
|
340
|
+
assert_equal(false, reader.closed?)
|
341
|
+
reader.close
|
342
|
+
assert(reader.closed?)
|
343
|
+
assert_equal(false, io.closed?)
|
344
|
+
|
345
|
+
# Constructed from an StringIO instance
|
346
|
+
io = StringIO.new(File.read(fixture("valid/valid_mono_pcm_16_44100.wav")))
|
347
|
+
reader = Reader.new(io)
|
348
|
+
assert_equal(false, reader.closed?)
|
349
|
+
reader.close
|
350
|
+
assert(reader.closed?)
|
351
|
+
assert_equal(false, io.closed?)
|
273
352
|
end
|
274
353
|
|
275
354
|
def test_read_after_close
|
276
355
|
reader = Reader.new(fixture("valid/valid_mono_pcm_16_44100.wav"))
|
277
|
-
|
356
|
+
reader.read(1024)
|
357
|
+
reader.close
|
358
|
+
assert_raises(ReaderClosedError) { reader.read(1024) }
|
359
|
+
|
360
|
+
io = File.open(fixture("valid/valid_mono_pcm_16_44100.wav"), "rb")
|
361
|
+
reader = Reader.new(io)
|
362
|
+
reader.read(1024)
|
278
363
|
reader.close
|
279
|
-
assert_raises(
|
364
|
+
assert_raises(ReaderClosedError) { reader.read(1024) }
|
280
365
|
end
|
281
366
|
|
282
367
|
def test_sample_counts_manual_reads
|
283
|
-
exhaustively_test do |channels, sample_format|
|
284
|
-
reader = Reader.new(fixture("valid/valid_#{channels}_#{sample_format}_44100.wav"))
|
368
|
+
exhaustively_test do |format_chunk_format, channels, sample_format|
|
369
|
+
reader = Reader.new(fixture("valid/valid_#{format_chunk_format}#{channels}_#{sample_format}_44100.wav"))
|
285
370
|
|
286
371
|
assert_equal(0, reader.current_sample_frame)
|
287
372
|
assert_equal(2240, reader.total_sample_frames)
|
@@ -319,10 +404,10 @@ class ReaderTest < MiniTest::Unit::TestCase
|
|
319
404
|
end
|
320
405
|
|
321
406
|
def test_sample_counts_each_buffer
|
322
|
-
exhaustively_test do |channels, sample_format|
|
407
|
+
exhaustively_test do |format_chunk_format, channels, sample_format|
|
323
408
|
expected_results = [ 1024, 2048, 2240 ]
|
324
409
|
|
325
|
-
file_name = fixture("valid/valid_#{channels}_#{sample_format}_44100.wav")
|
410
|
+
file_name = fixture("valid/valid_#{format_chunk_format}#{channels}_#{sample_format}_44100.wav")
|
326
411
|
reader = Reader.new(file_name)
|
327
412
|
|
328
413
|
assert_equal(0, reader.current_sample_frame)
|
@@ -365,6 +450,16 @@ private
|
|
365
450
|
sample_format.to_s.split("_").last.to_i
|
366
451
|
end
|
367
452
|
|
453
|
+
def string_io_from_file(file_name)
|
454
|
+
file_contents = File.read(file_name)
|
455
|
+
|
456
|
+
str_io = StringIO.new
|
457
|
+
str_io.syswrite(file_contents)
|
458
|
+
str_io.rewind
|
459
|
+
|
460
|
+
str_io
|
461
|
+
end
|
462
|
+
|
368
463
|
def test_duration(expected_hash, duration)
|
369
464
|
assert_equal(expected_hash[:hours], duration.hours)
|
370
465
|
assert_equal(expected_hash[:minutes], duration.minutes)
|