
3.2 Алгоритм работы функции Bending()
Шаг 1. Определение значения переменной с помощью заданной таблицы синусов, val = sinTab[k%12].
Шаг 2. Выполнение прямого преобразования Фурье над входным массивом x[N].
Шаг 3. Анализ знака val: если значение val ≥ 0, переходим на Шаг 4, если val < 0, переходим на Шаг 6.
Шаг 4. Заполнение первых val элементов выходного массива y[] нулями.
Шаг 5. Заполнение оставшихся элементов массива y[] первыми N/2 – val элементами массива x[]. Переход на Шаг 8.
Шаг 6. Заполнение первых N/2 – val элементов выходного массива y[] последними N/2 – val элементами массива x[].
Шаг 7. Заполнение оставшихся val элементов массива y[] нулями.
Шаг 8. Выполнение обратного преобразования Фурье над выходным массивом y[].
4 Практическая часть
Программа имеет вхождение в главной функции main.c, где вызывается функция aic3204_loop_stereo_in1.c. Эта функция настраивает AIC3204 и, получая отсчеты в канале stereo_in1 подает их на канал headphone.
Код программы:
#include "stdio.h"
#include "evm5515.h"
#include "Dsplib.h"
#include "math.h"
#define Rcv 0x08
#define Xmit 0x20
#define NX 1024 // number of points to FFT
/* Extern functions of DSPLib – needed for FFT and IFFT */
extern void rfft(DATA* , ushort, type);
extern void rifft(DATA* , ushort, type);
extern Int16 AIC3204_rset( Uint16 regnum, Uint16 regval);
void Bending(DATA *in, DATA *out, Int16 sin*, Int16 N, Int16 k);
/* Arrays for input, output channels and table of sines. */
DATA in1[NX];
DATA in2[NX];
DATA out1[NX];
DATA out2[NX];
Int16 sinTab[12] = {1, 2, 3, 2, 1, 0, -1, -2, -3, -2, -1, 0 };
/* Output input from STEREO IN 1 through the HEADPHONE jack */
Int16 aic3204_loop_stereo_in1( )
{
/* Pre-generated sine wave data, 16-bit signed samples */
Int16 data1, data2;
/* -----------------------------------------------------------*
* * * Configure AIC3204 ** CODEC_CLKIN = PLL CLK * * CODEC_CLKIN = NADC * MADC * AOSR * ADCFS *
* PLL_CLK = PLL_CLKIN * R * J.D / P *
* PLL_CLKIN = BCLK = 1.536MHz *
* ADCFS = 48KHz *
* ---------------------------------------------------------------------------------------- */
AIC3204_rset( 0, 0x00 ); // Select page 0
AIC3204_rset( 1, 0x01 ); // Reset codec
AIC3204_rset( 0, 0x01 ); // Select page 1
AIC3204_rset( 0, 0x08 ); // Disable crude AVDD generation from DVDD
AIC3204_rset( 2, 0x00 ); // Enable Analog Blocks
// PLL and Clocks config and Power Up
AIC3204_rset( 0, 0x00 ); // Select page 0
AIC3204_rset( 27, 0x00 ); // BCLK and WCLK is set as i/p to AIC3204(Slave)
AIC3204_rset( 4, 0x07 ); // PLL setting: PLLCLK <- BCLK and CODEC_CLKIN <-PLL CLK
AIC3204_rset( 6, 0x20 ); // PLL setting: J = 32
AIC3204_rset( 7, 0 ); // PLL setting: HI_BYTE(D)
AIC3204_rset( 8, 0 ); // PLL setting: LO_BYTE(D)
// For 8 KHz sampling
AIC3204_rset( 5, 0x92 ); // PLL setting: Power up PLL, P=1 and R=2
AIC3204_rset( 13, 0x00 ); // Hi_Byte(DOSR) for DOSR = 128 decimal or //0x0080 DAC oversamppling
AIC3204_rset( 14, 0x80 ); // Lo_Byte(DOSR) for DOSR = 128 decimal or 0x0080
AIC3204_rset( 20, 0x80 ); // AOSR for AOSR = 128 decimal or 0x0080 for decimation filters 1 to 6
AIC3204_rset( 11, 0x84 ); // Power up NDAC and set NDAC value to 4
AIC3204_rset( 12, 0x82 ); // Power up MDAC and set MDAC value to 2
AIC3204_rset( 18, 0x84 ); // Power up NADC and set NADC value to 4
AIC3204_rset( 19, 0x82 ); // Power up MADC and set MADC value to 2
// DAC ROUTING and Power Up
AIC3204_rset( 0, 0x01 ); // Select page 1
AIC3204_rset( 12, 0x08 ); // LDAC AFIR routed to HPL
AIC3204_rset( 13, 0x08 ); // RDAC AFIR routed to HPR
AIC3204_rset( 0, 0x00 ); // Select page 0
AIC3204_rset( 64, 0x02 ); // Left vol=right vol
AIC3204_rset( 65, 0x00 ); // Left DAC gain to 0dB VOL; Right tracks Left
AIC3204_rset( 63, 0xd4 ); // Power up left,right data paths and set channel
AIC3204_rset( 0, 0x01 ); // Select page 1
AIC3204_rset( 16, 0x00 ); // Unmute HPL , 0dB gain
AIC3204_rset( 17, 0x00 ); // Unmute HPR , 0dB gain
AIC3204_rset( 9, 0x30 ); // Power up HPL,HPR
AIC3204_rset( 0, 0x00 ); // Select page 0
EVM5515_wait( 500 ); // Wait
// ADC ROUTING and Power Up
AIC3204_rset( 0, 0x01 ); // Select page 1
AIC3204_rset( 52, 0x30 ); // STEREO 1 Jack
// IN2_L to LADC_P through 40 kohm
AIC3204_rset( 55, 0x30 ); // IN2_R to RADC_P through 40 kohmm
AIC3204_rset( 54, 0x03 ); // CM_1 (common mode) to LADC_M through 40 kohm
AIC3204_rset( 57, 0xC0 ); // CM_1 (common mode) to RADC_M through 40 kohm
AIC3204_rset( 59, 0x0f ); // MIC_PGA_L unmute
AIC3204_rset( 60, 0x0f ); // MIC_PGA_R unmute
AIC3204_rset( 0, 0x00 ); // Select page 0
AIC3204_rset( 81, 0xc0 ); // Powerup Left and Right ADC
AIC3204_rset( 82, 0x00 ); // Unmute Left and Right ADC
AIC3204_rset( 0, 0x00 );
EVM5515_wait( 200 ); // Wait
/* I2S settings */
I2S2_SRGR = 0x0015;
I2S2_ICMR = 0x0028; // Enable interrupts
I2S2_CR = 0x8012; // 16-bit word, Master, enable I2C
/* Play Tone */
for (i = 0; i < NX; i++) {
in1[i] = 0;
in2[i] = 0;
out1[i] = 0;
out2[i] = 0;
}
for ( k = 0 ; k < 10000 ; t++ )
{
for (i = 0 ; i < NX; i++ )
{
/* Read Digital audio */
while((Rcv & I2S2_IR) == 0);// Wait for receive interrupt //to be pending
data1 = I2S2_W0_MSW_R;
// 16 bit left channel received audio data
data2 = I2S2_W1_MSW_R;
// 16 bit right channel received audio data
in1[i] = data1;
in2[i] = data2;
}
Bending(in1, out1, sinTab, NX, k);
Bending(in2, out2, sinTab, NX, k);
for (i = 0 ; i < NX; i++ ) {
while((Xmit & I2S2_IR) == 0); // Wait for receive interrupt to be pending
I2S2_W0_MSW_W = out1[i]; // 16 bitleft channel transmit audio data
I2S2_W1_MSW_W = out2[i]; // 16 bit right channel transmit audio data
}
/* Disble I2S */
I2S0_CR = 0x00;
return 0;
}
void Bending(DATA *in, DATA *out, Int16 sin*, Int16 N, Int16 k)
{
Int15 val = 0;
val = sin[k%12];
rfft(in, N, NOSCALE);
if(val >= 0) {
for (i = 0; i < val, i++) {
out[i] = 0;
for (i = 0; i < N/2 - val; i++)
out[i + val] = in[i]
} else {
For(i = 0; i < N/2 – val; i++)
out[i] = in[i+val];
For(i = 0; i < val; i++)
out[N/2 – val + i] = 0;
rifft(out, N/2, NOSCALE);
}