wavefile 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +15 -0
  2. data/LICENSE +1 -1
  3. data/README.markdown +71 -18
  4. data/lib/wavefile/buffer.rb +63 -39
  5. data/lib/wavefile/duration.rb +34 -0
  6. data/lib/wavefile/format.rb +42 -16
  7. data/lib/wavefile/info.rb +5 -38
  8. data/lib/wavefile/reader.rb +88 -61
  9. data/lib/wavefile/writer.rb +57 -25
  10. data/lib/wavefile.rb +6 -4
  11. data/test/buffer_test.rb +227 -37
  12. data/test/duration_test.rb +73 -0
  13. data/test/fixtures/actual_output/{valid_mono_8_44100_with_padding_byte.wav → valid_mono_pcm_8_44100_with_padding_byte.wav} +0 -0
  14. data/test/fixtures/{expected_output → valid}/no_samples.wav +0 -0
  15. data/test/fixtures/valid/valid_mono_float_32_44100.wav +0 -0
  16. data/test/fixtures/valid/valid_mono_float_64_44100.wav +0 -0
  17. data/test/fixtures/{expected_output/valid_mono_16_44100.wav → valid/valid_mono_pcm_16_44100.wav} +0 -0
  18. data/test/fixtures/{expected_output/valid_mono_32_44100.wav → valid/valid_mono_pcm_32_44100.wav} +0 -0
  19. data/test/fixtures/{expected_output/valid_mono_8_44100.wav → valid/valid_mono_pcm_8_44100.wav} +0 -0
  20. data/test/fixtures/{expected_output/valid_mono_8_44100_with_padding_byte.wav → valid/valid_mono_pcm_8_44100_with_padding_byte.wav} +0 -0
  21. data/test/fixtures/valid/valid_stereo_float_32_44100.wav +0 -0
  22. data/test/fixtures/valid/valid_stereo_float_64_44100.wav +0 -0
  23. data/test/fixtures/{expected_output/valid_stereo_16_44100.wav → valid/valid_stereo_pcm_16_44100.wav} +0 -0
  24. data/test/fixtures/{expected_output/valid_stereo_32_44100.wav → valid/valid_stereo_pcm_32_44100.wav} +0 -0
  25. data/test/fixtures/{expected_output/valid_stereo_8_44100.wav → valid/valid_stereo_pcm_8_44100.wav} +0 -0
  26. data/test/fixtures/valid/valid_tri_float_32_44100.wav +0 -0
  27. data/test/fixtures/valid/valid_tri_float_64_44100.wav +0 -0
  28. data/test/fixtures/{expected_output/valid_tri_16_44100.wav → valid/valid_tri_pcm_16_44100.wav} +0 -0
  29. data/test/fixtures/{expected_output/valid_tri_32_44100.wav → valid/valid_tri_pcm_32_44100.wav} +0 -0
  30. data/test/fixtures/{expected_output/valid_tri_8_44100.wav → valid/valid_tri_pcm_8_44100.wav} +0 -0
  31. data/test/format_test.rb +88 -58
  32. data/test/info_test.rb +9 -37
  33. data/test/reader_test.rb +160 -63
  34. data/test/wavefile_io_test_helper.rb +40 -30
  35. data/test/writer_test.rb +124 -37
  36. metadata +29 -31
  37. data/test/fixtures/valid/valid_mono_16_44100.wav +0 -0
  38. data/test/fixtures/valid/valid_mono_32_44100.wav +0 -0
  39. data/test/fixtures/valid/valid_mono_8_44100.wav +0 -0
  40. data/test/fixtures/valid/valid_mono_8_44100_with_padding_byte.wav +0 -0
  41. data/test/fixtures/valid/valid_stereo_16_44100.wav +0 -0
  42. data/test/fixtures/valid/valid_stereo_32_44100.wav +0 -0
  43. data/test/fixtures/valid/valid_stereo_8_44100.wav +0 -0
  44. data/test/fixtures/valid/valid_tri_16_44100.wav +0 -0
  45. data/test/fixtures/valid/valid_tri_32_44100.wav +0 -0
  46. data/test/fixtures/valid/valid_tri_8_44100.wav +0 -0
data/test/writer_test.rb CHANGED
@@ -10,39 +10,39 @@ class WriterTest < Test::Unit::TestCase
10
10
  OUTPUT_FOLDER = "test/fixtures/actual_output"
11
11
 
12
12
  def setup
13
- clean_output_folder()
13
+ clean_output_folder
14
14
  end
15
15
 
16
16
  def test_write_file_with_no_sample_data
