Example #1
0
static int
mp4_track_get_info(mp4ff_t *mp4, int track, float *duration, int *samplerate, int *channels, int *totalsamples, int *mp4framesize) {
    int sr = -1;
    unsigned char*  buff = 0;
    unsigned int    buff_size = 0;
    mp4AudioSpecificConfig mp4ASC;
    mp4ff_get_decoder_config(mp4, track, &buff, &buff_size);
    if (buff) {
        int rc = AudioSpecificConfig(buff, buff_size, &mp4ASC);
        sr = mp4ASC.samplingFrequency;
        if(rc < 0) {
            free (buff);
            trace ("aac: AudioSpecificConfig returned result=%d\n", rc);
            return -1;
        }
    }

    unsigned long srate;
    unsigned char ch;
    int samples;

    // init mp4 decoding
    NeAACDecHandle dec = NeAACDecOpen ();
    if (NeAACDecInit2(dec, buff, buff_size, &srate, &ch) < 0) {
        trace ("NeAACDecInit2 returned error\n");
        goto error;
    }
    *samplerate = srate;
    *channels = ch;
    samples = (int64_t)mp4ff_num_samples(mp4, track);
    
    NeAACDecClose (dec);
    dec = NULL;

    if (samples <= 0) {
        goto error;
    }

    int i_sample_count = samples;
    int i_sample;

    int64_t total_dur = 0;
    for( i_sample = 0; i_sample < i_sample_count; i_sample++ )
    {
        total_dur += mp4ff_get_sample_duration (mp4, track, i_sample);
    }
    if (totalsamples) {
        *totalsamples = total_dur * (*samplerate) / mp4ff_time_scale (mp4, track);
        *mp4framesize = (*totalsamples) / i_sample_count;
    }
    *duration = total_dur / (float)mp4ff_time_scale (mp4, track);

    return 0;
error:
    if (dec) {
        NeAACDecClose (dec);
    }
    free (buff);
    return -1;
}
Example #2
0
int aac_deinit(struct sp* env){
	//deallocate things
	struct aac_data *data = env->private_data;
	NeAACDecClose(data->hAac); //let faad cleanup
	free(data); //clean up my struct
	return SP_OK;
}
Example #3
0
//---------------------------------------------------------------------------
File_Aac::~File_Aac()
{
    //libfaad specific
    #ifdef MEDIAINFO_FAAD_YES
        NeAACDecClose(hAac); //hAac=NULL;
    #endif
}
Example #4
0
FXbool AacDecoder::init(ConfigureEvent*event) {
  af=event->af;
  if (handle) {
    NeAACDecClose(handle);
    handle=NULL;
    }
  return true;
  }
Example #5
0
TaudioCodecLibFAAD::~TaudioCodecLibFAAD()
{
    if (m_decHandle) {
        NeAACDecClose(m_decHandle);
    }
    if (dll) {
        delete dll;
    }
}
Example #6
0
static void aac_close (void *prv_data)
{
	struct aac_data *data = (struct aac_data *)prv_data;

	NeAACDecClose (data->decoder);
	io_close (data->stream);
	decoder_error_clear (&data->error);
	free (data);
}
Example #7
0
File: faad.c Project: videolan/vlc
/*****************************************************************************
 * Close:
 *****************************************************************************/
static void Close( vlc_object_t *p_this )
{
    decoder_t *p_dec = (decoder_t *)p_this;
    decoder_sys_t *p_sys = p_dec->p_sys;

    NeAACDecClose( p_sys->hfaad );
    free( p_sys->p_buffer );
    free( p_sys );
}
Example #8
0
void SoundSourceM4A::close() {
    if (m_hDecoder) {
        NeAACDecClose(m_hDecoder);
        m_hDecoder = NULL;
    }
    if (MP4_INVALID_FILE_HANDLE != m_hFile) {
        MP4Close(m_hFile);
        m_hFile = MP4_INVALID_FILE_HANDLE;
    }
    m_inputBuffer.clear();
}
Example #9
0
static void
xmms_faad_destroy (xmms_xform_t *xform)
{
	xmms_faad_data_t *data;

	g_return_if_fail (xform);

	data = xmms_xform_private_data_get (xform);
	g_return_if_fail (data);

	NeAACDecClose (data->decoder);
	g_string_free (data->outbuf, TRUE);
	g_free (data);
}
Example #10
0
DecoderAAC::~DecoderAAC()
{
    if (data())
    {
        if (data()->handle)
            NeAACDecClose (data()->handle);
        delete data();
        m_data = 0;
    }
    if (m_input_buf)
        delete [] m_input_buf;
    m_input_buf = 0;
    m_bitrate = 0;
}
Example #11
0
int decoder_aac_close(struct decoder *dec)
{
	if(dec == NULL)
		return  0;

	/* Close faad */
	if(dec->hDec != NULL)
		NeAACDecClose(dec->hDec);

	/* Free structure */
	free(dec);

	return 0;
}
Example #12
0
int audio_dec_release(
#ifndef WIN32	
	audio_decoder_operations_t *adec_ops
#endif	
	)
{
	FaadContext *gFaadCxt =	(FaadContext*)adec_ops->pdecoder;
	if(gFaadCxt->hDecoder)
	    	NeAACDecClose(gFaadCxt->hDecoder);
	if(adec_ops->pdecoder){
		free(adec_ops->pdecoder);
		adec_ops->pdecoder = NULL;
	}	
	return 0;
}
Example #13
0
static void
aac_free (DB_fileinfo_t *_info) {
    aac_info_t *info = (aac_info_t *)_info;
    if (info) {
        if (info->file) {
            deadbeef->fclose (info->file);
        }
        if (info->mp4) {
            mp4ff_close (info->mp4);
        }
        if (info->dec) {
            NeAACDecClose (info->dec);
        }
        free (info);
    }
}
Example #14
0
static void
aac_free (DB_fileinfo_t *_info) {
    aac_info_t *info = (aac_info_t *)_info;
    if (info) {
        if (info->file) {
            deadbeef->fclose (info->file);
        }
        if (info->mp4file) {
#ifdef USE_MP4FF
            mp4ff_close (info->mp4file);
#else
            MP4Close (info->mp4file);
#endif
        }
        if (info->dec) {
            NeAACDecClose (info->dec);
        }
        free (info);
    }
}
Example #15
0
// returns -1 for error, 0 for mp4, 1 for aac
int
aac_probe (DB_FILE *fp, const char *fname, MP4FILE_CB *cb, float *duration, int *samplerate, int *channels, int *totalsamples, int *mp4track, MP4FILE *pmp4) {
    // try mp4
    trace ("aac_probe: pos=%lld, junk=%d\n", deadbeef->ftell (fp), ((aac_info_t*)cb->user_data)->junk);

    if (mp4track) {
        *mp4track = -1;
    }
    if (*pmp4) {
        *pmp4 = NULL;
    }
    *duration = -1;
#ifdef USE_MP4FF
    trace ("mp4ff_open_read\n");
    mp4ff_t *mp4 = mp4ff_open_read (cb);
#else
    MP4FileHandle mp4 = MP4ReadProvider (fname, 0, cb);
#endif
    if (!mp4) {
        trace ("not an mp4 file\n");
        return -1;
    }
    if (pmp4) {
        *pmp4 = mp4;
    }
#ifdef USE_MP4FF
    int ntracks = mp4ff_total_tracks (mp4);
    if (ntracks > 0) {
        trace ("m4a container detected, ntracks=%d\n", ntracks);
        int i = -1;
        trace ("looking for mp4 data...\n");
        int sr = -1;
        unsigned char*  buff = 0;
        unsigned int    buff_size = 0;
        for (i = 0; i < ntracks; i++) {
            mp4AudioSpecificConfig mp4ASC;
            mp4ff_get_decoder_config(mp4, i, &buff, &buff_size);
            if (buff) {
                int rc = AudioSpecificConfig(buff, buff_size, &mp4ASC);
                sr = mp4ASC.samplingFrequency;
                if(rc < 0) {
                    free (buff);
                    buff = 0;
                    continue;
                }
                break;
            }
        }
        if (i != ntracks && buff) 
        {
            trace ("found audio track (%d)\n", i);
            // init mp4 decoding
            NeAACDecHandle dec = NeAACDecOpen ();
            unsigned long srate;
            unsigned char ch;
            if (NeAACDecInit2(dec, buff, buff_size, &srate, &ch) < 0) {
                trace ("NeAACDecInit2 returned error\n");
                goto error;
            }
            *samplerate = srate;
            *channels = ch;
            int samples = mp4ff_num_samples(mp4, i);
            samples = (int64_t)samples * srate / mp4ff_time_scale (mp4, i);
            int tsamples = samples;
            NeAACDecConfigurationPtr conf = NeAACDecGetCurrentConfiguration (dec);
            conf->dontUpSampleImplicitSBR = 1;
            NeAACDecSetConfiguration (dec, conf);
            mp4AudioSpecificConfig mp4ASC;
            int mp4framesize;
            if (NeAACDecAudioSpecificConfig(buff, buff_size, &mp4ASC) >= 0)
            {
                mp4framesize = 1024;
                if (mp4ASC.frameLengthFlag == 1) {
                    mp4framesize = 960;
                }
                // commented this out, since it fixes double-duration bug on
                // some mp4 files
                //if (mp4ASC.sbr_present_flag == 1) {
                //    mp4framesize *= 2;
                //}
            }
            else {
                trace ("NeAACDecAudioSpecificConfig failed, can't get mp4framesize\n");
                goto error;
            }
            tsamples *= mp4framesize;

            trace ("mp4 nsamples=%d, samplerate=%d, timescale=%d, duration=%lld\n", samples, *samplerate, mp4ff_time_scale(mp4, i), mp4ff_get_track_duration(mp4, i));
            *duration = (float)tsamples / (*samplerate);
            trace ("mp4 duration: %f (tsamples %d/samplerate %d)\n", *duration, tsamples, *samplerate);
            
            NeAACDecClose (dec);

            if (totalsamples) {
                *totalsamples = tsamples;
            }
            if (mp4track) {
                *mp4track = i;
            }
            if (!*pmp4) {
                mp4ff_close (mp4);
            }
            return 0;
error:
            NeAACDecClose (dec);
            free (buff);
            if (!*pmp4) {
                mp4ff_close (mp4);
            }
            return -1;
        }
        else {
            trace ("audio track not found\n");
            mp4ff_close (mp4);
            mp4 = NULL;
        }
        if (buff) {
            free (buff);
            buff = NULL;
        }

    }
#else
    MP4FileHandle mp4File = mp4;
    MP4TrackId trackId = MP4FindTrackId(mp4File, 0, "audio", 0);
    trace ("trackid: %d\n", trackId);
    uint32_t timeScale = MP4GetTrackTimeScale(mp4File, trackId);
    MP4Duration trackDuration = MP4GetTrackDuration(mp4File, trackId);
    MP4SampleId numSamples = MP4GetTrackNumberOfSamples(mp4File, trackId);
    u_int8_t* pConfig;
    uint32_t configSize = 0;
    bool res = MP4GetTrackESConfiguration(mp4File, trackId, &pConfig, &configSize);
    if (res && pConfig) {
        mp4AudioSpecificConfig mp4ASC;
        int rc = AudioSpecificConfig(pConfig, configSize, &mp4ASC);
        free (pConfig);
        if (rc >= 0) {
            *samplerate = mp4ASC.samplingFrequency;
            *channels = MP4GetTrackAudioChannels (mp4File, trackId);
//            int64_t duration = MP4ConvertFromTrackDuration (mp4File, trackId, trackDuration, timeScale);
            int samples = MP4GetTrackNumberOfSamples (mp4File, trackId) * 1024 * (*channels);
            trace ("mp4 nsamples=%d, timescale=%d, samplerate=%d\n", samples, timeScale, *samplerate);
            *duration = (float)samples / (*samplerate);

            if (totalsamples) {
                *totalsamples = samples;
            }
            if (mp4track) {
                *mp4track = trackId;
            }
            if (!*pmp4) {
                MP4Close (mp4);
            }
            return 0;
        }
    }
#endif
    if (*pmp4) {
        *pmp4 = NULL;
    }

    if (mp4) {
#if USE_MP4FF
        mp4ff_close (mp4);
#else
        MP4Close (mp4);
#endif
        mp4 = NULL;
    }
    trace ("mp4 track not found, looking for aac stream...\n");

    // not an mp4, try raw aac
#if USE_MP4FF
    deadbeef->rewind (fp);
#endif
    if (parse_aac_stream (fp, samplerate, channels, duration, totalsamples) == -1) {
        trace ("aac stream not found\n");
        return -1;
    }
    trace ("found aac stream\n");
    return 1;
}
Example #16
0
File: aac.cpp Project: bgK/scummvm
AACStream::~AACStream() {
	NeAACDecClose(_handle);
	delete[] _inBuffer;
	delete[] _remainingSamples;
}
Example #17
0
static void *mp4Decode(void *args)
{
  FILE*		mp4file;

  pthread_mutex_lock(&mutex);
  seekPosition = -1;
  bPlaying = TRUE;

  if(!(mp4file = fopen(args, "rb"))){
    g_print("MP4!AAC - Can't open file\n");
    g_free(args);
    bPlaying = FALSE;
    pthread_mutex_unlock(&mutex);
    pthread_exit(NULL);

  }
  mp4_get_file_type(mp4file);
  fseek(mp4file, 0, SEEK_SET);
  if(mp4cfg.file_type == FILE_MP4){// We are reading a MP4 file
    mp4ff_callback_t*	mp4cb;
    mp4ff_t*		infile;
    gint		mp4track;

    mp4cb = getMP4FF_cb(mp4file);
    if(!(infile = mp4ff_open_read(mp4cb))){
      g_print("MP4 - Can't open file\n");
      goto end;
    }

    if((mp4track = getAACTrack(infile)) < 0){
      /*
       * TODO: check here for others Audio format.....
       *
      */
      g_print("Unsupported Audio track type\n");
      g_free(args);
      fclose(mp4file);
      bPlaying = FALSE;
      pthread_mutex_unlock(&mutex);
      pthread_exit(NULL);
    }else{
      NeAACDecHandle	decoder;
      unsigned char	*buffer	= NULL;
      guint		bufferSize = 0;
      gulong		samplerate;
      guchar		channels;
      //guint		avgBitrate;
      //MP4Duration	duration;
      int		msDuration;
      int		numSamples;
      int		sampleID = 0;
      unsigned int	framesize;
      mp4AudioSpecificConfig mp4ASC;
      gchar		*xmmstitle;

      decoder = NeAACDecOpen();
      mp4ff_get_decoder_config(infile, mp4track, &buffer, &bufferSize);
      if(NeAACDecInit2(decoder, buffer, bufferSize, &samplerate, &channels)<0){
          goto end;
      }
      if(buffer){
	framesize = 1024;
	if(NeAACDecAudioSpecificConfig(buffer, bufferSize, &mp4ASC) >= 0){
	  if(mp4ASC.frameLengthFlag == 1) framesize = 960;
	  if(mp4ASC.sbr_present_flag == 1) framesize *= 2;
	}
	g_free(buffer);
      }
      if(channels == 0){
	g_print("Number of Channels not supported\n");
	goto end;
      }

      //duration = MP4GetTrackDuration(mp4file, mp4track);
      //msDuration = MP4ConvertFromTrackDuration(mp4file, mp4track,
      //				       duration,MP4_MSECS_TIME_SCALE);

      //msDuration = mp4ff_get_track_duration(infile, mp4track);
      //printf("%d\n", msDuration);

      //numSamples = MP4GetTrackNumberOfSamples(mp4file, mp4track);
      numSamples = mp4ff_num_samples(infile, mp4track);
      {
	float f = 1024.0;
	if(mp4ASC.sbr_present_flag == 1)
	  f = f * 2.0;
	msDuration = ((float)numSamples*(float)(f-1.0)/
		      (float)samplerate)*1000;
      }
      xmmstitle = getMP4title(infile, args);
      mp4_ip.output->open_audio(FMT_S16_NE, samplerate, channels);
      mp4_ip.output->flush(0);
      mp4_ip.set_info(xmmstitle, msDuration, -1, samplerate/1000, channels);
      g_print("MP4 - %d channels @ %ld Hz\n", channels, samplerate);

      while(bPlaying){
	void*			sampleBuffer;
	faacDecFrameInfo	frameInfo;
	gint			rc;

	if(seekPosition!=-1){
	  /*
	  duration = MP4ConvertToTrackDuration(mp4file,
					       mp4track,
					       seekPosition*1000,
					       MP4_MSECS_TIME_SCALE);
	  sampleID = MP4GetSampleIdFromTime(mp4file, mp4track, duration, 0);
          */
          float f = 1024.0;
	  if(mp4ASC.sbr_present_flag == 1)
	    f = f * 2.0;
          sampleID = (float)seekPosition*(float)samplerate/(float)(f-1.0);
	  mp4_ip.output->flush(seekPosition*1000);
	  seekPosition = -1;
	}
	buffer=NULL;
	bufferSize=0;
	rc = mp4ff_read_sample(infile, mp4track, sampleID++,
			       &buffer, &bufferSize);
	//g_print("%d/%d\n", sampleID-1, numSamples);
	if((rc==0) || (buffer== NULL)){
	  g_print("MP4: read error\n");
	  sampleBuffer = NULL;
	  sampleID=0;
	  mp4_ip.output->buffer_free();
            goto end;
	}else{
	  sampleBuffer = NeAACDecDecode(decoder, &frameInfo, buffer, bufferSize);
	  if(frameInfo.error > 0){
	    g_print("MP4: %s\n",
		    faacDecGetErrorMessage(frameInfo.error));
	    goto end;
	  }
	  if(buffer){
	    g_free(buffer); buffer=NULL; bufferSize=0;
	  }
	  while(bPlaying && mp4_ip.output->buffer_free()<frameInfo.samples<<1)
	    xmms_usleep(30000);
	}
	mp4_ip.add_vis_pcm(mp4_ip.output->written_time(),
			   FMT_S16_NE,
			   channels,
			   frameInfo.samples<<1,
			   sampleBuffer);
	mp4_ip.output->write_audio(sampleBuffer, frameInfo.samples<<1);
	if(sampleID >= numSamples){
          break;
	}
      }
      while(bPlaying && mp4_ip.output->buffer_playing() && mp4_ip.output->buffer_free()){
	xmms_usleep(10000);
      }
end:
      mp4_ip.output->close_audio();
      g_free(args);
      NeAACDecClose(decoder);
      if(infile) mp4ff_close(infile);
      if(mp4cb) g_free(mp4cb);
      bPlaying = FALSE;
      fclose(mp4file);
      pthread_mutex_unlock(&mutex);
      pthread_exit(NULL);
    }
  }else{
    // WE ARE READING AN AAC FILE
    FILE		*file = NULL;
    NeAACDecHandle	decoder = 0;
    guchar		*buffer = 0;
    gulong		bufferconsumed = 0;
    gulong		samplerate = 0;
    guchar		channels;
    gulong		buffervalid = 0;
    TitleInput*		input;
    gchar		*temp = g_strdup(args);
    gchar		*ext  = strrchr(temp, '.');
    gchar		*xmmstitle = NULL;
    NeAACDecConfigurationPtr config;

    if((file = fopen(args, "rb")) == 0){
      g_print("AAC: can't find file %s\n", args);
      bPlaying = FALSE;
      pthread_mutex_unlock(&mutex);
      pthread_exit(NULL);
    }
    if((decoder = NeAACDecOpen()) == NULL){
      g_print("AAC: Open Decoder Error\n");
      fclose(file);
      bPlaying = FALSE;
      pthread_mutex_unlock(&mutex);
      pthread_exit(NULL);
    }
    config = NeAACDecGetCurrentConfiguration(decoder);
    config->useOldADTSFormat = 0;
    NeAACDecSetConfiguration(decoder, config);
    if((buffer = g_malloc(BUFFER_SIZE)) == NULL){
      g_print("AAC: error g_malloc\n");
      fclose(file);
      bPlaying = FALSE;
      NeAACDecClose(decoder);
      pthread_mutex_unlock(&mutex);
      pthread_exit(NULL);
    }
    if((buffervalid = fread(buffer, 1, BUFFER_SIZE, file))==0){
      g_print("AAC: Error reading file\n");
      g_free(buffer);
      fclose(file);
      bPlaying = FALSE;
      NeAACDecClose(decoder);
      pthread_mutex_unlock(&mutex);
      pthread_exit(NULL);
    }
    XMMS_NEW_TITLEINPUT(input);
    input->file_name = g_basename(temp);
    input->file_ext = ext ? ext+1 : NULL;
    input->file_path = temp;
    if(!strncmp(buffer, "ID3", 3)){
      gint size = 0;

      fseek(file, 0, SEEK_SET);
      size = (buffer[6]<<21) | (buffer[7]<<14) | (buffer[8]<<7) | buffer[9];
      size+=10;
      fread(buffer, 1, size, file);
      buffervalid = fread(buffer, 1, BUFFER_SIZE, file);
    }
    xmmstitle = xmms_get_titlestring(xmms_get_gentitle_format(), input);
    if(xmmstitle == NULL)
      xmmstitle = g_strdup(input->file_name);
    if(temp) g_free(temp);
    if(input->performer) g_free(input->performer);
    if(input->album_name) g_free(input->album_name);
    if(input->track_name) g_free(input->track_name);
    if(input->genre) g_free(input->genre);
    g_free(input);
    bufferconsumed = NeAACDecInit(decoder,
				 buffer,
				 buffervalid,
				 &samplerate,
				 &channels);
    if(mp4_ip.output->open_audio(FMT_S16_NE,samplerate,channels) == FALSE){
      g_print("AAC: Output Error\n");
      g_free(buffer); buffer=0;
      faacDecClose(decoder);
      fclose(file);
      mp4_ip.output->close_audio();
      /*
      if(positionTable){
	g_free(positionTable); positionTable=0;
      }
      */
      g_free(xmmstitle);
      bPlaying = FALSE;
      pthread_mutex_unlock(&mutex);
      pthread_exit(NULL);
    }
    //if(bSeek){
    //mp4_ip.set_info(xmmstitle, lenght*1000, -1, samplerate, channels);
      //}else{
    mp4_ip.set_info(xmmstitle, -1, -1, samplerate, channels);
      //}
    mp4_ip.output->flush(0);

    while(bPlaying && buffervalid > 0){
      NeAACDecFrameInfo	finfo;
      unsigned long	samplesdecoded;
      char*		sample_buffer = NULL;
      /*
	if(bSeek && seekPosition!=-1){
	fseek(file, positionTable[seekPosition], SEEK_SET);
	bufferconsumed=0;
	buffervalid = fread(buffer, 1, BUFFER_SIZE, file);
	aac_ip.output->flush(seekPosition*1000);
	seekPosition=-1;
	}
      */
      if(bufferconsumed > 0){
	memmove(buffer, &buffer[bufferconsumed], buffervalid-bufferconsumed);
	buffervalid -= bufferconsumed;
	buffervalid += fread(&buffer[buffervalid], 1,
			     BUFFER_SIZE-buffervalid, file);
	bufferconsumed = 0;
      }
      sample_buffer = NeAACDecDecode(decoder, &finfo, buffer, buffervalid);
      if(finfo.error){
	config = NeAACDecGetCurrentConfiguration(decoder);
	if(config->useOldADTSFormat != 1){
	  NeAACDecClose(decoder);
	  decoder = NeAACDecOpen();
	  config = NeAACDecGetCurrentConfiguration(decoder);
	  config->useOldADTSFormat = 1;
	  NeAACDecSetConfiguration(decoder, config);
	  finfo.bytesconsumed=0;
	  finfo.samples = 0;
	  NeAACDecInit(decoder,
		      buffer,
		      buffervalid,
		      &samplerate,
		      &channels);
	}else{
	  g_print("FAAD2 Warning %s\n", NeAACDecGetErrorMessage(finfo.error));
	  buffervalid = 0;
	}
      }
      bufferconsumed += finfo.bytesconsumed;
      samplesdecoded = finfo.samples;
      if((samplesdecoded<=0) && !sample_buffer){
	g_print("AAC: error sample decoding\n");
	continue;
      }
      while(bPlaying && mp4_ip.output->buffer_free() < (samplesdecoded<<1)){
	xmms_usleep(10000);
      }
      mp4_ip.add_vis_pcm(mp4_ip.output->written_time(),
			 FMT_S16_LE, channels,
			 samplesdecoded<<1, sample_buffer);
      mp4_ip.output->write_audio(sample_buffer, samplesdecoded<<1);
    }
    while(bPlaying && mp4_ip.output->buffer_playing()){
      xmms_usleep(10000);
    }
    mp4_ip.output->buffer_free();
    mp4_ip.output->close_audio();
    bPlaying = FALSE;
    g_free(buffer);
    NeAACDecClose(decoder);
    g_free(xmmstitle);
    fclose(file);
    seekPosition = -1;
    /*
    if(positionTable){
      g_free(positionTable); positionTable=0;
    }
    */
    bPlaying = FALSE;
    pthread_mutex_unlock(&mutex);
    pthread_exit(NULL);

  }
}
Example #18
0
int decoder_aac_open(struct decoder **decoder, const unsigned char *dec_config,
		     size_t dec_config_size, unsigned long *samplerate,
		     unsigned char *channels)
{
	NeAACDecConfigurationPtr config;
	struct decoder *dec;
	int ret;

	/* Alloc structure */
	*decoder = malloc(sizeof(struct decoder));
	if(*decoder == NULL)
		return -1;
	dec = *decoder;

	/* Init structure */
	dec->pcm_buffer = NULL;
	dec->pcm_length = 0;
	dec->pcm_remain = 0;

	/* Initialize faad */
	dec->hDec = NeAACDecOpen();

	/* Set the default object type and samplerate */
	config = NeAACDecGetCurrentConfiguration(dec->hDec);
#ifdef USE_FLOAT
	config->outputFormat = FAAD_FMT_FLOAT;
#else
	config->outputFormat = FAAD_FMT_24BIT;
#endif
	NeAACDecSetConfiguration(dec->hDec, config);

	/* PCM data remaining in output buffer */
	dec->pcm_remain = 0;

	/* Check if ADTS or ADIF header */
	if(dec_config != NULL &&
	  ((dec_config[0] == 0xFF && (dec_config[1] & 0xF6) == 0xF0) ||
	   memcmp(dec_config, "ADIF", 4) == 0))
	{
		/* Init decoder from frame */
		ret = NeAACDecInit(dec->hDec, (unsigned char *) dec_config,
				   dec_config_size, &dec->samplerate,
				   &dec->channels);
	}
	else
	{
		/* Init decoder */
		ret = NeAACDecInit2(dec->hDec, (unsigned char *) dec_config,
				    dec_config_size, &dec->samplerate,
				    &dec->channels);
	}

	/* Check init return */
	if(ret < 0)
	{
		NeAACDecClose(dec->hDec);
		dec->hDec = NULL;
		return -1;
	}

	/* Retunr samplerate and channels */
	if(samplerate != NULL)
		*samplerate = dec->samplerate;
	if(channels != NULL)
		*channels = dec->channels;

	return 0;
}
Example #19
0
int decodeMP4file(char *sndfile, aac_dec_opt *opt)
{
    int track;
    unsigned long samplerate;
    unsigned char channels;
    void *sample_buffer;

    mp4ff_t *infile;
    FILE *mp4File;
    int sampleId, numSamples;

    audio_file *aufile;

    NeAACDecHandle hDecoder;
    NeAACDecFrameInfo frameInfo;

    unsigned char *buffer;
    int buffer_size;

    int first_time = 1;

    /* initialise the callback structure */
    mp4ff_callback_t *mp4cb = malloc(sizeof(mp4ff_callback_t));

    mp4File = fopen(opt->filename, "rb");
    mp4cb->read = read_callback;
    mp4cb->seek = seek_callback;
    mp4cb->user_data = mp4File;

    infile = mp4ff_open_read(mp4cb);
    if (!infile)
    {
        /* unable to open file */
        error_handler("Error opening file: %s\n", opt->filename);
        return 1;
    }

    if ((track = GetAACTrack(infile)) < 0)
    {
        error_handler("Unable to find correct AAC sound track in the MP4 file.\n");
        mp4ff_close(infile);
        free(mp4cb);
        fclose(mp4File);
        return 1;
    }

    buffer = NULL;
    buffer_size = 0;
    mp4ff_get_decoder_config(infile, track, &buffer, &buffer_size);

    hDecoder = NeAACDecOpen();

    if(NeAACDecInit2(hDecoder, buffer, buffer_size, &samplerate, &channels) < 0)
    {
        /* If some error initializing occured, skip the file */
        error_handler("Error initializing decoder library.\n");
        NeAACDecClose(hDecoder);
        mp4ff_close(infile);
        free(mp4cb);
        fclose(mp4File);
        return 1;
    }
    if (buffer)
        free(buffer);

    numSamples = mp4ff_num_samples(infile, track);

    for (sampleId = 0; sampleId < numSamples; sampleId++)
    {
        int rc;

        /* get access unit from MP4 file */
        buffer = NULL;
        buffer_size = 0;

        rc = mp4ff_read_sample(infile, track, sampleId, &buffer, &buffer_size);
        if (rc == 0)
        {
            error_handler("Reading from MP4 file failed.\n");
            NeAACDecClose(hDecoder);
            mp4ff_close(infile);
            free(mp4cb);
            fclose(mp4File);
            return 1;
        }

        sample_buffer = NeAACDecDecode(hDecoder, &frameInfo, buffer, buffer_size);

        if (buffer)
            free(buffer);

        opt->progress_update((long)numSamples, sampleId);

        /* open the sound file now that the number of channels are known */
        if (first_time && !frameInfo.error)
        {
            if(opt->decode_mode == 0)
            {
                if (Set_WIN_Params (INVALID_FILEDESC, samplerate, SAMPLE_SIZE,
                                frameInfo.channels) < 0)
                {
                    error_handler("\nCan't access %s\n", "WAVE OUT");
                    NeAACDecClose(hDecoder);
                    mp4ff_close(infile);
                    free(mp4cb);
                    fclose(mp4File);
                    return (0);
                }
            }
            else
            {
                aufile = open_audio_file(sndfile, samplerate, frameInfo.channels,
                     opt->output_format, opt->file_type, aacChannelConfig2wavexChannelMask(&frameInfo));

                if (aufile == NULL)
                {
                    NeAACDecClose(hDecoder);
                    mp4ff_close(infile);
                    free(mp4cb);
                    fclose(mp4File);
                    return 0;
                }
            }
            first_time = 0;
        }

        if ((frameInfo.error == 0) && (frameInfo.samples > 0))
        {
            if(opt->decode_mode == 0)
                WIN_Play_Samples((short*)sample_buffer, frameInfo.channels*frameInfo.samples);
            else
                write_audio_file(aufile, sample_buffer, frameInfo.samples, 0);
        }

        if (frameInfo.error > 0)
        {
            error_handler("Error: %s\n",
            NeAACDecGetErrorMessage(frameInfo.error));
            break;
        }
        if(stop_decoding)
            break;
    }


    NeAACDecClose(hDecoder);


    mp4ff_close(infile);
    free(mp4cb);
    fclose(mp4File);

    if(opt->decode_mode == 0)
        WIN_Audio_close();
    else
    {
        if (!first_time)
            close_audio_file(aufile);
    }

    return frameInfo.error;
}
Example #20
0
/*	player thread; for every song a new thread is started
 *	@param aacPlayer structure
 *	@return NULL NULL NULL ...
 */
void *BarPlayerThread (void *data) {

	struct audioPlayer *player = data;
	char extraHeaders[25];
	void *ret = PLAYER_RET_OK;
	#ifdef ENABLE_FAAD
	NeAACDecConfigurationPtr conf;
	#endif
	WaitressReturn_t wRet = WAITRESS_RET_ERR;

	/* init handles */
	pthread_mutex_init (&player->pauseMutex, NULL);
	player->scale = computeReplayGainScale (player->gain);
	player->waith.data = (void *) player;
	/* extraHeaders will be initialized later */
	player->waith.extraHeaders = extraHeaders;

	switch (player->audioFormat) {
		#ifdef ENABLE_FAAD
		case PIANO_AF_AACPLUS:
			player->aacHandle = NeAACDecOpen();
			/* set aac conf */
			conf = NeAACDecGetCurrentConfiguration(player->aacHandle);
			conf->outputFormat = FAAD_FMT_16BIT;
		    conf->downMatrix = 1;
			NeAACDecSetConfiguration(player->aacHandle, conf);

			player->waith.callback = BarPlayerAACCb;
			break;
		#endif /* ENABLE_FAAD */

		#ifdef ENABLE_MAD
		case PIANO_AF_MP3:
		case PIANO_AF_MP3_HI:
			mad_stream_init (&player->mp3Stream);
			mad_frame_init (&player->mp3Frame);
			mad_synth_init (&player->mp3Synth);

			player->waith.callback = BarPlayerMp3Cb;
			break;
		#endif /* ENABLE_MAD */

		default:
		  printf("Unsupported audio format!\n");
			return PLAYER_RET_OK;
			break;
	}
	
	player->mode = PLAYER_INITIALIZED;

	/* This loop should work around song abortions by requesting the
	 * missing part of the song */
	do {
		snprintf (extraHeaders, sizeof (extraHeaders), "Range: bytes=%zu-\r\n",
				player->bytesReceived);
		wRet = WaitressFetchCall (&player->waith);
	} while (wRet == WAITRESS_RET_PARTIAL_FILE || wRet == WAITRESS_RET_TIMEOUT
			|| wRet == WAITRESS_RET_READ_ERR);

	switch (player->audioFormat) {
		#ifdef ENABLE_FAAD
		case PIANO_AF_AACPLUS:
			NeAACDecClose(player->aacHandle);
			break;
		#endif /* ENABLE_FAAD */

		#ifdef ENABLE_MAD
		case PIANO_AF_MP3:
		case PIANO_AF_MP3_HI:
			mad_synth_finish (&player->mp3Synth);
			mad_frame_finish (&player->mp3Frame);
			mad_stream_finish (&player->mp3Stream);
			break;
		#endif /* ENABLE_MAD */

		default:
			/* this should never happen: thread is aborted above */
			break;
	}
	if (player->aoError) {
		ret = (void *) PLAYER_RET_ERR;
	}

	if (player->audioOutDevice) 
	  ao_close(player->audioOutDevice);
	WaitressFree (&player->waith);
	#ifdef ENABLE_FAAD
	if (player->sampleSize != NULL) {
		free (player->sampleSize);
	}
	#endif /* ENABLE_FAAD */
	pthread_mutex_destroy (&player->pauseMutex);

	player->mode = PLAYER_FINISHED_PLAYBACK;

	return ret;
}
Example #21
0
AACDecoder::~AACDecoder() {
	NeAACDecClose(_handle);
}
Example #22
0
int audio_dec_decode(
#ifndef WIN32	
	audio_decoder_operations_t *adec_ops, 
#endif	
	char *outbuf, int *outlen, char *inbuf, int inlen)
{
	unsigned long samplerate;
	unsigned char channels;
	void *sample_buffer;
	NeAACDecFrameInfo frameInfo;
	int outmaxlen = 0;
	char *dec_buf;
	int    dec_bufsize;
	int  inbuf_consumed=0;
	int ret = 0;
	FaadContext *gFaadCxt =	(FaadContext*)adec_ops->pdecoder;
	dec_bufsize = inlen;
	dec_buf = inbuf;	
	outmaxlen = *outlen ;
	*outlen = 0; 
	if(!outbuf ||!inbuf || !inlen){
		audio_codec_print("decoder parameter error,check \n");
		goto exit;
	}
	if(gFaadCxt->init_start_flag == 0){
		audio_codec_print("MyFaadDecoder init first in \n");
		gFaadCxt->starttime = gettime();
		gFaadCxt->init_start_flag = 1;
	}		
	if (!gFaadCxt->init_flag)
	{
		gFaadCxt->error_count= 0;
		audio_codec_print("begin audio_decoder_init,buf size %d  \n",dec_bufsize);
		ret = audio_decoder_init(adec_ops,outbuf,outlen,dec_buf,dec_bufsize,&inbuf_consumed);
		if(ret ==  AAC_ERROR_NO_ENOUGH_DATA){
			audio_codec_print("decoder buf size %d,cost %d byte input data ,but initiation failed.^_^ \n",inlen,inbuf_consumed);
			dec_bufsize -= inbuf_consumed;
			goto exit;
		}
		gFaadCxt->init_flag = 1;	
		dec_buf += inbuf_consumed;
		dec_bufsize -= inbuf_consumed;
		gFaadCxt->init_cost += inbuf_consumed;
		gFaadCxt->endtime = gettime();
	        audio_codec_print(" MyFaadDecoder decoder init finished total cost %d bytes,consumed time %lld ms \n",gFaadCxt->init_cost,(gFaadCxt->endtime-gFaadCxt->starttime)/1000);	
	        gFaadCxt->init_cost = 0;
		if(dec_bufsize < 0)
			dec_bufsize = 0;
	}
	NeAACDecStruct* hDecoder = (NeAACDecStruct*)(gFaadCxt->hDecoder);
//TODO .fix to LATM aac decoder when ffmpeg parser return LATM aac  type	
#if 0
	if(adec_ops->nAudioDecoderType == ACODEC_FMT_AAC_LATM)
		hDecoder->latm_header_present = 1;
#endif	
	if(hDecoder->adts_header_present)
	{
		int nSeekNum = AACFindADTSSyncWord(dec_buf,dec_bufsize);
		if(nSeekNum == (dec_bufsize-1)){
			audio_codec_print("%d bytes data not found adts sync header \n",nSeekNum);	
		}
		dec_bufsize = dec_bufsize - nSeekNum;
		if(dec_bufsize < (get_frame_size(gFaadCxt)+FRAME_SIZE_MARGIN)/*AAC_INPUTBUF_SIZE/2*/){
			goto exit; 
		}
	}
	if(hDecoder->latm_header_present){
		int nSeekNum = AACFindLATMSyncWord(dec_buf,dec_bufsize);
		if(nSeekNum == (dec_bufsize-2)){
			audio_codec_print("%d bytes data not found latm sync header \n",nSeekNum);	
		}
		dec_bufsize = dec_bufsize - nSeekNum;
		if(dec_bufsize < (get_frame_size(gFaadCxt)+FRAME_SIZE_MARGIN)/*AAC_INPUTBUF_SIZE/2*/){
			goto exit; 
		}		
	}
	sample_buffer = NeAACDecDecode(gFaadCxt->hDecoder, &frameInfo, dec_buf, dec_bufsize);
	dec_bufsize -= frameInfo.bytesconsumed;
	if(frameInfo.error == 0 && sample_buffer == NULL && hDecoder->latm_header_present){
		dec_bufsize -= 3;
		goto exit;
	}
	if ((frameInfo.error == 0) && (frameInfo.samples > 0) && sample_buffer!=NULL )
	{
		store_frame_size(gFaadCxt,frameInfo.bytesconsumed);
		gFaadCxt->gSampleRate=frameInfo.samplerate;
		gFaadCxt->gChannels=frameInfo.channels;
		//code to mute first 1 s  ???
		#define  MUTE_S  0.2
		if(gFaadCxt->muted_samples == 0){
			gFaadCxt->muted_samples  = gFaadCxt->gSampleRate*gFaadCxt->gChannels*MUTE_S;
		}
		if(gFaadCxt->muted_count  < gFaadCxt->muted_samples){
			memset(sample_buffer,0,2*frameInfo.samples);
			gFaadCxt->muted_count += frameInfo.samples;
		}
		if( (outmaxlen-(*outlen)) >= (2*frameInfo.samples)){
			memcpy(outbuf+(*outlen), sample_buffer, 2*frameInfo.samples);
			*outlen+=2*frameInfo.samples;
			gFaadCxt->error_count = 0;	
		}else{
			audio_codec_print("[%s %d]WARNING: no enough space used for pcm!\n",__FUNCTION__,__LINE__);
		}
	}

	if (frameInfo.error > 0)//failed seek to the head
	{
        if(frameInfo.error != 34 &&frameInfo.error != 35 ){
		dec_bufsize -= RSYNC_SKIP_BYTES;
		audio_codec_print( "Error: %s,inlen %d\n", NeAACDecGetErrorMessage(frameInfo.error),inlen);		
        }
        // sr/ch changed info happened 5 times always,some times error maybe,skip bytes
	else if(frameInfo.error == 34 && gFaadCxt->error_count > 5){
		dec_bufsize -= RSYNC_SKIP_BYTES;
	  	audio_codec_print("%s,,inlen %d\n", NeAACDecGetErrorMessage(frameInfo.error),inlen);
	}
	gFaadCxt->error_count++;
		//err 34,means aac profile changed , PS.SBR,LC ....,normally happens when switch audio source
	if(gFaadCxt->error_count  >= ERROR_RESET_COUNT ||frameInfo.error == 34){
		if( gFaadCxt->hDecoder){
			NeAACDecClose(gFaadCxt->hDecoder);
			gFaadCxt->hDecoder=NULL;
		}
			gFaadCxt->init_flag = 0;
			gFaadCxt->init_start_flag = 0;
		}	
	}
exit:
    if(dec_bufsize < 0)
		dec_bufsize = 0;
    if(gFaadCxt->init_flag == 0)
    	gFaadCxt->init_cost += 	(inlen - dec_bufsize);	
    return inlen - dec_bufsize;
}
Example #23
0
static int audio_decoder_init( 
#ifndef WIN32	
	audio_decoder_operations_t *adec_ops, 
#endif	
	char *outbuf, int *outlen, char *inbuf, int inlen, long *inbuf_consumed)
{
    unsigned long samplerate;
    unsigned char channels;
    int ret;
    NeAACDecConfigurationPtr config = NULL;
    char *in_buf;
    int  inbuf_size;
    in_buf = inbuf;
    inbuf_size = inlen;
    int nReadLen=0;
    FaadContext *gFaadCxt  =	(FaadContext*)adec_ops->pdecoder;
    int islatm = 0;
    if(!in_buf || !inbuf_size ||!outbuf){
		audio_codec_print(" input/output buffer null or input len is 0 \n");
   } 
retry:
//fixed to LATM aac frame header sync to speed up seek speed
#if  1
   if(adec_ops->nAudioDecoderType == ACODEC_FMT_AAC_LATM){
	islatm = 1;
	int nSeekNum = AACFindLATMSyncWord(in_buf,inbuf_size);
	if(nSeekNum == (inbuf_size-2)){
		audio_codec_print("[%s]%d bytes data not found latm sync header \n",__FUNCTION__,nSeekNum);	
	}
	else{
		audio_codec_print("[%s]latm seek sync header cost %d,total %d,left %d \n",__FUNCTION__,nSeekNum,inbuf_size,inbuf_size - nSeekNum);
	}
	inbuf_size = inbuf_size - nSeekNum;
	if(inbuf_size < (get_frame_size(gFaadCxt)+FRAME_SIZE_MARGIN)/*AAC_INPUTBUF_SIZE/2*/){
		audio_codec_print("[%s]input size %d at least %d ,need more data \n",__FUNCTION__,inbuf_size,(get_frame_size(gFaadCxt)+FRAME_SIZE_MARGIN));
		*inbuf_consumed = inlen-inbuf_size;
		return AAC_ERROR_NO_ENOUGH_DATA; 
	}		
    }
#endif
    gFaadCxt->hDecoder = NeAACDecOpen();
    config = NeAACDecGetCurrentConfiguration(gFaadCxt->hDecoder);
    config->defObjectType = LC;
    config->outputFormat = FAAD_FMT_16BIT;
    config->downMatrix = 0x01;
    config->useOldADTSFormat = 0;
    //config->dontUpSampleImplicitSBR = 1;
    NeAACDecSetConfiguration(gFaadCxt->hDecoder, config);
    if ((ret = NeAACDecInit(gFaadCxt->hDecoder, in_buf,inbuf_size, &samplerate, &channels,islatm)) < 0)
    {
    		in_buf += RSYNC_SKIP_BYTES;
		inbuf_size -= RSYNC_SKIP_BYTES;
		NeAACDecClose(gFaadCxt->hDecoder);
		gFaadCxt->hDecoder=NULL;
		if(inbuf_size < 0)
			inbuf_size = 0;
		audio_codec_print("init fail,inbuf_size %d \n",inbuf_size);
		if(inbuf_size <  (get_frame_size(gFaadCxt)+FRAME_SIZE_MARGIN)/*AAC_INPUTBUF_SIZE/2*/){
			audio_codec_print("input size %d at least %d ,need more data \n",inbuf_size,(get_frame_size(gFaadCxt)+FRAME_SIZE_MARGIN));
			*inbuf_consumed = inlen-inbuf_size;
			return AAC_ERROR_NO_ENOUGH_DATA;
		}
		goto retry;
    }
    audio_codec_print("init sucess cost %d\n",ret);	
    in_buf += ret;
    inbuf_size -= ret;
    *inbuf_consumed = inlen-	inbuf_size;
    NeAACDecStruct* hDecoder = (NeAACDecStruct*)(gFaadCxt->hDecoder);
    gFaadCxt->init_flag=1;
    gFaadCxt->gChannels=channels;
    gFaadCxt->gSampleRate=samplerate;
    audio_codec_print("[%s] Init OK adif_present :%d adts_present:%d latm_present:%d,sr %d,ch %d\n",__FUNCTION__,hDecoder->adif_header_present,hDecoder->adts_header_present,hDecoder->latm_header_present,samplerate,channels);
    return 0;
}
Example #24
0
/*	player thread; for every song a new thread is started
 *	@param audioPlayer structure
 *	@return PLAYER_RET_*
 */
void *BarPlayerThread (void *data) {
	struct audioPlayer *player = data;
	char extraHeaders[32];
	void *ret = PLAYER_RET_OK;
	#ifdef ENABLE_FAAD
	NeAACDecConfigurationPtr conf;
	#endif
	WaitressReturn_t wRet = WAITRESS_RET_ERR;

	/* init handles */
	player->waith.data = (void *) player;
	/* extraHeaders will be initialized later */
	player->waith.extraHeaders = extraHeaders;
	player->buffer = malloc (BAR_PLAYER_BUFSIZE);

	switch (player->audioFormat) {
		#ifdef ENABLE_FAAD
		case PIANO_AF_AACPLUS:
			player->aacHandle = NeAACDecOpen();
			/* set aac conf */
			conf = NeAACDecGetCurrentConfiguration(player->aacHandle);
			conf->outputFormat = FAAD_FMT_16BIT;
		    conf->downMatrix = 1;
			NeAACDecSetConfiguration(player->aacHandle, conf);

			player->waith.callback = BarPlayerAACCb;
			break;
		#endif /* ENABLE_FAAD */

		#ifdef ENABLE_MAD
		case PIANO_AF_MP3:
			mad_stream_init (&player->mp3Stream);
			mad_frame_init (&player->mp3Frame);
			mad_synth_init (&player->mp3Synth);

			player->waith.callback = BarPlayerMp3Cb;
			break;
		#endif /* ENABLE_MAD */

		default:
			/* FIXME: leaks memory */
			BarUiMsg (player->settings, MSG_ERR, "Unsupported audio format!\n");
			return PLAYER_RET_OK;
			break;
	}
	
	player->mode = PLAYER_INITIALIZED;

	/* This loop should work around song abortions by requesting the
	 * missing part of the song */
	do {
		snprintf (extraHeaders, sizeof (extraHeaders), "Range: bytes=%zu-\r\n",
				player->bytesReceived);
		wRet = WaitressFetchCall (&player->waith);
	} while (wRet == WAITRESS_RET_PARTIAL_FILE || wRet == WAITRESS_RET_TIMEOUT
			|| wRet == WAITRESS_RET_READ_ERR);

	/* If the song was played all the way through tag it. */
	if (wRet == WAITRESS_RET_OK) {
		BarFlyTag(&player->fly, player->settings);
	}

	switch (player->audioFormat) {
		#ifdef ENABLE_FAAD
		case PIANO_AF_AACPLUS:
			NeAACDecClose(player->aacHandle);
			free (player->sampleSize);
			break;
		#endif /* ENABLE_FAAD */

		#ifdef ENABLE_MAD
		case PIANO_AF_MP3:
			mad_synth_finish (&player->mp3Synth);
			mad_frame_finish (&player->mp3Frame);
			mad_stream_finish (&player->mp3Stream);
			break;
		#endif /* ENABLE_MAD */

		default:
			/* this should never happen: thread is aborted above */
			break;
	}

	if (player->aoError) {
		ret = (void *) PLAYER_RET_ERR;
	}

	ao_close(player->audioOutDevice);
	WaitressFree (&player->waith);
	free (player->buffer);

	player->mode = PLAYER_FINISHED_PLAYBACK;

	return ret;
}
Example #25
0
static void finalize_faad_dec(value l)
{
  NeAACDecHandle dh = Dec_val(l);
  NeAACDecClose(dh);
}
Example #26
0
/*	player thread; for every song a new thread is started
 *	@param audioPlayer structure
 *	@return PLAYER_RET_*
 */
void *BarPlayerThread (void *data) {
	struct audioPlayer *player = data;
	char extraHeaders[32];
	void *ret = PLAYER_RET_OK;
	#ifdef ENABLE_FAAD
	NeAACDecConfigurationPtr conf;
	#endif
	WaitressReturn_t wRet = WAITRESS_RET_ERR;

	/* init handles */
	pthread_mutex_init (&player->pauseMutex, NULL);
	player->waith.data = (void *) player;
	/* extraHeaders will be initialized later */
	player->waith.extraHeaders = extraHeaders;
	player->buffer = malloc (BAR_PLAYER_BUFSIZE);

	switch (player->audioFormat) {
		#ifdef ENABLE_FAAD
		case PIANO_AF_AACPLUS:
			player->aacHandle = NeAACDecOpen();
			/* set aac conf */
			conf = NeAACDecGetCurrentConfiguration(player->aacHandle);
			conf->outputFormat = FAAD_FMT_16BIT;
		    conf->downMatrix = 1;
			NeAACDecSetConfiguration(player->aacHandle, conf);

			player->waith.callback = BarPlayerAACCb;
			break;
		#endif /* ENABLE_FAAD */

		#ifdef ENABLE_MAD
		case PIANO_AF_MP3:
			mad_stream_init (&player->mp3Stream);
			mad_frame_init (&player->mp3Frame);
			mad_synth_init (&player->mp3Synth);

			player->waith.callback = BarPlayerMp3Cb;
			break;
		#endif /* ENABLE_MAD */

		default:
			BarUiMsg (player->settings, MSG_ERR, "Unsupported audio format!\n");
			ret = (void *) PLAYER_RET_HARDFAIL;
			goto cleanup;
			break;
	}
	
	player->mode = PLAYER_INITIALIZED;

	/* This loop should work around song abortions by requesting the
	 * missing part of the song */
	do {
		snprintf (extraHeaders, sizeof (extraHeaders), "Range: bytes=%zu-\r\n",
				player->bytesReceived);
		wRet = WaitressFetchCall (&player->waith);
	} while (wRet == WAITRESS_RET_PARTIAL_FILE || wRet == WAITRESS_RET_TIMEOUT
			|| wRet == WAITRESS_RET_READ_ERR);

	switch (player->audioFormat) {
		#ifdef ENABLE_FAAD
		case PIANO_AF_AACPLUS:
			NeAACDecClose(player->aacHandle);
			free (player->sampleSize);
			break;
		#endif /* ENABLE_FAAD */

		#ifdef ENABLE_MAD
		case PIANO_AF_MP3:
			mad_synth_finish (&player->mp3Synth);
			mad_frame_finish (&player->mp3Frame);
			mad_stream_finish (&player->mp3Stream);
			break;
		#endif /* ENABLE_MAD */

		default:
			/* this should never happen */
			assert (0);
			break;
	}

	if (player->aoError) {
		ret = (void *) PLAYER_RET_HARDFAIL;
	}

	/* Pandora sends broken audio url’s sometimes (“bad request”). ignore them. */
	if (wRet != WAITRESS_RET_OK && wRet != WAITRESS_RET_CB_ABORT) {
		BarUiMsg (player->settings, MSG_ERR, "Cannot access audio file: %s\n",
				WaitressErrorToStr (wRet));
		ret = (void *) PLAYER_RET_SOFTFAIL;
	}

cleanup:
	ao_close (player->audioOutDevice);
	WaitressFree (&player->waith);
	free (player->buffer);

	player->mode = PLAYER_FINISHED_PLAYBACK;

	return ret;
}
Example #27
0
int decodeAACfile(char *sndfile, int def_srate, aac_dec_opt *opt)
{
    int tagsize;
    unsigned long samplerate;
    unsigned char channels;
    void *sample_buffer;

    FILE *infile;

    audio_file *aufile;

    NeAACDecHandle hDecoder;
    NeAACDecFrameInfo frameInfo;
    NeAACDecConfigurationPtr config;

    int first_time = 1;


    /* declare variables for buffering */
    DEC_BUFF_VARS

    infile = fopen(opt->filename, "rb");
    if (infile == NULL)
    {
        /* unable to open file */
        error_handler("Error opening file: %s\n", opt->filename);
        return 1;
    }
    INIT_BUFF(infile)

    tagsize = id3v2_tag(buffer);
    if (tagsize)
    {
        UPDATE_BUFF_SKIP(tagsize)
    }

    hDecoder = NeAACDecOpen();

    /* Set the default object type and samplerate */
    /* This is useful for RAW AAC files */
    config = NeAACDecGetCurrentConfiguration(hDecoder);
    if (def_srate)
        config->defSampleRate = def_srate;
    config->defObjectType = opt->object_type;
    config->outputFormat = opt->output_format;

    NeAACDecSetConfiguration(hDecoder, config);

    if ((bytesconsumed = NeAACDecInit(hDecoder, buffer, bytes_in_buffer,
        &samplerate, &channels)) < 0)
    {
        /* If some error initializing occured, skip the file */
        error_handler("Error initializing decoder library.\n");
        END_BUFF
        NeAACDecClose(hDecoder);
        fclose(infile);
        return 1;
    }
    buffer_index += bytesconsumed;

    do
    {
        /* update buffer */
        UPDATE_BUFF_READ

        sample_buffer = NeAACDecDecode(hDecoder, &frameInfo, buffer, bytes_in_buffer);

        /* update buffer indices */
        UPDATE_BUFF_IDX(frameInfo)

        if (frameInfo.error > 0)
        {
            error_handler("Error: %s\n",
            NeAACDecGetErrorMessage(frameInfo.error));
        }

        opt->progress_update((long)fileread, buffer_index);

        /* open the sound file now that the number of channels are known */
        if (first_time && !frameInfo.error)
        {
            if(opt->decode_mode == 0)
            {
                if (Set_WIN_Params (INVALID_FILEDESC, samplerate, SAMPLE_SIZE,
                                frameInfo.channels) < 0)
                {
                    error_handler("\nCan't access %s\n", "WAVE OUT");
                    END_BUFF
                    NeAACDecClose(hDecoder);
                    fclose(infile);
                    return (0);
                }
            }
            else
            {
                aufile = open_audio_file(sndfile, samplerate, frameInfo.channels,
                    opt->output_format, opt->file_type, aacChannelConfig2wavexChannelMask(&frameInfo));

                if (aufile == NULL)
                {
                    END_BUFF
                    NeAACDecClose(hDecoder);
                    fclose(infile);
                    return 0;
                }
            }
            first_time = 0;
        }

        if ((frameInfo.error == 0) && (frameInfo.samples > 0))
        {
            if(opt->decode_mode == 0)
                WIN_Play_Samples((short*)sample_buffer, frameInfo.channels*frameInfo.samples);
            else
                write_audio_file(aufile, sample_buffer, frameInfo.samples, 0);
        }

        if (buffer_index >= fileread)
            sample_buffer = NULL; /* to make sure it stops now */

        if(stop_decoding)
            break;

    } while (sample_buffer != NULL);

    NeAACDecClose(hDecoder);

    fclose(infile);

    if(opt->decode_mode == 0)
        WIN_Audio_close();
    else
    {
        if (!first_time)
            close_audio_file(aufile);
    }

    END_BUFF

    return frameInfo.error;
}
Example #28
0
File: faad.c Project: videolan/vlc
/*****************************************************************************
 * DecodeBlock:
 *****************************************************************************/
static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    block_t *p_block;

    if( !pp_block || !*pp_block ) return NULL;

    p_block = *pp_block;
    *pp_block = NULL;

    if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY | BLOCK_FLAG_CORRUPTED) )
    {
        Flush( p_dec );
        if( p_block->i_flags & (BLOCK_FLAG_CORRUPTED) )
        {
            block_Release( p_block );
            return NULL;
        }
    }

    /* Remove ADTS header if we have decoder specific config */
    if( p_dec->fmt_in.i_extra && p_block->i_buffer > 7 )
    {
        if( p_block->p_buffer[0] == 0xff &&
                ( p_block->p_buffer[1] & 0xf0 ) == 0xf0 ) /* syncword */
        {   /* ADTS header present */
            size_t i_header_size; /* 7 bytes (+ 2 bytes for crc) */
            i_header_size = 7 + ( ( p_block->p_buffer[1] & 0x01 ) ? 0 : 2 );
            /* FIXME: multiple blocks per frame */
            if( p_block->i_buffer > i_header_size )
            {
                p_block->p_buffer += i_header_size;
                p_block->i_buffer -= i_header_size;
            }
        }
    }

    /* Append the block to the temporary buffer */
    if( p_sys->i_buffer_size < p_sys->i_buffer + p_block->i_buffer )
    {
        size_t  i_buffer_size = p_sys->i_buffer + p_block->i_buffer;
        uint8_t *p_buffer     = realloc( p_sys->p_buffer, i_buffer_size );
        if( p_buffer )
        {
            p_sys->i_buffer_size = i_buffer_size;
            p_sys->p_buffer      = p_buffer;
        }
        else
        {
            p_block->i_buffer = 0;
        }
    }

    if( p_block->i_buffer > 0 )
    {
        memcpy( &p_sys->p_buffer[p_sys->i_buffer],
                p_block->p_buffer, p_block->i_buffer );
        p_sys->i_buffer += p_block->i_buffer;
        p_block->i_buffer = 0;
    }

    if( p_dec->fmt_out.audio.i_rate == 0 && p_dec->fmt_in.i_extra > 0 )
    {
        /* We have a decoder config so init the handle */
        unsigned long i_rate;
        unsigned char i_channels;

        if( NeAACDecInit2( p_sys->hfaad, p_dec->fmt_in.p_extra,
                           p_dec->fmt_in.i_extra,
                           &i_rate, &i_channels ) >= 0 )
        {
            p_dec->fmt_out.audio.i_rate = i_rate;
            p_dec->fmt_out.audio.i_channels = i_channels;
            p_dec->fmt_out.audio.i_physical_channels
                = p_dec->fmt_out.audio.i_original_channels
                  = pi_channels_guessed[i_channels];

            date_Init( &p_sys->date, i_rate, 1 );
        }
    }

    if( p_dec->fmt_out.audio.i_rate == 0 && p_sys->i_buffer )
    {
        unsigned long i_rate;
        unsigned char i_channels;

        /* Init faad with the first frame */
        if( NeAACDecInit( p_sys->hfaad,
                          p_sys->p_buffer, p_sys->i_buffer,
                          &i_rate, &i_channels ) < 0 )
        {
            block_Release( p_block );
            return NULL;
        }

        p_dec->fmt_out.audio.i_rate = i_rate;
        p_dec->fmt_out.audio.i_channels = i_channels;
        p_dec->fmt_out.audio.i_physical_channels
            = p_dec->fmt_out.audio.i_original_channels
              = pi_channels_guessed[i_channels];
        date_Init( &p_sys->date, i_rate, 1 );
    }

    if( p_block->i_pts > VLC_TS_INVALID && p_block->i_pts != date_Get( &p_sys->date ) )
    {
        date_Set( &p_sys->date, p_block->i_pts );
    }
    else if( !date_Get( &p_sys->date ) )
    {
        /* We've just started the stream, wait for the first PTS. */
        block_Release( p_block );
        p_sys->i_buffer = 0;
        return NULL;
    }

    /* Decode all data */
    if( p_sys->i_buffer > 1)
    {
        void *samples;
        NeAACDecFrameInfo frame;
        block_t *p_out;

        samples = NeAACDecDecode( p_sys->hfaad, &frame,
                                  p_sys->p_buffer, p_sys->i_buffer );

        if( frame.error > 0 )
        {
            msg_Warn( p_dec, "%s", NeAACDecGetErrorMessage( frame.error ) );

            if( frame.error == 21 || frame.error == 12 )
            {
                /*
                 * Once an "Unexpected channel configuration change"
                 * or a "Invalid number of channels" error
                 * occurs, it will occurs afterwards, and we got no sound.
                 * Reinitialization of the decoder is required.
                 */
                unsigned long i_rate;
                unsigned char i_channels;
                NeAACDecHandle *hfaad;
                NeAACDecConfiguration *cfg,*oldcfg;

                oldcfg = NeAACDecGetCurrentConfiguration( p_sys->hfaad );
                hfaad = NeAACDecOpen();
                cfg = NeAACDecGetCurrentConfiguration( hfaad );
                if( oldcfg->defSampleRate )
                    cfg->defSampleRate = oldcfg->defSampleRate;
                cfg->defObjectType = oldcfg->defObjectType;
                cfg->outputFormat = oldcfg->outputFormat;
                NeAACDecSetConfiguration( hfaad, cfg );

                if( NeAACDecInit( hfaad, p_sys->p_buffer, p_sys->i_buffer,
                                  &i_rate,&i_channels ) < 0 )
                {
                    /* reinitialization failed */
                    NeAACDecClose( hfaad );
                    NeAACDecSetConfiguration( p_sys->hfaad, oldcfg );
                }
                else
                {
                    NeAACDecClose( p_sys->hfaad );
                    p_sys->hfaad = hfaad;
                    p_dec->fmt_out.audio.i_rate = i_rate;
                    p_dec->fmt_out.audio.i_channels = i_channels;
                    p_dec->fmt_out.audio.i_physical_channels
                        = p_dec->fmt_out.audio.i_original_channels
                          = pi_channels_guessed[i_channels];
                    date_Init( &p_sys->date, i_rate, 1 );
                }
            }

            /* Flush the buffer */
            p_sys->i_buffer = 0;
            block_Release( p_block );
            return NULL;
        }

        if( frame.channels <= 0 || frame.channels > 8 || frame.channels == 7 )
        {
            msg_Warn( p_dec, "invalid channels count: %i", frame.channels );

            /* Flush the buffer */
            p_sys->i_buffer -= frame.bytesconsumed;
            if( p_sys->i_buffer > 0 )
            {
                memmove( p_sys->p_buffer,&p_sys->p_buffer[frame.bytesconsumed],
                         p_sys->i_buffer );
            }
            block_Release( p_block );
            return NULL;
        }

        if( frame.samples <= 0 )
        {
            msg_Warn( p_dec, "decoded zero sample" );

            /* Flush the buffer */
            p_sys->i_buffer -= frame.bytesconsumed;
            if( p_sys->i_buffer > 1 )
            {
                memmove( p_sys->p_buffer,&p_sys->p_buffer[frame.bytesconsumed],
                         p_sys->i_buffer );
            }
            else
            {
                /* Drop byte of padding */
                p_sys->i_buffer = 0;
            }
            block_Release( p_block );
            return NULL;
        }

        /* We decoded a valid frame */
        if( p_dec->fmt_out.audio.i_rate != frame.samplerate )
        {
            date_Init( &p_sys->date, frame.samplerate, 1 );
            date_Set( &p_sys->date, p_block->i_pts );
        }
        p_block->i_pts = VLC_TS_INVALID;  /* PTS is valid only once */

        p_dec->fmt_out.audio.i_rate = frame.samplerate;
        p_dec->fmt_out.audio.i_channels = frame.channels;

        /* Adjust stream info when dealing with SBR/PS */
        bool b_sbr = (frame.sbr == 1) || (frame.sbr == 2);
        if( p_sys->b_sbr != b_sbr || p_sys->b_ps != frame.ps )
        {
            const char *psz_ext = (b_sbr && frame.ps) ? "SBR+PS" :
                                  b_sbr ? "SBR" : "PS";

            msg_Dbg( p_dec, "AAC %s (channels: %u, samplerate: %lu)",
                     psz_ext, frame.channels, frame.samplerate );

            if( !p_dec->p_description )
                p_dec->p_description = vlc_meta_New();
            if( p_dec->p_description )
                vlc_meta_AddExtra( p_dec->p_description, _("AAC extension"), psz_ext );

            p_sys->b_sbr = b_sbr;
            p_sys->b_ps = frame.ps;
        }

        /* Convert frame.channel_position to our own channel values */
        p_dec->fmt_out.audio.i_physical_channels = 0;
        const uint32_t nbChannels = frame.channels;
        unsigned j;
        for( unsigned i = 0; i < nbChannels; i++ )
        {
            /* Find the channel code */
            for( j = 0; j < MAX_CHANNEL_POSITIONS; j++ )
            {
                if( frame.channel_position[i] == pi_channels_in[j] )
                    break;
            }
            if( j >= MAX_CHANNEL_POSITIONS )
            {
                msg_Warn( p_dec, "unknown channel ordering" );
                /* Invent something */
                j = i;
            }
            /* */
            p_sys->pi_channel_positions[i] = pi_channels_out[j];
            if( p_dec->fmt_out.audio.i_physical_channels & pi_channels_out[j] )
                frame.channels--; /* We loose a duplicated channel */
            else
                p_dec->fmt_out.audio.i_physical_channels |= pi_channels_out[j];
        }
        if ( nbChannels != frame.channels )
        {
            p_dec->fmt_out.audio.i_physical_channels
                = p_dec->fmt_out.audio.i_original_channels
                  = pi_channels_guessed[nbChannels];
        }
        else
        {
            p_dec->fmt_out.audio.i_original_channels =
                p_dec->fmt_out.audio.i_physical_channels;
        }
        p_dec->fmt_out.audio.i_channels = nbChannels;
        if( decoder_UpdateAudioFormat( p_dec ) )
            p_out = NULL;
        else
            p_out = decoder_NewAudioBuffer( p_dec, frame.samples / nbChannels );
        if( p_out == NULL )
        {
            p_sys->i_buffer = 0;
            block_Release( p_block );
            return NULL;
        }

        p_out->i_pts = date_Get( &p_sys->date );
        p_out->i_length = date_Increment( &p_sys->date,
                                          frame.samples / nbChannels )
                          - p_out->i_pts;

        DoReordering( (uint32_t *)p_out->p_buffer, samples,
                      frame.samples / nbChannels, nbChannels,
                      p_sys->pi_channel_positions );

        p_sys->i_buffer -= frame.bytesconsumed;
        if( p_sys->i_buffer > 0 )
        {
            memmove( p_sys->p_buffer, &p_sys->p_buffer[frame.bytesconsumed],
                     p_sys->i_buffer );
        }

        block_Release( p_block );
        return p_out;
    }
    else
    {
        /* Drop byte of padding */
        p_sys->i_buffer = 0;
    }

    block_Release( p_block );
    return NULL;
}
Example #29
0
File: faad.c Project: videolan/vlc
/*****************************************************************************
 * OpenDecoder: probe the decoder and return score
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    decoder_t *p_dec = (decoder_t*)p_this;
    decoder_sys_t *p_sys;
    NeAACDecConfiguration *cfg;

    if( p_dec->fmt_in.i_codec != VLC_CODEC_MP4A )
    {
        return VLC_EGENERIC;
    }

    /* Allocate the memory needed to store the decoder's structure */
    if( ( p_dec->p_sys = p_sys = malloc( sizeof(*p_sys) ) ) == NULL )
        return VLC_ENOMEM;

    /* Open a faad context */
    if( ( p_sys->hfaad = NeAACDecOpen() ) == NULL )
    {
        msg_Err( p_dec, "cannot initialize faad" );
        free( p_sys );
        return VLC_EGENERIC;
    }

    /* Misc init */
    date_Set( &p_sys->date, 0 );
    p_dec->fmt_out.i_cat = AUDIO_ES;

    p_dec->fmt_out.i_codec = HAVE_FPU ? VLC_CODEC_FL32 : VLC_CODEC_S16N;

    p_dec->fmt_out.audio.i_physical_channels =
        p_dec->fmt_out.audio.i_original_channels = 0;

    if( p_dec->fmt_in.i_extra > 0 )
    {
        /* We have a decoder config so init the handle */
        unsigned long i_rate;
        unsigned char i_channels;

        if( NeAACDecInit2( p_sys->hfaad, p_dec->fmt_in.p_extra,
                           p_dec->fmt_in.i_extra,
                           &i_rate, &i_channels ) < 0 )
        {
            msg_Err( p_dec, "Failed to initialize faad using extra data" );
            NeAACDecClose( p_sys->hfaad );
            free( p_sys );
            return VLC_EGENERIC;
        }

        p_dec->fmt_out.audio.i_rate = i_rate;
        p_dec->fmt_out.audio.i_channels = i_channels;
        p_dec->fmt_out.audio.i_physical_channels
            = p_dec->fmt_out.audio.i_original_channels
              = pi_channels_guessed[i_channels];
        date_Init( &p_sys->date, i_rate, 1 );
    }
    else
    {
        /* Will be initalised from first frame */
        p_dec->fmt_out.audio.i_rate = 0;
        p_dec->fmt_out.audio.i_channels = 0;
    }

    /* Set the faad config */
    cfg = NeAACDecGetCurrentConfiguration( p_sys->hfaad );
    if( p_dec->fmt_in.audio.i_rate )
        cfg->defSampleRate = p_dec->fmt_in.audio.i_rate;
    cfg->outputFormat = HAVE_FPU ? FAAD_FMT_FLOAT : FAAD_FMT_16BIT;
    NeAACDecSetConfiguration( p_sys->hfaad, cfg );

    /* buffer */
    p_sys->i_buffer = p_sys->i_buffer_size = 0;
    p_sys->p_buffer = NULL;

    p_sys->b_sbr = p_sys->b_ps = false;

    p_dec->pf_decode_audio = DecodeBlock;
    p_dec->pf_flush        = Flush;
    return VLC_SUCCESS;
}
Example #30
0
void SoundSourceM4A::closeDecoder() {
    if (m_hDecoder != nullptr) {
        NeAACDecClose(m_hDecoder);
        m_hDecoder = nullptr;
    }
}