wavefile 1.0.1 → 1.1.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 (54) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +21 -23
  3. data/README.markdown +27 -43
  4. data/lib/wavefile.rb +4 -1
  5. data/lib/wavefile/buffer.rb +7 -5
  6. data/lib/wavefile/chunk_readers.rb +1 -2
  7. data/lib/wavefile/chunk_readers/base_chunk_reader.rb +13 -0
  8. data/lib/wavefile/chunk_readers/data_chunk_reader.rb +12 -3
  9. data/lib/wavefile/chunk_readers/format_chunk_reader.rb +2 -10
  10. data/lib/wavefile/chunk_readers/riff_reader.rb +73 -26
  11. data/lib/wavefile/chunk_readers/sample_chunk_reader.rb +74 -0
  12. data/lib/wavefile/format.rb +13 -9
  13. data/lib/wavefile/reader.rb +15 -7
  14. data/lib/wavefile/sampler_info.rb +162 -0
  15. data/lib/wavefile/sampler_loop.rb +142 -0
  16. data/lib/wavefile/smpte_timecode.rb +61 -0
  17. data/lib/wavefile/writer.rb +7 -1
  18. data/test/fixtures/wave/invalid/data_chunk_ends_after_chunk_id.wav +0 -0
  19. data/test/fixtures/wave/invalid/data_chunk_has_incomplete_chunk_size.wav +0 -0
  20. data/test/fixtures/wave/invalid/data_chunk_truncated.wav +0 -0
  21. data/test/fixtures/wave/invalid/format_chunk_after_data_chunk.wav +0 -0
  22. data/test/fixtures/wave/invalid/incomplete_riff_format.wav +0 -0
  23. data/test/fixtures/wave/invalid/incomplete_riff_header.wav +1 -1
  24. data/test/fixtures/wave/invalid/no_format_chunk_size.wav +0 -0
  25. data/test/fixtures/wave/invalid/no_riff_format.wav +0 -0
  26. data/test/fixtures/wave/invalid/riff_chunk_has_incomplete_chunk_size.wav +1 -0
  27. data/test/fixtures/wave/invalid/smpl_chunk_empty.wav +0 -0
  28. data/test/fixtures/wave/invalid/smpl_chunk_fields_out_of_range.wav +0 -0
  29. data/test/fixtures/wave/invalid/smpl_chunk_loop_count_too_high.wav +0 -0
  30. data/test/fixtures/wave/invalid/smpl_chunk_truncated_sampler_specific_data.wav +0 -0
  31. data/test/fixtures/wave/invalid/truncated_smpl_chunk.wav +0 -0
  32. data/test/fixtures/wave/unsupported/bad_audio_format.wav +0 -0
  33. data/test/fixtures/wave/unsupported/bad_sample_rate.wav +0 -0
  34. data/test/fixtures/wave/unsupported/extensible_unsupported_subformat_guid.wav +0 -0
  35. data/test/fixtures/wave/unsupported/unsupported_audio_format.wav +0 -0
  36. data/test/fixtures/wave/unsupported/unsupported_bits_per_sample.wav +0 -0
  37. data/test/fixtures/wave/valid/valid_mono_pcm_16_44100_junk_chunk_final_chunk_missing_padding_byte.wav +0 -0
  38. data/test/fixtures/wave/valid/valid_mono_pcm_16_44100_junk_chunk_with_padding_byte.wav +0 -0
  39. data/test/fixtures/wave/valid/valid_mono_pcm_8_44100_with_padding_byte.wav +0 -0
  40. data/test/fixtures/wave/valid/valid_with_sample_chunk_after_data_chunk.wav +0 -0
  41. data/test/fixtures/wave/valid/valid_with_sample_chunk_after_data_chunk_and_data_chunk_has_padding_byte.wav +0 -0
  42. data/test/fixtures/wave/valid/valid_with_sample_chunk_before_data_chunk.wav +0 -0
  43. data/test/fixtures/wave/valid/valid_with_sample_chunk_no_loops.wav +0 -0
  44. data/test/fixtures/wave/valid/valid_with_sample_chunk_with_extra_unused_bytes.wav +0 -0
  45. data/test/fixtures/wave/valid/valid_with_sample_chunk_with_sampler_specific_data.wav +0 -0
  46. data/test/format_test.rb +4 -4
  47. data/test/reader_test.rb +266 -8
  48. data/test/sampler_info_test.rb +314 -0
  49. data/test/sampler_loop_test.rb +215 -0
  50. data/test/smpte_timecode_test.rb +103 -0
  51. data/test/writer_test.rb +1 -1
  52. metadata +30 -6
  53. data/lib/wavefile/chunk_readers/generic_chunk_reader.rb +0 -15
  54. data/lib/wavefile/chunk_readers/riff_chunk_reader.rb +0 -19