17
- writer = Writer.new("#{OUTPUT_FOLDER}/no_samples.wav", Format.new(1, 8, 44100))
18
- writer.close()
19
-
17
+ writer = Writer.new("#{OUTPUT_FOLDER}/no_samples.wav", Format.new(:mono, :pcm_8, 44100))
18
+ writer.close
19
+
20
20
  assert_equal(read_file(:expected, "no_samples.wav"), read_file(:actual, "no_samples.wav"))
21
21
  end
22
22
 
23
23
  def test_write_basic_file
24
- exhaustively_test do |channels, bits_per_sample|
25
- file_name = "valid_#{channels}_#{bits_per_sample}_44100.wav"
26
- format = Format.new(CHANNEL_ALIAS[channels], bits_per_sample, 44100)
24
+ exhaustively_test do |channels, sample_format|
25
+ file_name = "valid_#{channels}_#{sample_format}_44100.wav"
26
+ format = Format.new(CHANNEL_ALIAS[channels], sample_format, 44100)
27
27
 
28
28
  writer = Writer.new("#{OUTPUT_FOLDER}/#{file_name}", format)
29
- writer.write(Buffer.new(SQUARE_WAVE_CYCLE[channels][bits_per_sample] * 128, format))
30
- writer.write(Buffer.new(SQUARE_WAVE_CYCLE[channels][bits_per_sample] * 128, format))
31
- writer.write(Buffer.new(SQUARE_WAVE_CYCLE[channels][bits_per_sample] * 24, format))
32
- writer.close()
29
+ writer.write(Buffer.new(SQUARE_WAVE_CYCLE[channels][sample_format] * 128, format))
30
+ writer.write(Buffer.new(SQUARE_WAVE_CYCLE[channels][sample_format] * 128, format))
31
+ writer.write(Buffer.new(SQUARE_WAVE_CYCLE[channels][sample_format] * 24, format))
32
+ writer.close
33
33
 
34
34
  assert_equal(read_file(:expected, file_name), read_file(:actual, file_name))
35
35
  end
36
36
  end
37
37
 
38
38
  def test_write_basic_file_with_a_block
39
- exhaustively_test do |channels, bits_per_sample|
40
- file_name = "valid_#{channels}_#{bits_per_sample}_44100.wav"
41
- format = Format.new(CHANNEL_ALIAS[channels], bits_per_sample, 44100)
39
+ exhaustively_test do |channels, sample_format|
40
+ file_name = "valid_#{channels}_#{sample_format}_44100.wav"
41
+ format = Format.new(CHANNEL_ALIAS[channels], sample_format, 44100)
42
42
 
43
43
  writer = Writer.new("#{OUTPUT_FOLDER}/#{file_name}", format) do |writer|
44
44
  4.times do
45
- writer.write(Buffer.new(SQUARE_WAVE_CYCLE[channels][bits_per_sample] * 70, format))
45
+ writer.write(Buffer.new(SQUARE_WAVE_CYCLE[channels][sample_format] * 70, format))
46
46
  end
47
47
  end
48
48
 
@@ -52,58 +52,145 @@ class WriterTest < Test::Unit::TestCase
52
52
  end
53
53
 
54
54
  def test_write_buffers_of_different_formats
55
- file_name = "valid_mono_8_44100.wav"
56
- format_8bit_mono = Format.new(:mono, 8, 44100)
57
- format_16_bit_mono = Format.new(:mono, 16, 22050)
58
- format_16bit_stereo = Format.new(:stereo, 16, 44100)
55
+ file_name = "valid_mono_pcm_8_44100.wav"
56
+ format_8bit_mono = Format.new(:mono, :pcm_8, 44100)
57
+ format_16_bit_mono = Format.new(:mono, :pcm_16, 22050)
58
+ format_16bit_stereo = Format.new(:stereo, :pcm_16, 44100)
59
59
 
60
60
  writer = Writer.new("#{OUTPUT_FOLDER}/#{file_name}", format_8bit_mono)
61
- writer.write(Buffer.new(SQUARE_WAVE_CYCLE[:stereo][16] * 128, format_16bit_stereo))
62
- writer.write(Buffer.new(SQUARE_WAVE_CYCLE[:mono][16] * 128, format_16_bit_mono))
63
- writer.write(Buffer.new(SQUARE_WAVE_CYCLE[:stereo][16] * 24, format_16bit_stereo))
64
- writer.close()
61
+ writer.write(Buffer.new(SQUARE_WAVE_CYCLE[:stereo][:pcm_16] * 128, format_16bit_stereo))
62
+ writer.write(Buffer.new(SQUARE_WAVE_CYCLE[:mono][:pcm_16] * 128, format_16_bit_mono))
63
+ writer.write(Buffer.new(SQUARE_WAVE_CYCLE[:stereo][:pcm_16] * 24, format_16bit_stereo))
64
+ writer.close
65
65
 
