1 #include <stdint.h>
2 #include <stdlib.h>
3 #include <string.h>
4 
5 #include <neaacdec.h>
6 
7 #include <audacious/audtag.h>
8 #include <libaudcore/i18n.h>
9 #include <libaudcore/plugin.h>
10 #include <libaudcore/runtime.h>
11 
12 class AACDecoder : public InputPlugin
13 {
14 public:
15     static const char * const exts[];
16     static const char * const mimes[];
17 
18     static constexpr PluginInfo info = {
19         N_("AAC (Raw) Decoder"),
20         PACKAGE
21     };
22 
AACDecoder()23     constexpr AACDecoder () : InputPlugin (info, InputInfo ()
24         .with_exts (exts)
25         .with_mimes (mimes)) {}
26 
27     bool is_our_file (const char * filename, VFSFile & file);
28     bool read_tag (const char * filename, VFSFile & file, Tuple & tuple, Index<char> * image);
29     bool play (const char * filename, VFSFile & file);
30 };
31 
32 EXPORT AACDecoder aud_plugin_instance;
33 
34 const char * const AACDecoder::exts[] = {"aac", nullptr};
35 const char * const AACDecoder::mimes[] = {"audio/aac", nullptr};
36 
37 /*
38  * BUFFER_SIZE is the highest amount of memory that can be pulled.
39  * We use this for sanity checks, among other things, as mp4ff needs
40  * a labotomy sometimes.
41  */
42 #define BUFFER_SIZE (FAAD_MIN_STREAMSIZE * 16)
43 
44 /*
45  * These routines are derived from MPlayer.
46  */
47 
48 /// \param srate (out) sample rate
49 /// \param num (out) number of audio frames in this ADTS frame
50 /// \return size of the ADTS frame in bytes
51 /// aac_parse_frames needs a buffer at least 8 bytes long
aac_parse_frame(unsigned char * buf,int * srate,int * num)52 int aac_parse_frame (unsigned char * buf, int *srate, int *num)
53 {
54     int i = 0, sr, fl = 0;
55     static int srates[] =
56      { 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000,
57          11025, 8000, 0, 0, 0 };
58 
59     if ((buf[i] != 0xFF) || ((buf[i + 1] & 0xF6) != 0xF0))
60         return 0;
61 
62 /* We currently have no use for the id below.
63         id = (buf[i+1] >> 3) & 0x01;    //id=1 mpeg2, 0: mpeg4
64 */
65     sr = (buf[i + 2] >> 2) & 0x0F;
66     if (sr > 11)
67         return 0;
68     *srate = srates[sr];
69 
70     fl =
71      ((buf[i + 3] & 0x03) << 11) | (buf[i + 4] << 3) | ((buf[i +
72      5] >> 5) & 0x07);
73     *num = (buf[i + 6] & 0x02) + 1;
74 
75     return fl;
76 }
77 
78 #define PROBE_DEBUG(...)
79 
80 /* Searches <length> bytes of data for an ADTS header.  Returns the offset of
81  * the first header or -1 if none is found.  Sets <size> to the length of the
82  * frame. */
find_aac_header(unsigned char * data,int length,int * size)83 static int find_aac_header (unsigned char * data, int length, int * size)
84 {
85     int offset, a, b;
86 
87     for (offset = 0; offset <= length - 8; offset++)
88     {
89         if (data[offset] != 255)
90             continue;
91 
92         *size = aac_parse_frame (data + offset, &a, &b);
93 
94         if (*size < 8)
95             continue;
96 
97         return offset;
98     }
99 
100     return -1;
101 }
102 
is_our_file(const char * filename,VFSFile & stream)103 bool AACDecoder::is_our_file (const char * filename, VFSFile & stream)
104 {
105     unsigned char data[8192];
106     int offset, found, inner, size;
107 
108     size = 0;                   /* avoid bogus uninitialized variable warning */
109 
110     if (stream.fread (data, 1, sizeof data) != sizeof data)
111     {
112         PROBE_DEBUG ("Read failed.\n");
113         return false;
114     }
115 
116     offset = 0;
117 
118     for (found = 0; found < 3; found++)
119     {
120         inner = find_aac_header (data + offset, sizeof data - offset, &size);
121 
122         if (!(inner == 0 || (found == 0 && inner > 0)))
123         {
124             PROBE_DEBUG ("Only %d ADTS headers.\n", found);
125             return false;
126         }
127 
128         offset += inner + size;
129     }
130 
131     PROBE_DEBUG ("Accepted.\n");
132     return true;
133 }
134 
135 /* Quick search for an ADTS or ADIF header in the first <len> bytes of <buf>.
136  * Returns the byte offset of the header or <len> if none is found. */
137 
aac_probe(unsigned char * buf,int len)138 static int aac_probe (unsigned char * buf, int len)
139 {
140     for (int i = 0; i <= len - 4; i ++)
141     {
142         if ((buf[i] == 0xff && (buf[i + 1] & 0xf6) == 0xf0) || ! strncmp
143          ((char *) buf + i, "ADIF", 4))
144             return i;
145     }
146 
147     return len;
148 }
149 
150 /* Gets info (some approximated) from an AAC/ADTS file.  <length> is
151  * milliseconds, <bitrate> is kilobits per second.  Any parameters that cannot
152  * be read are set to -1. */
calc_aac_info(VFSFile & handle,int * length,int * bitrate,int * samplerate,int * channels)153 static void calc_aac_info (VFSFile & handle, int * length, int * bitrate,
154  int * samplerate, int * channels)
155 {
156     NeAACDecHandle decoder;
157     NeAACDecFrameInfo frame;
158     bool initted = false;
159     int size = handle.fsize ();
160     unsigned char buffer[BUFFER_SIZE];
161     int offset = 0, filled = 0;
162     int found, bytes_used = 0, time_used = 0;
163 
164     decoder = nullptr;             /* avoid bogus uninitialized variable warning */
165 
166     *length = -1;
167     *bitrate = -1;
168     *samplerate = -1;
169     *channels = -1;
170 
171     /* look for a representative bitrate in the middle of the file */
172     if (size < 0 || handle.fseek (size / 2, VFS_SEEK_SET) < 0)
173         goto DONE;
174 
175     for (found = 0; found < 32; found++)
176     {
177         if (filled < BUFFER_SIZE / 2)
178         {
179             memmove (buffer, buffer + offset, filled);
180             offset = 0;
181 
182             if (handle.fread (buffer + filled, 1, BUFFER_SIZE - filled)
183              != BUFFER_SIZE - filled)
184             {
185                 PROBE_DEBUG ("Read failed.\n");
186                 goto DONE;
187             }
188 
189             filled = BUFFER_SIZE;
190         }
191 
192         if (!initted)
193         {
194             int inner, a;
195             unsigned long r;
196             unsigned char ch;
197 
198             inner = find_aac_header (buffer + offset, filled, &a);
199 
200             if (inner < 0)
201             {
202                 PROBE_DEBUG ("No ADTS header.\n");
203                 goto DONE;
204             }
205 
206             offset += inner;
207             filled -= inner;
208 
209             decoder = NeAACDecOpen ();
210             inner = NeAACDecInit (decoder, buffer + offset, filled, &r, &ch);
211 
212             if (inner < 0)
213             {
214                 PROBE_DEBUG ("Decoder init failed.\n");
215                 NeAACDecClose (decoder);
216                 goto DONE;
217             }
218 
219             offset += inner;
220             filled -= inner;
221             bytes_used += inner;
222 
223             *samplerate = r;
224             *channels = ch;
225             initted = true;
226         }
227 
228         if (NeAACDecDecode (decoder, &frame, buffer + offset, filled) == nullptr)
229         {
230             PROBE_DEBUG ("Decode failed.\n");
231             goto DONE;
232         }
233 
234         if ((int)frame.samplerate != *samplerate || (int)frame.channels != *channels)
235         {
236             PROBE_DEBUG ("Parameter mismatch.\n");
237             goto DONE;
238         }
239 
240         offset += frame.bytesconsumed;
241         filled -= frame.bytesconsumed;
242         bytes_used += frame.bytesconsumed;
243         time_used += frame.samples / frame.channels * (int64_t) 1000 /
244          frame.samplerate;
245     }
246 
247     /* bits per millisecond = kilobits per second */
248     *bitrate = bytes_used * 8 / time_used;
249 
250     if (size > 0)
251         *length = size * (int64_t) time_used / bytes_used;
252 
253   DONE:
254     if (initted)
255         NeAACDecClose (decoder);
256 }
257 
read_tag(const char * filename,VFSFile & file,Tuple & tuple,Index<char> * image)258 bool AACDecoder::read_tag (const char * filename, VFSFile & file, Tuple & tuple,
259  Index<char> * image)
260 {
261     int length, bitrate, samplerate, channels;
262 
263     tuple.set_str (Tuple::Codec, "MPEG-2/4 AAC");
264 
265     // TODO: error handling
266     calc_aac_info (file, &length, &bitrate, &samplerate, &channels);
267 
268     if (length > 0)
269         tuple.set_int (Tuple::Length, length);
270     if (bitrate > 0)
271         tuple.set_int (Tuple::Bitrate, bitrate);
272     if (channels > 0)
273         tuple.set_int (Tuple::Channels, channels);
274 
275     tuple.fetch_stream_info (file);
276 
277     return true;
278 }
279 
aac_seek(VFSFile & file,NeAACDecHandle dec,int time,int len,void * buf,int size,int * buflen)280 static void aac_seek (VFSFile & file, NeAACDecHandle dec, int time, int len,
281  void * buf, int size, int * buflen)
282 {
283     /* == ESTIMATE BYTE OFFSET == */
284 
285     int64_t total = file.fsize ();
286     if (total < 0)
287     {
288         AUDERR ("File is not seekable.\n");
289         return;
290     }
291 
292     /* == SEEK == */
293 
294     if (file.fseek (total * time / len, VFS_SEEK_SET))
295         return;
296 
297     * buflen = file.fread (buf, 1, size);
298 
299     /* == FIND FRAME HEADER == */
300 
301     int used = aac_probe ((unsigned char *) buf, * buflen);
302 
303     if (used == * buflen)
304     {
305         AUDERR ("No valid frame header found.\n");
306         * buflen = 0;
307         return;
308     }
309 
310     if (used)
311     {
312         * buflen -= used;
313         memmove (buf, (char *) buf + used, * buflen);
314         * buflen += file.fread ((char *) buf + * buflen, 1, size - * buflen);
315     }
316 
317     /* == START DECODING == */
318 
319     unsigned char chan;
320     unsigned long rate;
321 
322     if ((used = NeAACDecInit (dec, (unsigned char *) buf, * buflen, & rate, & chan)))
323     {
324         * buflen -= used;
325         memmove (buf, (char *) buf + used, * buflen);
326         * buflen += file.fread ((char *) buf + * buflen, 1, size - * buflen);
327     }
328 }
329 
play(const char * filename,VFSFile & file)330 bool AACDecoder::play (const char * filename, VFSFile & file)
331 {
332     NeAACDecHandle decoder = 0;
333     NeAACDecConfigurationPtr decoder_config;
334     unsigned long samplerate = 0;
335     unsigned char channels = 0;
336 
337     Tuple tuple = get_playback_tuple ();
338     int bitrate = 1000 * aud::max (0, tuple.get_int (Tuple::Bitrate));
339 
340     if ((decoder = NeAACDecOpen ()) == nullptr)
341     {
342         AUDERR ("Open Decoder Error\n");
343         return false;
344     }
345 
346     decoder_config = NeAACDecGetCurrentConfiguration (decoder);
347     decoder_config->outputFormat = FAAD_FMT_FLOAT;
348     NeAACDecSetConfiguration (decoder, decoder_config);
349 
350     /* == FILL BUFFER == */
351 
352     unsigned char buf[BUFFER_SIZE];
353     int buflen;
354     buflen = file.fread (buf, 1, sizeof buf);
355 
356     /* == SKIP ID3 TAG == */
357 
358     if (buflen >= 10 && ! strncmp ((char *) buf, "ID3", 3))
359     {
360         int tagsize = 10 + (buf[6] << 21) + (buf[7] << 14) + (buf[8] << 7) + buf[9];
361 
362         if (file.fseek (tagsize, VFS_SEEK_SET))
363         {
364             AUDERR ("Failed to seek past ID3v2 tag.\n");
365             goto ERR_CLOSE_DECODER;
366         }
367 
368         buflen = file.fread (buf, 1, sizeof buf);
369     }
370 
371     /* == FIND FRAME HEADER == */
372 
373     int used;
374     used = aac_probe (buf, buflen);
375 
376     if (used == buflen)
377     {
378         AUDERR ("No valid frame header found.\n");
379         goto ERR_CLOSE_DECODER;
380     }
381 
382     if (used)
383     {
384         buflen -= used;
385         memmove (buf, buf + used, buflen);
386         buflen += file.fread (buf + buflen, 1, sizeof buf - buflen);
387     }
388 
389     /* == START DECODING == */
390 
391     if ((used = NeAACDecInit (decoder, buf, buflen, & samplerate, & channels)))
392     {
393         buflen -= used;
394         memmove (buf, buf + used, buflen);
395         buflen += file.fread (buf + buflen, 1, sizeof buf - buflen);
396     }
397 
398     /* == CHECK FOR METADATA == */
399 
400     if (tuple.fetch_stream_info (file))
401         set_playback_tuple (tuple.ref ());
402 
403     set_stream_bitrate (bitrate);
404 
405     /* == START PLAYBACK == */
406 
407     open_audio (FMT_FLOAT, samplerate, channels);
408 
409     /* == MAIN LOOP == */
410 
411     while (! check_stop ())
412     {
413         /* == HANDLE SEEK REQUESTS == */
414 
415         int seek_value = check_seek ();
416 
417         if (seek_value >= 0)
418         {
419             int length = tuple.get_int (Tuple::Length);
420             if (length > 0)
421                 aac_seek (file, decoder, seek_value, length, buf, sizeof buf, & buflen);
422         }
423 
424         /* == CHECK FOR END OF FILE == */
425 
426         if (! buflen)
427             break;
428 
429         /* == CHECK FOR METADATA == */
430 
431         if (tuple.fetch_stream_info (file))
432             set_playback_tuple (tuple.ref ());
433 
434         /* == DECODE A FRAME == */
435 
436         NeAACDecFrameInfo info;
437         void * audio = NeAACDecDecode (decoder, & info, buf, buflen);
438 
439         if (info.error)
440         {
441             AUDERR ("%s.\n", NeAACDecGetErrorMessage (info.error));
442 
443             if (buflen)
444             {
445                 used = 1 + aac_probe (buf + 1, buflen - 1);
446                 buflen -= used;
447                 memmove (buf, buf + used, buflen);
448                 buflen += file.fread (buf + buflen, 1, sizeof buf - buflen);
449             }
450 
451             continue;
452         }
453 
454         if ((used = info.bytesconsumed))
455         {
456             buflen -= used;
457             memmove (buf, buf + used, buflen);
458             buflen += file.fread (buf + buflen, 1, sizeof buf - buflen);
459         }
460 
461         /* == PLAY THE SOUND == */
462 
463         if (audio && info.samples)
464             write_audio (audio, sizeof (float) * info.samples);
465     }
466 
467     NeAACDecClose (decoder);
468     return true;
469 
470 ERR_CLOSE_DECODER:
471     NeAACDecClose (decoder);
472     return false;
473 }
474