# LP filter using demo assembly app for SYMPHONY SOUNDBITE

Started by August 5, 2009
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
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 coficients.

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
> Subject: Re: [motoroladsp] LP filter using demo assembly app for SYMPHONY SOUNDBITE
> To: c...@hotmail.com; m...
>
> 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 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_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

> 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
> coficients.
>
> 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
> > Subject: Re: [motoroladsp] LP filter using demo assembly app for SYMPHONY
> SOUNDBITE
> > To: c...@hotmail.com ;
> m...
> >
> > 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 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_BackToSchool_Cashback_BTSCashback_1x1
>

--
Best Regards.

Johnny Chen