66
66
  assert_equal(read_file(:expected, file_name), read_file(:actual, file_name))
67
67
  end
68
68
 
69
69
  def test_write_file_with_padding_byte
70
- file_name = "valid_mono_8_44100_with_padding_byte.wav"
71
- format = Format.new(1, 8, 44100)
70
+ file_name = "valid_mono_pcm_8_44100_with_padding_byte.wav"
71
+ format = Format.new(:mono, :pcm_8, 44100)
72
72
 
73
73
  writer = Writer.new("#{OUTPUT_FOLDER}/#{file_name}", format)
74
- writer.write(Buffer.new(SQUARE_WAVE_CYCLE[:mono][8] * 128, format))
75
- writer.write(Buffer.new(SQUARE_WAVE_CYCLE[:mono][8] * 128, format))
76
- writer.write(Buffer.new(SQUARE_WAVE_CYCLE[:mono][8] * 23 + [88, 88, 88, 88, 167, 167, 167], format))
77
- writer.close()
74
+ writer.write(Buffer.new(SQUARE_WAVE_CYCLE[:mono][:pcm_8] * 128, format))
75
+ writer.write(Buffer.new(SQUARE_WAVE_CYCLE[:mono][:pcm_8] * 128, format))
76
+ writer.write(Buffer.new(SQUARE_WAVE_CYCLE[:mono][:pcm_8] * 23 + [88, 88, 88, 88, 167, 167, 167], format))
77
+ writer.close
78
78
 
79
79
  assert_equal(read_file(:expected, file_name), read_file(:actual, file_name))
80
80
  end
81
-
81
+
82
+ def test_file_name
83
+ file_name = "#{OUTPUT_FOLDER}/example.wav"
84
+
85
+ writer = Writer.new(file_name, Format.new(:mono, :pcm_8, 44100))
86
+ assert_equal("#{OUTPUT_FOLDER}/example.wav", writer.file_name)
87
+
88
+ writer.close
89
+ assert_equal("#{OUTPUT_FOLDER}/example.wav", writer.file_name)
90
+ end
91
+
82
92
  def test_closed?
83
- writer = Writer.new("#{OUTPUT_FOLDER}/closed_test.wav", Format.new(1, 16, 44100))
93
+ writer = Writer.new("#{OUTPUT_FOLDER}/closed_test.wav", Format.new(:mono, :pcm_16, 44100))
84
94
  assert_equal(false, writer.closed?)
85
- writer.close()
95
+ writer.close
86
96
  assert(writer.closed?)
87
97
  end
88
98
 
89
99
  def test_attempt_to_write_after_close
90
- format = Format.new(1, 8, 44100)
100
+ format = Format.new(:mono, :pcm_8, 44100)
91
101
 
92
102
  writer = Writer.new("#{OUTPUT_FOLDER}/write_after_close.wav", format)
93
103
  writer.write(Buffer.new([1, 2, 3, 4], format))
94
- writer.close()
104
+ writer.close
95
105
 
96
106
  assert_raise(IOError) { writer.write(Buffer.new([5, 6, 7, 8], format)) }
97
107
  end
98
108
 
109
+ def test_total_duration
110
+ exhaustively_test do |channels, sample_format|
111
+ format = Format.new(CHANNEL_ALIAS[channels], sample_format, 44100)
112
+
113
+ writer = Writer.new("#{OUTPUT_FOLDER}/total_duration_#{channels}_#{sample_format}_44100.wav", format)
114
+
115
+ assert_equal(0, writer.total_sample_frames)
116
+ duration = writer.total_duration
117
+ assert_equal(0, duration.sample_frame_count)
118
+ assert_equal(44100, duration.sample_rate)
119
+ assert_equal(0, duration.hours)
120
+ assert_equal(0, duration.minutes)
121
+ assert_equal(0, duration.seconds)
122
+ assert_equal(0, duration.milliseconds)
123
+
124
+ writer.write(Buffer.new(SQUARE_WAVE_CYCLE[channels][sample_format] * 2756, format))
125
+
126
+ assert_equal(8 * 2756, writer.total_sample_frames)
127
+ duration = writer.total_duration
128
+ assert_equal(8 * 2756, duration.sample_frame_count)
129
+ assert_equal(44100, duration.sample_rate)
130
+ assert_equal(0, duration.hours)
131
+ assert_equal(0, duration.minutes)
132
+ assert_equal(0, duration.seconds)
133
+ assert_equal(499, duration.milliseconds)
134
+
135
+ writer.write(Buffer.new(SQUARE_WAVE_CYCLE[channels][sample_format] * 2756, format))
136
+ writer.write(Buffer.new(SQUARE_WAVE_CYCLE[channels][sample_format] * 2756, format))
137
+
138
+ assert_equal(8 * 2756 * 3, writer.total_sample_frames)
139
+ duration = writer.total_duration
140
+ assert_equal(8 * 2756 * 3, duration.sample_frame_count)
141
+ assert_equal(44100, duration.sample_rate)
142
+ assert_equal(0, duration.hours)
143
+ assert_equal(0, duration.minutes)
144
+ assert_equal(1, duration.seconds)
145
+ assert_equal(499, duration.milliseconds)
146
+
147
+ writer.close
148
+
149
+ assert_equal(8 * 2756 * 3, writer.total_sample_frames)
150
+ duration = writer.total_duration
151
+ assert_equal(8 * 2756 * 3, duration.sample_frame_count)
152
+ assert_equal(44100, duration.sample_rate)
153
+ assert_equal(0, duration.hours)
154
+ assert_equal(0, duration.minutes)
155
+ assert_equal(1, duration.seconds)
156
+ assert_equal(499, duration.milliseconds)
157
+ end
158
+ end
159
+
160
+ # Cause an exception within the block passed to Writer.new, to prove
161
+ # that close is still called (due to an ensure statement in Writer.new).
162
+ def test_exception_with_block
163
+ format = Format.new(:mono, :pcm_8, 44100)
164
+ samples = [1, 2, 3, 4, 5, 6]
165
+ Writer.new("#{OUTPUT_FOLDER}/exception_with_block.wav", format) do |writer|
166
+ begin
167
+ writer.write(Buffer.new(samples, format))
168
+ 1 / 0 # cause divide-by-zero exception
169
+ rescue
170
+ # catch the exception and ignore, so test passes OK
171
+ end
172
+ end
173
+
174
+ reader = Reader.new("#{OUTPUT_FOLDER}/exception_with_block.wav")
175
+ assert_equal(samples.size, reader.total_sample_frames)
176
+ end
177
+
99
178
  private
100
179
 
101
180
  def read_file(type, file_name)
102
- # For Windows compatibility with binary files, File.read() is not directly used
103
- return File.open("test/fixtures/#{type}_output/#{file_name}", "rb") {|f| f.read() }
181
+ if type == :expected
182
+ fixture_folder = 'valid'
183
+ elsif type == :actual
184
+ fixture_folder = 'actual_output'
185
+ else
186
+ raise 'Invalid fixture type'
187
+ end
188
+
189
+ # For Windows compatibility with binary files, File.read is not directly used
190
+ File.open("test/fixtures/#{fixture_folder}/#{file_name}", "rb") {|f| f.read }
104
191
  end
105
192
 
106
- def clean_output_folder()
193
+ def clean_output_folder
107
194
  # Make the folder if it doesn't already exist
108
195
  Dir.mkdir(OUTPUT_FOLDER) unless File.exists?(OUTPUT_FOLDER)
109
196
 
metadata CHANGED
@@ -1,17 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wavefile
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
5
- prerelease:
4
+ version: 0.5.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Joel Strait
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-01-01 00:00:00.000000000 Z
11
+ date: 2013-02-25 00:00:00.000000000 Z
13
12
  dependencies: []
14
- description:
13
+ description: You can use this gem to create Ruby programs that produce audio. Since
14
+ it is written in pure Ruby (as opposed to wrapping an existing C library), you can
15
+ use it without having to compile a separate extension.
15
16
  email: joel dot strait at Google's popular web mail service
16
17
  executables: []
17
18
  extensions: []
@@ -21,24 +22,15 @@ files:
21
22
  - README.markdown
22
23
  - Rakefile
23
24
  - lib/wavefile/buffer.rb
25
+ - lib/wavefile/duration.rb
24
26
  - lib/wavefile/format.rb
25
27
  - lib/wavefile/info.rb
26
28
  - lib/wavefile/reader.rb
27
29
  - lib/wavefile/writer.rb
28
30
  - lib/wavefile.rb
29
31
  - test/buffer_test.rb
