Click here to Skip to main content
Click here to Skip to main content

AAC Encode

, 17 Feb 2012
Rate this:
Please Sign up or sign in to vote.
Raw Audio data is encoded to AAC compression using ffmmpeg library.

Introduction

This article is 2nd article of audio capturing, encoding and streaming. It describes to how to encode capture PCM data to AAC encoding and write to audio file.

Back Ground.

It is for software developers who are interested in audio related applications. Mostly suits for Audio software developers who are interested in encoding and decoding audio files to AAC encoding using FFMPEG libraries in windows platform. It is not required to know AAC encoding and decoding details unless one wants to decode captured data manually.

Total application is written in "C" language consists of simple functions and simple port audio library and ffmpeg library calls. It uses ffmpeg libraries calls intensively it is better have some ffmpeg knowledge.

Port-Audio

Port-Audio is a free, cross-platform, open-source, audio I/O library. It lets you write simple audio programs in 'C' or C++ that will compile and run on many platforms including Windows, Macintosh OS X, and Unix (OSS/ALSA). It is intended to promote the exchange of audio software between developers on different platforms. Port Audio software many useful examples.

Official web site http://www.portaudio.com.

FFMPEG

ffmpeg is a very fast video and audio converter that can also grab from a live audio/video source. It can also convert between arbitrary sample rates and resize video on the fly with a high quality polyphase filter.

ffmpeg reads from an arbitrary number of input "files" (which can be regular files, pipes, network streams, grabbing devices, etc.), specified by the -i option, and writes to an arbitrary number of output "files", which are specified by a plain output filename. Anything found on the command line which cannot be interpreted as an option is considered to be an output filename.

Official ffmpeg web site http://ffmpeg.org/

AAC Audio Encoding Data flow Diagram.

Data flow diagram is as follows

AACEncode

Software details

For more details on port audio calls see the port-audio documentation, and AMR narrow band see opencore-amr documentation.

Step1: Initialize port audio and register record callback function.

Initialize the port audio and open port audio stream with record call back function with following configurations 8000 sampling rate, 16 bit signed PCM data, frame size of 80 samples mean 10 milliseconds audio data in one frame. After stream is started, record call back is called for every 10 ms with one frame of audio data.

static PaError
yakAudioStreamOpen(paTestData *yakData)
static PaError yakAudioStreamOpen(paTestData *yakData)
{ 
PaStreamParametersinputParameters;
PaStream*stream;
PaErrorerr = paNoError;
 
// register signal SIGINT and signal handler
signal(SIGINT, signalHandler);
 
err = Pa_Initialize();
if( err != paNoError ) goto done;
 
inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
if (inputParameters.device == paNoDevice) {
fprintf(stderr,"Error: No default input device.\n");
goto done;
}
inputParameters.channelCount = NUM_CHANNELS;/* stereo input */
inputParameters.sampleFormat = PA_SAMPLE_TYPE;
inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
inputParameters.hostApiSpecificStreamInfo = NULL;

/* Record some audio. -------------------------------------------- */
err = Pa_OpenStream(
&stream,
&inputParameters,
NULL,/* &outputParameters, */
SAMPLE_RATE,
SAMPLES_PER_FRAME,
paClipOff,/* we won't output out of range samples so don't bother clipping them */
yakAudioRecordCallback,
yakData );
if( err != paNoError ) goto done;
 
yakData->recordStream = stream; 
return paNoError;
 
done:
Pa_Terminate();
if( err != paNoError )
{
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
err = 1;/* Always return 0 or 1, but no other return codes. */
}
return err;
}

Step 2: Initialize FFMPEG library.

Initialize opencore-amr library to with proper configuration parameters to match port-audio capture configuration.

Code snippet as follows

AVCodecContext*audioCodec;
AVCodec *codec;

avcodec_register_all();


