📄 realtime_dspbios.c
字号:
//
// Project: Experiment 5.7.6: DSP/BIOS implementation of IIR filter in real-time - Chapter 5
// File name: realtime_DSPBIOS.c
//
// Description: This is the test program for the real-time IIR filtering using DSPBIOS
//
// For the book "Real Time Digital Signal Processing:
// Implementation and Application, 2nd Ed"
// By Sen M. Kuo, Bob H. Lee, and Wenshun Tian
// Publisher: John Wiley and Sons, Ltd
// Tools used: CCS v.2.12.07
// TMS320VC5510 DSK Rev-C
//
//
//
// This example demonstrates the use of LIO drivers with PIPs and the
// lio_pip adapter code.
//
// The application performs IIR filter loopback in real-time, that
// reads audio data from rx PIP connected to an input LIO channel,
// the data is filtered by and then written back out to a PIP connected
// to an output LIO channel.
//
// The following objects need to be created in the DSP/BIOS
// configuration for this application:
//
// 1 A SWI object named swiAudioProcess.
// Configure the function as _audioProcess and the mailbox value as 3.
//
// 2 Two PIP objects, one named pipTx, the other pipRx. The length of the
// buffers should be the same and. Our example requires 128.
// See the comments by the declarations below of pipTx and pipRx for the
// writer and reader notify function settings.
//
#include <std.h>
#include <pip.h>
#include <swi.h>
#include <sys.h>
#include <lio.h>
#include <plio.h>
#include "dsk5510_led.h"
// Set CONTROLLER_FXN_TABLE in the linker command file
#define CONTROLLER_FXN_TABLE DSK5510_DMA_AIC23_ILIO
extern LIO_Fxns CONTROLLER_FXN_TABLE;
static LIO_Fxns *controller = &CONTROLLER_FXN_TABLE;
extern PIP_Obj pipRx; // writerNotify -> PLIO_rxPrime(plioRx)
// readerNotify -> SWI_andn(swiEcho,1)
extern PIP_Obj pipTx; // writerNotify -> SWI_andn(swiEcho,2)
// readerNotify -> PLIO_txPrime(plioTx)
// 'plioRx' and 'plioTx' objects will be initialized by PLIO_new().
PLIO_Obj plioRx, plioTx;
// Codec configuration settings
#include "dsk5510_aic23.h"
DSK5510_AIC23_Config config = { \
0x0017, /* 0 DSK5510_AIC23_LEFTINVOL Left line input channel volume */ \
0x0017, /* 1 DSK5510_AIC23_RIGHTINVOL Right line input channel volume */\
0x01f9, /* 2 DSK5510_AIC23_LEFTHPVOL Left channel headphone volume */ \
0x01f9, /* 3 DSK5510_AIC23_RIGHTHPVOL Right channel headphone volume */ \
0x0010, /* 4 DSK5510_AIC23_ANAPATH Analog audio path control */ \
0x0000, /* 5 DSK5510_AIC23_DIGPATH Digital audio path control */ \
0x0000, /* 6 DSK5510_AIC23_POWERDOWN Power down control */ \
0x0043, /* 7 DSK5510_AIC23_DIGIF Digital audio interface format */ \
0x008D, /* 8 DSK5510_AIC23_SAMPLERATE Sample rate control */ \
0x0001 /* 9 DSK5510_AIC23_DIGACT Digital interface activation */ \
};
// IIR filter related variables
#include "asmIIR.h"
#include "fdacoefsMATLAB.h"
#define SECTIONS ((MWSPT_NSEC-1)/2) // Number of 2nd order sections
short C[SECTIONS*5]; // Filter coefficients obtained from example 5.14 MATLAB FDATool
// C[]=A[i][1], A[i][2], B[i][2], B[i][0], B[i][1]...
short w[SECTIONS*2]; // Filter delay line
// w[]=w[i][n-1],w[i+1][n-1],...,w[i][n-2],w[i+1][n-2],...
#define SIZE 128 // This size must be the same as the PIP of the DSP/BIOS setting
// for stereo settings
short in[SIZE/2],out[SIZE/2]; // SIZE/2 is due to we only work on a single channel
void main()
{
short i,k,n;
short gainNUM,gainDEN;
long temp32;
// Initializes the AIC23 device
DSK5510_DMA_AIC23_init();
// AIC23 configures, if parameter is NULL
// Open AIC23 for 8 kHz sampling rate, Line-in, 16-bit data
DSK5510_AIC23_openCodec(0, &config);
// Link the PIPs to LIO channels
PLIO_new(&plioRx, &pipRx, LIO_INPUT, controller, NULL);
PLIO_new(&plioTx, &pipTx, LIO_OUTPUT, controller, NULL);
//
// Prime the transmit side with buffers of silence.
// The transmitter should be started before the receiver.
// This results in input-to-output latency being one full
// buffer period if the pipes is configured for 2 frames.
//
PLIO_txStart(&plioTx, PIP_getWriterNumFrames(&pipTx), 0);
// Prime the receive side with empty buffers to be filled.
PLIO_rxStart(&plioRx, PIP_getWriterNumFrames(&pipRx));
// Initialize IIR filter delay line
for (i=0; i<SECTIONS*2;i++)
{
w[i] = 0;
}
// Get coefficients from DEN[][] and NUM[][]
for(k=0, n=0, i=0; i<SECTIONS; i++)
{
gainDEN = DEN[k][0];
gainNUM = NUM[k++][0];
temp32 = (long)gainDEN * DEN[k][1];
C[n++] = (short)(temp32>>14);
temp32 = (long)gainDEN * DEN[k][2];
C[n++] = (short)(temp32>>14);
temp32 = (long)gainNUM * NUM[k][2];
C[n++] = (short)(temp32>>14);
temp32 = (long)gainNUM * NUM[k][0];
C[n++] = (short)(temp32>>14);
temp32 = (long)gainNUM * NUM[k++][1];
C[n++] = (short)(temp32>>14);
}
}
//
// This function (swiAudioProcess) is executed from DSP/BIOS SWI thread
// created statically with the DSP/BIOS configuration tool.
//
// The PLIO adapter posts the swi when an input PIP has a buffer of data
// and the output PIP has an empty buffer to put new data into.
//
// This function passes the input PIP to the sample rate convertor for
// sample rate decimation, process, and interpolation, and then places the
// processed and interpolated samples to output PIP.
//
Void audioProcess(Void)
{
short *src, *dst, size, i;
// Get the full rx buffer from the receive PIP
PIP_get(&pipRx);
src = PIP_getReaderAddr(&pipRx);
size = PIP_getReaderSize(&pipRx) * sizeof(short);
// Get the empty tx buffer from the transmit PIP
PIP_alloc(&pipTx);
dst = PIP_getWriterAddr(&pipTx);
// Since we are single IIR, we only use one channel data
// the size represents stereo, so we divide it by 2.
for(i=0; i<(size>>1); i++)
{
in[i] = *src++; // Get left input channel
src++; // Skip right input channel
}
// Filter a block of samples, size/2 for mono channel IIR
asmIIR(in,(size>>1),out,C,SECTIONS,w);
for(i=0; i<(size>>1); i++)
{
*dst++ = out[i]; // Output to left channel
*dst++ = out[i]; // Copy data to right channel as well
}
// Record the amount of actual data being sent
PIP_setWriterSize(&pipTx, PIP_getReaderSize(&pipRx));
// Free the receive buffer, put the transmit buffer
PIP_free(&pipRx);
PIP_put(&pipTx);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -