Technical discussions about Freescale (Motorola) DSPs (including the DSP56000, DSP56300, DSP56600, 56800 DSPs).
Hello, I'm using a Symphony Soundbite development board. (dsp56371) I'm using the assembly sourcecode, you can find on the Freescale website. I'm trying to make a simple Low Pass filter. (just 4th order; and only 1 left channel) But it is not working properly. I get a very thick sine wave at the output. There seems to be some kind of LP filtering; but not that correct, I think. I designed a LP with 4 taps using some software. Cutoff was around 2kHz, but at my scope it starts to lessen at 10kHz; to get zero around 24kHz. So, there are 2 problems, I think. The filtering is not at correct values; and the resulting sinewave is very thick. (looks like 2 sine waves, phase shifted a little bit from each other; and then the spaces in between them are full) I put the coefficients in my code like this (at the end of the file): org y:$100 S_01 dc $1D0984 ; .226853 S_02 dc $1CE104 ; .225617 S_03 dc $1CE104 ; .225617 S_04 dc $1D0984 ; .226853 Here is the code, I made in the PROCESS_AUDIO routine: PROCESS_AUDIO: move x0,x:(r7)+ ; preserve x0 before processing move r6,x:(r7)+ ; also preserve r6 and m6 (not necessary, I think) move m6,x:(r7)+ move #coeff,r6 ; r6 is pointer to begin of coefficient move #modulo,m6 ; we put the modulo on 3 (#taps-1) clr a x:(r0)-,x0 y:(r6)+,y0 ; clear reg a; put last sample x(n) into x0; decrement r0, so it points to x(n-1) ; put first coeff h(1) of filter into y0 rep #taps-1 ; repeat next instruction 3 times (#taps-1) mac x0,y0,a x:(r0)-,x0 y:(r6)+,y0 ; multiply coeff with sample and keep adding macr x0,y0,a ; do the same mac one last time (4th time); and round move a,x:(r0+TX_BUFF_BASE-RX_BUFF_BASE) ; put the result in the output buffer -> a = h(1)*x(n) + h(2)*x(n-1) + h(3)*x(n-2) + h(4)*x(n-3) clr a (r0)+ ; clear a (not necessary); increment r0, so it points to the oldest sample x(n-3) ; |-> Is incrementing of r0 necessary???; but if I leave out this code, I get even weirder result move x:-(r7),m6 ; restore x0,r6 and m6 after processing move x:-(r7),r6 move x:-(r7),x0 rts Somewhere at the beginning of the code, I put these constants: taps equ 4 ;#taps modulo equ 3 ;#taps-1 coeff equ y:$100 ;adress of table with filter coeff Also, I changed the keep in the sb_isr_esais.asm file keep equ 4 ; 4 = current sample plus past 3 samples for each channel If anyone could help me with this problem; I would be very thankfull. Maybe, someone designed a filter, using the demo assembly program of Freescale? Thank you very much.______________________________
Hi, please not that the assembly code template uses almost all registers, see p. 4-18 in the SNDBASMTPL.pdf: Table 5-1: Reserved Registers and their usage. Register Description of Usage R0 Input buffer pointer used for all ESAI_1 input channels R2 Output pointer used for ESAI SDO0 [AK4584 codec (U5), J2] R3 Output pointer used for ESAI SDO1 [AK4556 codec (U2), J4] R4 Output pointer used for ESAI SDO2 [AK4556 codec (U3), J6] R5 Output pointer used for ESAI SDO3 [AK4556 codec (U4), J8] R7 Software stack pointer used by interrupt service routines N0, N2, N3, N4, N5 Offset registers used with the input and output pointers used for incrementing the Rx registers by buffsize (see sb_isr_esais.asm) M0, M2, M3, M4, M5 Modifier registers set with the value keep (see sb_isr_esais.asm) to make the Rx registers behave as circular buffer pointers M7 Modifier register for R7, keeps default linear arithmetic value of $FFFFFF So only registers R0(M0,N0)and R6(M6,N6)are left unused. If you intend to reuse the other registers you need to store them and write back afterwards. Here is a working example for the FIR filter: PROCESS_AUDIO: ; Replace the code in this routine with your own custom audio processing ; routine. This is just a copy of the pass-through code above... ; remember to preserve registers not in the reserved register list ; so-as not to stomp on any main loop usage of them. ; copy input to output directly (duplicate of above) move x0,x:(r7)+ ; with no processing... move x1,x:(r7)+ ; preserve x0,x1,y0,y1 before processing move y0,x:(r7)+ move y1,x:(r7)+ move x:(r0),x0 ; left data copy move x:(r0+1),x1 move x:(r0+2),y0 ; the offsets below copy the current sample to the move x:(r0+3),y1 ; same position in the ouptut buffer for each channel ;prog here move x0,x:-(r1) clr a x:(r1)+,x1 y:(r6)+,y0 rep #N-1 mac x1,y0,a x:(r1)+,x1 y:(r6)+,y0 macr x1,y0,a nop move a,x0 ;stop progging here move x0,x:(r0+TX_BUFF_BASE-RX_BUFF_BASE) move x1,x:(r0+TX_BUFF_BASE-RX_BUFF_BASE+1) move y0,x:(r0+TX_BUFF_BASE-RX_BUFF_BASE+2) move y1,x:(r0+TX_BUFF_BASE-RX_BUFF_BASE+3) move y:(r0),x0 ; right data copy move y:(r0+1),x1 move y:(r0+2),y0 ; the offsets below copy the current sample to the move y:(r0+3),y1 ; same position in the ouptut buffer for each channel ;prog here move x0,x:-(r1) clr a x:(r1)+,x1 y:(r6)+,y0 rep #N-1 mac x1,y0,a x:(r1)+,x1 y:(r6)+,y0 ;macr x1,y0,a nop move a,x0 ;stop progging here move x0,y:(r0+TX_BUFF_BASE-RX_BUFF_BASE) move x1,y:(r0+TX_BUFF_BASE-RX_BUFF_BASE+1) move y0,y:(r0+TX_BUFF_BASE-RX_BUFF_BASE+2) move y1,y:(r0+TX_BUFF_BASE-RX_BUFF_BASE+3) move x:-(r7),y1 ; restore x0,x1,y0,y1 after processing move x:-(r7),y0 move x:-(r7),x1 move x:-(r7),x0 rts______________________________
Hi,
Thank you very much for your answer. I'm still having some trouble, though.
I Assume you use R6 as a pointer to the beginning of the filter co=EBfficie=
nts.
So I include:
at the beginning:
taps equ 4 ;#taps
modulo equ 3 ;#taps-1
coeff equ y:$100 ;adress of table with filter coeff
In the process_audio code:
move #coeff,r6=20=20=20=20=20=20=20=20
move #modulo,m6
At the end:
org y:$100
S_01 dc $1D0984 ; .226853
S_02 dc $1CE104 ; .225617
S_03 dc $1CE104 ; .225617
S_04 dc $1D0984 ; .226853
That is correct, you think?
Then, I don't know where your R1 is pointing to? Can you explain this?
> move x0,x:-(r1)
> clr a x:(r1)+,x1 y:(r6)+,y0
> rep #N-1
> mac x1,y0,a x:(r1)+,x1 y:(r6)+,y0
> macr x1,y0,a=20
> nop
> move a,x0
Thank you very much!!
Best regards,
Jan
> Date: Fri, 7 Aug 2009 10:51:26 +0200
> From: c...@gmx.de
> Subject: Re: [motoroladsp] LP filter using demo assembly app for SYMPHONY=
SOUNDBITE
> To: c...@hotmail.com; m...@yahoogroups.com
>=20
> Hi,
>=20
> please not that the assembly code template uses almost all registers, see=
p. 4-18 in the SNDBASMTPL.pdf:
>=20
> Table 5-1: Reserved Registers and their usage.
>=20
> Register Description of Usage
> R0 Input buffer pointer used for all ESAI_1 input channels
> R2 Output pointer used for ESAI SDO0 [AK4584 codec (U5), J2]
> R3 Output pointer used for ESAI SDO1 [AK4556 codec (U2), J4]
> R4 Output pointer used for ESAI SDO2 [AK4556 codec (U3), J6]
> R5 Output pointer used for ESAI SDO3 [AK4556 codec (U4), J8]
> R7 Software stack pointer used by interrupt service routines
> N0, N2, N3, N4, N5
>=20
> Offset registers used with the input and output pointers used for
> incrementing the Rx registers by buffsize (see sb_isr_esais.asm)
> M0, M2, M3, M4, M5
> Modifier registers set with the value keep (see sb_isr_esais.asm) to
> make the Rx registers behave as circular buffer pointers
> M7 Modifier register for R7, keeps default linear arithmetic value of
> $FFFFFF
>=20
> So only registers R0(M0,N0)and R6(M6,N6)are left unused. If you intend to=
reuse the other registers you need to store them and write back afterwards=
.
--> I assume, you mean R1 and R6.
>=20
> Here is a working example for the FIR filter:
>=20
>=20=20
> PROCESS_AUDIO: ; Replace the code in this routine with your own custom au=
dio processing=20
> ; routine. This is just a copy of the pass-through code above...
> ; remember to preserve registers not in the reserved register list
> ; so-as not to stomp on any main loop usage of them.
>=20
> ; copy input to output directly (duplicate of above)
> move x0,x:(r7)+ ; with no processing...
> move x1,x:(r7)+ ; preserve x0,x1,y0,y1 before processing
> move y0,x:(r7)+
> move y1,x:(r7)+
>=20
> move x:(r0),x0 ; left data copy
> move x:(r0+1),x1
> move x:(r0+2),y0 ; the offsets below copy the current sample to the
> move x:(r0+3),y1 ; same position in the ouptut buffer for each channel
>=20=09
> ;prog here
> move x0,x:-(r1)
>=20=09
> clr a x:(r1)+,x1 y:(r6)+,y0
> rep #N-1
> mac x1,y0,a x:(r1)+,x1 y:(r6)+,y0
> macr x1,y0,a=20
> nop
> move a,x0
> ;stop progging here
>=20=09
> move x0,x:(r0+TX_BUFF_BASE-RX_BUFF_BASE)
> move x1,x:(r0+TX_BUFF_BASE-RX_BUFF_BASE+1)
> move y0,x:(r0+TX_BUFF_BASE-RX_BUFF_BASE+2)
> move y1,x:(r0+TX_BUFF_BASE-RX_BUFF_BASE+3)
>=20
> move y:(r0),x0 ; right data copy
> move y:(r0+1),x1
> move y:(r0+2),y0 ; the offsets below copy the current sample to the
> move y:(r0+3),y1 ; same position in the ouptut buffer for each channel
>=20=09
> ;prog here
> move x0,x:-(r1)
>=20=09
> clr a x:(r1)+,x1 y:(r6)+,y0
> rep #N-1
> mac x1,y0,a x:(r1)+,x1 y:(r6)+,y0
> ;macr x1,y0,a=20
> nop
> move a,x0
>=20=09
> ;stop progging here
>=20=09
> move x0,y:(r0+TX_BUFF_BASE-RX_BUFF_BASE)
> move x1,y:(r0+TX_BUFF_BASE-RX_BUFF_BASE+1)
> move y0,y:(r0+TX_BUFF_BASE-RX_BUFF_BASE+2)
> move y1,y:(r0+TX_BUFF_BASE-RX_BUFF_BASE+3)
>=20
> move x:-(r7),y1 ; restore x0,x1,y0,y1 after processing
> move x:-(r7),y0
> move x:-(r7),x1
> move x:-(r7),x0
>=20=09
> rts
>=20
> --=20
> GRATIS f=FCr alle GMX-Mitglieder: Die maxdome Movie-FLAT!
> Jetzt freischalten unter http://portal.gmx.net/de/go/maxdome01
_________________________________________________________________
Get back to school stuff for them and cashback for you.
http://www.bing.com/cashback?form=3DMSHYCB&publ=3DWLHMTAG&crea=3DTEXT_MS
HYC=
B_BackToSchool_Cashback_BTSCashback_1x1
_____________________________________
______________________________Hi You have misunderstood the structure of I/O buffer. For you code, input buffer in X space should be: L1,L2,L3,L4;Ls1,Ls2,Ls3,Ls4;C1,C2,C3,C4;Lb1,Lb2,Lb3,Lb4 Actually, it's something like below: L0,Ls0,C0,Lb0;L2,Ls2,2C,Lb2;L3,Ls3,C3,Lb3;L4,Ls4,C4,Lb4 So, all r0+ or r0- should be (r0)+n0, (r0)-n0 Please note before return from this sub processing, r0 should keep unchanged. You can push it into stack at the begining and restore at the end of this sub routine. Actually the buffer structure in this template can be updated to you desired way which can be easy understood, however you need to update rx/tx isr. I think R1 in that example code is use as point to the reallocated buffer for left channel input 4 samples. I attached another simple passthru code with FIR processing for 371. Please note to add AKM codec setup code into it if you want to play it with Soundbite. 2009/8/7 jan carremans <c...@hotmail.com> > Hi, > > Thank you very much for your answer. I'm still having some trouble, though. > > I Assume you use R6 as a pointer to the beginning of the filter > coëfficients. > > So I include: > > at the beginning: > taps equ 4 ;#taps > modulo equ 3 ;#taps-1 > coeff equ y:$100 ;adress of table with filter coeff > > In the process_audio code: > move #coeff,r6 > move #modulo,m6 > > At the end: > org y:$100 > S_01 dc $1D0984 ; .226853 > S_02 dc $1CE104 ; .225617 > S_03 dc $1CE104 ; .225617 > S_04 dc $1D0984 ; .226853 > > That is correct, you think? > > Then, I don't know where your R1 is pointing to? Can you explain this? > > > move x0,x:-(r1) > > clr a x:(r1)+,x1 y:(r6)+,y0 > > rep #N-1 > > mac x1,y0,a x:(r1)+,x1 y:(r6)+,y0 > > macr x1,y0,a > > nop > > move a,x0 > > Thank you very much!! > > Best regards, > > Jan > > > Date: Fri, 7 Aug 2009 10:51:26 +0200 > > From: c...@gmx.de <clangen%40gmx.de> > > Subject: Re: [motoroladsp] LP filter using demo assembly app for SYMPHONY > SOUNDBITE > > To: c...@hotmail.com <carrejans%40hotmail.com>; > m...@yahoogroups.com <motoroladsp%40yahoogroups.com> > > > > Hi, > > > > please not that the assembly code template uses almost all registers, see > p. 4-18 in the SNDBASMTPL.pdf: > > > > Table 5-1: Reserved Registers and their usage. > > > > Register Description of Usage > > R0 Input buffer pointer used for all ESAI_1 input channels > > R2 Output pointer used for ESAI SDO0 [AK4584 codec (U5), J2] > > R3 Output pointer used for ESAI SDO1 [AK4556 codec (U2), J4] > > R4 Output pointer used for ESAI SDO2 [AK4556 codec (U3), J6] > > R5 Output pointer used for ESAI SDO3 [AK4556 codec (U4), J8] > > R7 Software stack pointer used by interrupt service routines > > N0, N2, N3, N4, N5 > > > > Offset registers used with the input and output pointers used for > > incrementing the Rx registers by buffsize (see sb_isr_esais.asm) > > M0, M2, M3, M4, M5 > > Modifier registers set with the value keep (see sb_isr_esais.asm) to > > make the Rx registers behave as circular buffer pointers > > M7 Modifier register for R7, keeps default linear arithmetic value of > > $FFFFFF > > > > So only registers R0(M0,N0)and R6(M6,N6)are left unused. If you intend to > reuse the other registers you need to store them and write back afterwards. > > --> I assume, you mean R1 and R6. > > > > > Here is a working example for the FIR filter: > > > > > > PROCESS_AUDIO: ; Replace the code in this routine with your own custom > audio processing > > ; routine. This is just a copy of the pass-through code above... > > ; remember to preserve registers not in the reserved register list > > ; so-as not to stomp on any main loop usage of them. > > > > ; copy input to output directly (duplicate of above) > > move x0,x:(r7)+ ; with no processing... > > move x1,x:(r7)+ ; preserve x0,x1,y0,y1 before processing > > move y0,x:(r7)+ > > move y1,x:(r7)+ > > > > move x:(r0),x0 ; left data copy > > move x:(r0+1),x1 > > move x:(r0+2),y0 ; the offsets below copy the current sample to the > > move x:(r0+3),y1 ; same position in the ouptut buffer for each channel > > > > ;prog here > > move x0,x:-(r1) > > > > clr a x:(r1)+,x1 y:(r6)+,y0 > > rep #N-1 > > mac x1,y0,a x:(r1)+,x1 y:(r6)+,y0 > > macr x1,y0,a > > nop > > move a,x0 > > ;stop progging here > > > > move x0,x:(r0+TX_BUFF_BASE-RX_BUFF_BASE) > > move x1,x:(r0+TX_BUFF_BASE-RX_BUFF_BASE+1) > > move y0,x:(r0+TX_BUFF_BASE-RX_BUFF_BASE+2) > > move y1,x:(r0+TX_BUFF_BASE-RX_BUFF_BASE+3) > > > > move y:(r0),x0 ; right data copy > > move y:(r0+1),x1 > > move y:(r0+2),y0 ; the offsets below copy the current sample to the > > move y:(r0+3),y1 ; same position in the ouptut buffer for each channel > > > > ;prog here > > move x0,x:-(r1) > > > > clr a x:(r1)+,x1 y:(r6)+,y0 > > rep #N-1 > > mac x1,y0,a x:(r1)+,x1 y:(r6)+,y0 > > ;macr x1,y0,a > > nop > > move a,x0 > > > > ;stop progging here > > > > move x0,y:(r0+TX_BUFF_BASE-RX_BUFF_BASE) > > move x1,y:(r0+TX_BUFF_BASE-RX_BUFF_BASE+1) > > move y0,y:(r0+TX_BUFF_BASE-RX_BUFF_BASE+2) > > move y1,y:(r0+TX_BUFF_BASE-RX_BUFF_BASE+3) > > > > move x:-(r7),y1 ; restore x0,x1,y0,y1 after processing > > move x:-(r7),y0 > > move x:-(r7),x1 > > move x:-(r7),x0 > > > > rts > > > > -- > > GRATIS für alle GMX-Mitglieder: Die maxdome Movie-FLAT! > > Jetzt freischalten unter http://portal.gmx.net/de/go/maxdome01 > > __________________________________________________________ > Get back to school stuff for them and cashback for you. > > http://www.bing.com/cashback?form=MSHYCB&publ=WLHMTAG&crea=TEXT_MSHYCB_B ackToSchool_Cashback_BTSCashback_1x1 > -- Best Regards. Johnny Chen______________________________