lame 0.0.3 → 0.0.4
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 +7 -0
- data/.travis.yml +3 -4
- data/README.md +51 -17
- data/lib/lame.rb +1 -0
- data/lib/lame/buffer.rb +1 -1
- data/lib/lame/encoder.rb +10 -11
- data/lib/lame/encoding/long_buffer_encoder.rb +1 -1
- data/lib/lame/encoding/stereo_buffer_encoder.rb +1 -0
- data/lib/lame/ffi.rb +2 -0
- data/lib/lame/version.rb +1 -1
- data/spec/buffer_spec.rb +8 -8
- data/spec/configuration_spec.rb +76 -76
- data/spec/decoder_spec.rb +34 -34
- data/spec/decoding/decoded_frame_spec.rb +7 -7
- data/spec/decoding/id3_tag_parser_spec.rb +3 -3
- data/spec/decoding/mp3_data_header_parser_spec.rb +21 -21
- data/spec/decoding/mpeg_audio_frame_finder_spec.rb +15 -15
- data/spec/decoding/mpeg_audio_frame_matcher_spec.rb +2 -2
- data/spec/decoding/single_frame_decoder_spec.rb +36 -35
- data/spec/decoding/stream_decoder_spec.rb +10 -10
- data/spec/delegation_spec.rb +37 -37
- data/spec/encoder_spec.rb +100 -100
- data/spec/encoding/flusher_spec.rb +16 -16
- data/spec/encoding/id3_spec.rb +38 -38
- data/spec/encoding/interleaved_buffer_encoder_spec.rb +25 -25
- data/spec/encoding/stereo_buffer_encoder_spec.rb +34 -33
- data/spec/encoding/vbr_info_spec.rb +16 -16
- data/spec/ffi/decode_flags_spec.rb +3 -2
- data/spec/ffi/encoding_spec.rb +22 -22
- data/spec/ffi/global_flags_spec.rb +159 -157
- data/spec/ffi/id3tag_spec.rb +24 -24
- data/spec/ffi/mp3_data_spec.rb +3 -3
- data/spec/integration/encoding_spec.rb +75 -3
- data/spec/integration/id3_tags_spec.rb +18 -18
- data/spec/lib/custom_matchers.rb +4 -4
- data/spec/lib/wave_file_generator.rb +9 -9
- data/spec/spec_helper.rb +0 -1
- metadata +38 -60
data/spec/decoder_spec.rb
CHANGED
@@ -3,16 +3,16 @@ require 'spec_helper'
|
|
3
3
|
module LAME
|
4
4
|
describe Decoder do
|
5
5
|
|
6
|
-
let(:decode_flags) {
|
7
|
-
let(:mp3_file) {
|
8
|
-
let(:id3_tag_parser) {
|
9
|
-
let(:mp3_data_header_parser) {
|
6
|
+
let(:decode_flags) { double("decode flags") }
|
7
|
+
let(:mp3_file) { double("mp3 file") }
|
8
|
+
let(:id3_tag_parser) { double("id3 tag parser", :skip! => nil) }
|
9
|
+
let(:mp3_data_header_parser) { double("mp3 data header parser", :parse! => nil) }
|
10
10
|
|
11
11
|
# Stub away all collaborators:
|
12
12
|
before do
|
13
|
-
Decoding::Id3TagParser.
|
14
|
-
Decoding::Mp3DataHeaderParser.
|
15
|
-
FFI::DecodeFlags.
|
13
|
+
allow(Decoding::Id3TagParser).to receive(:new).and_return(id3_tag_parser)
|
14
|
+
allow(Decoding::Mp3DataHeaderParser).to receive(:new).and_return(mp3_data_header_parser)
|
15
|
+
allow(FFI::DecodeFlags).to receive(:new).and_return(decode_flags)
|
16
16
|
end
|
17
17
|
|
18
18
|
subject(:decoder) { Decoder.new(mp3_file) }
|
@@ -20,74 +20,74 @@ module LAME
|
|
20
20
|
context "initialization" do
|
21
21
|
|
22
22
|
it "initializes DecodeFlags" do
|
23
|
-
FFI::DecodeFlags.
|
23
|
+
expect(FFI::DecodeFlags).to receive(:new)
|
24
24
|
Decoder.new(mp3_file)
|
25
25
|
end
|
26
26
|
|
27
27
|
it "has the DecodeFlags" do
|
28
|
-
decode_flags =
|
29
|
-
FFI::DecodeFlags.
|
30
|
-
decoder.decode_flags.
|
28
|
+
decode_flags = double("decode_flags")
|
29
|
+
allow(FFI::DecodeFlags).to receive(:new).and_return(decode_flags)
|
30
|
+
expect(decoder.decode_flags).to eql decode_flags
|
31
31
|
end
|
32
32
|
|
33
33
|
it "has the mp3 file path" do
|
34
|
-
decoder.mp3_file.
|
34
|
+
expect(decoder.mp3_file).to eql mp3_file
|
35
35
|
end
|
36
36
|
|
37
37
|
it "skips the id3 offset" do
|
38
|
-
Decoding::Id3TagParser.
|
39
|
-
id3_tag_parser.
|
38
|
+
expect(Decoding::Id3TagParser).to receive(:new).with(mp3_file)
|
39
|
+
expect(id3_tag_parser).to receive(:skip!)
|
40
40
|
|
41
41
|
decoder
|
42
42
|
end
|
43
43
|
|
44
44
|
it "parses the mp3 data header" do
|
45
|
-
parser =
|
46
|
-
mp3_data =
|
47
|
-
Decoding::Mp3DataHeaderParser.
|
48
|
-
parser.
|
45
|
+
parser = double("parser")
|
46
|
+
mp3_data = double("mp3_data")
|
47
|
+
expect(Decoding::Mp3DataHeaderParser).to receive(:new).with(decode_flags, mp3_file).and_return(parser)
|
48
|
+
expect(parser).to receive(:parse!).and_return(mp3_data)
|
49
49
|
|
50
|
-
decoder.mp3_data.
|
50
|
+
expect(decoder.mp3_data).to eql mp3_data
|
51
51
|
end
|
52
52
|
|
53
53
|
end
|
54
54
|
|
55
55
|
context "after initialization" do
|
56
56
|
|
57
|
-
let(:mp3_data) {
|
57
|
+
let(:mp3_data) { double("mp3 data") }
|
58
58
|
|
59
59
|
# stubbing galore!
|
60
60
|
before do
|
61
|
-
FFI::DecodeFlags.
|
61
|
+
allow(FFI::DecodeFlags).to receive(:new).and_return(decode_flags)
|
62
62
|
|
63
|
-
parser =
|
64
|
-
Decoding::Mp3DataHeaderParser.
|
65
|
-
parser.
|
63
|
+
parser = double("parser")
|
64
|
+
allow(Decoding::Mp3DataHeaderParser).to receive(:new).and_return(parser)
|
65
|
+
allow(parser).to receive(:parse!).and_return(mp3_data)
|
66
66
|
end
|
67
67
|
|
68
68
|
describe "#each_decoded_frame" do
|
69
69
|
|
70
|
-
let(:stream_decoder) {
|
70
|
+
let(:stream_decoder) { double("stream_decoder") }
|
71
71
|
before do
|
72
|
-
Decoding::StreamDecoder.
|
72
|
+
allow(Decoding::StreamDecoder).to receive(:new).and_return(stream_decoder)
|
73
73
|
end
|
74
74
|
|
75
75
|
it "initializes a stream decoder with mp3 file and mp3 data" do
|
76
|
-
stream_decoder.
|
76
|
+
allow(stream_decoder).to receive(:each_decoded_frame)
|
77
77
|
|
78
|
-
Decoding::StreamDecoder.
|
78
|
+
expect(Decoding::StreamDecoder).to receive(:new).with(decode_flags, mp3_data, mp3_file)
|
79
79
|
|
80
80
|
decoder.each_decoded_frame
|
81
81
|
end
|
82
82
|
|
83
83
|
it "delegates to a stream decoder" do
|
84
|
-
stream_decoder.
|
84
|
+
expect(stream_decoder).to receive(:each_decoded_frame)
|
85
85
|
|
86
86
|
decoder.each_decoded_frame
|
87
87
|
end
|
88
88
|
|
89
89
|
it "re-yields the stream decoder's yield" do
|
90
|
-
stream_decoder.
|
90
|
+
allow(stream_decoder).to receive(:each_decoded_frame).and_yield(:one).and_yield(:two)
|
91
91
|
|
92
92
|
expect { |block|
|
93
93
|
decoder.each_decoded_frame(&block)
|
@@ -99,8 +99,8 @@ module LAME
|
|
99
99
|
describe "#channel_mode" do
|
100
100
|
|
101
101
|
it "delegates to mp3_data" do
|
102
|
-
mp3_data.
|
103
|
-
decoder.channel_mode.
|
102
|
+
expect(mp3_data).to receive(:channel_mode).and_return(:stereo)
|
103
|
+
expect(decoder.channel_mode).to eql :stereo
|
104
104
|
end
|
105
105
|
|
106
106
|
end
|
@@ -108,8 +108,8 @@ module LAME
|
|
108
108
|
describe "#sample_rate" do
|
109
109
|
|
110
110
|
it "delegates to mp3_data" do
|
111
|
-
mp3_data.
|
112
|
-
decoder.sample_rate.
|
111
|
+
allow(mp3_data).to receive(:sample_rate).and_return(44100)
|
112
|
+
expect(decoder.sample_rate).to eql 44100
|
113
113
|
end
|
114
114
|
|
115
115
|
end
|
@@ -5,13 +5,13 @@ module LAME
|
|
5
5
|
describe DecodedFrame do
|
6
6
|
|
7
7
|
it "is initialized with left and right samples" do
|
8
|
-
left =
|
9
|
-
right =
|
8
|
+
left = double("left")
|
9
|
+
right = double("right")
|
10
10
|
|
11
11
|
decoded_frame = DecodedFrame.new(left, right)
|
12
12
|
|
13
|
-
decoded_frame.left.
|
14
|
-
decoded_frame.right.
|
13
|
+
expect(decoded_frame.left).to eql left
|
14
|
+
expect(decoded_frame.right).to eql right
|
15
15
|
end
|
16
16
|
|
17
17
|
it "can be built with FFI Buffers" do
|
@@ -23,8 +23,8 @@ module LAME
|
|
23
23
|
|
24
24
|
decoded_frame = DecodedFrame.from_short_buffers(left_buffer, right_buffer)
|
25
25
|
|
26
|
-
decoded_frame.left.
|
27
|
-
decoded_frame.right.
|
26
|
+
expect(decoded_frame.left).to eql [1,2,3,4]
|
27
|
+
expect(decoded_frame.right).to eql [5,6,7,8]
|
28
28
|
end
|
29
29
|
|
30
30
|
describe "#samples" do
|
@@ -35,7 +35,7 @@ module LAME
|
|
35
35
|
|
36
36
|
decoded_frame = DecodedFrame.new(left, right)
|
37
37
|
|
38
|
-
decoded_frame.samples.
|
38
|
+
expect(decoded_frame.samples).to eql [[1,5],[2,6],[3,7],[4,8]]
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
@@ -21,13 +21,13 @@ module LAME
|
|
21
21
|
|
22
22
|
it "seeks the file until after the id3 tag" do
|
23
23
|
parser.skip!
|
24
|
-
stream.pos.
|
24
|
+
expect(stream.pos).to eql 351
|
25
25
|
end
|
26
26
|
|
27
27
|
it "start from the start of the stream" do
|
28
28
|
stream.seek(42)
|
29
29
|
parser.skip!
|
30
|
-
stream.pos.
|
30
|
+
expect(stream.pos).to eql 351
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
@@ -43,7 +43,7 @@ module LAME
|
|
43
43
|
|
44
44
|
it "does not seek the stream if no header is present" do
|
45
45
|
parser.skip!
|
46
|
-
stream.pos.
|
46
|
+
expect(stream.pos).to eql 0
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
@@ -6,22 +6,22 @@ module LAME
|
|
6
6
|
|
7
7
|
subject(:parser) { Mp3DataHeaderParser.new(decode_flags, stream) }
|
8
8
|
|
9
|
-
let(:decode_flags) {
|
9
|
+
let(:decode_flags) { double("decode flags") }
|
10
10
|
let(:stream) { StringIO.new(stream_string) }
|
11
|
-
let(:mpeg_finder) {
|
11
|
+
let(:mpeg_finder) { double("mpeg_finder") }
|
12
12
|
|
13
13
|
let(:stream_string) { "a"*100 }
|
14
14
|
|
15
15
|
before do
|
16
|
-
LAME.
|
16
|
+
allow(LAME).to receive(:hip_decode1_headersB) do |_, _, _, _, _, mp3_data, _, _|
|
17
17
|
# fake that the header was found
|
18
18
|
mp3_data[:header_parsed] = 1
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
22
|
it "seeks the input stream until the first mpeg frame" do
|
23
|
-
MPEGAudioFrameFinder.
|
24
|
-
mpeg_finder.
|
23
|
+
expect(MPEGAudioFrameFinder).to receive(:new).with(stream).and_return(mpeg_finder)
|
24
|
+
expect(mpeg_finder).to receive(:find!)
|
25
25
|
|
26
26
|
parser.parse!
|
27
27
|
end
|
@@ -29,20 +29,20 @@ module LAME
|
|
29
29
|
context "decoding headers" do
|
30
30
|
|
31
31
|
before do
|
32
|
-
MPEGAudioFrameFinder.
|
32
|
+
allow(MPEGAudioFrameFinder).to receive(:new).and_return(double.as_null_object)
|
33
33
|
end
|
34
34
|
|
35
35
|
it "reads 100 bytes from the stream" do
|
36
|
-
stream.
|
36
|
+
expect(stream).to receive(:read).with(100).and_return("a"*100)
|
37
37
|
parser.parse!
|
38
38
|
end
|
39
39
|
|
40
40
|
it "parses headers with LAME" do
|
41
|
-
LAME.
|
42
|
-
decode_flags.
|
43
|
-
in_buffer.get_string(0).
|
44
|
-
size.
|
45
|
-
mp3_data.
|
41
|
+
expect(LAME).to receive(:hip_decode1_headersB) do |decode_flags, in_buffer, size, _, _, mp3_data, _, _|
|
42
|
+
expect(decode_flags).to eql decode_flags
|
43
|
+
expect(in_buffer.get_string(0)).to eql "a"*100
|
44
|
+
expect(size).to eql 100
|
45
|
+
expect(mp3_data).to be_a(LAME::FFI::MP3Data)
|
46
46
|
|
47
47
|
# fake that the header was found
|
48
48
|
mp3_data[:header_parsed] = 1
|
@@ -57,9 +57,9 @@ module LAME
|
|
57
57
|
it "reads 100 bytes until a header was parsed" do
|
58
58
|
decode_count = 0
|
59
59
|
|
60
|
-
LAME.
|
60
|
+
expect(LAME).to receive(:hip_decode1_headersB).exactly(expected_reads).times
|
61
61
|
|
62
|
-
LAME.
|
62
|
+
allow(LAME).to receive(:hip_decode1_headersB) do |_, _, _, _, _, mp3_data, _, _|
|
63
63
|
decode_count += 1
|
64
64
|
|
65
65
|
# simulate parsed header after 5 reads:
|
@@ -71,17 +71,17 @@ module LAME
|
|
71
71
|
end
|
72
72
|
|
73
73
|
it "returns the parsed mp3 data if a header was parsed" do
|
74
|
-
mp3_data =
|
75
|
-
LAME::FFI::MP3Data.
|
76
|
-
LAME.
|
74
|
+
mp3_data = double("mp3 data", :header_parsed? => true)
|
75
|
+
allow(LAME::FFI::MP3Data).to receive(:new).and_return(mp3_data)
|
76
|
+
allow(LAME).to receive(:hip_decode1_headersB)
|
77
77
|
|
78
|
-
parser.parse
|
78
|
+
expect(parser.parse!).to eql mp3_data
|
79
79
|
end
|
80
80
|
|
81
81
|
it "raises an error if the header could not be parsed" do
|
82
|
-
mp3_data =
|
83
|
-
LAME::FFI::MP3Data.
|
84
|
-
LAME.
|
82
|
+
mp3_data = double("mp3 data", :header_parsed? => false)
|
83
|
+
allow(LAME::FFI::MP3Data).to receive(:new).and_return(mp3_data)
|
84
|
+
allow(LAME).to receive(:hip_decode1_headersB)
|
85
85
|
|
86
86
|
expect {
|
87
87
|
parser.parse!
|
@@ -10,35 +10,35 @@ module LAME
|
|
10
10
|
let(:stream_string) { "1234567890" }
|
11
11
|
|
12
12
|
it "tries to find the mpeg frame 4 bytes at a time until a header is found" do
|
13
|
-
matcher1 =
|
14
|
-
matcher2 =
|
15
|
-
matcher3 =
|
13
|
+
matcher1 = double("matcher", :match? => false)
|
14
|
+
matcher2 = double("matcher", :match? => false)
|
15
|
+
matcher3 = double("matcher", :match? => true)
|
16
16
|
|
17
|
-
MPEGAudioFrameMatcher.
|
18
|
-
MPEGAudioFrameMatcher.
|
19
|
-
MPEGAudioFrameMatcher.
|
17
|
+
expect(MPEGAudioFrameMatcher).to receive(:new).with("1234").and_return(matcher1)
|
18
|
+
expect(MPEGAudioFrameMatcher).to receive(:new).with("2345").and_return(matcher2)
|
19
|
+
expect(MPEGAudioFrameMatcher).to receive(:new).with("3456").and_return(matcher3)
|
20
20
|
|
21
21
|
finder.find!
|
22
22
|
end
|
23
23
|
|
24
24
|
it "seeks the stream at the position of the found frame" do
|
25
|
-
matcher1 =
|
26
|
-
matcher2 =
|
27
|
-
matcher3 =
|
25
|
+
matcher1 = double("matcher", :match? => false)
|
26
|
+
matcher2 = double("matcher", :match? => false)
|
27
|
+
matcher3 = double("matcher", :match? => true)
|
28
28
|
|
29
|
-
MPEGAudioFrameMatcher.
|
30
|
-
MPEGAudioFrameMatcher.
|
31
|
-
MPEGAudioFrameMatcher.
|
29
|
+
allow(MPEGAudioFrameMatcher).to receive(:new).with("1234").and_return(matcher1)
|
30
|
+
allow(MPEGAudioFrameMatcher).to receive(:new).with("2345").and_return(matcher2)
|
31
|
+
allow(MPEGAudioFrameMatcher).to receive(:new).with("3456").and_return(matcher3)
|
32
32
|
|
33
33
|
finder.find!
|
34
34
|
|
35
|
-
stream.pos.
|
35
|
+
expect(stream.pos).to eql 2
|
36
36
|
end
|
37
37
|
|
38
38
|
it "raises an error if no header could be found" do
|
39
|
-
matcher =
|
39
|
+
matcher = double("matcher", :match? => false)
|
40
40
|
|
41
|
-
MPEGAudioFrameMatcher.
|
41
|
+
allow(MPEGAudioFrameMatcher).to receive(:new).and_return(matcher)
|
42
42
|
|
43
43
|
expect {
|
44
44
|
finder.find!
|
@@ -41,14 +41,14 @@ module LAME
|
|
41
41
|
shared_examples_for "4 valid bytes" do
|
42
42
|
it "matches" do
|
43
43
|
bytes = [b1, b2, b3, b4].pack("C*")
|
44
|
-
MPEGAudioFrameMatcher.new(bytes).match
|
44
|
+
expect(MPEGAudioFrameMatcher.new(bytes).match?).to be_truthy
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
48
|
shared_examples_for "4 invalid bytes" do
|
49
49
|
it "does not match" do
|
50
50
|
bytes = [b1, b2, b3, b4].pack("C*")
|
51
|
-
MPEGAudioFrameMatcher.new(bytes).match
|
51
|
+
expect(MPEGAudioFrameMatcher.new(bytes).match?).to be_falsy
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
@@ -6,41 +6,41 @@ module LAME
|
|
6
6
|
|
7
7
|
subject(:decoder) { SingleFrameDecoder.new(decode_flags, mp3_data) }
|
8
8
|
|
9
|
-
let(:decode_flags) {
|
10
|
-
let(:mp3_data) {
|
9
|
+
let(:decode_flags) { double("decode flags") }
|
10
|
+
let(:mp3_data) { double("mp3 data") }
|
11
11
|
let(:data) { "a"*1024 }
|
12
12
|
|
13
13
|
it "always checks if there is a decoded frame in the internal buffer" do
|
14
14
|
# initial decoded frame
|
15
|
-
LAME.
|
16
|
-
flags.
|
17
|
-
in_buffer.size.
|
18
|
-
in_size.
|
19
|
-
out_left.size.
|
20
|
-
out_right.size.
|
21
|
-
mp3_data_arg.
|
15
|
+
expect(LAME).to receive(:hip_decode1_headers) do |flags, in_buffer, in_size, out_left, out_right, mp3_data_arg|
|
16
|
+
expect(flags).to eql decode_flags
|
17
|
+
expect(in_buffer.size).to eql 0
|
18
|
+
expect(in_size).to eql 0
|
19
|
+
expect(out_left.size).to eql 1152*2 # short is 2 bytes
|
20
|
+
expect(out_right.size).to eql 1152*2
|
21
|
+
expect(mp3_data_arg).to eql mp3_data
|
22
22
|
0
|
23
23
|
end
|
24
24
|
# new data
|
25
|
-
LAME.
|
25
|
+
allow(LAME).to receive(:hip_decode1_headers).and_return(0)
|
26
26
|
|
27
27
|
decoder.decode(data)
|
28
28
|
end
|
29
29
|
|
30
30
|
it "writes the input data into the LAME decoder" do
|
31
31
|
# initial
|
32
|
-
LAME.
|
33
|
-
in_buffer.size.
|
32
|
+
expect(LAME).to receive(:hip_decode1_headers) do |_, in_buffer, _, _ , _, _|
|
33
|
+
expect(in_buffer.size).to eql 0
|
34
34
|
0
|
35
35
|
end
|
36
36
|
# new data
|
37
|
-
LAME.
|
38
|
-
flags.
|
39
|
-
in_buffer.size.
|
40
|
-
in_size.
|
41
|
-
out_left.size.
|
42
|
-
out_right.size.
|
43
|
-
mp3_data_arg.
|
37
|
+
expect(LAME).to receive(:hip_decode1_headers) do |flags, in_buffer, in_size, out_left, out_right, mp3_data_arg|
|
38
|
+
expect(flags).to eql decode_flags
|
39
|
+
expect(in_buffer.size).to eql 1024
|
40
|
+
expect(in_size).to eql 1024
|
41
|
+
expect(out_left.size).to eql 1152*2 # short is 2 bytes
|
42
|
+
expect(out_right.size).to eql 1152*2
|
43
|
+
expect(mp3_data_arg).to eql mp3_data
|
44
44
|
0
|
45
45
|
end
|
46
46
|
|
@@ -48,14 +48,14 @@ module LAME
|
|
48
48
|
end
|
49
49
|
|
50
50
|
it "decodes until no more frames were decoded" do
|
51
|
-
LAME.
|
52
|
-
LAME.
|
51
|
+
allow(LAME).to receive(:hip_decode1_headers).and_return(0, 1, 1, 0)
|
52
|
+
expect(LAME).to receive(:hip_decode1_headers).exactly(4).times
|
53
53
|
|
54
54
|
decoder.decode(data) {}
|
55
55
|
end
|
56
56
|
|
57
57
|
it "yields decoded frames if one is left in internal buffer" do
|
58
|
-
LAME.
|
58
|
+
allow(LAME).to receive(:hip_decode1_headers).and_return(1, 0)
|
59
59
|
|
60
60
|
expect { |block|
|
61
61
|
decoder.decode(data, &block)
|
@@ -63,7 +63,7 @@ module LAME
|
|
63
63
|
end
|
64
64
|
|
65
65
|
it "yields decoded frames for new data" do
|
66
|
-
LAME.
|
66
|
+
allow(LAME).to receive(:hip_decode1_headers).and_return(0, 1, 1, 0)
|
67
67
|
|
68
68
|
expect { |block|
|
69
69
|
decoder.decode(data, &block)
|
@@ -71,31 +71,32 @@ module LAME
|
|
71
71
|
end
|
72
72
|
|
73
73
|
it "raises an error if decoding failed" do
|
74
|
-
LAME.
|
74
|
+
allow(LAME).to receive(:hip_decode1_headers).and_return(-1)
|
75
75
|
|
76
76
|
expect {
|
77
77
|
decoder.decode(data)
|
78
78
|
}.to raise_error(DecodingError)
|
79
79
|
end
|
80
80
|
|
81
|
-
|
82
|
-
|
83
|
-
LAME.stub(:hip_decode1_headers).and_return(0, 1, 1, 0)
|
81
|
+
it "yields until no more data is decoded" do
|
82
|
+
allow(LAME).to receive(:hip_decode1_headers).and_return(0, 1, 1, 0)
|
84
83
|
|
85
|
-
LAME.
|
84
|
+
expect(LAME).to receive(:hip_decode1_headers).exactly(4).times
|
86
85
|
|
87
|
-
expect {
|
88
|
-
decoder.decode(data)
|
86
|
+
expect { |block|
|
87
|
+
decoder.decode(data, &block)
|
89
88
|
}.to yield_control.exactly(2).times
|
90
89
|
end
|
91
90
|
|
92
|
-
|
93
|
-
|
91
|
+
it "yields if the decoder still had a decoded frame " do
|
92
|
+
# the initial '1' indicates a frame was still in the internal buffer (flush)
|
93
|
+
# the subsequent '1's are newly decoded frames
|
94
|
+
allow(LAME).to receive(:hip_decode1_headers).and_return(1, 0, 1, 1, 0)
|
94
95
|
|
95
|
-
LAME.
|
96
|
+
expect(LAME).to receive(:hip_decode1_headers).exactly(5).times
|
96
97
|
|
97
|
-
expect {
|
98
|
-
decoder.decode(data)
|
98
|
+
expect { |block|
|
99
|
+
decoder.decode(data, &block)
|
99
100
|
}.to yield_control.exactly(3).times
|
100
101
|
end
|
101
102
|
|