Here's the 10 FIR test code (some code left out and replaced with ... to shorten up the text so that this message board would accept it). I'll run this tonight if I have time :-)
#include <stdint.h>
#include <math.h>
#include <string.h>
#include "xio.h"
const char* product_name_string = "Test";
const int audio_sample_rate = 24000;
const int flexfx_unit_number = 0;
const int audio_clock_mode = 1; // 0=internal/master,1=external/master,2=slave
const int usb_output_chan_count = 2; // 2 USB audio class 2.0 output channels
const int usb_input_chan_count = 2; // 2 USB audio class 2.0 input channels
const int i2s_channel_count = 2; // Channels per SDIN/SDOUT wire (2,4,or 8)
const int i2s_sync_word[8] = { 0xFFFFFFFF,0x00000000,0,0,0,0,0,0 };
// FQ converts Q28 fixed-point to floating point, QF converts floating-point to Q28
#define QQ 28
#define FQ(hh) (((hh)<0.0)?((int)((double)(1u<<QQ)*(hh)-0.5)):((int)(((double)(1u<<QQ)-1)*(hh)+0.5)))
#define QF(xx) (((int)(xx)<0)?((double)(int)(xx))/(1u<<QQ):((double)(xx))/((1u<<QQ)-1))
// MAC performs 32x32 multiply and 64-bit accumulation, SAT saturates a 64-bit result, EXT converts
// a 64-bit result to a 32-bit value, LDn/STn loads/stores two 32-values from/to 64-bit aligned
// 32-bit data arrays at address PP[2*n]. All 32-bit fixed-point values are Q28 fixed-point values.
//
// AH (high) and AL (low) form the 64-bit signed accumulator
// XX, YY, and AA are 32-bit QQQ fixed point values
// PP is a ** 64-bit aligned ** pointer to two 32-bit QQQ values
//
// For CRC: YY and XX are the next and previous results, SS is the seed value, PP is the CRC polynomial.
#define DSP_LD00( pp, xx, yy ) asm volatile("ldd %0,%1,%2[ 0]":"=r"(xx),"=r"(yy):"r"(pp));
#define DSP_LD01( pp, xx, yy ) asm volatile("ldd %0,%1,%2[ 1]":"=r"(xx),"=r"(yy):"r"(pp));
#define DSP_LD02( pp, xx, yy ) asm volatile("ldd %0,%1,%2[ 2]":"=r"(xx),"=r"(yy):"r"(pp));
#define DSP_LD03( pp, xx, yy ) asm volatile("ldd %0,%1,%2[ 3]":"=r"(xx),"=r"(yy):"r"(pp));
#define DSP_LD04( pp, xx, yy ) asm volatile("ldd %0,%1,%2[ 4]":"=r"(xx),"=r"(yy):"r"(pp));
#define DSP_LD05( pp, xx, yy ) asm volatile("ldd %0,%1,%2[ 5]":"=r"(xx),"=r"(yy):"r"(pp));
#define DSP_LD06( pp, xx, yy ) asm volatile("ldd %0,%1,%2[ 6]":"=r"(xx),"=r"(yy):"r"(pp));
#define DSP_LD07( pp, xx, yy ) asm volatile("ldd %0,%1,%2[ 7]":"=r"(xx),"=r"(yy):"r"(pp));
#define DSP_LD08( pp, xx, yy ) asm volatile("ldd %0,%1,%2[ 8]":"=r"(xx),"=r"(yy):"r"(pp));
#define DSP_LD09( pp, xx, yy ) asm volatile("ldd %0,%1,%2[ 9]":"=r"(xx),"=r"(yy):"r"(pp));
#define DSP_LD10( pp, xx, yy ) asm volatile("ldd %0,%1,%2[10]":"=r"(xx),"=r"(yy):"r"(pp));
#define DSP_LD11( pp, xx, yy ) asm volatile("ldd %0,%1,%2[11]":"=r"(xx),"=r"(yy):"r"(pp));
#define DSP_ST00( pp, xx, yy ) asm volatile("std %0,%1,%2[ 0]"::"r"(xx), "r"(yy),"r"(pp));
#define DSP_ST01( pp, xx, yy ) asm volatile("std %0,%1,%2[ 1]"::"r"(xx), "r"(yy),"r"(pp));
#define DSP_ST02( pp, xx, yy ) asm volatile("std %0,%1,%2[ 2]"::"r"(xx), "r"(yy),"r"(pp));
#define DSP_ST03( pp, xx, yy ) asm volatile("std %0,%1,%2[ 3]"::"r"(xx), "r"(yy),"r"(pp));
#define DSP_ST04( pp, xx, yy ) asm volatile("std %0,%1,%2[ 4]"::"r"(xx), "r"(yy),"r"(pp));
#define DSP_ST05( pp, xx, yy ) asm volatile("std %0,%1,%2[ 5]"::"r"(xx), "r"(yy),"r"(pp));
#define DSP_ST06( pp, xx, yy ) asm volatile("std %0,%1,%2[ 6]"::"r"(xx), "r"(yy),"r"(pp));
#define DSP_ST07( pp, xx, yy ) asm volatile("std %0,%1,%2[ 7]"::"r"(xx), "r"(yy),"r"(pp));
#define DSP_ST08( pp, xx, yy ) asm volatile("std %0,%1,%2[ 8]"::"r"(xx), "r"(yy),"r"(pp));
#define DSP_ST09( pp, xx, yy ) asm volatile("std %0,%1,%2[ 9]"::"r"(xx), "r"(yy),"r"(pp));
#define DSP_ST10( pp, xx, yy ) asm volatile("std %0,%1,%2[10]"::"r"(xx), "r"(yy),"r"(pp));
#define DSP_ST11( pp, xx, yy ) asm volatile("std %0,%1,%2[11]"::"r"(xx), "r"(yy),"r"(pp));
#define DSP_MUL( ah, al, xx, yy ) asm volatile("maccs %0,%1,%2,%3":"=r"(ah),"=r"(al):"r"(xx),"r"(yy),"0"(0),"1"(0) );
#define DSP_MAC( ah, al, xx, yy ) asm volatile("maccs %0,%1,%2,%3":"=r"(ah),"=r"(al):"r"(xx),"r"(yy),"0"(ah),"1"(al) );
#define DSP_EXT( ah, al, xx, qq ) asm volatile("lextract %0,%1,%2,%3,32":"=r"(xx):"r"(ah),"r"(al),"r"(QQ+qq));
#define DSP_SAT( ah, al ) asm volatile("lsats %0,%1,%2":"=r"(ah),"=r"(al):"r"(QQ),"0"(ah),"1"(al));
#define DSP_DIV( qq,rr,ah,al,xx ) asm volatile("ldivu %0,%1,%2,%3,%4":"=r"(qq):"r"(rr),"r"(ah),"r"(al),"r"(xx));
#define DSP_CRC( xx,yy,ss,pp ) asm volatile("crc32 %0,%2,%3":"=r"(xx):"0"(yy),"r"(ss),"r"(pp));
inline int dsp_mult( int xx, int yy ) // RR = XX * YY
{
int ah; unsigned al; DSP_MUL(ah,al,xx,yy); DSP_EXT(ah,al,xx,0); return xx;
}
inline int dsp_extract( int ah, int al ) // RR = AH:AL >> (64-QQ)
{
DSP_EXT( ah, al, ah,0 ); return ah;
}
#define dsp_convolve24( ah, al, cc, ss, xx ) \
{ \
s0 = xx; \
DSP_LD00( cc, b1, b0 ); DSP_LD00( ss, s2, s1 ); DSP_ST00( ss, s1, s0 ); \
DSP_MAC( ah, al, b0, s0 ); DSP_MAC( ah, al, b1, s1 ); \
DSP_LD01( cc, b1, b0 ); DSP_LD01( ss, s0, s3 ); DSP_ST01( ss, s3, s2 ); \
DSP_MAC( ah, al, b0, s2 ); DSP_MAC( ah, al, b1, s3 ); \
DSP_LD02( cc, b1, b0 ); DSP_LD02( ss, s2, s1 ); DSP_ST02( ss, s1, s0 ); \
DSP_MAC( ah, al, b0, s0 ); DSP_MAC( ah, al, b1, s1 ); \
DSP_LD03( cc, b1, b0 ); DSP_LD03( ss, s0, s3 ); DSP_ST03( ss, s3, s2 ); \
DSP_MAC( ah, al, b0, s2 ); DSP_MAC( ah, al, b1, s3 ); \
DSP_LD04( cc, b1, b0 ); DSP_LD04( ss, s2, s1 ); DSP_ST04( ss, s1, s0 ); \
DSP_MAC( ah, al, b0, s0 ); DSP_MAC( ah, al, b1, s1 ); \
DSP_LD05( cc, b1, b0 ); DSP_LD05( ss, s0, s3 ); DSP_ST05( ss, s3, s2 ); \
DSP_MAC( ah, al, b0, s2 ); DSP_MAC( ah, al, b1, s3 ); \
DSP_LD06( cc, b1, b0 ); DSP_LD06( ss, s2, s1 ); DSP_ST06( ss, s1, s0 ); \
DSP_MAC( ah, al, b0, s0 ); DSP_MAC( ah, al, b1, s1 ); \
DSP_LD07( cc, b1, b0 ); DSP_LD07( ss, s0, s3 ); DSP_ST07( ss, s3, s2 ); \
DSP_MAC( ah, al, b0, s2 ); DSP_MAC( ah, al, b1, s3 ); \
DSP_LD08( cc, b1, b0 ); DSP_LD08( ss, s2, s1 ); DSP_ST08( ss, s1, s0 ); \
DSP_MAC( ah, al, b0, s0 ); DSP_MAC( ah, al, b1, s1 ); \
DSP_LD09( cc, b1, b0 ); DSP_LD09( ss, s0, s3 ); DSP_ST09( ss, s3, s2 ); \
DSP_MAC( ah, al, b0, s2 ); DSP_MAC( ah, al, b1, s3 ); \
DSP_LD10( cc, b1, b0 ); DSP_LD10( ss, s2, s1 ); DSP_ST10( ss, s1, s0 ); \
DSP_MAC( ah, al, b0, s0 ); DSP_MAC( ah, al, b1, s1 ); \
DSP_LD11( cc, b1, b0 ); DSP_LD11( ss, s0, s3 ); DSP_ST11( ss, s3, s2 ); \
DSP_MAC( ah, al, b0, s2 ); DSP_MAC( ah, al, b1, s3 ); \
xx = s0; \
}
void xio_startup( void )
{
}
void xio_control( const int rcv_prop[6], int snd_prop[6], int dsp_prop[6] )
{
}
void xio_mixer( const int usb_output_q31[2], int usb_input_q31[2],
const int adc_output_q31[2], int dac_input_q31[2],
const int dsp_output_q28[8], int dsp_input_q28[8], const int property[6] )
{
// Send instrument signal from ADC to each FIR.
dsp_input_q28[0] = dsp_input_q28[1] = dsp_input_q28[2] = dsp_input_q28[3]
= dsp_input_q28[4] = adc_output_q31[0] / 8;
dsp_input_q28[5] = dsp_input_q28[6] = dsp_input_q28[7] = dsp_input_q28[8]
= dsp_input_q28[9] = adc_output_q31[0] / 8;
// Combine FIR outputs and send to the DAC (5 outputs to left channel, other 5 to right).
dac_input_q31[0] = dsp_output_q28[0] + dsp_output_q28[1] + dsp_output_q28[2]
+ dsp_output_q28[3] + dsp_output_q28[4];
dac_input_q31[1] = dsp_output_q28[5] + dsp_output_q28[6] + dsp_output_q28[7]
+ dsp_output_q28[8] + dsp_output_q28[9];
}
int fir0_coeff[768], fir0_state[768];
int fir1_coeff[768], fir1_state[768];
int fir2_coeff[768], fir2_state[768];
int fir3_coeff[768], fir3_state[768];
int fir4_coeff[768], fir4_state[768];
int fir5_coeff[768], fir5_state[768];
int fir6_coeff[768], fir6_state[768];
int fir7_coeff[768], fir7_state[768];
int fir8_coeff[768], fir8_state[768];
int fir9_coeff[768], fir9_state[768];
void xio_initialize( void )
{
memset(fir0_coeff,0,sizeof(fir0_coeff)); memset(fir0_state,0,sizeof(fir0_state));
memset(fir1_coeff,0,sizeof(fir1_coeff)); memset(fir1_state,0,sizeof(fir1_state));
memset(fir2_coeff,0,sizeof(fir2_coeff)); memset(fir2_state,0,sizeof(fir2_state));
memset(fir3_coeff,0,sizeof(fir3_coeff)); memset(fir3_state,0,sizeof(fir3_state));
memset(fir4_coeff,0,sizeof(fir4_coeff)); memset(fir4_state,0,sizeof(fir4_state));
memset(fir5_coeff,0,sizeof(fir5_coeff)); memset(fir5_state,0,sizeof(fir5_state));
memset(fir6_coeff,0,sizeof(fir6_coeff)); memset(fir6_state,0,sizeof(fir6_state));
memset(fir7_coeff,0,sizeof(fir7_coeff)); memset(fir7_state,0,sizeof(fir7_state));
memset(fir8_coeff,0,sizeof(fir8_coeff)); memset(fir8_state,0,sizeof(fir8_state));
memset(fir9_coeff,0,sizeof(fir9_coeff)); memset(fir9_state,0,sizeof(fir9_state));
fir0_coeff[0] = fir1_coeff[0] = fir2_coeff[0] = fir3_coeff[0] = fir4_coeff[0] = FQ(1.0);
fir5_coeff[0] = fir6_coeff[0] = fir7_coeff[0] = fir8_coeff[0] = fir9_coeff[0] = FQ(1.0);
}
void xio_thread1( int samples[32], const int property[6] )
{
unsigned al; int ah, xx, b0,b1,s0,s1,s2,s3;
ah = 0; al = 1<<(QQ-1); xx = samples[0];
dsp_convolve24( ah, al, fir0_coeff + 24* 0, fir0_state + 24* 0, xx );
...
...
...
dsp_convolve24( ah, al, fir0_coeff + 24*28, fir0_state + 24*28, xx );
DSP_EXT( ah, al, samples[0],0 );
ah = 0; al = 1<<(QQ-1); xx = samples[1];
dsp_convolve24( ah, al, fir1_coeff + 24* 0, fir1_state + 24* 0, xx );
...
...
...
dsp_convolve24( ah, al, fir1_coeff + 24*28, fir1_state + 24*28, xx );
DSP_EXT( ah, al, samples[1],0 );
}
void xio_thread2( int samples[32], const int property[6] )
{
unsigned al; int ah, xx, b0,b1,s0,s1,s2,s3;
ah = 0; al = 1<<(QQ-1); xx = samples[2];
dsp_convolve24( ah, al, fir2_coeff + 24* 0, fir2_state + 24* 0, xx );
...
...
...
dsp_convolve24( ah, al, fir2_coeff + 24*28, fir2_state + 24*28, xx );
DSP_EXT( ah, al, samples[2],0 );
ah = 0; al = 1<<(QQ-1); xx = samples[3];
dsp_convolve24( ah, al, fir3_coeff + 24* 0, fir3_state + 24* 0, xx );
...
...
...
dsp_convolve24( ah, al, fir3_coeff + 24*28, fir3_state + 24*28, xx );
DSP_EXT( ah, al, samples[3],0 );
}
void xio_thread3( int samples[32], const int property[6] )
{
unsigned al; int ah, xx, b0,b1,s0,s1,s2,s3;
ah = 0; al = 1<<(QQ-1); xx = samples[4];
dsp_convolve24( ah, al, fir4_coeff + 24* 0, fir4_state + 24* 0, xx );
...
...
...
dsp_convolve24( ah, al, fir4_coeff + 24*28, fir4_state + 24*28, xx );
DSP_EXT( ah, al, samples[0],0 );
ah = 0; al = 1<<(QQ-1); xx = samples[5];
dsp_convolve24( ah, al, fir5_coeff + 24* 0, fir5_state + 24* 0, xx );
...
...
...
dsp_convolve24( ah, al, fir5_coeff + 24*28, fir5_state + 24*28, xx );
DSP_EXT( ah, al, samples[5],0 );
}
void xio_thread4( int samples[32], const int property[6] )
{
unsigned al; int ah, xx, b0,b1,s0,s1,s2,s3;
ah = 0; al = 1<<(QQ-1); xx = samples[6];
dsp_convolve24( ah, al, fir6_coeff + 24* 0, fir6_state + 24* 0, xx );
...
...
...
dsp_convolve24( ah, al, fir6_coeff + 24*28, fir6_state + 24*28, xx );
DSP_EXT( ah, al, samples[6],0 );
ah = 0; al = 1<<(QQ-1); xx = samples[7];
dsp_convolve24( ah, al, fir7_coeff + 24* 0, fir7_state + 24* 0, xx );
...
...
...
dsp_convolve24( ah, al, fir7_coeff + 24*28, fir7_state + 24*28, xx );
DSP_EXT( ah, al, samples[7],0 );
}
void xio_thread5( int samples[32], const int property[6] )
{
unsigned al; int ah, xx, b0,b1,s0,s1,s2,s3;
ah = 0; al = 1<<(QQ-1); xx = samples[8];
dsp_convolve24( ah, al, fir8_coeff + 24* 0, fir8_state + 24* 0, xx );
...
...
...
dsp_convolve24( ah, al, fir8_coeff + 24*28, fir8_state + 24*28, xx );
DSP_EXT( ah, al, samples[8],0 );
ah = 0; al = 1<<(QQ-1); xx = samples[9];
dsp_convolve24( ah, al, fir9_coeff + 24* 0, fir9_state + 24* 0, xx );
...
...
...
dsp_convolve24( ah, al, fir9_coeff + 24*28, fir9_state + 24*28, xx );
DSP_EXT( ah, al, samples[9],0 );
}