Part Number: TMS320C5515
Tool/software: Code Composer Studio
I am developing a audio effect algorithm for "Multiband compressor".
The problem is that the use of float data is prohibited, since the processor does not implement this data type.
Thats why I need to convert it to Q15 format. But I dont know how can I do it. Please help.
#include "C5515.h"
#include "gpio.h"
#include "i2c.h"
#include "i2s.h"
#include "TMS320.h"
#include "stdio.h"
#include "math.h"
#include "dsplib.h"
#include "dsplib_c.h"
#include "aic3204.h"
#define W_LEN 512
#define I 1
#define NH 21
#define EFFECT_FLAG 1
#define NO_EFFECT_FLAG 0
#define IER0 (*(unsigned int*)0x00)
#define IVPD (*(unsigned int*)0x000049)
#define IVPH (*(unsigned int*)0x00004A)
extern unsigned int VECSTART;
/*********Áóôåðû ëåâîãî è ïðàâîãî êàíàëà************/
Int16 b1[W_LEN] = { 0 };
Int16 b2[W_LEN] = { 0 };
Int16 b3[W_LEN] = { 0 };
Int16 b4[W_LEN] = { 0 };
Int16 b5[W_LEN] = { 0 };
Int16 b6[W_LEN] = { 0 };
Int16 b7[W_LEN] = { 0 };
Int16 b8[W_LEN] = { 0 };
Int16* buf_in_left_1 = b1;
Int16* buf_in_right_1 = b2;
Int16* buf_out_left_1 = b3;
Int16* buf_out_right_1 = b4;
Int16* buf_in_left_2 = b5;
Int16* buf_in_right_2 = b6;
Int16* buf_out_left_2 = b7;
Int16* buf_out_right_2 = b8;
Int16* change;
Int16 buf_index = 0;
Int16 effect_flag = NO_EFFECT_FLAG;
/* Îáðàáîò÷èê ïðåðûâàíèÿ ïî ïåðåäà÷å */
interrupt void i2s2_tx_isr()
{
I2S2_W0_MSW_W = buf_out_left_2[buf_index];
I2S2_W1_MSW_W = buf_out_right_2[buf_index];
while ((Rcv & I2S2_IR) == 0);
buf_in_left_2[buf_index] = I2S2_W0_MSW_R;
buf_in_right_2[buf_index] = I2S2_W1_MSW_R;
buf_index++;
if (buf_index >= W_LEN) {
change = buf_in_left_2;
buf_in_left_2 = buf_in_left_1;
buf_in_left_1 = change;
change = buf_out_left_2;
buf_out_left_2 = buf_out_left_1;
buf_out_left_1 = change;
change = buf_in_right_2;
buf_in_right_2 = buf_in_right_1;
buf_in_right_1 = change;
change = buf_out_right_2;
buf_out_right_2 = buf_out_right_1;
buf_out_right_1 = change;
buf_index = 0;
effect_flag = EFFECT_FLAG;
}
}
/*
// 1. to 0-4800
DATA h1[NH] = {
13, 58, 174, 401, 777, 1311, 1969, 2673, 3306,
3748, 3907, 3748, 3306, 2673, 1969, 1311, 777, 401,
174, 58, 13
};
// 2. 5000-5500
DATA h2[NH] = {
1913, -7536, -1914, -389, 84, 119, -67, -194, -116,
87, 199, 87, -116, -194, -67, 119, 84, -389,
-1914, -7536, 1913
};
// 3. 5500-6000
DATA h3[NH] = {
5388, -4079, -2986, -2035, -1211, -730, -634, -657, -516,
-227, -81, -227, -516, -657, -634, -730, -1211, -2035,
-2986, -4079, 5388
};
// 4. 6000-6500
DATA h4[NH] = {
3867, 6140, -3004, 1204, -682, 526, -56, -71, -223,
78, 195, 78, -223, -71, -56, 526, -682, 1204,
-3004, 6140, 3867
};
// 6500-7000
DATA h5[NH] = {
-626, 7957, 668, -127, -114, 138, 160, -92, -189,
32, 202, 32, -189, -92, 160, 138, -114, -127,
668, 7957, -626
};
// 7000-7500
DATA h6[NH] = {
-4748, 5156, 3199, 1717, 867, 690, 585, 197, -57,
114, 306, 114, -57, 197, 585, 690, 867, 1717,
3199, 5156, -4748
};
// 7500-8000
DATA h7[NH] = {
-4750, -5153, 3196, -1715, 868, -694, 588, -199, -56,
-115, 307, -115, -56, -199, 588, -694, 868, -1715,
3196, -5153, -4750
};
// 8000-8500
DATA h8[NH] = {
-627, -7958, 671, 127, -111, -141, 158, 93, -191,
-29, 197, -29, -191, 93, 158, -141, -111, 127,
671, -7958, -627
};
// 8500-9000
DATA h9[NH] = {
3866, -6140, -3003, -1203, -683, -528, -57, 73, -220,
-78, 193, -78, -220, 73, -57, -528, -683, -1203,
-3003, -6140, 3866
};
// 9000-9500
DATA h10[NH] = {
5494, 4159, -3044, 2075, -1236, 747, -649, 671, -525,
228, -79, 228, -525, 671, -649, 747, -1236, 2075,
-3044, 4159, 5494
};
// 9500-10000
DATA h11[NH] = {
1915, 7540, -1914, 388, 84, -116, -63, 196, -117,
-94, 191, -94, -117, 196, -63, -116, 84, 388,
-1914, 7540, 1915
};
// 10000-10500
DATA h12[NH] = {
-2735, 7089, 2347, 648, 473, 41, -111, 215, -79,
-112, 207, -112, -79, 215, -111, 41, 473, 648,
2347, 7089, -2735
};
// 10500-11000
DATA h13[NH] = {
-6161, -3152, 2605, -2132, 1642, -1160, 806, -646, 683,
-797, 851, -797, 683, -646, 806, -1160, 1642, -2132,
2605, -3152, -6161
};
// 11000-11500
DATA h14[NH] = {
-3310, -6609, 2859, -1233, 453, -53, -113, 103, 14,
-142, 195, -142, 14, 103, -113, -53, 453, -1233,
2859, -6609, -3310
};
// 11500-12000
DATA h15[NH] = {
1173, -7850, -990, -178, -140, 196, -185, 94, 40,
-157, 205, -157, 40, 94, -185, 196, -140, -178,
-990, -7850, 1173
};
// 12000-12500
DATA h16[NH] = {
6790, 2119, -1918, 1768, -1638, 1478, -1300, 1113, -935,
808, -763, 808, -935, 1113, -1300, 1478, -1638, 1768,
-1918, 2119, 6790
};
// 12500-13000
DATA h17[NH] = {
4929, 4972, -3127, 1992, -1276, 808, -476, 236, -77,
-28, 55, -28, -77, 236, -476, 808, -1276, 1992,
-3127, 4972, 4929
};
// 13000-13500
DATA h18[NH] = {
1344, 7774, -1452, 369, -147, 56, 15, -91, 146,
-179, 190, -179, 146, -91, 15, 56, -147, 369,
-1452, 7774, 1344
};
// 13500-14000
DATA h19[NH] = {
-7452, -1001, 971, -946, 939, -948, 960, -970, 979,
-986, 989, -986, 979, -970, 960, -948, 939, -946,
971, -1001, -7452
};
// 14000-15000
DATA h20[NH] = {
-7452, -1001, 971, -946, 939, -948, 960, -970, 979,
-986, 989, -986, 979, -970, 960, -948, 939, -946,
971, -1001, -7452
};
DATA* hArr1[4] = { h1, h2, h3, h4 };
DATA* hArr2[4] = { h5, h6, h7, h8 };
DATA* hArr3[4] = { h9, h10, h11, h12 };
DATA* hArr4[4] = { h13, h14, h15, h16 };
DATA* hArr5[4] = { h17, h18, h19, h20 };
DATA** hArr[5] = { hArr1, hArr2, hArr3, hArr4, hArr5 };
DATA in1b[W_LEN * 2] = {0};
DATA in2b[W_LEN * 2] = {0};
DATA* rin = in1b;
DATA* lin = in2b;
DATA db[NH + 2]; */
/*extern ushort fir(DATA *x, DATA *h, DATA *r, DATA *dbuffer, ushort nx, ushort nh);
int counter = 0;
void Equalizer() {
/// 1 time
int i = 0;
for (i = 0; i < W_LEN; ++i) {
rin[i] = buf_in_right_1[i];
lin[i] = buf_in_left_1[i];
}
fir(rin, hArr[counter / 5][0], rin, db, W_LEN, NH);
fir(lin, hArr[counter / 5][0], lin, db, W_LEN, NH);
for (i = 0; i < W_LEN; ++i) {
buf_out_right_1[i] = rin[i];
buf_out_left_1[i] = lin[i];
}
// 2 time
for (i = 0; i < W_LEN; ++i) {
rin[i] = buf_in_right_1[i];
lin[i] = buf_in_left_1[i];
}
fir(rin, hArr[counter / 5][1], rin, db, W_LEN, NH);
fir(lin, hArr[counter / 5][1], lin, db, W_LEN, NH);
for (i = 0; i < W_LEN; ++i) {
buf_out_right_1[i] += rin[i];
buf_out_left_1[i] += lin[i];
}
// 3 time
for (i = 0; i < W_LEN; ++i) {
rin[i] = buf_in_right_1[i];
lin[i] = buf_in_left_1[i];
}
fir(rin, hArr[counter / 5][2], rin, db, W_LEN, NH);
fir(lin, hArr[counter / 5][2], lin, db, W_LEN, NH);
for (i = 0; i < W_LEN; ++i) {
buf_out_right_1[i] += rin[i];
buf_out_left_1[i] += lin[i];
}
// 4 time
for (i = 0; i < W_LEN; ++i) {
rin[i] = buf_in_right_1[i];
lin[i] = buf_in_left_1[i];
}
fir(rin, hArr[counter / 5][3], rin, db, W_LEN, NH);
fir(lin, hArr[counter / 5][3], lin, db, W_LEN, NH);
for (i = 0; i < W_LEN; ++i) {
buf_out_right_1[i] += rin[i];
buf_out_left_1[i] += lin[i];
}
counter = ++counter % 20;
}
*/
Int16 in1b[W_LEN] = {0};
Int16 in2b[W_LEN] = {0};
DATA* rin = in1b;
DATA* lin = in2b;
//DATA in1b[W_LEN * 2] = {0};
//DATA in2b[W_LEN * 2] = {0};
//DATA* rin = in1b;
//DATA* lin = in2b;
//struct Q15 {
// int num;
// static const int n = 15;
//};
float min(float num1, float num2, float num3) {
if(num1 < num2 && num1 < num3) return num1;
else if(num2 < num3) return num2;
else return num3;
}
//1, 0.5, 1, -0.5
##################In this part I need to use Q15 format instead of short and float##############################
void compexp(short CT, short CS, short ET, short ES) {
//void compexp(0x7333, 0x7333, 0x7333, 0x7333) {
float tav = 0.01;
float at = 0.03;
float rt = 0.003;
// int delay = 150;
int xrms = 0;
int g = 1;
DATA buffer[150] = {0};
int i;
for (i = 0; i < W_LEN; ++i) {
rin[i] = buf_in_right_1[i];
lin[i] = buf_in_left_1[i];
}
for(i = 0; i < W_LEN; ++i) {
xrms = (1 -tav) * xrms + tav * pow(rin[i], 2);
float X = 10 * log(xrms);
float G = min(0, CS * (CT - X), ES * (ET - X));
int f = pow (10, G / 20);
float coeff;
if (f < g) {
coeff = at;
} else {
coeff = rt;
}
g = (1 - coeff) * g + coeff * f;
buf_out_right_1[i] = g * buffer[149];
buf_out_left_1[i] = g * buffer[149];
buffer[0] = buf_in_left_1[i];
}
}
void main(void) {
/* Initialize BSL */
c5515_init();
/* Configure Parallel Port */
SYS_EXBUSSEL &= ~0x7000;
SYS_EXBUSSEL |= 0x1000; // Configure Parallel Port for I2S2
/* Configure Serial Port */
SYS_EXBUSSEL &= ~0x0C00;
SYS_EXBUSSEL |= 0x0400; // Serial Port mode 1 (I2S1 and GP[11:10]).
c5515_GPIO_init();
c5515_GPIO_setDirection(GPIO10, GPIO_OUT);
c5515_GPIO_setOutput(GPIO10, 1); // Take AIC3201 chip out of reset
I2C_init(); // Initialize I2C
asm(" BSET INTM");
unsigned long int vector;
vector = (unsigned long int) &VECSTART;
vector = vector >> 8;
IVPD = (unsigned short) vector;
IVPH = (unsigned short) vector;
IER0 |= 0x4000;
asm(" BCLR INTM");
/* I2S settings */
I2S2_SRGR = 0x0015;
I2S2_ICMR = 0x0028; // Enable interrupts
I2S2_CR = 0x8012; // 16-bit word, Master, enable I2C
aic3204_stereo_in1();
while (1) {
if (effect_flag == EFFECT_FLAG) {
/* äîáàâèòü ôóíêöèþ ýôôåêòà */
// Equalizer();
compexp(1, 0.5, 1, -0.5);
buf_out_left_1 = buf_in_left_1;
buf_out_right_1 = buf_in_right_1;
effect_flag = NO_EFFECT_FLAG;
}
}
}