Main Page   Data Structures   File List   Data Fields   Globals  

aac.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2006 by André Lindhjem <belgarat@sdf.lonestar.org>,     *
00003  *                         Kjetil Holien <kjetil.holien@gmail.com>,        *
00004  *                         Terje Risa <terje.risa@gmail.com> &             *
00005  *                         Øyvind Nerbråten <oyvind@nerbraten.com>         *
00006  *                                                                         *
00007  *   This program is free software; you can redistribute it and/or modify  *
00008  *   it under the terms of the GNU General Public License as published by  *
00009  *   the Free Software Foundation; either version 2 of the License, or     *
00010  *   (at your option) any later version.                                   *
00011  *                                                                         *
00012  *   This program is distributed in the hope that it will be useful,       *
00013  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00014  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00015  *   GNU General Public License for more details.                          *
00016  *                                                                         *
00017  *   You should have received a copy of the GNU General Public License     *
00018  *   along with this program; if not, write to the                         *
00019  *   Free Software Foundation, Inc.,                                       *
00020  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00021  ***************************************************************************
00022  *
00023  * \file aac.c
00024  * \author André Lindhjem, Kjetil Holien, Terje Risa & Øyvind Nerbråten
00025  * \date 24.02.2006
00026  *
00027  * Functinality for controlling aac placyback using faad and ao. With the aac_play
00028  * function we can specify a mp4/aac file and start and stop offsets. The audio_play
00029  * function starts decoding the aac file.
00030  * Much of this file are copyed / inspired by the (minimalistic) FAAD API
00031  * and the FAAD frontend code.
00032  * 
00033  * To build with AAC support, this is required:
00034  * - faad2-0 and faad2-dev installed.
00035  * - faad and mp4ff must be linked during build. "gcc (....) -lfaad -lmp4ff"
00036  * 
00037  * TODO: Clean up! There's too much code here wich we don't use.
00038  * NOTE: This AAC decoder are not yet fully implemented, so AAC support in libdaisy are not yet complete.
00039  */
00040 #ifdef WITH_AAC             
00042 #include <faad.h>
00043 #include <string.h>
00044 #include <mp4ff.h>          
00045 #include <stdbool.h>        
00047 #include "aac.h"            
00048 #include "audio.h"          
00049 #include "faad2/audio.h"    
00050 #include "report.h"         
00051 #include "common.h"         
00055 /* ************************************************ *
00056  *  Global type definitions and datastructures      *
00057  * ************************************************ */
00058 
00059 #define AAC_MAX_CHANNELS 6 /* make this higher to support files with
00060                               more channels */
00061 
00062 #ifndef min
00063 #define min(a,b) ( (a) < (b) ? (a) : (b) )
00064 #endif
00065 
00066 
00067 
00068 /* FAAD file buffering routines */
00069 typedef struct {
00070     long bytes_into_buffer;
00071     long bytes_consumed;
00072     long file_offset;
00073     unsigned char *buffer;
00074     int at_eof;
00075     FILE *infile;
00076 } aac_buffer;
00077 
00078 
00079 /* MicroSoft channel definitions */
00080 #define SPEAKER_FRONT_LEFT              0x1
00081 #define SPEAKER_FRONT_RIGHT             0x2
00082 #define SPEAKER_FRONT_CENTER            0x4
00083 #define SPEAKER_LOW_FREQUENCY           0x8
00084 #define SPEAKER_BACK_LEFT               0x10
00085 #define SPEAKER_BACK_RIGHT              0x20
00086 #define SPEAKER_FRONT_LEFT_OF_CENTER    0x40
00087 #define SPEAKER_FRONT_RIGHT_OF_CENTER   0x80
00088 #define SPEAKER_BACK_CENTER             0x100
00089 #define SPEAKER_SIDE_LEFT               0x200
00090 #define SPEAKER_SIDE_RIGHT              0x400
00091 #define SPEAKER_TOP_CENTER              0x800
00092 #define SPEAKER_TOP_FRONT_LEFT          0x1000
00093 #define SPEAKER_TOP_FRONT_CENTER        0x2000
00094 #define SPEAKER_TOP_FRONT_RIGHT         0x4000
00095 #define SPEAKER_TOP_BACK_LEFT           0x8000
00096 #define SPEAKER_TOP_BACK_CENTER         0x10000
00097 #define SPEAKER_TOP_BACK_RIGHT          0x20000
00098 #define SPEAKER_RESERVED                0x80000000
00099 
00100 static int adts_sample_rates[] = {96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000,7350,0,0,0};
00101 
00102 
00103 
00104 /* ************************************************ *
00105  *          Static function declarations            *
00106  * ************************************************ */
00107  
00108 static
00109 int GetAACTrack(mp4ff_t *infile);
00110 
00111 static
00112 int decodeMP4file(struct_audio_data_t *data, char *mp4file, char *sndfile, char *adts_fn, int to_stdout,
00113                   int outputFormat, int fileType, int downMatrix, int noGapless,
00114                   int infoOnly, int adts_out, float *song_length);
00115 
00116 static
00117 int decodeAACfile(struct_audio_data_t *data, char *aacfile, char *sndfile, char *adts_fn, int to_stdout,
00118                   int def_srate, int object_type, int outputFormat, int fileType,
00119                   int downMatrix, int infoOnly, int adts_out, int old_format,
00120                   float *song_length);
00121 
00122 static
00123 uint32_t read_callback(void *user_data, void *buffer, uint32_t length);
00124 
00125 static
00126 uint32_t seek_callback(void *user_data, uint64_t position);
00127 
00128 static
00129 int adts_parse(aac_buffer *b, int *bitrate, float *length);
00130 
00131 static
00132 void advance_buffer(aac_buffer *b, int bytes);
00133 
00134 static
00135 int fill_buffer(aac_buffer *b);
00136 
00137 static
00138 unsigned char *MakeAdtsHeader(int *dataSize, faacDecFrameInfo *hInfo, int old_format);
00139 
00140 static
00141 int FindAdtsSRIndex(int sr);
00142 
00143 static
00144 long aacChannelConfig2wavexChannelMask(faacDecFrameInfo *hInfo);
00145 
00146 static
00147 char *position2string(int position);
00148 
00149 static
00150 int GetAACTrack(mp4ff_t *infile);
00151 
00152 
00153 
00154 /* ************************************************ *
00155  *          Static function definitions             *
00156  * ************************************************ */
00157 
00158 /*
00159  * Finds out wich track in an MP4 file that is the AAC track.
00160  * @parm mp4ff_t *infile - the  MP4 file.
00161  */
00162 static
00163 int GetAACTrack(mp4ff_t *infile)
00164 {
00165     /* find AAC track */
00166     int i, rc;
00167     int numTracks = mp4ff_total_tracks(infile);
00168 
00169     for (i = 0; i < numTracks; i++)
00170     {
00171         unsigned char *buff = NULL;
00172         unsigned int buff_size = 0;
00173         mp4AudioSpecificConfig mp4ASC;
00174 
00175         mp4ff_get_decoder_config(infile, i, &buff, &buff_size);
00176 
00177         if (buff)
00178         {
00179             rc = AudioSpecificConfig(buff, buff_size, &mp4ASC);
00180             free(buff);
00181 
00182             if (rc < 0)
00183                 continue;
00184             return i;
00185         }
00186     }
00187 
00188     /* can't decode this */
00189     return -1;
00190 }
00191 
00192 static
00193 long aacChannelConfig2wavexChannelMask(faacDecFrameInfo *hInfo)
00194 {
00195     if (hInfo->channels == 6 && hInfo->num_lfe_channels)
00196     {
00197         return SPEAKER_FRONT_LEFT + SPEAKER_FRONT_RIGHT +
00198             SPEAKER_FRONT_CENTER + SPEAKER_LOW_FREQUENCY +
00199             SPEAKER_BACK_LEFT + SPEAKER_BACK_RIGHT;
00200     } else {
00201         return 0;
00202     }
00203 }
00204 
00210 static
00211 int FindAdtsSRIndex(int sr)
00212 {
00213     int i;
00214 
00215     for (i = 0; i < 16; i++)
00216     {
00217         if (sr == adts_sample_rates[i])
00218             return i;
00219     }
00220     return 16 - 1;
00221 }
00222 
00230 static
00231 unsigned char *MakeAdtsHeader(int *dataSize, faacDecFrameInfo *hInfo, int old_format)
00232 {
00233     unsigned char *data;
00234     int profile = (hInfo->object_type - 1) & 0x3;
00235     int sr_index = ((hInfo->sbr == SBR_UPSAMPLED) || (hInfo->sbr == NO_SBR_UPSAMPLED)) ?
00236         FindAdtsSRIndex(hInfo->samplerate / 2) : FindAdtsSRIndex(hInfo->samplerate);
00237     int skip = (old_format) ? 8 : 7;
00238     int framesize = skip + hInfo->bytesconsumed;
00239 
00240     if (hInfo->header_type == ADTS)
00241         framesize -= skip;
00242 
00243     *dataSize = 7;
00244 
00245     data = malloc(*dataSize * sizeof(unsigned char));
00246     memset(data, 0, *dataSize * sizeof(unsigned char));
00247 
00248     data[0] += 0xFF; /* 8b: syncword */
00249 
00250     data[1] += 0xF0; /* 4b: syncword */
00251     /* 1b: mpeg id = 0 */
00252     /* 2b: layer = 0 */
00253     data[1] += 1; /* 1b: protection absent */
00254 
00255     data[2] += ((profile << 6) & 0xC0); /* 2b: profile */
00256     data[2] += ((sr_index << 2) & 0x3C); /* 4b: sampling_frequency_index */
00257     /* 1b: private = 0 */
00258     data[2] += ((hInfo->channels >> 2) & 0x1); /* 1b: channel_configuration */
00259 
00260     data[3] += ((hInfo->channels << 6) & 0xC0); /* 2b: channel_configuration */
00261     /* 1b: original */
00262     /* 1b: home */
00263     /* 1b: copyright_id */
00264     /* 1b: copyright_id_start */
00265     data[3] += ((framesize >> 11) & 0x3); /* 2b: aac_frame_length */
00266 
00267     data[4] += ((framesize >> 3) & 0xFF); /* 8b: aac_frame_length */
00268 
00269     data[5] += ((framesize << 5) & 0xE0); /* 3b: aac_frame_length */
00270     data[5] += ((0x7FF >> 6) & 0x1F); /* 5b: adts_buffer_fullness */
00271 
00272     data[6] += ((0x7FF << 2) & 0x3F); /* 6b: adts_buffer_fullness */
00273     /* 2b: num_raw_data_blocks */
00274 
00275     return data;
00276 }
00277 
00283 static
00284 int fill_buffer(aac_buffer *b)
00285 {
00286     int bread;
00287 
00288     if (b->bytes_consumed > 0)
00289     {
00290         if (b->bytes_into_buffer)
00291         {
00292             memmove((void*)b->buffer, (void*)(b->buffer + b->bytes_consumed),
00293                 b->bytes_into_buffer*sizeof(unsigned char));
00294         }
00295 
00296         if (!b->at_eof)
00297         {
00298             bread = fread((void*)(b->buffer + b->bytes_into_buffer), 1,
00299                 b->bytes_consumed, b->infile);
00300 
00301             if (bread != b->bytes_consumed)
00302                 b->at_eof = 1;
00303 
00304             b->bytes_into_buffer += bread;
00305         }
00306 
00307         b->bytes_consumed = 0;
00308 
00309         if (b->bytes_into_buffer > 3)
00310         {
00311             if (memcmp(b->buffer, "TAG", 3) == 0)
00312                 b->bytes_into_buffer = 0;
00313         }
00314         if (b->bytes_into_buffer > 11)
00315         {
00316             if (memcmp(b->buffer, "LYRICSBEGIN", 11) == 0)
00317                 b->bytes_into_buffer = 0;
00318         }
00319         if (b->bytes_into_buffer > 8)
00320         {
00321             if (memcmp(b->buffer, "APETAGEX", 8) == 0)
00322                 b->bytes_into_buffer = 0;
00323         }
00324     }
00325 
00326     return 1;
00327 }
00328 
00334 static
00335 void advance_buffer(aac_buffer *b, int bytes)
00336 {
00337     b->file_offset += bytes;
00338     b->bytes_consumed = bytes;
00339     b->bytes_into_buffer -= bytes;
00340 }
00341 
00349 static
00350 int adts_parse(aac_buffer *b, int *bitrate, float *length)
00351 {
00352     int frames, frame_length;
00353     int t_framelength = 0;
00354     int samplerate;
00355     float frames_per_sec, bytes_per_frame;
00356 
00357     /* Read all frames to ensure correct time and bitrate */
00358     for (frames = 0; /* */; frames++)
00359     {
00360         fill_buffer(b);
00361 
00362         if (b->bytes_into_buffer > 7)
00363         {
00364             /* check syncword */
00365             if (!((b->buffer[0] == 0xFF)&&((b->buffer[1] & 0xF6) == 0xF0)))
00366                 break;
00367 
00368             if (frames == 0)
00369                 samplerate = adts_sample_rates[(b->buffer[2]&0x3c)>>2];
00370 
00371             frame_length = ((((unsigned int)b->buffer[3] & 0x3)) << 11)
00372                 | (((unsigned int)b->buffer[4]) << 3) | (b->buffer[5] >> 5);
00373 
00374             t_framelength += frame_length;
00375 
00376             if (frame_length > b->bytes_into_buffer)
00377                 break;
00378 
00379             advance_buffer(b, frame_length);
00380         } else {
00381             break;
00382         }
00383     }
00384 
00385     frames_per_sec = (float)samplerate/1024.0f;
00386     if (frames != 0)
00387         bytes_per_frame = (float)t_framelength/(float)(frames*1000);
00388     else
00389         bytes_per_frame = 0;
00390     *bitrate = (int)(8. * bytes_per_frame * frames_per_sec + 0.5);
00391     if (frames_per_sec != 0)
00392         *length = (float)frames/frames_per_sec;
00393     else
00394         *length = 1;
00395 
00396     return 1;
00397 }
00398 
00406 static
00407 uint32_t read_callback(void *user_data, void *buffer, uint32_t length)
00408 {
00409     return fread(buffer, 1, length, (FILE*)user_data);
00410 }
00411 
00418 static
00419 uint32_t seek_callback(void *user_data, uint64_t position)
00420 {
00421     return fseek((FILE*)user_data, position, SEEK_SET);
00422 }
00423 
00441 static
00442 int decodeAACfile(struct_audio_data_t *data, char *aacfile, char *sndfile, char *adts_fn, int to_stdout,
00443                   int def_srate, int object_type, int outputFormat, int fileType,
00444                   int downMatrix, int infoOnly, int adts_out, int old_format,
00445                   float *song_length)
00446 {
00447     int tagsize;
00448     unsigned long samplerate;
00449     unsigned char channels;
00450     void *sample_buffer;
00451 
00452     audio_file *aufile;
00453 
00454     FILE *adtsFile;
00455     unsigned char *adtsData;
00456     int adtsDataSize;
00457 
00458     faacDecHandle hDecoder;
00459     faacDecFrameInfo frameInfo;
00460     faacDecConfigurationPtr config;
00461 
00462     char percents[200];
00463     int percent, old_percent = -1;
00464     int bread, fileread;
00465     int header_type = 0;
00466     int bitrate = 0;
00467     float length = 0;
00468 
00469     int first_time = 1;
00470 
00471     aac_buffer b;
00472 
00473     memset(&b, 0, sizeof(aac_buffer));
00474 
00475     if (adts_out)
00476     {
00477         adtsFile = fopen(adts_fn, "wb");
00478         if (adtsFile == NULL)
00479         {
00480             fprintf(stderr, "Error opening file: %s\n", adts_fn);
00481             return 1;
00482         }
00483     }
00484 
00485     b.infile = fopen(aacfile, "rb");
00486     if (b.infile == NULL)
00487     {
00488         /* unable to open file */
00489         fprintf(stderr, "Error opening file: %s\n", aacfile);
00490         return 1;
00491     }
00492 
00493     fseek(b.infile, 0, SEEK_END);
00494     fileread = ftell(b.infile);
00495     fseek(b.infile, 0, SEEK_SET);
00496 
00497     if (!(b.buffer = (unsigned char*)malloc(FAAD_MIN_STREAMSIZE*AAC_MAX_CHANNELS)))
00498     {
00499         fprintf(stderr, "Memory allocation error\n");
00500         return 0;
00501     }
00502     memset(b.buffer, 0, FAAD_MIN_STREAMSIZE*AAC_MAX_CHANNELS);
00503 
00504     bread = fread(b.buffer, 1, FAAD_MIN_STREAMSIZE*AAC_MAX_CHANNELS, b.infile);
00505     b.bytes_into_buffer = bread;
00506     b.bytes_consumed = 0;
00507     b.file_offset = 0;
00508 
00509     if (bread != FAAD_MIN_STREAMSIZE*AAC_MAX_CHANNELS)
00510         b.at_eof = 1;
00511 
00512     tagsize = 0;
00513     if (!memcmp(b.buffer, "ID3", 3))
00514     {
00515         /* high bit is not used */
00516         tagsize = (b.buffer[6] << 21) | (b.buffer[7] << 14) |
00517             (b.buffer[8] <<  7) | (b.buffer[9] <<  0);
00518 
00519         tagsize += 10;
00520         advance_buffer(&b, tagsize);
00521         fill_buffer(&b);
00522     }
00523 
00524     hDecoder = faacDecOpen();
00525 
00526     /* Set the default object type and samplerate */
00527     /* This is useful for RAW AAC files */
00528     config = faacDecGetCurrentConfiguration(hDecoder);
00529     if (def_srate)
00530         config->defSampleRate = def_srate;
00531     config->defObjectType = object_type;
00532     config->outputFormat = outputFormat;
00533     config->downMatrix = downMatrix;
00534     config->useOldADTSFormat = old_format;
00535     config->dontUpSampleImplicitSBR = 1;
00536     faacDecSetConfiguration(hDecoder, config);
00537 
00538     /* get AAC infos for printing */
00539     header_type = 0;
00540     if ((b.buffer[0] == 0xFF) && ((b.buffer[1] & 0xF6) == 0xF0))
00541     {
00542         adts_parse(&b, &bitrate, &length);
00543         fseek(b.infile, tagsize, SEEK_SET);
00544 
00545         bread = fread(b.buffer, 1, FAAD_MIN_STREAMSIZE*AAC_MAX_CHANNELS, b.infile);
00546         if (bread != FAAD_MIN_STREAMSIZE*AAC_MAX_CHANNELS)
00547             b.at_eof = 1;
00548         else
00549             b.at_eof = 0;
00550         b.bytes_into_buffer = bread;
00551         b.bytes_consumed = 0;
00552         b.file_offset = tagsize;
00553 
00554         header_type = 1;
00555     } else if (memcmp(b.buffer, "ADIF", 4) == 0) {
00556         int skip_size = (b.buffer[4] & 0x80) ? 9 : 0;
00557         bitrate = ((unsigned int)(b.buffer[4 + skip_size] & 0x0F)<<19) |
00558             ((unsigned int)b.buffer[5 + skip_size]<<11) |
00559             ((unsigned int)b.buffer[6 + skip_size]<<3) |
00560             ((unsigned int)b.buffer[7 + skip_size] & 0xE0);
00561 
00562         length = (float)fileread;
00563         if (length != 0)
00564         {
00565             length = ((float)length*8.f)/((float)bitrate) + 0.5f;
00566         }
00567 
00568         bitrate = (int)((float)bitrate/1000.0f + 0.5f);
00569 
00570         header_type = 2;
00571     }
00572 
00573     *song_length = length;
00574 
00575     fill_buffer(&b);
00576     if ((bread = faacDecInit(hDecoder, b.buffer,
00577         b.bytes_into_buffer, &samplerate, &channels)) < 0)
00578     {
00579         /* If some error initializing occured, skip the file */
00580         fprintf(stderr, "Error initializing decoder library.\n");
00581         if (b.buffer)
00582             free(b.buffer);
00583         faacDecClose(hDecoder);
00584         fclose(b.infile);
00585         return 1;
00586     }
00587     advance_buffer(&b, bread);
00588     fill_buffer(&b);
00589 
00590     /* print AAC file info */
00591     fprintf(stderr, "%s file info:\n", aacfile);
00592     switch (header_type)
00593     {
00594     case 0:
00595         fprintf(stderr, "RAW\n\n");
00596         break;
00597     case 1:
00598         fprintf(stderr, "ADTS, %.3f sec, %d kbps, %lu Hz\n\n",
00599             length, bitrate, samplerate);
00600         break;
00601     case 2:
00602         fprintf(stderr, "ADIF, %.3f sec, %d kbps, %lu Hz\n\n",
00603             length, bitrate, samplerate);
00604         break;
00605     }
00606 
00607     if (infoOnly)
00608     {
00609         faacDecClose(hDecoder);
00610         fclose(b.infile);
00611         if (b.buffer)
00612             free(b.buffer);
00613         return 0;
00614     }
00615 
00616     do
00617     {
00618         sample_buffer = faacDecDecode(hDecoder, &frameInfo,
00619             b.buffer, b.bytes_into_buffer);
00620 
00621         if (adts_out == 1)
00622         {
00623             int skip = (old_format) ? 8 : 7;
00624             adtsData = MakeAdtsHeader(&adtsDataSize, &frameInfo, old_format);
00625 
00626             /* write the adts header */
00627             if (DEBUG_AAC) report ("I write the adts header", REP_DEBUG);
00628             fwrite(adtsData, 1, adtsDataSize, adtsFile);
00629 
00630             /* write the frame data */
00631             if (DEBUG_AAC) report ("I write the adts frame data", REP_DEBUG);
00632             if (frameInfo.header_type == ADTS)
00633                 fwrite(b.buffer + skip, 1, frameInfo.bytesconsumed - skip, adtsFile);
00634             else
00635                 fwrite(b.buffer, 1, frameInfo.bytesconsumed, adtsFile);
00636         }
00637 
00638         /* update buffer indices */
00639         advance_buffer(&b, frameInfo.bytesconsumed);
00640 
00641         if (frameInfo.error > 0)
00642         {
00643             fprintf(stderr, "Error: %s\n",
00644                 faacDecGetErrorMessage(frameInfo.error));
00645         }
00646 
00647         /* open the sound file now that the number of channels are known */
00648         if (first_time && !frameInfo.error)
00649         {
00650 
00651             if (!adts_out)
00652             {
00653                 /* open output file */
00654                 if (!to_stdout)
00655                 {
00656                     aufile = open_audio_file(sndfile, frameInfo.samplerate, frameInfo.channels,
00657                         outputFormat, fileType, aacChannelConfig2wavexChannelMask(&frameInfo));
00658                 } else {
00659                     aufile = open_audio_file("-", frameInfo.samplerate, frameInfo.channels,
00660                         outputFormat, fileType, aacChannelConfig2wavexChannelMask(&frameInfo));
00661                 }
00662                 if (aufile == NULL)
00663                 {
00664                     if (b.buffer)
00665                         free(b.buffer);
00666                     faacDecClose(hDecoder);
00667                     fclose(b.infile);
00668                     return 0;
00669                 }
00670             } else {
00671                 fprintf(stderr, "Writing output MPEG-4 AAC ADTS file.\n\n");
00672             }
00673             first_time = 0;
00674         }
00675 
00676         if ((frameInfo.error == 0) && (frameInfo.samples > 0) && (!adts_out))
00677         {
00678             if (DEBUG_AAC) report ("write_audio_file1", REP_DEBUG);
00679             write_audio_file(aufile, sample_buffer, frameInfo.samples, 0);
00680         }
00681 
00682         /* fill buffer */
00683         fill_buffer(&b);
00684 
00685         if (b.bytes_into_buffer == 0)
00686             sample_buffer = NULL; /* to make sure it stops now */
00687 
00688     } while (sample_buffer != NULL);
00689 
00690     faacDecClose(hDecoder);
00691 
00692     if (adts_out == 1)
00693     {
00694         fclose(adtsFile);
00695     }
00696 
00697     fclose(b.infile);
00698 
00699     if (!first_time && !adts_out)
00700         close_audio_file(aufile);
00701 
00702     if (b.buffer)
00703         free(b.buffer);
00704 
00705     return frameInfo.error;
00706 }
00707 
00723 static
00724 int decodeMP4file(struct_audio_data_t *data, char *mp4file, char *sndfile, char *adts_fn, int to_stdout,
00725                   int outputFormat, int fileType, int downMatrix, int noGapless,
00726                   int infoOnly, int adts_out, float *song_length)
00727 {
00728     int track;
00729     unsigned long samplerate;
00730     unsigned char channels;
00731     void *sample_buffer;
00732 
00733     mp4ff_t *infile;
00734     long sampleId, numSamples;
00735 
00736     audio_file *aufile;
00737 
00738     FILE *mp4File;
00739     FILE *adtsFile;
00740     unsigned char *adtsData;
00741     int adtsDataSize;
00742 
00743     faacDecHandle hDecoder;
00744     faacDecConfigurationPtr config;
00745     faacDecFrameInfo frameInfo;
00746     mp4AudioSpecificConfig mp4ASC;
00747 
00748     unsigned char *buffer;
00749     int buffer_size;
00750 
00751     char percents[200];
00752     int percent, old_percent = -1;
00753 
00754     int first_time = 1;
00755 
00756     /* for gapless decoding */
00757     unsigned int useAacLength = 1;
00758     unsigned int initial = 1;
00759     unsigned int framesize;
00760     unsigned long timescale;
00761 
00762 
00763     /* initialise the callback structure */
00764     mp4ff_callback_t *mp4cb = malloc(sizeof(mp4ff_callback_t));
00765 
00766     mp4File = fopen(mp4file, "rb");
00767     mp4cb->read = read_callback;
00768     mp4cb->seek = seek_callback;
00769     mp4cb->user_data = mp4File;
00770 
00771 
00772     hDecoder = faacDecOpen();
00773 
00774     /* Set configuration */
00775     config = faacDecGetCurrentConfiguration(hDecoder);
00776 
00777     if (DEBUG_AAC) {
00778         char msg[STRLEN];
00779         snprintf (msg, STRLEN, "\noutputFormat: %d\ndownMatrix: %d", outputFormat, downMatrix);
00780         report (msg, REP_DEBUG);
00781     }
00782 
00783     config->outputFormat = outputFormat;
00784     config->downMatrix = downMatrix;
00785     config->dontUpSampleImplicitSBR = 1;
00786     faacDecSetConfiguration(hDecoder, config);
00787 
00788     if (adts_out)
00789     {
00790         adtsFile = fopen(adts_fn, "wb");
00791         if (adtsFile == NULL)
00792         {
00793             fprintf(stderr, "Error opening file: %s\n", adts_fn);
00794             return 1;
00795         }
00796     }
00797 
00798     infile = mp4ff_open_read(mp4cb);
00799     if (!infile)
00800     {
00801         /* unable to open file */
00802         fprintf(stderr, "Error opening file: %s\n", mp4file);
00803         return 1;
00804     }
00805 
00806     if ((track = GetAACTrack(infile)) < 0)
00807     {
00808         fprintf(stderr, "Unable to find correct AAC sound track in the MP4 file.\n");
00809         faacDecClose(hDecoder);
00810         mp4ff_close(infile);
00811         free(mp4cb);
00812         fclose(mp4File);
00813         return 1;
00814     }
00815 
00816     buffer = NULL;
00817     buffer_size = 0;
00818     mp4ff_get_decoder_config(infile, track, &buffer, &buffer_size);
00819 
00820     if(faacDecInit2(hDecoder, buffer, buffer_size,
00821                     &samplerate, &channels) < 0)
00822     {
00823         /* If some error initializing occured, skip the file */
00824         fprintf(stderr, "Error initializing decoder library.\n");
00825         faacDecClose(hDecoder);
00826         mp4ff_close(infile);
00827         free(mp4cb);
00828         fclose(mp4File);
00829         return 1;
00830     }
00831 
00835     libao_initiate(AO_FMT_LITTLE, channels, samplerate);
00836 
00837     timescale = mp4ff_time_scale(infile, track);
00838     framesize = 1024;
00839     useAacLength = 0;
00840 
00841     if (buffer)
00842     {
00843         if (AudioSpecificConfig(buffer, buffer_size, &mp4ASC) >= 0)
00844         {
00845             if (mp4ASC.frameLengthFlag == 1) framesize = 960;
00846             if (mp4ASC.sbr_present_flag == 1) framesize *= 2;
00847         }
00848         free(buffer);
00849     }
00850 
00851     /* print some mp4 file info */
00852     fprintf(stderr, "%s file info:\n\n", mp4file);
00853     {
00854         char *tag = NULL, *item = NULL;
00855         int k, j;
00856         char *ot[6] = { "NULL", "MAIN AAC", "LC AAC", "SSR AAC", "LTP AAC", "HE AAC" };
00857         long samples = mp4ff_num_samples(infile, track);
00858         float f = 1024.0;
00859         float seconds;
00860         if (mp4ASC.sbr_present_flag == 1)
00861         {
00862             f = f * 2.0;
00863         }
00864         seconds = (float)samples*(float)(f-1.0)/(float)mp4ASC.samplingFrequency;
00865 
00866         *song_length = seconds;
00867 
00868         fprintf(stderr, "%s\t%.3f secs, %d ch, %d Hz\n\n", ot[(mp4ASC.objectTypeIndex > 5)?0:mp4ASC.objectTypeIndex],
00869             seconds, mp4ASC.channelsConfiguration, mp4ASC.samplingFrequency);
00870 
00871 #define PRINT_MP4_METADATA
00872 #ifdef PRINT_MP4_METADATA
00873         j = mp4ff_meta_get_num_items(infile);
00874         for (k = 0; k < j; k++)
00875         {
00876             if (mp4ff_meta_get_by_index(infile, k, &item, &tag))
00877             {
00878                 if (item != NULL && tag != NULL)
00879                 {
00880                     fprintf(stderr, "%s: %s\n", item, tag);
00881                     free(item); item = NULL;
00882                     free(tag); tag = NULL;
00883                 }
00884             }
00885         }
00886         if (j > 0) fprintf(stderr, "\n");
00887 #endif
00888     }
00889 
00890     if (infoOnly)
00891     {
00892         faacDecClose(hDecoder);
00893         mp4ff_close(infile);
00894         free(mp4cb);
00895         fclose(mp4File);
00896         return 0;
00897     }
00898 
00899     numSamples = mp4ff_num_samples(infile, track);
00900 
00901     for (sampleId = 0; sampleId < numSamples; sampleId++)
00902     {
00903         int rc;
00904         long dur;
00905         unsigned int sample_count;
00906         unsigned int delay = 0;
00907 
00908         /* get acces unit from MP4 file */
00909         buffer = NULL;
00910         buffer_size = 0;
00911 
00912         dur = mp4ff_get_sample_duration(infile, track, sampleId);
00913 
00914         rc = mp4ff_read_sample(infile, track, sampleId, &buffer,  &buffer_size);
00915         if (rc == 0)
00916         {
00917             fprintf(stderr, "Reading from MP4 file failed.\n");
00918             faacDecClose(hDecoder);
00919             mp4ff_close(infile);
00920             free(mp4cb);
00921             fclose(mp4File);
00922             return 1;
00923         }
00924 
00925         sample_buffer = faacDecDecode(hDecoder, &frameInfo, buffer, buffer_size);
00926 
00927         if (adts_out == 1)
00928         {
00929             adtsData = MakeAdtsHeader(&adtsDataSize, &frameInfo, 0);
00930 
00931             /* write the adts header */
00932             if (DEBUG_AAC) report ("I write the adts header", REP_DEBUG);
00933             fwrite(adtsData, 1, adtsDataSize, adtsFile);
00934 
00935             fwrite(buffer, 1, frameInfo.bytesconsumed, adtsFile);
00936         }
00937 
00938         if (buffer) free(buffer);
00939 
00940         if (!noGapless)
00941         {
00942             if (sampleId == 0) dur = 0;
00943 
00944             if (useAacLength || (timescale != samplerate)) {
00945                 sample_count = frameInfo.samples;
00946             } else {
00947                 sample_count = (unsigned int)(dur * frameInfo.channels);
00948 
00949                 if (!useAacLength && !initial && (sampleId < numSamples/2) && (sample_count != frameInfo.samples))
00950                 {
00951                     fprintf(stderr, "MP4 seems to have incorrect frame duration, using values from AAC data.\n");
00952                     useAacLength = 1;
00953                     sample_count = frameInfo.samples;
00954                 }
00955             }
00956 
00957             if (initial && (sample_count < framesize*frameInfo.channels) && (frameInfo.samples > sample_count))
00958                 delay = frameInfo.samples - sample_count;
00959         } else {
00960             sample_count = frameInfo.samples;
00961         }
00962 
00963         /* open the sound file now that the number of channels are known */
00964         if (first_time && !frameInfo.error)
00965         {
00966             /* print some channel info */
00967 /*            print_channel_info(&frameInfo); */
00968 
00969             if (!adts_out)
00970             {
00971                 /* open output file */
00972                 if(!to_stdout)
00973                 {
00974                     aufile = open_audio_file(sndfile, frameInfo.samplerate, frameInfo.channels,
00975                         outputFormat, fileType, aacChannelConfig2wavexChannelMask(&frameInfo));
00976                 } else {
00977                     aufile = open_audio_file("-", frameInfo.samplerate, frameInfo.channels,
00978                         outputFormat, fileType, aacChannelConfig2wavexChannelMask(&frameInfo));
00979                 }
00980                 if (aufile == NULL)
00981                 {
00982                     faacDecClose(hDecoder);
00983                     mp4ff_close(infile);
00984                     free(mp4cb);
00985                     fclose(mp4File);
00986                     return 0;
00987                 }
00988             }
00989             first_time = 0;
00990         }
00991 
00992         if (sample_count > 0) initial = 0;
00993 
00994         percent = min((int)(sampleId*100)/numSamples, 100);
00995         if (percent > old_percent)
00996         {
00997             old_percent = percent;
00998             sprintf(percents, "%d%% decoding %s.", percent, mp4file);
00999             fprintf(stderr, "%s\r", percents);
01000         }
01001         
01006         printf ("sampleId: %li\tnumSamples: %li\tsampple_count_pr_channel: %d\n", sampleId, numSamples, sample_count/channels);
01007 
01012         callback (data, dur);   /* struct_audio_data_t, duration in milliseconds */
01013 
01014         if ((frameInfo.error == 0) && (sample_count > 0) && (!adts_out))
01015         {
01022             libao_play(data->device, sample_buffer, sample_count*channels);
01023         }
01024 
01025         if (frameInfo.error > 0)
01026         {
01027             fprintf(stderr, "Warning: %s\n",
01028                 faacDecGetErrorMessage(frameInfo.error));
01029         }
01030     }
01031 
01032     faacDecClose(hDecoder);
01033 
01034     if (adts_out == 1)
01035     {
01036         fclose(adtsFile);
01037     }
01038 
01039 
01040     /* Closing daisylibao */
01041     libao_terminate(data->device);
01042 
01043     mp4ff_close(infile);
01044 
01045     if (!first_time && !adts_out)
01046         close_audio_file(aufile);
01047 
01048     free(mp4cb);
01049     fclose(mp4File);
01050 
01051     return frameInfo.error;
01052 }
01053 
01054 
01055 
01056 /* ************************************************ *
01057  *          Global function declarations            *
01058  * ************************************************ */
01059 
01064 bool aac_play (struct_audio_data_t *data)
01065 {
01066     int result;
01067     int infoOnly = 0;
01068     int writeToStdio = 0;
01069     int object_type = LC;
01070     int def_srate = 0;
01071     int downMatrix = 0;
01072     int format = 1;
01073     int outputFormat = FAAD_FMT_16BIT;
01074     int adts_out = 0;
01075     int old_format = 0;
01076     int mp4file = 0;
01077     int noGapless = 0;
01078     char aacFileName[STRLEN];
01079     char audioFileName[STRLEN];
01080     char adtsFileName[STRLEN];
01081     unsigned char header[8];
01082     float length = 0;
01083     FILE *hMP4File;
01084 
01085     strncpy (aacFileName, data->file_name, STRLEN);
01086 
01087     /* check for mp4 file */
01088     mp4file = 0;
01089     hMP4File = fopen(aacFileName, "rb");
01090     if (!hMP4File)
01091     {
01092         fprintf(stderr, "Error opening file: %s\n", aacFileName);
01093         return 1;
01094     }
01095     fread(header, 1, 8, hMP4File);
01096     fclose(hMP4File);
01097     if (header[4] == 'f' && header[5] == 't' && header[6] == 'y' && header[7] == 'p')
01098         mp4file = 1;
01099 
01100 
01104     if (mp4file)
01105     {
01106         if (DEBUG_AAC) report ("File is mp4", REP_DEBUG);
01107         result = decodeMP4file(data, aacFileName, audioFileName, adtsFileName, writeToStdio,
01108             outputFormat, format, downMatrix, noGapless, infoOnly, adts_out, &length);
01109     } else {
01110         if (DEBUG_AAC) report ("File is aac", REP_DEBUG);
01111         result = decodeAACfile(data, aacFileName, audioFileName, adtsFileName, writeToStdio,
01112             def_srate, object_type, outputFormat, format, downMatrix, infoOnly, adts_out,
01113             old_format, &length);
01114     }
01115     return 0;
01116 }
01117 
01122 void aac_initiate (struct_audio_data_t *data)
01123 {
01124     data = data;
01125     printf ("aac_init: \n");
01126     if (DEBUG_AAC) report ("aac_init", REP_DEBUG);
01127 }
01128 
01133 void aac_terminate (struct_audio_data_t *data)
01134 {
01135     data = data;
01136     printf ("aac_close: \n");
01137     if (DEBUG_AAC) report ("aac_close", REP_DEBUG);
01138 }
01139 
01140 
01141 
01142 #endif  /* WITH_AAC */

Generated on Tue Sep 5 12:14:06 2006 for libdaisy by doxygen1.2.15