PageRenderTime 342ms CodeModel.GetById 61ms app.highlight 214ms RepoModel.GetById 57ms app.codeStats 1ms

/thirdparty/liblastfm2/src/fingerprint/contrib/AacSource.cpp

http://github.com/tomahawk-player/tomahawk
C++ | 953 lines | 672 code | 167 blank | 114 comment | 139 complexity | bca1a8e971400d45d4152bbb427d6dcc MD5 | raw file
  1/*
  2   Copyright 2009 Last.fm Ltd. 
  3   Copyright 2009 John Stamp <jstamp@users.sourceforge.net>
  4   Portions Copyright 2003-2005 M. Bakker, Nero AG, http://www.nero.com
  5      - Adapted from main.c found in the FAAD2 source tarball.
  6
  7   This file is part of liblastfm.
  8
  9   liblastfm is free software: you can redistribute it and/or modify
 10   it under the terms of the GNU General Public License as published by
 11   the Free Software Foundation, either version 3 of the License, or
 12   (at your option) any later version.
 13
 14   liblastfm is distributed in the hope that it will be useful,
 15   but WITHOUT ANY WARRANTY; without even the implied warranty of
 16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 17   GNU General Public License for more details.
 18
 19   You should have received a copy of the GNU General Public License
 20   along with liblastfm.  If not, see <http://www.gnu.org/licenses/>.
 21*/
 22#include "AacSource.h"
 23#include "AacSource_p.h"
 24
 25#include <QFile>
 26#include <algorithm>
 27#include <cassert>
 28#include <limits>
 29#include <iostream>
 30#include <stdexcept>
 31#include <errno.h>
 32#include <string.h>
 33
 34
 35////////////////////////////////////////////////////////////////////////
 36//
 37// AAC_File
 38//
 39////////////////////////////////////////////////////////////////////////
 40AAC_File::AAC_File(const QString& fileName, int headerType)
 41    : m_fileName(fileName)
 42    , m_inBuf(NULL)
 43    , m_inBufSize(0)
 44    , m_decoder(0)
 45    , m_overflow(static_cast<unsigned char*>(malloc( sizeof(unsigned char) * 1024 )))
 46    , m_overflowSize(0)
 47    , m_header(headerType)
 48{
 49}
 50
 51
 52AAC_File::~AAC_File()
 53{
 54    // common
 55    if ( m_decoder )
 56    {
 57        NeAACDecClose( m_decoder );
 58        m_decoder = NULL;
 59    }
 60    if ( m_inBuf )
 61    {
 62        free( m_inBuf );
 63        m_inBufSize = 0;
 64        m_inBuf = NULL;
 65    }
 66    if ( m_overflow )
 67    {
 68        free( m_overflow );
 69        m_overflowSize = 0;
 70        m_overflow = NULL;
 71    }
 72}
 73
 74
 75
 76////////////////////////////////////////////////////////////////////////
 77//
 78// AAC with ADTS or ADIF headers
 79//
 80////////////////////////////////////////////////////////////////////////
 81
 82
 83#define MAX_CHANNELS 6 // Output will get mixed down to 2 channels
 84#define ADTS_HEADER_SIZE 8
 85
 86static int adts_sample_rates[] =
 87{
 88    96000,
 89    88200,
 90    64000,
 91    48000,
 92    44100,
 93    32000,
 94    24000,
 95    22050,
 96    16000,
 97    12000,
 98    11025,
 99     8000,
100     7350,
101        0,
102        0,
103        0
104};
105
106AAC_ADTS_File::AAC_ADTS_File( const QString& fileName, int headerType ) : AAC_File(fileName, headerType)
107    , m_file( NULL )
108    , m_adifSamplerate( 0 )
109    , m_adifChannels( 0 )
110{
111}
112
113
114AAC_ADTS_File::~AAC_ADTS_File()
115{
116    if ( m_file )
117    {
118        fclose( m_file );
119    }
120}
121
122
123void AAC_ADTS_File::fillBuffer( FILE*& fp, unsigned char*& buf, size_t& bufSize, const size_t bytesConsumed )
124{
125    size_t bread;
126
127    if ( bytesConsumed > 0 )
128    {
129        if ( bufSize )
130            memmove( (void*)buf, (void*)(buf + bytesConsumed), bufSize*sizeof(unsigned char) );
131
132        bread = fread( (void*)(buf + bufSize), 1, bytesConsumed, fp );
133        bufSize += bread;
134
135        if ( bufSize > 3 )
136        {
137            if ( memcmp( buf, "TAG", 3 ) == 0 )
138                bufSize = 0;
139        }
140        if ( bufSize > 11 )
141        {
142            if ( memcmp( buf, "LYRICSBEGIN", 11 ) == 0 )
143                bufSize = 0;
144        }
145        if ( bufSize > 8 )
146        {
147            if ( memcmp( buf, "APETAGEX", 8 ) == 0 )
148                bufSize = 0;
149        }
150    }
151}
152
153
154void AAC_ADTS_File::parse( FILE*& fp, unsigned char*& buf, size_t& bufSize, int &bitrate, double &length )
155{
156    unsigned int frames, frame_length = 0;
157    int t_framelength = 0;
158    int samplerate = 0;
159    double frames_per_sec, bytes_per_frame;
160
161    // Read all frames to ensure correct time and bitrate
162    for ( frames = 0; /* */; frames++ )
163    {
164        fillBuffer( fp, buf, bufSize, frame_length );
165
166        if ( bufSize > 7 )
167        {
168            /* check syncword */
169            if ( !( (buf[0] == 0xFF) && ((buf[1] & 0xF6) == 0xF0) ) )
170                break;
171
172            if ( frames == 0 )
173                samplerate = adts_sample_rates[ (buf[2] & 0x3c) >> 2 ];
174
175            frame_length = (  ((buf[3] & 0x3) << 11)
176                            | ((buf[4]) << 3)
177                            | (buf[5] >> 5) );
178
179            t_framelength += frame_length - ADTS_HEADER_SIZE;
180
181            if ( frame_length > bufSize )
182                break;
183
184            bufSize -= frame_length;
185        }
186        else
187        {
188            break;
189        }
190    }
191
192    frames_per_sec = samplerate / 1024.0;
193
194    if ( frames != 0 )
195        bytes_per_frame = t_framelength / frames;
196    else
197        bytes_per_frame = 0;
198
199    bitrate = static_cast<int>(8 * bytes_per_frame * frames_per_sec + 0.5);
200
201    if ( frames_per_sec != 0 )
202        length = frames / frames_per_sec;
203    else
204        length = 1;
205}
206
207
208int32_t AAC_ADTS_File::commonSetup( FILE*& fp, NeAACDecHandle& decoder, unsigned char*& buf, size_t& bufSize, uint32_t& samplerate, uint8_t& channels )
209{
210    samplerate = 0;
211    channels = 0;
212
213    fp = fopen(QFile::encodeName(m_fileName), "rb" );
214    if( !fp )
215    {
216        std::cerr << "ERROR: Failed to open " << strerror( errno ) << std::endl;
217        return -1;
218    }
219
220    if ( !(buf = static_cast<unsigned char*>( malloc(FAAD_MIN_STREAMSIZE*MAX_CHANNELS)) ) )
221    {
222        std::cerr << "Memory allocation error" << std::endl;
223        fclose ( fp );
224        return -1;
225    }
226
227    memset( buf, 0, FAAD_MIN_STREAMSIZE*MAX_CHANNELS );
228
229    bufSize = fread( buf, 1, FAAD_MIN_STREAMSIZE * MAX_CHANNELS, fp );
230
231    int tagsize = 0;
232    if ( !memcmp( buf, "ID3", 3 ) )
233    {
234        /* high bit is not used */
235        tagsize = (buf[6] << 21) | (buf[7] << 14) |
236            (buf[8] <<  7) | (buf[9] <<  0);
237
238        tagsize += 10;
239        bufSize -= tagsize;
240        fillBuffer( fp, buf, bufSize, tagsize );
241    }
242
243    decoder = NeAACDecOpen();
244
245    /* Set configuration */
246    NeAACDecConfigurationPtr config;
247    config = NeAACDecGetCurrentConfiguration(decoder);
248    config->outputFormat = FAAD_FMT_16BIT;
249    config->downMatrix = 1; // Turn 5.1 channels into 2
250    NeAACDecSetConfiguration( decoder, config);
251
252    int32_t initval = 0;
253    if ((initval = NeAACDecInit(decoder, buf,
254        FAAD_MIN_STREAMSIZE*MAX_CHANNELS, &samplerate, &channels)) < 0)
255    {
256        std::cerr << "Error: could not set up AAC decoder" << std::endl;
257        if ( buf )
258            free( buf );
259        buf = NULL;
260        NeAACDecClose( decoder );
261        decoder = NULL;
262        fclose( fp );
263        fp = NULL;
264    }
265    return initval;
266}
267
268
269bool AAC_ADTS_File::init()
270{
271    uint32_t initSamplerate = 0;
272    uint8_t initChannels = 0;
273    int32_t initval = commonSetup( m_file, m_decoder, m_inBuf, m_inBufSize, initSamplerate, initChannels );
274
275     if ( initval >= 0 )
276     {
277        m_inBufSize -= initval;
278        fillBuffer( m_file, m_inBuf, m_inBufSize, initval );
279
280        // These two only needed for skipping AAC ADIF files
281        m_adifSamplerate = initSamplerate;
282        m_adifChannels = initChannels;
283
284        return true;
285     }
286
287     throw std::runtime_error( "ERROR: Could not initialize AAC file reader!" );
288     return false;
289}
290
291
292/*QString AAC_ADTS_File::getMbid()
293{
294    char out[MBID_BUFFER_SIZE];
295    int const r = getMP3_MBID(QFile::encodeName(m_fileName), out);
296    if ( r == 0 )
297        return QString::fromLatin1( out );
298    return QString();
299}*/
300
301void AAC_ADTS_File::getInfo( int& lengthSecs, int& samplerate, int& bitrate, int& nchannels )
302{
303    long fileread;
304    uint32_t initSamplerate;
305    uint8_t initChannels;
306    double initLength = 0;
307    unsigned char *tempBuf = NULL;
308    size_t tempBufSize;
309    FILE *fp = NULL;
310    NeAACDecHandle decoder = NULL;
311    commonSetup( fp, decoder, tempBuf, tempBufSize, initSamplerate, initChannels );
312
313    long origpos = ftell( fp );
314    fseek( fp, 0, SEEK_END );
315    fileread = ftell( fp );
316    fseek( fp, origpos, SEEK_SET );
317
318    if ( (tempBuf[0] == 0xFF) && ((tempBuf[1] & 0xF6) == 0xF0) )
319    {
320        parse( fp, tempBuf, tempBufSize, bitrate, initLength );
321    }
322    else if (memcmp(tempBuf, "ADIF", 4) == 0)
323    {
324        int skip_size = (tempBuf[4] & 0x80) ? 9 : 0;
325        bitrate = ((tempBuf[4 + skip_size] & 0x0F)<<19) |
326            (tempBuf[5 + skip_size]<<11) |
327            (tempBuf[6 + skip_size]<<3) |
328            (tempBuf[7 + skip_size] & 0xE0);
329
330        if ( fileread != 0)
331        {
332            initLength = static_cast<double>(fileread) * 8 / bitrate + 0.5;
333        }
334    }
335
336    lengthSecs = static_cast<int>(initLength);
337    nchannels = initChannels;
338    samplerate = initSamplerate;
339
340    if ( decoder )
341        NeAACDecClose( decoder );
342    if ( fp )
343        fclose( fp );
344    if ( tempBuf )
345        free( tempBuf );
346}
347
348
349void AAC_ADTS_File::skip( const int mSecs )
350{
351    if ( m_header == AAC_ADTS )
352    {
353        // As AAC is VBR we need to check all ADTS headers to enable seeking...
354        // There is no other solution
355        unsigned char header[8];
356        unsigned int frameCount, frameLength;
357        double seconds = 0;
358
359        // We need to find the ATDS syncword so rewind to the beginning
360        // of the unprocessed data.
361        if ( m_inBufSize > 0 )
362        {
363            fseek ( m_file, -m_inBufSize, SEEK_CUR );
364            m_inBufSize = 0;
365        }
366
367        for( frameCount = 1; seconds * 1000 < mSecs; frameCount++ )
368        {
369            if ( fread( header, 1, ADTS_HEADER_SIZE, m_file ) != ADTS_HEADER_SIZE )
370            {
371                break;
372            }
373            if ( !strncmp( (char*)header, "ID3", 3 ) )
374            {
375                // high bit is not used
376                unsigned char rest[2];
377                fread( rest, 1, 2, m_file );
378                int tagsize = (header[6] << 21) | (header[7] << 14) |
379                    (rest[0] <<  7) | (rest[1] <<  0);
380
381                fseek( m_file, tagsize, SEEK_CUR );
382                fread( header, 1, ADTS_HEADER_SIZE, m_file );
383            }
384            if ( !((header[0] == 0xFF) && ((header[1] & 0xF6) == 0xF0)) )
385            {
386                std::cerr << "Error: Bad frame header; file may be corrupt!" << std::endl;
387                break;
388            }
389
390            int samplerate = adts_sample_rates[ (header[2] & 0x3c) >> 2 ];
391            frameLength = ( ( header[3] & 0x3 ) << 11 )
392                          | ( header[4] << 3 )
393                          | ( header[5] >> 5 );
394
395            if ( samplerate > 0 )
396                seconds += 1024.0 / samplerate;
397            else
398            {
399                std::cerr << "Error: Bad frame header; file may be corrupt!" << std::endl;
400                break;
401            }
402
403            if ( fseek( m_file, frameLength - ADTS_HEADER_SIZE, SEEK_CUR ) == -1 )
404                break;
405        }
406        m_inBufSize = fread( m_inBuf, 1, FAAD_MIN_STREAMSIZE * MAX_CHANNELS, m_file );
407    }
408    else if ( m_header == AAC_ADIF )
409    {
410        // AAC ADIF is even worse.  There's only the one header at the
411        // beginning of the file.  If you want to skip forward, you have to
412        // decode block by block and check how far along you are.  Lovely, eh?
413
414        unsigned long totalSamples = 0;
415        void *sampleBuffer = NULL;
416
417        do
418        {
419            NeAACDecFrameInfo frameInfo;
420            sampleBuffer = NeAACDecDecode(m_decoder, &frameInfo, m_inBuf, static_cast<uint32_t>(m_inBufSize) );
421            totalSamples += frameInfo.samples;
422            if ( frameInfo.bytesconsumed > 0 )
423            {
424                m_inBufSize -= frameInfo.bytesconsumed;
425                fillBuffer( m_file, m_inBuf, m_inBufSize, frameInfo.bytesconsumed );
426            }
427            if ( totalSamples >= ( mSecs * m_adifSamplerate * m_adifChannels / 1000 ) )
428                break;
429        } while ( sampleBuffer != NULL );
430    }
431}
432
433
434void AAC_ADTS_File::postDecode(unsigned long bytesConsumed)
435{
436    m_inBufSize -= bytesConsumed;
437    fillBuffer( m_file, m_inBuf, m_inBufSize, bytesConsumed );
438}
439
440
441////////////////////////////////////////////////////////////////////////
442//
443// AAC in an MP4 wrapper
444//
445////////////////////////////////////////////////////////////////////////
446
447
448uint32_t read_callback( void *user_data, void *buffer, uint32_t length )
449{
450    return static_cast<uint32_t>(fread( buffer, 1, length, static_cast<FILE*>(user_data) ));
451}
452
453
454uint32_t seek_callback( void *user_data, uint64_t position )
455{
456    return fseek( static_cast<FILE*>(user_data), static_cast<long>(position), SEEK_SET );
457}
458
459AAC_MP4_File::AAC_MP4_File( const QString& fileName, int headerType ) : AAC_File(fileName, headerType)
460    , m_mp4AudioTrack( -1 )
461    , m_mp4SampleId( 0 )
462    , m_mp4File ( NULL )
463    , m_mp4cb ( NULL )
464{
465}
466
467int32_t AAC_MP4_File::readSample()
468{
469    unsigned int bsize;
470    int32_t rc = mp4ff_read_sample( m_mp4File, m_mp4AudioTrack, m_mp4SampleId, &m_inBuf,  &bsize );
471    m_inBufSize = bsize;
472    // Not necessarily an error.  Could just mean end of file.
473    //if ( rc == 0 )
474    //    std::cerr << "Reading samples failed." << std::endl;
475    return rc;
476}
477
478
479int32_t AAC_MP4_File::getTrack( const mp4ff_t *f )
480{
481    // find AAC track
482    int32_t numTracks = mp4ff_total_tracks( f );
483
484    for ( int32_t i = 0; i < numTracks; i++ )
485    {
486        unsigned char *buff = NULL;
487        unsigned int buff_size = 0;
488        mp4AudioSpecificConfig mp4ASC;
489
490        mp4ff_get_decoder_config( f, i, &buff, &buff_size );
491
492        if ( buff )
493        {
494            int8_t rc = NeAACDecAudioSpecificConfig( buff, buff_size, &mp4ASC );
495            free( buff );
496
497            if ( rc < 0 )
498                continue;
499            return i;
500        }
501    }
502
503    // can't decode this, probably DRM
504    return -1;
505}
506
507
508bool AAC_MP4_File::commonSetup( NeAACDecHandle& decoder, mp4ff_callback_t*& cb, FILE*& fp, mp4ff_t*& mp4, int32_t& audioTrack )
509{
510    fp = fopen(QFile::encodeName(m_fileName), "rb");
511    if ( !fp )
512    {
513        throw std::runtime_error( "Error: failed to open AAC file!" );
514        return false;
515    }
516
517    decoder = NeAACDecOpen();
518
519    // Set configuration
520    NeAACDecConfigurationPtr config;
521    config = NeAACDecGetCurrentConfiguration( decoder );
522    config->outputFormat = FAAD_FMT_16BIT;
523    config->downMatrix = 1; // Turn 5.1 channels into 2
524    NeAACDecSetConfiguration( decoder, config );
525
526    // initialise the callback structure
527    cb = static_cast<mp4ff_callback_t*>( malloc( sizeof(mp4ff_callback_t) ) );
528
529    cb->read = read_callback;
530    cb->seek = seek_callback;
531    cb->user_data = fp;
532
533    mp4 = mp4ff_open_read( cb );
534
535    if ( !mp4 )
536    {
537        // unable to open file
538        free( cb );
539        cb = NULL;
540        NeAACDecClose( decoder );
541        decoder = NULL;
542        fclose( fp );
543        fp = NULL;
544        throw std::runtime_error( "Error: failed to set up AAC decoder!" );
545        return false;
546    }
547
548    if ( ( audioTrack = getTrack( mp4 )) < 0 )
549    {
550        free( cb );
551        cb = NULL;
552        NeAACDecClose( decoder );
553        decoder = NULL;
554        fclose( fp );
555        fp = NULL;
556        mp4ff_close( mp4 );
557        mp4 = NULL;
558        audioTrack = 0;
559        throw std::runtime_error( "Error: Unable to find an audio track. Is the file DRM protected?" );
560        return false;
561    }
562    return true;
563}
564
565
566/*QString AAC_MP4_File::getMbid()
567{
568    int j = mp4ff_meta_get_num_items( m_mp4File );
569    if ( j > 0 )
570    {
571        int k;
572        for ( k = 0; k < j; k++ )
573        {
574            char *tag = NULL, *item = NULL;
575            if ( mp4ff_meta_get_by_index( m_mp4File, k, &item, &tag ) )
576            {
577                if ( item != NULL && tag != NULL )
578                {
579                    QString key(item);
580                    if ( key.toLower() == "musicbrainz track id" )
581                    {
582                        QString ret(tag);
583                        free( item );
584                        free( tag );
585                        return ret;
586                    }
587                    free( item );
588                    free( tag );
589                }
590            }
591        }
592    }
593    return QString();
594}*/
595
596
597void AAC_MP4_File::getInfo( int& lengthSecs, int& samplerate, int& bitrate, int& nchannels )
598{
599    FILE* fp = NULL;
600    mp4ff_callback_t *cb = NULL;
601    NeAACDecHandle decoder = NULL;
602    mp4ff_t* mp4 = NULL;
603    int32_t audioTrack;
604
605    bool success = commonSetup( decoder, cb, fp, mp4, audioTrack );
606
607    if ( success )
608    {
609        // get basic file info
610        mp4AudioSpecificConfig mp4ASC;
611        unsigned char* buffer = NULL;
612        unsigned int buffer_size = 0;
613        double f = 1024.0;
614        unsigned int framesize = 1024;
615
616        int32_t samples = mp4ff_num_samples( mp4, audioTrack );
617
618        if ( buffer )
619        {
620            if ( NeAACDecAudioSpecificConfig(buffer, buffer_size, &mp4ASC) >= 0 )
621            {
622                if ( mp4ASC.frameLengthFlag == 1 )
623                    framesize = 960;
624                if ( mp4ASC.sbr_present_flag == 1 )
625                    framesize *= 2;
626                if ( mp4ASC.sbr_present_flag == 1 )
627                    f = f * 2.0;
628            }
629            free( buffer );
630        }
631
632        samplerate = mp4ff_get_sample_rate( mp4, audioTrack );
633        if ( samplerate > 0 )
634            lengthSecs = static_cast<int>(samples * f / samplerate + 0.5);
635        bitrate = mp4ff_get_avg_bitrate( mp4, audioTrack );
636        nchannels = mp4ff_get_channel_count( mp4, audioTrack );
637
638        mp4ff_close( mp4 );
639        NeAACDecClose( decoder );
640        free( cb );
641        fclose( fp );
642    }
643}
644
645
646bool AAC_MP4_File::init()
647{
648    FILE* fp = NULL;
649
650    bool success = commonSetup( m_decoder, m_mp4cb, fp, m_mp4File, m_mp4AudioTrack );
651    if ( !success )
652        return false;
653
654    unsigned char* buffer = NULL;
655    unsigned int buffer_size = 0;
656    uint32_t samplerate;
657    uint8_t channels;
658
659    mp4ff_get_decoder_config( m_mp4File, m_mp4AudioTrack, &buffer, &buffer_size );
660
661    if( NeAACDecInit2( m_decoder, buffer, buffer_size, &samplerate, &channels) < 0 )
662    {
663        // If some error initializing occured, skip the file
664        if ( fp )
665            fclose( fp );
666        throw std::runtime_error( "Error: unable to initialize AAC decoder library!" );
667        return false;
668    }
669
670    if ( buffer )
671        free( buffer );
672
673    return true;
674}
675
676
677void AAC_MP4_File::postDecode(unsigned long)
678{
679            free( m_inBuf );
680            m_inBuf = NULL;
681            m_mp4SampleId++;
682}
683
684void AAC_MP4_File::skip( const int mSecs )
685{
686    double dur = 0.0;
687    int f = 1;
688    unsigned char *buff = NULL;
689    unsigned int buff_size = 0;
690    uint32_t totalSamples = mp4ff_num_samples( m_mp4File, m_mp4AudioTrack );
691    mp4AudioSpecificConfig mp4ASC;
692
693    mp4ff_get_decoder_config( m_mp4File, m_mp4AudioTrack, &buff, &buff_size );
694
695    if ( buff )
696    {
697        int8_t rc = NeAACDecAudioSpecificConfig( buff, buff_size, &mp4ASC );
698        free( buff );
699        if ( rc >= 0 && mp4ASC.sbr_present_flag == 1 )
700            f = 2;
701
702        // I think the f multiplier is needed here.
703        while ( dur * 1000.0 * f / static_cast<double>(mp4ASC.samplingFrequency) < mSecs && m_mp4SampleId < totalSamples )
704        {
705            dur += mp4ff_get_sample_duration( m_mp4File, m_mp4AudioTrack, m_mp4SampleId );
706            m_mp4SampleId++;
707        }
708    }
709    else
710        std::cerr << "Error: could not skip " << mSecs << " milliseconds" << std::endl;
711}
712
713
714AAC_MP4_File::~AAC_MP4_File()
715{
716    if ( m_mp4File )
717        mp4ff_close( m_mp4File );
718    if ( m_mp4cb )
719    {
720        free( m_mp4cb );
721    }
722}
723
724
725////////////////////////////////////////////////////////////////////////
726//
727// AacSource
728//
729////////////////////////////////////////////////////////////////////////
730
731AacSource::AacSource()
732    : m_eof( false )
733    , m_aacFile( NULL )
734{}
735
736
737AacSource::~AacSource()
738{
739    delete m_aacFile;
740}
741
742
743int AacSource::checkHeader()
744{
745    FILE *fp = NULL;
746    unsigned char header[10];
747
748    // check for mp4 file
749    fp = fopen(QFile::encodeName(m_fileName), "rb");
750    if ( !fp )
751    {
752        std::cerr << "Error: failed to open " << strerror( errno ) << std::endl;
753        return AAC_File::AAC_UNKNOWN;
754    }
755
756    fread( header, 1, 10, fp );
757
758    // MP4 headers
759    if ( !memcmp( &header[4], "ftyp", 4 ) )
760    {
761        fclose( fp );
762        return AAC_File::AAC_MP4;
763    }
764
765    // Skip id3 tags
766    int tagsize = 0;
767    if ( !memcmp( header, "ID3", 3 ) )
768    {
769        /* high bit is not used */
770        tagsize = (header[6] << 21) | (header[7] << 14) |
771            (header[8] <<  7) | (header[9] <<  0);
772
773        tagsize += 10;
774        fseek( fp, tagsize, SEEK_SET );
775        fread( header, 1, 10, fp );
776    }
777
778    // Check for ADTS OR ADIF headers
779    if ( (header[0] == 0xFF) && ((header[1] & 0xF6) == 0xF0) )
780    {
781        fclose( fp );
782        return AAC_File::AAC_ADTS;
783    }
784    else if (memcmp(header, "ADIF", 4) == 0)
785    {
786        fclose( fp );
787        return AAC_File::AAC_ADIF;
788    }
789
790    fclose( fp );
791    return AAC_File::AAC_UNKNOWN;
792}
793
794
795void AacSource::getInfo( int& lengthSecs, int& samplerate, int& bitrate, int& nchannels )
796{
797    // get the header plus some other stuff..
798
799    m_aacFile->getInfo( lengthSecs, samplerate, bitrate, nchannels );
800}
801
802
803void AacSource::init(const QString& fileName)
804{
805    m_fileName = fileName;
806    
807    int headerType = checkHeader();
808    if ( headerType != AAC_File::AAC_UNKNOWN )
809    {
810        if ( headerType == AAC_File::AAC_MP4 )
811            m_aacFile = new AAC_MP4_File(m_fileName, headerType);
812        else
813            m_aacFile = new AAC_ADTS_File( m_fileName, headerType );
814    }    
815    
816    if ( m_aacFile )
817        m_aacFile->init();
818    else
819        throw std::runtime_error( "ERROR: No suitable AAC decoder found!" );
820}
821
822
823/*QString AacSource::getMbid()
824{
825    QString mbid = m_aacFile->getMbid();
826    return mbid;
827}*/
828
829
830void AacSource::skip( const int mSecs )
831{
832    if ( mSecs < 0 || !m_aacFile->m_decoder )
833        return;
834
835        m_aacFile->skip( mSecs );
836}
837
838
839void AacSource::skipSilence(double silenceThreshold /* = 0.0001 */)
840{
841    if ( !m_aacFile->m_decoder )
842        return;
843
844    silenceThreshold *= static_cast<double>( std::numeric_limits<short>::max() );
845
846    for (;;)
847    {
848        if ( m_aacFile->m_header == AAC_File::AAC_MP4 )
849        {
850            if ( !static_cast<AAC_MP4_File*>(m_aacFile)->readSample() )
851                break;
852        }
853        NeAACDecFrameInfo frameInfo;
854
855        void* sampleBuffer = NeAACDecDecode(m_aacFile->m_decoder, &frameInfo, m_aacFile->m_inBuf, static_cast<uint32_t>(m_aacFile->m_inBufSize) );
856
857        m_aacFile->postDecode( frameInfo.bytesconsumed );
858
859        if ( frameInfo.error > 0 )
860        {
861            break;
862        }
863        else if ( frameInfo.samples > 0 )
864        {
865            double sum = 0;
866            int16_t *buf = static_cast<int16_t*>(sampleBuffer);
867            switch ( frameInfo.channels )
868            {
869                case 1:
870                    for (size_t j = 0; j < frameInfo.samples; ++j)
871                        sum += abs( buf[j] );
872                    break;
873                case 2:
874                    for (size_t j = 0; j < frameInfo.samples; j+=2)
875                        sum += abs( (buf[j] >> 1) + (buf[j+1] >> 1) );
876                    break;
877            }
878            if ( (sum >= silenceThreshold * static_cast<short>(frameInfo.samples/frameInfo.channels) ) )
879                break;
880        }
881    }
882}
883
884
885int AacSource::updateBuffer( signed short *pBuffer, size_t bufferSize )
886{
887    size_t nwrit = 0; //number of samples written to the output buffer
888
889    if ( m_aacFile->m_overflowSize > 0 )
890    {
891        size_t samples_to_use = bufferSize < m_aacFile->m_overflowSize ? bufferSize : m_aacFile->m_overflowSize;
892        memcpy( pBuffer, m_aacFile->m_overflow, samples_to_use * sizeof(signed short) );
893        nwrit += samples_to_use;
894        m_aacFile->m_overflowSize -= samples_to_use;
895        memmove( (void*)(m_aacFile->m_overflow), (void*)(m_aacFile->m_overflow + samples_to_use*sizeof(signed short)), samples_to_use*sizeof(signed short) );
896    }
897
898    if ( !m_aacFile->m_decoder )
899        return 0;
900
901    for (;;)
902    {
903        signed short* pBufferIt = pBuffer + nwrit;
904        void* sampleBuffer;
905
906        assert( nwrit <= bufferSize );
907
908        if ( m_aacFile->m_header == AAC_File::AAC_MP4 )
909        {
910            if ( !static_cast<AAC_MP4_File*>(m_aacFile)->readSample() )
911            {
912                m_eof = true;
913                return static_cast<int>(nwrit);
914            }
915        }
916        NeAACDecFrameInfo frameInfo;
917
918        sampleBuffer = NeAACDecDecode(m_aacFile->m_decoder, &frameInfo, m_aacFile->m_inBuf, static_cast<uint32_t>(m_aacFile->m_inBufSize) );
919        size_t samples_to_use = (bufferSize - nwrit) < frameInfo.samples ? bufferSize-nwrit : frameInfo.samples;
920
921        if ( samples_to_use > 0 && sampleBuffer != NULL )
922        {
923            memcpy( pBufferIt, sampleBuffer, samples_to_use * sizeof(signed short) );
924            nwrit += samples_to_use;
925        }
926
927        if ( samples_to_use < frameInfo.samples )
928        {
929            m_aacFile->m_overflow = static_cast<unsigned char*>(realloc( m_aacFile->m_overflow, (frameInfo.samples - samples_to_use) * sizeof(signed short) ) );
930            memcpy( m_aacFile->m_overflow, static_cast<signed short*>(sampleBuffer) + samples_to_use, (frameInfo.samples - samples_to_use) * sizeof(signed short) );
931            m_aacFile->m_overflowSize = frameInfo.samples - samples_to_use;
932        }
933
934        m_aacFile->postDecode( frameInfo.bytesconsumed );
935
936        if ( sampleBuffer == NULL )
937        {
938            m_eof = true;
939            break;
940        }
941
942        if ( frameInfo.error > 0 )
943        {
944            std::cerr << "Error: " << NeAACDecGetErrorMessage(frameInfo.error) << std::endl;
945            break;
946        }
947
948        if ( nwrit == bufferSize )
949            break;
950   }
951
952   return static_cast<int>(nwrit);
953}