icanhasaudio 0.1.1 → 0.1.2
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.
- data/History.txt +6 -0
- data/Manifest.txt +24 -14
- data/README.txt +2 -0
- data/Rakefile +15 -8
- data/ext/icanhasaudio/audio_mpeg_decoder.c +220 -0
- data/ext/icanhasaudio/audio_mpeg_decoder.h +8 -0
- data/ext/icanhasaudio/audio_mpeg_decoder_mp3data.c +96 -0
- data/ext/icanhasaudio/audio_mpeg_decoder_mp3data.h +8 -0
- data/ext/{mpeg_encoder.c → icanhasaudio/audio_mpeg_encoder.c} +94 -102
- data/ext/icanhasaudio/audio_mpeg_encoder.h +8 -0
- data/ext/{rb_ogg.c → icanhasaudio/audio_ogg_decoder.c} +18 -9
- data/ext/icanhasaudio/audio_ogg_decoder.h +8 -0
- data/ext/{extconf.rb → icanhasaudio/extconf.rb} +2 -2
- data/ext/{get_audio.c → icanhasaudio/get_audio.c} +1 -6
- data/ext/{get_audio.h → icanhasaudio/get_audio.h} +2 -0
- data/ext/icanhasaudio/native.c +9 -0
- data/ext/icanhasaudio/native.h +21 -0
- data/ext/{rb_wav.c → icanhasaudio/rb_wav.c} +1 -2
- data/ext/{rb_wav.h → icanhasaudio/rb_wav.h} +1 -2
- data/lib/icanhasaudio.rb +4 -0
- data/lib/icanhasaudio/mpeg.rb +1 -24
- data/lib/icanhasaudio/mpeg/decoder.rb +95 -0
- data/lib/icanhasaudio/ogg.rb +1 -21
- data/lib/icanhasaudio/ogg/decoder.rb +31 -0
- data/lib/icanhasaudio/version.rb +8 -0
- data/lib/icanhasaudio/wav.rb +1 -0
- data/lib/icanhasaudio/wav/file.rb +62 -0
- data/test/assets/icha.mp3 +0 -0
- data/test/helper.rb +15 -0
- data/test/mpeg/test_decoder.rb +20 -0
- data/test/test_mpeg_encoder.rb +2 -4
- metadata +31 -18
- data/ext/decoder.c +0 -95
- data/ext/decoder.h +0 -3
- data/ext/icanhasaudio.c +0 -183
- data/ext/icanhasaudio.h +0 -8
- data/ext/mpeg_encoder.h +0 -10
- data/ext/syncword.c +0 -45
- data/ext/syncword.h +0 -3
data/test/test_mpeg_encoder.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
|
-
require '
|
2
|
-
require 'icanhasaudio'
|
3
|
-
require 'tempfile'
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'helper'))
|
4
2
|
|
5
|
-
class MPEGEncoderTest <
|
3
|
+
class MPEGEncoderTest < ICANHASAUDIO::TestCase
|
6
4
|
include Audio::MPEG
|
7
5
|
|
8
6
|
WAV_FILE = File.dirname(__FILE__) + "/assets/testcase.wav"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: icanhasaudio
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aaron Patterson
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-
|
12
|
+
date: 2008-09-28 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -27,7 +27,7 @@ email: aaronp@rubyforge.org
|
|
27
27
|
executables: []
|
28
28
|
|
29
29
|
extensions:
|
30
|
-
- ext/extconf.rb
|
30
|
+
- ext/icanhasaudio/extconf.rb
|
31
31
|
extra_rdoc_files:
|
32
32
|
- History.txt
|
33
33
|
- LICENSE.txt
|
@@ -42,27 +42,39 @@ files:
|
|
42
42
|
- examples/decoder.rb
|
43
43
|
- examples/encoder.rb
|
44
44
|
- examples/kexp.rb
|
45
|
-
- ext/
|
46
|
-
- ext/
|
47
|
-
- ext/
|
48
|
-
- ext/
|
49
|
-
- ext/
|
50
|
-
- ext/icanhasaudio.
|
51
|
-
- ext/icanhasaudio.
|
52
|
-
- ext/
|
53
|
-
- ext/
|
54
|
-
- ext/
|
55
|
-
- ext/
|
56
|
-
- ext/
|
57
|
-
- ext/
|
58
|
-
- ext/
|
45
|
+
- ext/icanhasaudio/audio_mpeg_decoder.c
|
46
|
+
- ext/icanhasaudio/audio_mpeg_decoder.h
|
47
|
+
- ext/icanhasaudio/audio_mpeg_decoder_mp3data.c
|
48
|
+
- ext/icanhasaudio/audio_mpeg_decoder_mp3data.h
|
49
|
+
- ext/icanhasaudio/audio_mpeg_encoder.c
|
50
|
+
- ext/icanhasaudio/audio_mpeg_encoder.h
|
51
|
+
- ext/icanhasaudio/audio_ogg_decoder.c
|
52
|
+
- ext/icanhasaudio/audio_ogg_decoder.h
|
53
|
+
- ext/icanhasaudio/extconf.rb
|
54
|
+
- ext/icanhasaudio/get_audio.c
|
55
|
+
- ext/icanhasaudio/get_audio.h
|
56
|
+
- ext/icanhasaudio/native.c
|
57
|
+
- ext/icanhasaudio/native.h
|
58
|
+
- ext/icanhasaudio/rb_wav.c
|
59
|
+
- ext/icanhasaudio/rb_wav.h
|
60
|
+
- lib/icanhasaudio.rb
|
59
61
|
- lib/icanhasaudio/mpeg.rb
|
62
|
+
- lib/icanhasaudio/mpeg/decoder.rb
|
60
63
|
- lib/icanhasaudio/mpeg/encoder.rb
|
61
64
|
- lib/icanhasaudio/ogg.rb
|
65
|
+
- lib/icanhasaudio/ogg/decoder.rb
|
66
|
+
- lib/icanhasaudio/version.rb
|
67
|
+
- lib/icanhasaudio/wav.rb
|
68
|
+
- lib/icanhasaudio/wav/file.rb
|
69
|
+
- test/assets/icha.mp3
|
62
70
|
- test/assets/testcase.wav
|
71
|
+
- test/helper.rb
|
72
|
+
- test/mpeg/test_decoder.rb
|
63
73
|
- test/test_mpeg_encoder.rb
|
64
74
|
has_rdoc: true
|
65
|
-
homepage:
|
75
|
+
homepage: |
|
76
|
+
http://icanhasaudio.com/
|
77
|
+
|
66
78
|
post_install_message:
|
67
79
|
rdoc_options:
|
68
80
|
- --main
|
@@ -90,4 +102,5 @@ signing_key:
|
|
90
102
|
specification_version: 2
|
91
103
|
summary: icanhasaudio is a lame/vorbis wrapper for decoding ur mp3s and ur oggs.
|
92
104
|
test_files:
|
105
|
+
- test/mpeg/test_decoder.rb
|
93
106
|
- test/test_mpeg_encoder.rb
|
data/ext/decoder.c
DELETED
@@ -1,95 +0,0 @@
|
|
1
|
-
#include <ruby.h>
|
2
|
-
#include <lame/lame.h>
|
3
|
-
#include <assert.h>
|
4
|
-
#include <decoder.h>
|
5
|
-
#include <get_audio.h>
|
6
|
-
#include <rb_wav.h>
|
7
|
-
|
8
|
-
int
|
9
|
-
lame_decoder(VALUE self, VALUE infile, VALUE outf, mp3data_struct * mp3data)
|
10
|
-
{
|
11
|
-
lame_global_flags * gfp;
|
12
|
-
short int Buffer[2][1152];
|
13
|
-
int iread;
|
14
|
-
double wavsize;
|
15
|
-
int i;
|
16
|
-
int tmp_num_channels;
|
17
|
-
int skip;
|
18
|
-
char headbuf[44];
|
19
|
-
VALUE raw;
|
20
|
-
|
21
|
-
raw = rb_iv_get(self, "@raw");
|
22
|
-
if(raw == Qnil) {
|
23
|
-
raw = Qfalse;
|
24
|
-
rb_iv_set(self, "@raw", Qfalse);
|
25
|
-
}
|
26
|
-
|
27
|
-
Data_Get_Struct(self, lame_global_flags, gfp);
|
28
|
-
tmp_num_channels = lame_get_num_channels( gfp );
|
29
|
-
|
30
|
-
skip = lame_get_encoder_delay(gfp)+528+1;
|
31
|
-
|
32
|
-
if(!raw) {
|
33
|
-
rb_iv_set(self, "@bits", INT2NUM(16));
|
34
|
-
prelim_header( self,
|
35
|
-
headbuf,
|
36
|
-
0x7FFFFFFF,
|
37
|
-
0,
|
38
|
-
tmp_num_channels,
|
39
|
-
lame_get_in_samplerate( gfp )
|
40
|
-
);
|
41
|
-
rb_funcall(outf, rb_intern("write"), 1, rb_str_new(headbuf, 44));
|
42
|
-
}
|
43
|
-
|
44
|
-
wavsize = -skip;
|
45
|
-
mp3data->totalframes = mp3data->nsamp / mp3data->framesize;
|
46
|
-
|
47
|
-
assert(tmp_num_channels >= 1 && tmp_num_channels <= 2);
|
48
|
-
|
49
|
-
do {
|
50
|
-
char BitBuffer16[1152 * 4];
|
51
|
-
int bit_16_i = 0;
|
52
|
-
int total = 0;
|
53
|
-
iread = get_audio16(self, infile, Buffer, mp3data);
|
54
|
-
mp3data->framenum += iread / mp3data->framesize;
|
55
|
-
wavsize += iread;
|
56
|
-
|
57
|
-
memset(&BitBuffer16, 0, 1152 * 4);
|
58
|
-
|
59
|
-
skip -= (i = skip < iread ? skip : iread); /* 'i' samples are to skip in this frame */
|
60
|
-
|
61
|
-
for (; i < iread; i++) {
|
62
|
-
/* Write the 0 channel */
|
63
|
-
BitBuffer16[bit_16_i] = Buffer[0][i] & 0xFF;
|
64
|
-
BitBuffer16[bit_16_i + 1] = ((Buffer[0][i] >> 8) & 0xFF);
|
65
|
-
|
66
|
-
if (tmp_num_channels == 2) {
|
67
|
-
BitBuffer16[bit_16_i + 2] = Buffer[1][i] & 0xFF;
|
68
|
-
BitBuffer16[bit_16_i + 3] = ((Buffer[1][i] >> 8) & 0xFF);
|
69
|
-
bit_16_i += 4;
|
70
|
-
} else {
|
71
|
-
bit_16_i += 2;
|
72
|
-
}
|
73
|
-
}
|
74
|
-
rb_funcall(outf, rb_intern("write"), 1, rb_str_new(BitBuffer16, bit_16_i));
|
75
|
-
} while (iread);
|
76
|
-
|
77
|
-
i = (16 / 8) * tmp_num_channels;
|
78
|
-
assert(i > 0);
|
79
|
-
if (wavsize <= 0) {
|
80
|
-
wavsize = 0;
|
81
|
-
}
|
82
|
-
else if (wavsize > 0xFFFFFFD0 / i) {
|
83
|
-
wavsize = 0xFFFFFFD0;
|
84
|
-
}
|
85
|
-
else {
|
86
|
-
wavsize *= i;
|
87
|
-
}
|
88
|
-
|
89
|
-
if(!raw && rb_funcall(self, rb_intern("attempt_rewind"), 1, outf)) {
|
90
|
-
rewrite_header(headbuf, (int)wavsize);
|
91
|
-
rb_funcall(outf, rb_intern("write"), 1, rb_str_new(headbuf, 44));
|
92
|
-
}
|
93
|
-
return 0;
|
94
|
-
}
|
95
|
-
|
data/ext/decoder.h
DELETED
data/ext/icanhasaudio.c
DELETED
@@ -1,183 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
* Most of this code was take from the lame front end. So thank you to the
|
3
|
-
* lame team! The good parts are theirs, the bad parts are mine.
|
4
|
-
*
|
5
|
-
* The rest of it is (c) 2007 Aaron Patterson <aaronp@tenderlovemaking.com>
|
6
|
-
*
|
7
|
-
* Released under the GPL
|
8
|
-
*/
|
9
|
-
#include "icanhasaudio.h"
|
10
|
-
#include "syncword.h"
|
11
|
-
#include "decoder.h"
|
12
|
-
#include "mpeg_encoder.h"
|
13
|
-
#include "get_audio.h"
|
14
|
-
|
15
|
-
static VALUE rb_mAudio;
|
16
|
-
static VALUE rb_mMpeg;
|
17
|
-
static VALUE rb_cDecoder;
|
18
|
-
static VALUE rb_mOgg;
|
19
|
-
static VALUE rb_cOggDecoder;
|
20
|
-
|
21
|
-
static void reader_mark(lame_global_flags * lgf) {}
|
22
|
-
static void reader_free(lame_global_flags * gfp) {
|
23
|
-
lame_close(gfp);
|
24
|
-
}
|
25
|
-
|
26
|
-
/*
|
27
|
-
* call-seq:
|
28
|
-
* decoder.decode(input_io, output_io)
|
29
|
-
*
|
30
|
-
* Decode the input IO and write it to the output IO.
|
31
|
-
*/
|
32
|
-
VALUE method_ogg_decode(VALUE self, VALUE infile, VALUE outf);
|
33
|
-
|
34
|
-
/*
|
35
|
-
* call-seq:
|
36
|
-
* Audio::MPEG::Decoder.new
|
37
|
-
*
|
38
|
-
* Returns a new MPEG Decoder object.
|
39
|
-
*/
|
40
|
-
static VALUE
|
41
|
-
reader_allocate(VALUE klass) {
|
42
|
-
int i = 0;
|
43
|
-
lame_global_flags * gfp = lame_init();
|
44
|
-
lame_set_decode_only(gfp, 1);
|
45
|
-
i = lame_init_params(gfp);
|
46
|
-
|
47
|
-
if(i < 0) {
|
48
|
-
rb_raise(rb_eRuntimeError, "Fatal error during initialization.\n");
|
49
|
-
}
|
50
|
-
lame_decode_init();
|
51
|
-
return Data_Wrap_Struct(klass, reader_mark, reader_free, gfp);
|
52
|
-
}
|
53
|
-
|
54
|
-
/*
|
55
|
-
* call-seq:
|
56
|
-
* Audio::MPEG::Decoder.lame_version
|
57
|
-
*
|
58
|
-
* Returns the version of lame you are using.
|
59
|
-
*/
|
60
|
-
static VALUE method_lame_version(VALUE klass) {
|
61
|
-
const char * version = get_lame_version();
|
62
|
-
return rb_str_new(version, strlen(version));
|
63
|
-
}
|
64
|
-
|
65
|
-
static int lame_decode_initfile(VALUE file, mp3data_struct * mp3data) {
|
66
|
-
unsigned char * buf;
|
67
|
-
VALUE str;
|
68
|
-
int len = 4;
|
69
|
-
int enc_delay;
|
70
|
-
int enc_padding;
|
71
|
-
int ret;
|
72
|
-
short int pcm_l[1152], pcm_r[1152];
|
73
|
-
|
74
|
-
str = rb_funcall(file, rb_intern("read"), 1, INT2NUM(len));
|
75
|
-
buf = StringValuePtr(str);
|
76
|
-
if(buf[0] == 'I' && buf[1] == 'D' && buf[2] == '3') {
|
77
|
-
len = 6;
|
78
|
-
str = rb_funcall(file, rb_intern("read"), 1, INT2NUM(len));
|
79
|
-
buf = StringValuePtr(str);
|
80
|
-
|
81
|
-
buf[2] &= 127; buf[3] &= 127; buf[4] &= 127; buf[5] &= 127;
|
82
|
-
len = (((((buf[2] << 7) + buf[3]) << 7) + buf[4]) << 7) + buf[5];
|
83
|
-
|
84
|
-
rb_funcall( file,
|
85
|
-
rb_intern("read"),
|
86
|
-
1,
|
87
|
-
INT2NUM(len));
|
88
|
-
|
89
|
-
len = 4;
|
90
|
-
str = rb_funcall(file, rb_intern("read"), 1, INT2NUM(len));
|
91
|
-
buf = StringValuePtr(str);
|
92
|
-
|
93
|
-
/* Check for Album ID */
|
94
|
-
if(0 == rb_str_cmp(str, rb_str_new2("AiD\1"))) {
|
95
|
-
/* FIXME */
|
96
|
-
rb_raise(rb_eRuntimeError, "Found Album ID.\n");
|
97
|
-
}
|
98
|
-
|
99
|
-
while (!is_syncword_mp123(buf)) {
|
100
|
-
int i;
|
101
|
-
for(i = 0; i < len - 1; i++) {
|
102
|
-
buf[i] = buf[i + 1];
|
103
|
-
}
|
104
|
-
buf[len - 1] = NUM2INT(rb_funcall(file, rb_intern("getc"), 0));
|
105
|
-
}
|
106
|
-
|
107
|
-
if ((buf[2] & 0xF0) == 0) {
|
108
|
-
printf("Input file is freeformat\n");
|
109
|
-
}
|
110
|
-
|
111
|
-
ret = lame_decode1_headersB(buf, len, pcm_l, pcm_r, mp3data, &enc_delay, &enc_padding);
|
112
|
-
if(ret == -1)
|
113
|
-
rb_raise(rb_eRuntimeError, "Decode headers failed.\n");
|
114
|
-
|
115
|
-
while(!mp3data->header_parsed) {
|
116
|
-
str = rb_funcall(file, rb_intern("read"), 1, INT2NUM(100));
|
117
|
-
buf = StringValuePtr(str);
|
118
|
-
ret = lame_decode1_headersB(buf, 100, pcm_l, pcm_r, mp3data,&enc_delay,&enc_padding);
|
119
|
-
if(ret == -1)
|
120
|
-
rb_raise(rb_eRuntimeError, "Decode headers failed.\n");
|
121
|
-
}
|
122
|
-
|
123
|
-
if(mp3data->totalframes > 0) {
|
124
|
-
} else {
|
125
|
-
mp3data->nsamp = MAX_U_32_NUM;
|
126
|
-
}
|
127
|
-
}
|
128
|
-
return 0;
|
129
|
-
}
|
130
|
-
|
131
|
-
/*
|
132
|
-
* call-seq:
|
133
|
-
* decoder.decode(input_io, output_io)
|
134
|
-
*
|
135
|
-
* Decode the input IO and write it to the output IO.
|
136
|
-
*/
|
137
|
-
static VALUE method_lame_decode(VALUE self, VALUE file, VALUE outf) {
|
138
|
-
mp3data_struct mp3data;
|
139
|
-
lame_global_flags * gfp;
|
140
|
-
|
141
|
-
memset(&mp3data, 0, sizeof(mp3data_struct));
|
142
|
-
lame_decode_initfile(file, &mp3data);
|
143
|
-
|
144
|
-
Data_Get_Struct (self, lame_global_flags, gfp);
|
145
|
-
|
146
|
-
rb_iv_set(self, "@stereo", INT2NUM(mp3data.stereo));
|
147
|
-
rb_iv_set(self, "@samplerate", INT2NUM(mp3data.samplerate));
|
148
|
-
rb_iv_set(self, "@bitrate", INT2NUM(mp3data.bitrate));
|
149
|
-
rb_iv_set(self, "@mode", INT2NUM(mp3data.mode));
|
150
|
-
rb_iv_set(self, "@mode_ext", INT2NUM(mp3data.mode_ext));
|
151
|
-
rb_iv_set(self, "@framesize", INT2NUM(mp3data.framesize));
|
152
|
-
|
153
|
-
lame_decoder(self, file, outf, &mp3data);
|
154
|
-
|
155
|
-
return Qnil;
|
156
|
-
}
|
157
|
-
|
158
|
-
void Init_icanhasaudio() {
|
159
|
-
rb_mAudio = rb_define_module("Audio");
|
160
|
-
rb_mMpeg = rb_define_module_under(rb_mAudio, "MPEG");
|
161
|
-
rb_cDecoder = rb_define_class_under(rb_mMpeg, "Decoder", rb_cObject);
|
162
|
-
|
163
|
-
rb_mOgg = rb_define_module_under(rb_mAudio, "OGG");
|
164
|
-
rb_cOggDecoder = rb_define_class_under(rb_mOgg, "Decoder", rb_cObject);
|
165
|
-
|
166
|
-
/* VERSION = '0.1.1' */
|
167
|
-
rb_define_const(rb_cDecoder, "VERSION", rb_str_new2("0.1.1"));
|
168
|
-
rb_define_singleton_method(
|
169
|
-
rb_cDecoder,
|
170
|
-
"lame_version",
|
171
|
-
method_lame_version,
|
172
|
-
0
|
173
|
-
);
|
174
|
-
|
175
|
-
rb_define_alloc_func(rb_cDecoder, reader_allocate);
|
176
|
-
rb_define_method(rb_cDecoder, "decode", method_lame_decode, 2);
|
177
|
-
rb_define_method(rb_cOggDecoder, "decode", method_ogg_decode, 2);
|
178
|
-
|
179
|
-
init_MpegEncoder(rb_mMpeg);
|
180
|
-
rb_require("icanhasaudio/mpeg");
|
181
|
-
rb_require("icanhasaudio/ogg");
|
182
|
-
}
|
183
|
-
|
data/ext/icanhasaudio.h
DELETED
data/ext/mpeg_encoder.h
DELETED
data/ext/syncword.c
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
* Taken from lame, get_audio.c
|
3
|
-
*/
|
4
|
-
|
5
|
-
int is_syncword_mp123(const void *const headerptr)
|
6
|
-
{
|
7
|
-
const unsigned char *const p = headerptr;
|
8
|
-
static const char abl2[16] =
|
9
|
-
{ 0, 7, 7, 7, 0, 7, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8 };
|
10
|
-
|
11
|
-
if ((p[0] & 0xFF) != 0xFF)
|
12
|
-
return 0; /* first 8 bits must be '1' */
|
13
|
-
if ((p[1] & 0xE0) != 0xE0)
|
14
|
-
return 0; /* next 3 bits are also */
|
15
|
-
if ((p[1] & 0x18) == 0x08)
|
16
|
-
return 0; /* no MPEG-1, -2 or -2.5 */
|
17
|
-
if ((p[1] & 0x06) == 0x00)
|
18
|
-
return 0; /* no Layer I, II and III */
|
19
|
-
#ifndef USE_LAYER_1
|
20
|
-
if ((p[1] & 0x06) == 0x03*2)
|
21
|
-
return 0; /* layer1 is not supported */
|
22
|
-
#endif
|
23
|
-
#ifndef USE_LAYER_2
|
24
|
-
if ((p[1] & 0x06) == 0x02*2)
|
25
|
-
return 0; /* layer1 is not supported */
|
26
|
-
#endif
|
27
|
-
/*
|
28
|
-
if (!(((p[1] & 0x06) == 0x03*2 && input_format == sf_mp1)
|
29
|
-
|| ((p[1] & 0x06) == 0x02*2 && input_format == sf_mp2)
|
30
|
-
|| ((p[1] & 0x06) == 0x01*2 && input_format == sf_mp3)))
|
31
|
-
*/
|
32
|
-
if(!(p[1] & 0x06) == 0x01*2)
|
33
|
-
return 0; /* imcompatible layer with input file format */
|
34
|
-
if ((p[2] & 0xF0) == 0xF0)
|
35
|
-
return 0; /* bad bitrate */
|
36
|
-
if ((p[2] & 0x0C) == 0x0C)
|
37
|
-
return 0; /* no sample frequency with (32,44.1,48)/(1,2,4) */
|
38
|
-
if ((p[1] & 0x18) == 0x18 && (p[1] & 0x06) == 0x04
|
39
|
-
&& abl2[p[2] >> 4] & (1 << (p[3] >> 6)))
|
40
|
-
return 0;
|
41
|
-
if ((p[3] & 3) == 2)
|
42
|
-
return 0; /* reserved enphasis mode */
|
43
|
-
return 1;
|
44
|
-
}
|
45
|
-
|