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

📄 audio_thread.c

📁 TI workshop 培训资料。 是关于如何创建DAVINCI平台下codec engine
💻 C
字号:
/* Standard Linux headers */#include <stdio.h>		// always include stdio.h#include <stdlib.h>		// always include stdlib.h#include <fcntl.h>		// defines open, read, write methods#include <unistd.h>		// defines close and sleep methods#include <sys/ioctl.h>		// defines driver ioctl method#include <linux/soundcard.h>	// defines OSS driver functions#include <string.h>		// defines memcpy/* Codec Engine headers */#include <xdc/std.h>			// xdc base definitions. Must come 1st#include <ti/sdo/ce/Engine.h>		// required for any CE application#include <ti/sdo/ce/audio/auddec.h>	// defines audio encoder methods#include <ti/sdo/ce/audio/audenc.h>	// defines audio decoder methods/* Application headers */#include "debug.h"		// DBG and ERR macros#include "audio_thread.h"	// audio thread definitions#include "audio_input_output.h"	// audio driver input and output functions#include "engine.h"             // Helper utilities for engine_open and close#include "audio_encoder.h"	// audio encoder functions#include "audio_decoder.h"	// audio decoder functions/* OSS and Mixer devices */#define SOUND_DEVICE "/dev/dsp"#define MIXER_DEVICE "/dev/mixer"/* Audio encoder and decoder names */#define AUDIO_DECODER "audio_decoder"#define AUDIO_ENCODER "audio_encoder"/* The sample rate of the audio codec.*/#define SAMPLE_RATE 44100/* The gain (0-100) of the left channel.*/#define LEFT_GAIN 100/* The gain (0-100) of the right channel.*/#define RIGHT_GAIN 100/*  Parameters for audio thread execution */#define BLOCKSIZE 44100/****************************************************************************** * audio_thread_fxn ******************************************************************************//*  input parameters:                                                         *//*      void *envByRef       --  a pointer to an audio_thread_env structure   *//*                               as defined in audio_thread.h                 *//*                                                                            *//*          envByRef.quit    -- when quit != 0, thread will cleanup and exit  *//*                                                                            *//*  return value:                                                             *//*      void *     --  AUDIO_THREAD_SUCCESS or AUDIO_THREAD_FAILURE as        *//*                     defined in audio_thread.h                              *//******************************************************************************/void *audio_thread_fxn(void *envByRef){/*  Thread parameters and return value */    audio_thread_env *envPtr = envByRef;		// see above    void    	     *status = AUDIO_THREAD_SUCCESS;	// see above/*  The levels of initialization for initMask */#define INPUT_OSS_INITIALIZED   0x1#define INPUT_BUFFER_ALLOCATED  0x2#define OUTPUT_OSS_INITIALIZED  0x4#define OUTPUT_BUFFER_ALLOCATED 0x8#define AUDIOENCODERCREATED    0x10#define AUDIODECODERCREATED    0x20#define ENCODEDBUFFERALLOCATED  0x40#define ENGINEOPENED		0x80    unsigned int initMask = 0x0;// used to only cleanup items that were init'ed/*  Input and output driver variables  */    int     inputFd = 0;	// input driver file descriptor (i.e. handle)    int     outputFd = 0;	// output driver file descriptor (i.e. handle)    int     blksize = BLOCKSIZE;// raw input or output frame size    char   *inputBuffer = NULL;	// input buffer for driver to read into    char   *outputBuffer = NULL;// output buffer for driver to read from    int     vol = LEFT_GAIN | (RIGHT_GAIN << 8);  // volume setting    int     i; 			// loop counter to initialize output buffer/*  Intermediate buffer for encoded audio */    char   *encodedBuffer   = NULL;  // pointer to encoded buffer    int     encodedSize = 0;	// size of encoded buffer (numbytes specifies				//     how full it is, numbytes < encodedSize)    int     numbytes;		// number of bytes in an encoded frame/*  Codec engine variables */    Engine_Handle engineHandle = NULL;	 // handle to the engine    AUDENC_Handle encoderHandle = NULL;	// handle to audio encoder     AUDDEC_Handle decoderHandle = NULL;	// handle to audio decoder    /* Thread Create Phase -- secure and initialize resources */    /* Open an OSS device channel for audio input */    if(audio_input_setup(&inputFd, SOUND_DEVICE, MIXER_DEVICE, 			SOUND_MASK_LINE, vol, SAMPLE_RATE, &blksize)			== AUDIO_FAILURE){        ERR("audio_input_setup failed in audio_thread_fxn\n\n");	status = AUDIO_THREAD_FAILURE;	goto cleanup;    }    /* Record that input OSS device was opened in initialization bitmask */    initMask |= INPUT_OSS_INITIALIZED;    /*  Create output buffer to write from into OSS output device */    if((inputBuffer = malloc(blksize)) == NULL) {        ERR("Failed to allocate memory for input block (%d)\n", blksize);	status = AUDIO_THREAD_FAILURE;	goto cleanup;    }    DBG("Allocated input audio buffer of size %d to address %p\n", 						blksize, inputBuffer);    /* Record that the output buffer was allocated in initialization bitmask */    initMask |= INPUT_BUFFER_ALLOCATED;    /* open the codec engine */    /* note: codec engine should be opened in each thread that uses it */    if(engine_setup(&engineHandle,envPtr->engineName,NULL) != ENGINE_SUCCESS){	ERR("engine_setup failed in audio_thread_fxn\n");	status = AUDIO_THREAD_FAILURE;	goto cleanup;    }    /* Allocate and initialize audio encoder on the engine */    /*     uses engineHandle global variable assumed set before entry */    if(audio_encoder_setup(engineHandle, AUDIO_ENCODER, &encoderHandle) 				== AENC_FAILURE) {	ERR("audio_encoder_setup failed in audio_thread_fxn\n");	status = AUDIO_THREAD_FAILURE;	goto cleanup;    }    initMask |= AUDIOENCODERCREATED;    /* Allocate and initialize audio decoder on the engine */    if(audio_decoder_setup(engineHandle, AUDIO_DECODER, &decoderHandle) 				== ADEC_FAILURE) {	ERR("audio_decoder_setup failed in audio_thread_fxn\n");	status = AUDIO_THREAD_FAILURE;	goto cleanup;    }    initMask |= AUDIODECODERCREATED;    /* Initialize the output OSS device                                       */    if(audio_output_setup(&outputFd, SOUND_DEVICE, SAMPLE_RATE)			== AUDIO_FAILURE){        ERR("audio_output_setup failed in audio_thread_fxn\n");	status = AUDIO_THREAD_FAILURE;	goto cleanup;    }    /* Record that input OSS device was opened in initialization bitmask */    initMask |= OUTPUT_OSS_INITIALIZED;    /*  Create output buffer to write from into OSS output device */    if((outputBuffer = malloc(blksize)) == NULL) {        ERR("Failed to allocate memory for output block (%d)\n", blksize);	status = AUDIO_THREAD_FAILURE;	goto cleanup;    }    DBG("Allocated output audio buffer of size %d to address %p\n", 						blksize, outputBuffer);    /* Record that the output buffer was allocated in initialization bitmask */    initMask |= OUTPUT_BUFFER_ALLOCATED;    /*  Create encoded buffer to store encoded audio */    /*  If copy codec is used, encoded buffer is the same size as raw buffer */    /*       and real codecs will have smaller encoded sizes than this       */    encodedSize = blksize;    if ((encodedBuffer = malloc(encodedSize)) == NULL) {        ERR("Failed to allocate memory for output block (%d)\n", blksize);	status = AUDIO_THREAD_FAILURE;	goto cleanup;    }    initMask |= ENCODEDBUFFERALLOCATED;    DBG("Allocated intermediate audio buffer of size %d\n", blksize);    DBG("\tto address %p\n", encodedBuffer);    /* Write two buffers into OSS output device for some room to work */    /*     once the driver begins output, a starvation condition      */    /*     will lock the driver up!!!                                 */    for (i=0; i<blksize; i++){	outputBuffer[i] = 0;    }    if (write(outputFd, outputBuffer, blksize) == -1) {        ERR("Error writing the data to file descriptor %d\n", outputFd);	status = AUDIO_THREAD_FAILURE;	goto cleanup;    }     if (write(outputFd, outputBuffer, blksize) == -1) {        ERR("Error writing the data to file descriptor %d\n", outputFd);	status = AUDIO_THREAD_FAILURE;	goto cleanup;    }    /* Thread Execute Phase -- perform I/O and processing */    DBG("Entering audio_thread_fxn processing loop\n");    while (!envPtr->quit){	/*  Reverb variables */	short *shBufPtr = NULL;	// Audio data is 16-bit, so helps to recast	short *shRevPtr = NULL;	// Audio data is 16-bit, so helps to recast#define REVERB_SIZE 11024#define REV_FACTOR 0.5    	/* REVERB_SIZE must be >= blksize (3072) and even */    	/* REVERB_SIZE of 5512-11024, REV_FACTOR 0.5 tends to thicken music */    	/* REVERB_SIZE of 44100, REV_FACTOR 0.8 tends to make your music    */    	/*      sound like the theme to "halloween"                         */    	char    reverbBuffer[REVERB_SIZE];// Previous data for reverb	/*  Read input buffer from OSS input device */        if ((int) read(inputFd, inputBuffer, blksize) < blksize) {            ERR("Error reading the data from file descriptor %d\n", inputFd);	    status = AUDIO_THREAD_FAILURE;	    goto cleanup;        }	/* Set short pointers to buffer locations */	shBufPtr = (short *) inputBuffer;	shRevPtr = (short *) reverbBuffer;	/* Multiply delayed values by REV_FACTOR and add into input stream */	/* Divide by 1+REV_FACTOR to maintain gain of 1 */	for(i=0;i<(blksize>>1);i++){	    shBufPtr[i] = (int)((float)shBufPtr[i] / (float)(1.0 +REV_FACTOR));	    shBufPtr[i] += (int)((float)shRevPtr[i]*(float)REV_FACTOR / 						     (float)(1.0 +REV_FACTOR));	}	/* Maintain the delay line by moving old values down and adding */	/*    input buffer to the top.  Note, this code assumes that    */	/*    REVERB_SIZE > blksize, otherwise, it will break!          */	memcpy(reverbBuffer, reverbBuffer + blksize, REVERB_SIZE - blksize);	memcpy(reverbBuffer + REVERB_SIZE - blksize, inputBuffer, blksize);	/* On input to encode_audio, this value is size of encodedBuffer */	numbytes = encodedSize;        /* Encode the buffer */        if (encode_audio(encoderHandle, inputBuffer, blksize, 					encodedBuffer, &numbytes) 			== AENC_FAILURE) {	    ERR("Error encoding audio data (encoder handle %p)\n",							encoderHandle);            status = AUDIO_THREAD_FAILURE;	    break;        }        /* Decode the buffer */        if (decode_audio(decoderHandle, encodedBuffer, numbytes, 					outputBuffer, blksize) 			== ADEC_FAILURE) {	    ERR("Error decoding audio data (decoder handle %p)\n",							decoderHandle);            status = AUDIO_THREAD_FAILURE;	    break;        }	/* Write output buffer into OSS output device */        if (write(outputFd, outputBuffer, blksize) == -1) {            ERR("Error writing the data to file descriptor %d\n", outputFd);	    status = AUDIO_THREAD_FAILURE;	    goto cleanup;        }    }cleanup:    DBG("Exited audio_thread_fxn processing loop\n");    DBG("Starting audio thread cleanup to return resources to system\n");    /* Thread Delete Phase -- clean up resources used */    /* Use the initMask to only free resources that were allocated */    /* Nothing to be done for mixer device, it was closed after init */    /* Note the OSS output device must be closed before anything else */    /*      if this driver expends it's backlog of data before it is  */    /*      closed, it will lock up the application.                  */    /* Close output OSS device */    if(initMask & OUTPUT_OSS_INITIALIZED)	if(audio_output_cleanup(outputFd) != AUDIO_SUCCESS) {	    ERR("audio_output_cleanup failed for file descriptor %d\n", 							outputFd);	    status = AUDIO_THREAD_FAILURE;	}    /* Free output buffer */    if(initMask & OUTPUT_BUFFER_ALLOCATED){        DBG("Freed audio output buffer at location %p\n", outputBuffer);	free(outputBuffer);    }    /* Close input OSS device */    if(initMask & INPUT_OSS_INITIALIZED)	if(audio_input_cleanup(inputFd) != AUDIO_SUCCESS) {	    ERR("audio_output_cleanup failed for file descriptor %d\n", 							inputFd);	    status = AUDIO_THREAD_FAILURE;	}    /* Delete audio decoder */    if (initMask & AUDIODECODERCREATED)        if( audio_decoder_cleanup(decoderHandle) != ADEC_SUCCESS ) {	    ERR("audio_decoder_cleanup failed\n");	    status = AUDIO_THREAD_FAILURE;	}    /* Delete audio encoder */    if (initMask & AUDIOENCODERCREATED)         if( audio_encoder_cleanup(encoderHandle) != AENC_SUCCESS ) {	    ERR("audio_encoder_cleanup failed\n");	    status = AUDIO_THREAD_FAILURE;	}    /* Close the engine */    if (initMask & ENGINEOPENED){	engine_cleanup(engineHandle);    }    /* Free input buffer */    if(initMask & INPUT_BUFFER_ALLOCATED){        DBG("Freed audio input buffer at location %p\n", inputBuffer);	free(inputBuffer);    }    /* Free intermediate (encoded) buffer */    if (initMask & ENCODEDBUFFERALLOCATED) {        DBG("Freed intermediate audio buffer at %p\n", encodedBuffer);        free(encodedBuffer);    }    /* Return the status of the thread execution */    DBG("Audio thread cleanup complete. Exiting audio_thread_fxn\n");    return status;}

⌨️ 快捷键说明

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