@@ -0,0 +1,103 @@
1
+ require 'minitest/autorun'
2
+ require 'wavefile.rb'
3
+
4
+ include WaveFile
5
+
6
+ class SMPTETimecodeTest < Minitest::Test
7
+ VALID_8_BIT_SIGNED_INTEGER_TEST_VALUES = [0, 1, -1, -128, 127]
8
+ INVALID_8_BIT_SIGNED_INTEGER_TEST_VALUES = ["dsfsfsdf", :foo, -129, 128, 2.5, 2.0, -2.0, [10], nil]
9
+ VALID_8_BIT_UNSIGNED_INTEGER_TEST_VALUES = [0, 1, 128, 255]
10
+ INVALID_8_BIT_UNSIGNED_INTEGER_TEST_VALUES = ["dsfsfsdf", :foo, -1, 256, 2.5, 2.0, [10], nil]
11
+
12
+ def test_missing_keywords
13
+ assert_raises(ArgumentError) { SMPTETimecode.new }
14
+ end
15
+
16
+ def test_valid_hours
17
+ VALID_8_BIT_SIGNED_INTEGER_TEST_VALUES.each do |valid_value|
18
+ smpte_timecode = SMPTETimecode.new(hours: valid_value,
19
+ minutes: 0,
20
+ seconds: 0,
21
+ frames: 0)
22
+
23
+ assert_equal(valid_value, smpte_timecode.hours)
24
+ end
25
+ end
26
+
27
+ def test_invalid_hours
28
+ INVALID_8_BIT_SIGNED_INTEGER_TEST_VALUES.each do |invalid_value|
29
+ assert_raises(InvalidSMPTETimecodeError) do
30
+ SMPTETimecode.new(hours: invalid_value,
31
+ minutes: 0,
32
+ seconds: 0,
33
+ frames: 0)
34
+ end
35
+ end
36
+ end
37
+
38
+ def test_valid_minutes
39
+ VALID_8_BIT_UNSIGNED_INTEGER_TEST_VALUES.each do |valid_value|
40
+ smpte_timecode = SMPTETimecode.new(hours: 0,
41
+ minutes: valid_value,
42
+ seconds: 0,
43
+ frames: 0)
44
+
45
+ assert_equal(valid_value, smpte_timecode.minutes)
46
+ end
47
+ end
48
+
49
+ def test_invalid_minutes
50
+ INVALID_8_BIT_UNSIGNED_INTEGER_TEST_VALUES.each do |invalid_value|
51
+ assert_raises(InvalidSMPTETimecodeError) do
52
+ SMPTETimecode.new(hours: 0,
53
+ minutes: invalid_value,
54
+ seconds: 0,
55
+ frames: 0)
56
+ end
57
+ end
58
+ end
59
+
60
+ def test_valid_seconds
61
+ VALID_8_BIT_UNSIGNED_INTEGER_TEST_VALUES.each do |valid_value|
62
+ smpte_timecode = SMPTETimecode.new(hours: 0,
63
+ minutes: 0,
64
+ seconds: valid_value,
65
+ frames: 0)
66
+
67
+ assert_equal(valid_value, smpte_timecode.seconds)
68
+ end
69
+ end
70
+
71
+ def test_invalid_seconds
72
+ INVALID_8_BIT_UNSIGNED_INTEGER_TEST_VALUES.each do |invalid_value|
73
+ assert_raises(InvalidSMPTETimecodeError) do
74
+ SMPTETimecode.new(hours: 0,
75
+ minutes: 0,
76
+ seconds: invalid_value,
77
+ frames: 0)
78
+ end
79
+ end
80
+ end
81
+
82
+ def test_valid_frames
83
+ VALID_8_BIT_UNSIGNED_INTEGER_TEST_VALUES.each do |valid_value|
84
+ smpte_timecode = SMPTETimecode.new(hours: 0,
85
+ minutes: 0,
86
+ seconds: 0,
87
+ frames: valid_value)
88
+
89
+ assert_equal(valid_value, smpte_timecode.frames)
90
+ end
91
+ end
92
+
93
+ def test_invalid_frames
94
+ INVALID_8_BIT_UNSIGNED_INTEGER_TEST_VALUES.each do |invalid_value|
95
+ assert_raises(InvalidSMPTETimecodeError) do
96
+ SMPTETimecode.new(hours: 0,
97
+ minutes: 0,
98
+ seconds: 0,
99
+ frames: invalid_value)
100
+ end
101
+ end
102
+ end
103
+ end
data/test/writer_test.rb CHANGED
@@ -164,7 +164,7 @@ class WriterTest < Minitest::Test
164
164
  writer = Writer.new(io_or_file_name, format)
165
165
  writer.write(Buffer.new(SQUARE_WAVE_CYCLE[:mono][:pcm_8] * 128, format))
166
166
  writer.write(Buffer.new(SQUARE_WAVE_CYCLE[:mono][:pcm_8] * 128, format))
167
- writer.write(Buffer.new(SQUARE_WAVE_CYCLE[:mono][:pcm_8] * 23 + [88, 88, 88, 88, 167, 167, 167], format))
167
+ writer.write(Buffer.new(SQUARE_WAVE_CYCLE[:mono][:pcm_8] * 24 + [88], format))
168
168
  writer.close
169
169
 
170
170
  assert_equal(read_file(:expected, file_name), read_file(:actual, file_name))
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wavefile
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joel Strait
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-02 00:00:00.000000000 Z
11
+ date: 2019-01-20 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: You can use this gem to create Ruby programs that work with audio, by
14
14
  reading and writing Wave sound files (*.wav). Since it is written in pure Ruby (as
@@ -28,12 +28,14 @@ files:
28
28
  - lib/wavefile/chunk_readers/base_chunk_reader.rb
29
29
  - lib/wavefile/chunk_readers/data_chunk_reader.rb
30
30
  - lib/wavefile/chunk_readers/format_chunk_reader.rb
31
- - lib/wavefile/chunk_readers/generic_chunk_reader.rb
32
- - lib/wavefile/chunk_readers/riff_chunk_reader.rb
33
31
  - lib/wavefile/chunk_readers/riff_reader.rb
32
+ - lib/wavefile/chunk_readers/sample_chunk_reader.rb
34
33
  - lib/wavefile/duration.rb
35
34
  - lib/wavefile/format.rb
36
35
  - lib/wavefile/reader.rb
36
+ - lib/wavefile/sampler_info.rb
37
+ - lib/wavefile/sampler_loop.rb
38
+ - lib/wavefile/smpte_timecode.rb
37
39
  - lib/wavefile/unvalidated_format.rb
38
40
  - lib/wavefile/writer.rb
39
41
  - test/buffer_test.rb
@@ -41,12 +43,25 @@ files:
41
43
  - test/duration_test.rb
42
44
  - test/fixtures/wave/invalid/bad_riff_header.wav
43
45
  - test/fixtures/wave/invalid/bad_wavefile_format.wav
46
+ - test/fixtures/wave/invalid/data_chunk_ends_after_chunk_id.wav
47
+ - test/fixtures/wave/invalid/data_chunk_has_incomplete_chunk_size.wav
48
+ - test/fixtures/wave/invalid/data_chunk_truncated.wav
44
49
  - test/fixtures/wave/invalid/empty.wav
45
50
  - test/fixtures/wave/invalid/empty_format_chunk.wav
51
+ - test/fixtures/wave/invalid/format_chunk_after_data_chunk.wav
52
+ - test/fixtures/wave/invalid/incomplete_riff_format.wav
46
53
  - test/fixtures/wave/invalid/incomplete_riff_header.wav
47
54
  - test/fixtures/wave/invalid/insufficient_format_chunk.wav
48
55
  - test/fixtures/wave/invalid/no_data_chunk.wav
49
56
  - test/fixtures/wave/invalid/no_format_chunk.wav
57
+ - test/fixtures/wave/invalid/no_format_chunk_size.wav
58
+ - test/fixtures/wave/invalid/no_riff_format.wav
59
+ - test/fixtures/wave/invalid/riff_chunk_has_incomplete_chunk_size.wav
60
+ - test/fixtures/wave/invalid/smpl_chunk_empty.wav
61
+ - test/fixtures/wave/invalid/smpl_chunk_fields_out_of_range.wav
62
+ - test/fixtures/wave/invalid/smpl_chunk_loop_count_too_high.wav
63
+ - test/fixtures/wave/invalid/smpl_chunk_truncated_sampler_specific_data.wav
64
+ - test/fixtures/wave/invalid/truncated_smpl_chunk.wav
50
65
  - test/fixtures/wave/unsupported/bad_audio_format.wav
51
66
  - test/fixtures/wave/unsupported/bad_channel_count.wav
52
67
  - test/fixtures/wave/unsupported/bad_sample_rate.wav
@@ -85,6 +100,7 @@ files:
85
100
  - test/fixtures/wave/valid/valid_mono_float_32_44100.wav
86
101
  - test/fixtures/wave/valid/valid_mono_float_64_44100.wav
87
102
  - test/fixtures/wave/valid/valid_mono_pcm_16_44100.wav
103
+ - test/fixtures/wave/valid/valid_mono_pcm_16_44100_junk_chunk_final_chunk_missing_padding_byte.wav
88
104
  - test/fixtures/wave/valid/valid_mono_pcm_16_44100_junk_chunk_with_padding_byte.wav
89
105
  - test/fixtures/wave/valid/valid_mono_pcm_16_44100_with_extension.wav
90
106
  - test/fixtures/wave/valid/valid_mono_pcm_24_44100.wav
@@ -103,8 +119,17 @@ files:
103
119
  - test/fixtures/wave/valid/valid_tri_pcm_24_44100.wav
104
120
  - test/fixtures/wave/valid/valid_tri_pcm_32_44100.wav
105
121
  - test/fixtures/wave/valid/valid_tri_pcm_8_44100.wav
122
+ - test/fixtures/wave/valid/valid_with_sample_chunk_after_data_chunk.wav
123
+ - test/fixtures/wave/valid/valid_with_sample_chunk_after_data_chunk_and_data_chunk_has_padding_byte.wav
124
+ - test/fixtures/wave/valid/valid_with_sample_chunk_before_data_chunk.wav
125
+ - test/fixtures/wave/valid/valid_with_sample_chunk_no_loops.wav
126
+ - test/fixtures/wave/valid/valid_with_sample_chunk_with_extra_unused_bytes.wav
127
+ - test/fixtures/wave/valid/valid_with_sample_chunk_with_sampler_specific_data.wav
106
128
  - test/format_test.rb
107
129
  - test/reader_test.rb
130
+ - test/sampler_info_test.rb
131
+ - test/sampler_loop_test.rb
132
+ - test/smpte_timecode_test.rb
108
133
  - test/unvalidated_format_test.rb
109
134
  - test/wavefile_io_test_helper.rb
110
135
  - test/writer_test.rb
@@ -128,8 +153,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
128
153
  - !ruby/object:Gem::Version
129
154
  version: '0'
130
155
  requirements: []
131
- rubyforge_project:
132
- rubygems_version: 2.7.6
156
+ rubygems_version: 3.0.1
133
157
  signing_key:
134
158
  specification_version: 4
135
159
  summary: A pure Ruby library for reading and writing Wave sound files (*.wav)
@@ -1,15 +0,0 @@
1
- module WaveFile
2
- module ChunkReaders
3
- # Internal
4
- class GenericChunkReader < BaseChunkReader # :nodoc:
5
- def initialize(io, chunk_size)
6
- @io = io
7
- @chunk_size = chunk_size
8
- end
9
-
10
- def read
11
- @io.sysread(@chunk_size)
12
- end
13
- end
14
- end
15
- end
@@ -1,19 +0,0 @@
1
- module WaveFile
2
- module ChunkReaders
3
- # Internal
4
- class RiffChunkReader < BaseChunkReader # :nodoc:
5
- def initialize(io, chunk_size)
6
- @io = io
7
- @chunk_size = chunk_size
8
- end
9
-
10
- def read
11
- riff_format = @io.sysread(4)
12
-
13
- unless riff_format == WAVEFILE_FORMAT_CODE
14
- raise_error InvalidFormatError, "Expected RIFF format of '#{WAVEFILE_FORMAT_CODE}', but was '#{riff_format}'"
15
- end
16
- end
17
- end
18
- end
19
- end