30
- - test/fixtures/actual_output/valid_mono_8_44100_with_padding_byte.wav
31
- - test/fixtures/expected_output/no_samples.wav
32
- - test/fixtures/expected_output/valid_mono_16_44100.wav
33
- - test/fixtures/expected_output/valid_mono_32_44100.wav
34
- - test/fixtures/expected_output/valid_mono_8_44100.wav
35
- - test/fixtures/expected_output/valid_mono_8_44100_with_padding_byte.wav
36
- - test/fixtures/expected_output/valid_stereo_16_44100.wav
37
- - test/fixtures/expected_output/valid_stereo_32_44100.wav
38
- - test/fixtures/expected_output/valid_stereo_8_44100.wav
39
- - test/fixtures/expected_output/valid_tri_16_44100.wav
40
- - test/fixtures/expected_output/valid_tri_32_44100.wav
41
- - test/fixtures/expected_output/valid_tri_8_44100.wav
32
+ - test/duration_test.rb
33
+ - test/fixtures/actual_output/valid_mono_pcm_8_44100_with_padding_byte.wav
42
34
  - test/fixtures/invalid/bad_riff_header.wav
43
35
  - test/fixtures/invalid/bad_wavefile_format.wav
44
36
  - test/fixtures/invalid/empty.wav
@@ -54,17 +46,24 @@ files:
54
46
  - test/fixtures/unsupported/README.markdown
55
47
  - test/fixtures/unsupported/unsupported_audio_format.wav
56
48
  - test/fixtures/unsupported/unsupported_bits_per_sample.wav
49
+ - test/fixtures/valid/no_samples.wav
57
50
  - test/fixtures/valid/README.markdown
58
- - test/fixtures/valid/valid_mono_16_44100.wav
59
- - test/fixtures/valid/valid_mono_32_44100.wav
60
- - test/fixtures/valid/valid_mono_8_44100.wav
61
- - test/fixtures/valid/valid_mono_8_44100_with_padding_byte.wav
62
- - test/fixtures/valid/valid_stereo_16_44100.wav
63
- - test/fixtures/valid/valid_stereo_32_44100.wav
64
- - test/fixtures/valid/valid_stereo_8_44100.wav
65
- - test/fixtures/valid/valid_tri_16_44100.wav
66
- - test/fixtures/valid/valid_tri_32_44100.wav
67
- - test/fixtures/valid/valid_tri_8_44100.wav
51
+ - test/fixtures/valid/valid_mono_float_32_44100.wav
52
+ - test/fixtures/valid/valid_mono_float_64_44100.wav
53
+ - test/fixtures/valid/valid_mono_pcm_16_44100.wav
54
+ - test/fixtures/valid/valid_mono_pcm_32_44100.wav
55
+ - test/fixtures/valid/valid_mono_pcm_8_44100.wav
56
+ - test/fixtures/valid/valid_mono_pcm_8_44100_with_padding_byte.wav
57
+ - test/fixtures/valid/valid_stereo_float_32_44100.wav
58
+ - test/fixtures/valid/valid_stereo_float_64_44100.wav
59
+ - test/fixtures/valid/valid_stereo_pcm_16_44100.wav
60
+ - test/fixtures/valid/valid_stereo_pcm_32_44100.wav
61
+ - test/fixtures/valid/valid_stereo_pcm_8_44100.wav
62
+ - test/fixtures/valid/valid_tri_float_32_44100.wav
63
+ - test/fixtures/valid/valid_tri_float_64_44100.wav
64
+ - test/fixtures/valid/valid_tri_pcm_16_44100.wav
65
+ - test/fixtures/valid/valid_tri_pcm_32_44100.wav
66
+ - test/fixtures/valid/valid_tri_pcm_8_44100.wav
68
67
  - test/format_test.rb
69
68
  - test/info_test.rb
70
69
  - test/reader_test.rb
@@ -72,26 +71,25 @@ files:
72
71
  - test/writer_test.rb
73
72
  homepage: http://www.joelstrait.com/
74
73
  licenses: []
74
+ metadata: {}
75
75
  post_install_message:
76
76
  rdoc_options: []
77
77
  require_paths:
78
78
  - lib
79
79
  required_ruby_version: !ruby/object:Gem::Requirement
80
- none: false
81
80
  requirements:
82
81
  - - ! '>='
83
82
  - !ruby/object:Gem::Version
84
83
  version: '0'
85
84
  required_rubygems_version: !ruby/object:Gem::Requirement
86
- none: false
87
85
  requirements:
88
86
  - - ! '>='
89
87
  - !ruby/object:Gem::Version
90
88
  version: '0'
91
89
  requirements: []
92
90
  rubyforge_project:
93
- rubygems_version: 1.8.10
91
+ rubygems_version: 2.0.0
94
92
  signing_key:
95
- specification_version: 3
96
- summary: A class for reading and writing Wave sound files (*.wav)
93
+ specification_version: 4
94
+ summary: A pure Ruby library for reading and writing Wave sound files (*.wav)
97
95
  test_files: []