⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 audio.c

📁 TI DM6446板卡上调用decode engine进行解码的例子程序
💻 C
字号:
/* * audio.c * * ============================================================================ * Copyright (c) Texas Instruments Inc 2005 * * Use of this software is controlled by the terms and conditions found in the * license agreement under which this software has been supplied or provided. * ============================================================================ *//* Standard Linux headers */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <fcntl.h>#include <errno.h>#include <linux/soundcard.h>/* Codec Engine headers */#include <xdc/std.h>#include <ti/sdo/ce/Engine.h>#include <ti/sdo/ce/osal/Memory.h>#include <ti/sdo/ce/audio/auddec.h>/* Demo headers */#include <rendezvous.h>#include "decode.h"#include "audio.h"#include "loader.h"/* The max amount of bytes of audio data to process at once */#define SOUNDBLKSIZE           2 * 1024/* The maximum size of the raw decoded samples */ #define RAWBUFSIZE             SOUNDBLKSIZE * 5/* The size of the read buffer */#define READBUFSIZE            60 * 1024/* The number of channels of the audio codec */#define NUM_CHANNELS           2/* The sample rate of the audio codec */#define SAMPLE_RATE            44100/* The gain (0-100) of the left and right channels */#define LEFT_GAIN              100#define RIGHT_GAIN             100/* The levels of initialization */#define AUDIOFILEINITIALIZED   0x1#define SOUNDDEVICEINITIALIZED 0x2#define ENGINEOPENED           0x4#define AUDIODECODERCREATED    0x8#define READBUFFERALLOCATED    0x10#define RAWBUFFERALLOCATED     0x20/* Video decoder names */char *audioDecodeAlgNames[NUM_AUDIO_DECODERS] = {    "aacdec",    "mp3dec"};/* Local function prototypes */static int audioDecodeAlgCreate(Engine_Handle hEngine,                                AUDDEC_Handle *hDecodePtr,                                enum AudioDecoder audioDecoder);static int decodeAudioBuffer(AUDDEC_Handle hDecode, char *inBuf, int inBufSize,                             char *outBuf, int *outBufSize,                             int *bytesProcessed, int *framesRejectedPtr);static int setSampleRate(int soundFd, int sampleRate);static int initSoundDevice(void);/****************************************************************************** * audioDecodeAlgCreate ******************************************************************************/static int audioDecodeAlgCreate(Engine_Handle hEngine,                                AUDDEC_Handle *hDecodePtr,                                enum AudioDecoder audioDecoder){    AUDDEC_DynamicParams    dynamicParams;    AUDDEC_Params           params;    AUDDEC_Status           decStatus;    XDAS_Int32              status;    char                   *algName;    AUDDEC_Handle           hDecode;    algName = audioDecodeAlgNames[audioDecoder];    params.size           = sizeof(AUDDEC_Params);    params.maxSampleRate  = 48000;    params.maxBitrate     = 448000;    params.maxNoOfCh      = IAUDIO_STEREO;    params.dataEndianness = XDM_BYTE;    /* Create audio decoder */    hDecode = AUDDEC_create(hEngine, algName, &params);    if (hDecode == NULL) {        ERR("Can't open audio decode algorithm\n");        return FAILURE;     }    /* Reset codec */    decStatus.size = sizeof(AUDDEC_Status);    dynamicParams.size = sizeof(AUDDEC_DynamicParams);    status = AUDDEC_control(hDecode, XDM_RESET, &dynamicParams, &decStatus);    if (status != AUDDEC_EOK) {        ERR("XDM_RESET failed, status=%ld\n", status);        return FAILURE;    }    /* Set default dynamic parameters */    decStatus.size = sizeof(AUDDEC_Status);    dynamicParams.size = sizeof(AUDDEC_DynamicParams);    status = AUDDEC_control(hDecode, XDM_SETDEFAULT, &dynamicParams,                            &decStatus);    if (status != AUDDEC_EOK) {        ERR("XDM_SETDEFAULT failed, status=%ld\n", status);        return FAILURE;    }    /* Set dynamic parameters */    decStatus.size = sizeof(AUDDEC_Status);    dynamicParams.size = sizeof(AUDDEC_DynamicParams);    dynamicParams.outputFormat = IAUDIO_INTERLEAVED;    status = AUDDEC_control(hDecode, XDM_SETPARAMS, &dynamicParams,                            &decStatus);    if (status != AUDDEC_EOK) {        ERR("XDM_SETPARAMS failed, status=%ld\n", status);        return FAILURE;    }    *hDecodePtr = hDecode;    return SUCCESS;}/****************************************************************************** * decodeAudioBuffer ******************************************************************************/static int decodeAudioBuffer(AUDDEC_Handle hDecode, char *inBuf, int inBufSize,                             char *outBuf, int *outBufSize,                             int *bytesProcessed, int *framesRejectedPtr){    static int              sampleRateInitialized = FALSE;    AUDDEC_DynamicParams    dynamicParams;    XDAS_Int32              inBufSizeArray[1];    XDAS_Int32              outBufSizeArray[1];    XDM_BufDesc             inBufDesc;    XDM_BufDesc             outBufDesc;    XDAS_Int32              status;    AUDDEC_InArgs           inArgs;    AUDDEC_OutArgs          outArgs;    AUDDEC_Status           decStatus;    inBufSizeArray[0]       = inBufSize;    outBufSizeArray[0]      = RAWBUFSIZE;    inBufDesc.bufSizes      = inBufSizeArray;    inBufDesc.bufs          = (XDAS_Int8 **) &inBuf;    inBufDesc.numBufs       = 1;    outBufDesc.bufSizes     = outBufSizeArray;    outBufDesc.bufs         = (XDAS_Int8 **) &outBuf;    outBufDesc.numBufs      = 1;    inArgs.size             = sizeof(AUDDEC_InArgs);    inArgs.numBytes         = inBufSize;    outArgs.size            = sizeof(AUDDEC_OutArgs);    /* Decode the audio buffer */    status = AUDDEC_process(hDecode, &inBufDesc, &outBufDesc, &inArgs,                            &outArgs);    *bytesProcessed = outArgs.bytesConsumed;    if (status != AUDDEC_EOK) {        if (status == AUDDEC_ERUNTIME ||            outArgs.bytesConsumed == 0 ||            XDM_ISFATALERROR(outArgs.extendedError)) {            ERR("AUDDEC_process() failed with a fatal error (%ld ext: %#lx\n",                status, outArgs.extendedError);            return FAILURE;        }        else {            /* Make sure we don't output the corrupt samples */            *outBufSize = 0;            (*framesRejectedPtr)++;            return SUCCESS;        }    }    /* Get the dynamic codec status */    decStatus.size = sizeof(AUDDEC_Status);    dynamicParams.size = sizeof(AUDDEC_DynamicParams);    status = AUDDEC_control(hDecode, XDM_GETSTATUS, &dynamicParams,                            &decStatus);    if (status != AUDDEC_EOK) {        ERR("XDM_GETSTATUS failed, status=%ld\n", status);        return FAILURE;    }    /* Detect which sample rate was really used to encode the data */    if (!sampleRateInitialized) {        if (setSampleRate(0, decStatus.sampleRate) == FAILURE) {            return FAILURE;        }        gblSetSamplingFrequency(decStatus.sampleRate);        sampleRateInitialized = TRUE;    }    *outBufSize = decStatus.frameLen * 4;    *bytesProcessed = outArgs.bytesConsumed;    return SUCCESS;}/****************************************************************************** * setSampleRate ******************************************************************************/static int setSampleRate(int soundFd, int sampleRate){     static int fd = 0;    if (!fd) {        if (!soundFd) {            ERR("No valid sound filedescriptor available\n");            return FAILURE;        }        fd = soundFd;    }    /* Set the sample rate */    if (ioctl(fd, SNDCTL_DSP_SPEED, &sampleRate) == -1) {        ERR("Could not set sample rate (%d)\n", sampleRate);        return FAILURE;    }    return SUCCESS;}/****************************************************************************** * initSoundDevice ******************************************************************************/static int initSoundDevice(void){    int     channels    = NUM_CHANNELS;    int     format      = AFMT_S16_LE;    int     soundFd;    /* Open the sound device for writing */    soundFd = open(SOUND_DEVICE, O_WRONLY);    if (soundFd == -1) {        ERR("Failed to open the sound device (%s)\n", SOUND_DEVICE);        return FAILURE;    }    /* Set the sound format (only AFMT_S16_LE supported) */    if (ioctl(soundFd, SNDCTL_DSP_SETFMT, &format) == -1) {        ERR("Could not set format %d\n", format);        return FAILURE;    }    /* Set the number of channels */    if (ioctl(soundFd, SNDCTL_DSP_CHANNELS, &channels) == -1) {        ERR("Could not set mixer to %d channels\n", channels);        return FAILURE;    }    /* Set the sample rate */    if (setSampleRate(soundFd, SAMPLE_RATE) == FAILURE) {        return FAILURE;    }    return soundFd;}/****************************************************************************** * audioThrFxn ******************************************************************************/void *audioThrFxn(void *arg){    Engine_Handle   hEngine        = NULL;    unsigned int    initMask       = 0;    AudioEnv       *envp           = (AudioEnv *) arg;    void           *status         = THREAD_SUCCESS;    char           *rawBuffer      = NULL;    int             framesRejected = 0;    int             frameSize      = 0;    int             outputFd       = 0;    AUDDEC_Handle   hDecode;    char           *framePtr;    int             rawBufferSize;    LoaderState     lState;    /* Initialize loader state */    lState.loop = envp->loop;    lState.readBufSize = READBUFSIZE;    lState.readSize = SOUNDBLKSIZE;    lState.doneMask = SOUND_DONE;    /* Open the audio file */    lState.inputFd = open(envp->audioFile, O_RDONLY);    if (lState.inputFd == -1) {        ERR("Failed to open %s (%s)\n", envp->audioFile, strerror(errno));        cleanup(THREAD_FAILURE);    }    DBG("Audio file successfully opened\n");    initMask |= AUDIOFILEINITIALIZED;    /* Initialize the AIC33 audio codec for writing */    outputFd = initSoundDevice();    if (outputFd == FAILURE) {        cleanup(THREAD_FAILURE);    }    DBG("Sound device initialized\n");    initMask |= SOUNDDEVICEINITIALIZED;    /* Reset, load, and start DSP Engine */    hEngine = Engine_open(ENGINE_NAME, NULL, NULL);    if (hEngine == NULL) {        ERR("Failed to open codec engine %s\n", ENGINE_NAME);        cleanup(THREAD_FAILURE);    }    DBG("Codec Engine opened in audio thread\n");    initMask |= ENGINEOPENED;    /* Allocate and initialize audio decoder on the engine */    if (audioDecodeAlgCreate(hEngine, &hDecode,                             envp->audioDecoder) == FAILURE) {        cleanup(THREAD_FAILURE);    }    DBG("Audio decoder created\n");    initMask |= AUDIODECODERCREATED;    /* Allocate intermediate buffer (for encoded data) */    lState.readBuffer = (char *) Memory_contigAlloc(lState.readBufSize,                                                    Memory_DEFAULTALIGNMENT);        if (lState.readBuffer == NULL) {        ERR("Failed to allocate contiguous memory block.\n");        cleanup(THREAD_FAILURE);    }    DBG("Contiguous buffer allocated with physical address %#lx\n",        Memory_getPhysicalAddress(lState.readBuffer));    initMask |= READBUFFERALLOCATED;    /* Allocate buffer for raw data */    rawBuffer = (char *) Memory_contigAlloc(RAWBUFSIZE,                                            Memory_DEFAULTALIGNMENT);        if (rawBuffer == NULL) {        ERR("Failed to allocate contiguous memory block.\n");        cleanup(THREAD_FAILURE);    }    DBG("Contiguous buffer allocated with physical address %#lx\n",        Memory_getPhysicalAddress(rawBuffer));    initMask |= RAWBUFFERALLOCATED;    /* Signal that initialization is done and wait for other threads */    Rendezvous_meet(envp->hRendezvous);    /* Prime the file loader */    if (loaderPrime(&lState, &framePtr) == FAILURE) {        cleanup(THREAD_FAILURE);    }    DBG("Entering audio main loop.\n");    while (!gblGetQuit()) {        if (!gblGetPlay()) {            usleep(PAUSE);            continue;        }        /* Decode the encoded frame to the raw buffer */        if (decodeAudioBuffer(hDecode, framePtr, lState.readSize,                              rawBuffer, &rawBufferSize,                              &frameSize, &framesRejected) == FAILURE) {            breakLoop(THREAD_FAILURE);        }        /* Write samples to the device driver from contiguous buffer */        if (write(outputFd, rawBuffer, rawBufferSize) == -1) {            ERR("Error writing data to %s (%s)\n", SOUND_DEVICE,                strerror(errno));            breakLoop(THREAD_FAILURE);        }        /* Read a new frame of encoded data from disk */        if (loaderGetFrame(&lState, frameSize, &framePtr) == FAILURE) {            breakLoop(THREAD_FAILURE);        }        if (lState.endClip) {            /* Recreate the algorithm */            AUDDEC_delete(hDecode);            if (audioDecodeAlgCreate(hEngine, &hDecode,                                     envp->audioDecoder) == FAILURE) {                breakLoop(THREAD_FAILURE);            }            /* Prime the file loader */            if (loaderPrime(&lState, &framePtr) == FAILURE) {                breakLoop(THREAD_FAILURE);            }        }        /* Increment statistics for OSD display */        gblIncSoundBytesEncoded(frameSize);    }    printf("\nTotal number of audio frames rejected: %d\n", framesRejected);cleanup:    /* Make sure the other threads aren't waiting for init to complete */    Rendezvous_force(envp->hRendezvous);    /* Clean up the audio thread */    if (initMask & RAWBUFFERALLOCATED) {        Memory_contigFree(rawBuffer, RAWBUFSIZE);    }    if (initMask & READBUFFERALLOCATED) {        Memory_contigFree(lState.readBuffer, lState.readBufSize);    }    if (initMask & AUDIODECODERCREATED) {        AUDDEC_delete(hDecode);    }    if (initMask & ENGINEOPENED) {        Engine_close(hEngine);    }    if (initMask & SOUNDDEVICEINITIALIZED) {        close(outputFd);    }    if (initMask & AUDIOFILEINITIALIZED) {        close(lState.inputFd);    }    return status;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -