Panning

Algorithm development and general DSP issues

Moderator: frank

Post Reply
alpignolo
Posts: 20
Joined: Tue May 27, 2014 8:40 am

Panning

Post by alpignolo »

Hi.
I would like to create a code to get a PANNING effect between the outputs.
I have write this code but there is an audio "click" whenever the signal changes output.
where is the problem?
Thanks

;Panning

equ panning reg0
equ wave reg1

skp run , start
wlds sin1,0,4096
sof 0, 0
wrax panning, 0
start:

ldax panning
skp neg, TWO
rdax adcl , 1
wrax dacl, 0
skp zro,END_2

TWO:
rdax adcl , 1
wrax dacr, 0
skp zro,END_2

END_2: ;

;========= SIN_1 ==============
rdax pot0,1
mulx pot0 ;square
sof 0.8,0.02 ;scale rate
wrax sin1_rate,0 ;sin1 rate register

cho rdal,sin1 ; +/-0.5
;sof 1,0.5 ; 0 to 1
wrax wave,0 ; Sine wave

ldax wave
skp neg, ONE
sof 0, 0.5
wrax panning, 0
skp zro,END

ONE:
sof 0, -0.5
wrax panning, 0
skp zro,END

END:
potul
Posts: 76
Joined: Tue Sep 26, 2017 12:33 am

Re: Panning

Post by potul »

Not sure if this is the case,... but I see you are copying ADCL to DACL or DACR alternatively, but never "reset" the unused dac to 0. This may create some jumps...

Maybe it would be a better approach to copy ADCL to both DACs first, .. and then set to 0 the one you don't want to hear. OR simply leave it as it is but ensure the dac not used is set to 0.

If this is not working, maybe you should smooth the transition somehow using some filtering.

Mat
alpignolo
Posts: 20
Joined: Tue May 27, 2014 8:40 am

Re: Panning

Post by alpignolo »

Thanks Potul,
I have tried your suggestion but the problem persists.
Maybe it's a problem of approach because I have the same problem also on this code even if I don't panning between the outputs but only between two registers:

;Ping pong Pitch

mem mem_dly 32767

equ ping_pong reg0 ;
equ hp_filter reg1
equ lp_filter reg3
equ mono reg4
equ fbk reg5 ;
equ wave reg6
equ potfil reg7

skp run , start
wlds sin1,0,10
sof 0, -1
wrax ping_pong, 0
start:

ldax fbk
mulx pot1
mulx pot1
rdax adcl, 1
wrax mono, 0

ldax ping_pong
skp neg, TWO
sof 0, 0
wrax hp_filter, 0
ldax mono
; LPF
RDFX 10 , 0.005
WRAX 10 , 1
wrax lp_filter, 0
skp zro, END_2

TWO:
sof 0, 0
wrax lp_filter, 0
ldax mono
sof 1.2, 0
; HPF
RDFX 11 , 0.005
WRAX 11 , -1
wrax hp_filter, 0
skp zro, END_2

END_2:

ldax hp_filter
rdax lp_filter, 1
wrax dacl, 1
wrax fbk, 0

;========= SIN_1 ==============
rdax pot0,1
mulx pot0 ;square
sof 0.8,0.02 ;scale rate
wrax sin1_rate,0 ;sin1 rate register

cho rdal, sin1
wrax wave, 0 ; wave

ldax wave
skp neg, ONE
sof 0, 0.5
wrax ping_pong, 0
skp zro, END

ONE:
sof 0, -0.5
wrax ping_pong, 0
skp zro, END

END:
frank
Posts: 1244
Joined: Wed Oct 19, 2005 12:26 pm
Contact:

Re: Panning

Post by frank »

Problem is you are hard jumping based on sign of the wave, you really want to fade in and out the output signals, something more like:

my_sin = (sin_from_lfo * 0.5) + 0.5 // my_sin ranges 0 to 1
dacl = input * my_sin
dacr = input * (1.0 - my_sin)

Now as one output increases the other decreases but there is no jump, it is a continuous change in volume.
Frank Thomson
Experimental Noize
Digital Larry
Posts: 338
Joined: Mon Nov 12, 2012 1:12 pm
Contact:

Re: Panning

Post by Digital Larry »

Here's a simple LFO panner I made using SpinCAD. What's weird is that when I audition it on my laptop with a noise input, it seems the timbre is different between left and right. My ears aren't what they used to be (I blame it on being in the front row at that Frank Zappa show in 1981). Or maybe it's the speakers?

If you are not used to SpinCAD generated code, you will notice that it's probably NOT the way you would have written it by hand, but with that in mind....

Code: Select all

; Untitled
; null
; Pot 0: 
; Pot 1: 
; Pot 2: 
; 
; 
; ----------------------------
;------ Input
;------ Pot 0
;------ Scale/Offset <--- constrains the LFO range
RDAX POT0,1.0000000000
SOF 0.8400000000,0.1600000000
WRAX REG0,0.0000000000
;------ LFO 0
SKP RUN ,1
WLDS 0,210,32767
RDAX REG0,0.4109589041
WRAX SIN0_RATE,0.0000000000
CHO RDAL,0
SOF 0.5000000000,0.5000000000
WRAX REG1,0.0000000000
;------ Panner
RDAX ADCL,1.0000000000
MULX REG1
WRAX REG3,-1.0000000000
RDAX ADCL,1.0000000000
WRAX REG2,0.0000000000
;------ Output
RDAX REG2,1.0000000000
WRAX DACL,0.0000000000
RDAX REG3,1.0000000000
WRAX DACR,0.0000000000
I think the logic of the panner block is OK.

Code: Select all

;------ Panner
RDAX ADCL,1.0000000000 ; read the input signal
MULX REG1 ; multiply it by the "panning coefficient" (the LFO output which is sweeping from 0 to 1) - let's call this "c"
WRAX REG3,-1.0000000000 ; write the result into REG3 and invert the ACC.  Now REG3 is c * ADCL and ACC is -(c * ADDCL)
RDAX ADCL,1.0000000000 ; add it to the ADCL again - now ACC is ADCL - (c * ADCL) or ADCL * (1 - c)
WRAX REG2,0.0000000000 ; write ACC to REG2
Note that this is not "equal power" panning and volume wise there's actually a dip in the middle.
Post Reply