thraudioproc.c
来自「DSP体系结构实现与应用源代码」· C语言 代码 · 共 329 行
C
329 行
/*
* Copyright 2003 by Texas Instruments Incorporated.
* All rights reserved. Property of Texas Instruments Incorporated.
* Restricted rights to use, duplicate or disclose this code are
* granted through contract.
*
*/
/* "@(#) ReferenceFrameworks 2.20.00.08 07-18-03 (swat-f02)" */
/*
* ======== thrAudioproc.c ========
*
* Static and dynamic initialization of thread Audioproc,
* and its runtime procedure
*/
#include <std.h>
#include <pip.h>
#include <utl.h> /* debug/diagnostics utility functions */
#include <dsplib.h>
#include <intrindefs.h>
#include "appResources.h" /* application-wide common info */
#include "appThreads.h" /* thread-wide common info */
#include "vol.h" /* interface for VOL algorithm */
#include "thrAudioproc.h" /* definition of thrAudioproc objects */
// 5 band FIR equalizer
Void FIR_equalizer(DATA *in, DATA *out);
// declaration of the data buffers used in the fir() in dsplib
#pragma DATA_SECTION(dataBuf0, ".dataBuf0");
#pragma DATA_SECTION(dataBuf1, ".dataBuf1");
#pragma DATA_SECTION(dataBuf2, ".dataBuf2");
#pragma DATA_SECTION(dataBuf3, ".dataBuf3");
#pragma DATA_SECTION(dataBuf4, ".dataBuf4");
DATA dataBuf0[FILTORDER0];
DATA dataBuf1[FILTORDER1];
DATA dataBuf2[FILTORDER2];
DATA dataBuf3[FILTORDER3];
DATA dataBuf4[FILTORDER4];
// pointers to the delay buffers for fir()
DATA *dbptr0 = &dataBuf0[0];
DATA *dbptr1 = &dataBuf1[0];
DATA *dbptr2 = &dataBuf2[0];
DATA *dbptr3 = &dataBuf3[0];
DATA *dbptr4 = &dataBuf4[0];
// filter coefficients used in the 5 band equalizer
#pragma DATA_SECTION(filterBand0, ".filterBand0");
#pragma DATA_SECTION(filterBand1, ".filterBand1");
#pragma DATA_SECTION(filterBand2, ".filterBand2");
#pragma DATA_SECTION(filterBand3, ".filterBand3");
#pragma DATA_SECTION(filterBand4, ".filterBand4");
#pragma DATA_SECTION(audioBuffer, ".audioBuffer");
DATA audioBuffer[FRAMELEN * NUMBANDS];
DATA filterBand0[FILTORDER0] = {
-212, -6, 82, 211, 340, 420, 408, 285, 71,
-175, -371, -436, -327, -58, 291, 594, 720, 576,
160, -430, -1001, -1318, -1171, -445, 828, 2461, 4147,
5535, 6317, 6317, 5535, 4147, 2461, 828, -445, -1171,
-1318, -1001, -430, 160, 576, 720, 594, 291, -58,
-327, -436, -371, -175, 71, 285, 408, 420, 340,
211, 82, -6, -212
};
DATA filterBand1[FILTORDER1] = {
-132, 254, 281, 141, -83, -152, -45, -32, -270,
-448, -101, 676, 1101, 546, -577, -1148, -661, 105,
109, -444, -201, 1399, 2785, 1663, -1996, -5036, -4002,
941, 5560, 5560, 941, -4002, -5036, -1996, 1663, 2785,
1399, -201, -444, 109, 105, -661, -1148, -577, 546,
1101, 676, -101, -448, -270, -32, -45, -152, -83,
141, 281, 254, -132
};
DATA filterBand2[FILTORDER2] = {
159, 287, -258, -170, 182, 132, -67, 64, -184,
-355, 500, 667, -778, -873, 877, 831, -668, -437,
83, -332, 849, 1392, -1990, -2559, 3119, 3592, -3991,
-4260, 4404, 4404, -4260, -3991, 3592, 3119, -2559, -1990,
1392, 849, -332, 83, -437, -668, 831, 877, -873,
-778, 667, 500, -355, -184, 64, -67, 132, 182,
-170, -258, 287, 159
};
DATA filterBand3[FILTORDER3] = {
332, -195, -63, 313, -289, 47, 80, 44, -115,
-201, 680, -642, -179, 1095, -1122, 189, 678, -611,
61, -204, 1151, -1379, -437, 3210, -3899, 793, 3965,
-5922, 2813, 2813, -5922, 3965, 793, -3899, 3210, -437,
-1379, 1151, -204, 61, -611, 678, 189, -1122, 1095,
-179, -642, 680, -201, -115, 44, 80, 47, -289,
313, -63, -195, 332
};
DATA filterBand4[FILTORDER4] = {
-240, 191, -189, 121, 8, -169, 313, -385, 349,
-200, -23, 245, -380, 360, -166, -155, 499, -728,
725, -437, -89, 701, -1179, 1290, -861, -152, 1638,
-3343, 4925, -6044, 6447, -6044, 4925, -3343, 1638, -152,
-861, 1290, -1179, 701, -89, -437, 725, -728, 499,
-155, -166, 360, -380, 245, -23, -200, 349, -385,
313, -169, 8, 121, -189, 191, -240
};
/*
* Initialization of the thread resources structure:
* NULL for algorithm handles, addresses of appropriate
* pipe objects for input and output pipes,
* NULL for globally visible temporary pointers to pipe frames,
* addresses of intermediate buffers for this thread,
* and everything else thread-specific.
*/
ThrAudioproc thrAudioproc[ NUMCHANNELS ] = {
{ /* channel #0 */
/* algorithm handle(s) (to be initialized in runtime) */
{NULL, NULL, NULL, NULL, NULL}, /* algVOL */
/* input pipe(s) */
&pipRx, /* pipIn */
/* output pipe(s) */
&pipTx, /* pipOut */
/* buffer(s) */
{bufAudioproc0, bufAudioproc1, bufAudioproc2, bufAudioproc3, bufAudioproc4}
/* everything else private for the thread */
}, /* end channel # 0 */
};
/*
* Dynamic part of thread initialization
*/
/*
* ========= thrAudioprocInit ========
* Initialization of data structures for the thread(s), called from
* appThreads.c:thrInit() at init time.
*
* Here we create one instance of FIR algorithm per channel and
* one instance of VOL algorithm per channel. In a loop, we create
* parameters for algorithm instance for each channel by using the
* default parameters and modifying fields that are different.
* (If the parameters are the same across channels, they can be
* created outside of the loop.)
*/
Void thrAudioprocInit( Void )
{
/* declaration of volume parameter structure */
VOL_Params volParams;
Int i;
Int j;
// reset the data buffers for the filters
/*for (i = 0; i < FILTORDER4; i++) {
if(i < FILTORDER0){
dataBuf0[i] = 0;
dataBuf1[i] = 0;
dataBuf2[i] = 0;
dataBuf3[i] = 0;
}
dataBuf4[i] = 0;
}*/
for (i = 0; i < NUMCHANNELS; i++) {
/*create parameters structure for VOL algorithm*/
for ( j = 0; j < NUMBANDS; j++ ) {
volParams = VOL_PARAMS; /* default parameters */
volParams.frameSize = FRAMELEN; /* size in samples */
volParams.gainPercentage = 0; /* default gain */
/* create instance, confirm creation success, show memory usage */
thrAudioproc[i].algVOL[j] = VOL_create( &VOL_IVOL, &volParams );
UTL_assert( thrAudioproc[i].algVOL[j] != NULL );
UTL_showAlgMem( thrAudioproc[i].algVOL[j] );
}
}
}
/*
* Runtime thread code, invoked by the appropriate SWI object
* every time the object is posted
*/
/*
* ========= thrAudioprocRun ========
* The "body" of the swiAudioproc0, swiAudioproc1,... threads.
*
* The single argument of this function is the channel number:
* 0, 1, 2 etc. up to NUM_CHANNELS - 1. All the SWI objects
* that invoke this function pass the channel number as the
* argument.
*
* Based on the channel number, the thread -- the procedure --
* decides which thread resource object to access.
*/
Void thrAudioprocRun( Arg aChan )
{
DATA *src;
DATA *dst;
Int size; /* in samples */
Int chan;
/*
* cast 'Arg' types to 'Int'. This is required on 55x large data model
* since Arg is not the same size as Int and Ptr in that model.
* On all other devices (54x, 55x small, 6x) ArgToInt is a simple cast
*/
chan = ArgToInt( aChan );
/*
* Check that the preconditions are met, that is the in-pipe
* has a ready-to-consume buffer of data and the out-pipe
* has a free buffer, in other words that this thread has
* not been posted in error.
*/
UTL_assert( PIP_getReaderNumFrames( thrAudioproc[chan].pipIn ) > 0 );
UTL_assert( PIP_getWriterNumFrames( thrAudioproc[chan].pipOut ) > 0 );
/* get the full buffer from the input pipe */
PIP_get( thrAudioproc[chan].pipIn );
src = (DATA *)PIP_getReaderAddr( thrAudioproc[chan].pipIn );
/* get the size in samples (the function below returns it in words) */
size = sizeInSamples( PIP_getReaderSize( thrAudioproc[chan].pipIn ) );
/* get the empty buffer from the out-pipe */
PIP_alloc( thrAudioproc[chan].pipOut );
dst = (DATA *)PIP_getWriterAddr( thrAudioproc[chan].pipOut );
// Start measuring execution time
UTL_stsStart(stsTime0);
// perform the 5 band FIR equalization operation
FIR_equalizer(src, dst);
// Stop measuring execution time
UTL_stsStop(stsTime0);
/* Record the amount of actual data being sent */
PIP_setWriterSize( thrAudioproc[chan].pipOut, sizeInWords( size ) );
/* Free the receive buffer, put the transmit buffer */
PIP_free( thrAudioproc[chan].pipIn );
PIP_put ( thrAudioproc[chan].pipOut );
}
/*
* ========= thrAudioprocSetOutputVolume ========
* Procedure that changes output volume for an Audioproc thread
*
* This procedure is called from the likes of the Control thread.
* Instead of having the control thread directly write to
* thread Audioproc's variables, it calls this function which
* changes the state of the VOL algorithm instance for the
* given channel.
*/
Void thrAudioprocSetOutputVolume( Int chan, Int *volume )
{
/* VOL algorithm control structure */
IVOL_Status status;
Int i;
UTL_assert( chan < NUMCHANNELS ); /* sanity checking */
/*
* Apply volume gain information to the appropriate alg. instance.
* Retrieve the current parameters, change the fields that need
* to be changed, and apply the new parameters. Volume gain is
* a percentage, a number from 0 to 200, 100 being the normal
* volume (100%).
*/
for(i=0; i<NUMBANDS; i++) {
VOL_control( thrAudioproc[ chan ].algVOL[i], IVOL_GETSTATUS, &status );
status.gainPercentage = volume[i];
VOL_control( thrAudioproc[ chan ].algVOL[i], IVOL_SETSTATUS, &status );
}
}
/*
* ========= FIR_equalizer ========
*
* This function performs the audio equalization operation.
* 5 bands of equalizer settings are made available to the
* user via the GEL menu. This equalizer is implemented
* with the fir() from TI DSPLIB.
*/
Void FIR_equalizer(DATA *in, DATA *out){
DATA *audioOut0 = &audioBuffer[0];
DATA *audioOut1 = &audioBuffer[FRAMELEN];
DATA *audioOut2 = &audioBuffer[FRAMELEN * 2];
DATA *audioOut3 = &audioBuffer[FRAMELEN * 3];
DATA *audioOut4 = &audioBuffer[FRAMELEN * 4];
Int i;
// perform the fir filtering for the 5 frequency bands
fir(in,filterBand0, thrAudioproc[0].bufInterm[0], &dbptr0, FILTORDER0, FRAMELEN);
fir(in,filterBand1, thrAudioproc[0].bufInterm[1], &dbptr1, FILTORDER1, FRAMELEN);
fir(in,filterBand2, thrAudioproc[0].bufInterm[2], &dbptr2, FILTORDER2, FRAMELEN);
fir(in,filterBand3, thrAudioproc[0].bufInterm[3], &dbptr3, FILTORDER3, FRAMELEN);
fir(in,filterBand4, thrAudioproc[0].bufInterm[4], &dbptr4, FILTORDER4, FRAMELEN);
// amplify the signal in the interm. buffer and store result in dst
VOL_apply( thrAudioproc[0].algVOL[0], thrAudioproc[0].bufInterm[0], audioOut0 );
VOL_apply( thrAudioproc[0].algVOL[1], thrAudioproc[0].bufInterm[1], audioOut1 );
VOL_apply( thrAudioproc[0].algVOL[2], thrAudioproc[0].bufInterm[2], audioOut2 );
VOL_apply( thrAudioproc[0].algVOL[3], thrAudioproc[0].bufInterm[3], audioOut3 );
VOL_apply( thrAudioproc[0].algVOL[4], thrAudioproc[0].bufInterm[4], audioOut4 );
// Start measuring execution time
//UTL_stsStart(stsTime1);
// sum the 5 bands of audio signals together to obtain the processed audio signal
for ( i = 0; i < FRAMELEN; i++ ){
out[i] = _sadd(audioOut0[i], audioOut1[i]);
out[i] = _sadd(out[i], audioOut2[i]);
out[i] = _sadd(out[i], audioOut3[i]);
out[i] = _sadd(out[i], audioOut4[i]);
out[i] = out[i] & 0xfffe;
}
// Stop measuring execution time
//UTL_stsStop(stsTime1);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?