//Set up audio encoder
codec = avcodec_find_encoder(CODEC_ID_AAC);
if (codec == NULL) 
{
printf("avcodec_find_encoder: ERROR\n");
return NULL;
}
audioCodec = avcodec_alloc_context();
audioCodec->bit_rate = audioBitrate;
audioCodec->sample_fmt = SAMPLE_FMT_S16;
audioCodec->sample_rate = sampleRate;
audioCodec->channels = channels;
audioCodec->profile = FF_PROFILE_AAC_MAIN;
//audioCodec->time_base = (AVRational){1, sampleRate};
audioCodec->time_base.num= 1;
audioCodec->time_base.den= sampleRate;
 
audioCodec->codec_type = AVMEDIA_TYPE_AUDIO;
if (avcodec_open(audioCodec, codec) < 0) 
{
printf("avcodec_open: ERROR\n");
return NULL;
}
 
return audioCodec;
}

Step 3: Encode Raw Audio Frame.

When port-audio record callback is called, raw audio data is stored input buffer, pass the buffer and length to amr encoder, amr encoder returns encoded data.

static void yakAudioEncode(paTestData *yakData, uint8_t *rawData, int rawDataSize)
{
int frameBytes;

frameBytes = yakData->c->frame_size * yakData->c->channels * sizeof(SAMPLE);

// Note: revisit the while loop
// BUG-1
while (rawDataSize >= frameBytes) 
{
int packetSize;
 
packetSize = avcodec_encode_audio(yakData->c, yakData->encoderOutput, 
yakData->allocOutputSize, (short *)rawData);
//printf("EncodePaData (%d-%d-%d)\n",packetSize,audioSize,frameBytes);
 
yakData->encoderOutputSize+= packetSize;
rawData += frameBytes;
rawDataSize -= frameBytes;
} 
}

Step 4: write to file.

static void EncodePaData(paTestData *yakData, uint8_t *rawData, int rawDataSize)
{
yakAudioEncode(yakData, rawData, rawDataSize);
fwrite(yakData->encoderOutput, sizeof(uint8_t), yakData->encoderOutputSize, 
yakData->recFileStream);
yakData->encoderOutputSize = 0;
}

Step 6: close ffmpeg library

Close all resources related ffmpeg AvCodecContext and AvCodec libraries.

Step 7: Stop, close audio stream and close port audio.

static PaError yakCloseAudioStream(paTestData *yakData) 

{ 

return Pa_CloseStream( yakData->recordStream); 

}

Required software

The following software are required to execute and listen captured audio file.

VC++, portaudio library/dll, ffmpeg library/dll and ant AAC capable audio player (VLC).

NOTE:

FFMPEG development release software is required to run this application. please download ffmpeg development version. and specificy required paths for include and libraries.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

potluri_suresh
Software Developer (Senior) 3k Techonologies
United States United States
Suresh Potluri has worked in Windows device drivers, Solid experience in NDIS Layer, developed many NDIS Miniport drivers. Extensive experience in developing NDIS miniport drivers, building WHQL/DTM setup, clearing all WHQL/DTM tests, and subsequently getting device signature/logo process for the developed drivers. He also was also solely responsible for debugging traps and blue screens for a number of years.
he also worked on many PCI based boards, developed Board support packages, Vx-Works firmware for Power PC, firmware for ARM based boards for Wireless LAN devices.
 
he is interested in Embedded, NDIS, MPEG.
 
Previously worked in Tandberg TV, Sunnyvale, Chlesio Communications, Sunnyvale, Hellosoft, Hyderabad.

Comments and Discussions

 
Generali like this article Pinmemberjacky_zz3-Sep-13 2:11 
Generalavcodec-53.dll missing PinmemberMember 797223912-May-13 13:54 
SuggestionCode formatting PinmentorDaveAuld18-Feb-12 7:48 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140823.1 | Last Updated 18 Feb 2012
Article Copyright 2012 by potluri_suresh
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid