addr_ptr with cho rda

Algorithm development and general DSP issues

Moderator: frank

Post Reply
jakesteffes
Posts: 5
Joined: Thu May 09, 2013 8:21 am
Location: United States

addr_ptr with cho rda

Post by jakesteffes »

Hi, I'm trying to use the cho rda command to read from a point in memory, but I'd like to use a pot to control which point from memory the sin/cos oscillates about. How should I implement this?

This is the general idea of what I'm trying to do:

ldax pot0
wrax addr_ptr, 0
cho rda, sin0, %0, addr_ptr*k ;k is a constant

: however, it seems to just read from a fixed point which changes with k. Any help would be very much appreciated.
frank
Posts: 1244
Joined: Wed Oct 19, 2005 12:26 pm
Contact:

Post by frank »

I'm not sure what you are trying to do but you cannot use "cho rda" like you are trying to. The values must be fixed so you must use a fixed value in the address field, not a register.
Frank Thomson
Experimental Noize
Aaron
Posts: 54
Joined: Wed Mar 04, 2015 8:10 pm
Location: Oklahoma

Post by Aaron »

I have been running into this same issue. I am wanting to modulate a delay around the address pointer but I have not been successful in any of my attempts. I have tried writing the RMPA value to another delay and modulating it, which works but not quite the way I am wanting. The closest I have come to this is writing the LFO and pot values to the address pointer, but of course this introduces unwanted zipper noise. Any suggestions?
frank
Posts: 1244
Joined: Wed Oct 19, 2005 12:26 pm
Contact:

Post by frank »

Try 2 delay blocks, one is the fixed modulation delay (only as long as necessary for the depth of the sin wave) the other is the feed delay so write to feed, use the pot to select where to read from feed and write to modulation delay.
Frank Thomson
Experimental Noize
Digital Larry
Posts: 338
Joined: Mon Nov 12, 2012 1:12 pm
Contact:

Post by Digital Larry »

frank wrote:Try 2 delay blocks, one is the fixed modulation delay (only as long as necessary for the depth of the sin wave) the other is the feed delay so write to feed, use the pot to select where to read from feed and write to modulation delay.
My recommendation exactly.
Aaron
Posts: 54
Joined: Wed Mar 04, 2015 8:10 pm
Location: Oklahoma

Post by Aaron »

I have tried something like this:


mem delay 983 ;30ms
mem lfo 98 ;3ms

skp run,1
wlds sin0,30,98 ;initialize lfo

rdax pot0,0.03 ;get pot0 scaled for 30ms of delay
wrax addr_ptr,0 ;save to addr_ptr, clear ACC

rdax adcl,1 ;get input
wra delay,0 ;write to delay, clear ACC

rmpa 1 ;get delay sample from addr_ptr
wra lfo,0 ;write to lfo, clear ACC

cho rda,sin0,sin|reg|compc,lfo^ ;do modulation
cho rda,sin0,sin,lfo^+1

rdax adcl,1 ;add input
wrax dacl,0 ;write to output


Where as this technically works it is not quite what I am looking for. Thgis setup gives you the ability to change the delay time but the modulation just sounds like it is "on top" of the delay instead of the delay itself being modulated. The idea I am kind of going for is shorter delay times yielding more of a flange effect while higher delay times yield a chorus effect.
frank
Posts: 1244
Joined: Wed Oct 19, 2005 12:26 pm
Contact:

Post by frank »

What I think you really want to do is adjust the range of the sin wave by writing to SIN0_RANGE in that case to change the depth of the effect.
Frank Thomson
Experimental Noize
Aaron
Posts: 54
Joined: Wed Mar 04, 2015 8:10 pm
Location: Oklahoma

Post by Aaron »

Looking into this more, I think what needs to happen is a linear interpolation as in the ROM Flanger/Rev code, but this goes beyond my scope of understanding for the time being.
Digital Larry
Posts: 338
Joined: Mon Nov 12, 2012 1:12 pm
Contact:

Post by Digital Larry »

Sounds like what you want to do is along the lines of having both a "width" and "center" control so that you can get from flange (short delay) to chorus (longer delay) with a knob.

You could try the servo delay approach, which doesn't use the SIN LFO in the CHO RDA instruction. Using the CHO RDA with RAMP limits you ( a bit) to a max of 4096 samples, which is actually plenty for this.

Then you'd need to make a control signal which is a fixed value (the center) combined with an adjustable width (you can use the SIN LFO with CHO RDAL).

You'll want to be careful that the sum of the center and +/- width stays inside the range of 0 - 4095 of the buffer.

I'm a little surprised that the example you gave didn't work out, although in my experience, a max swing of only 3 msec when the total delay time is 30 msec is not going to give a strong chorusing effect.

It's an interesting challenge.

See if this is more along the lines of what you want.

It uses a servo delay block.

Pot 0 controls the speed of SIN LFO 0.

The LFO is a SIN LFO scaled (by a following SOF) to go from 0 to (x) whatever the default WLDS width setting is. This is helpful in some cases because normally the SINx_WIDTH control adjusts +/- swings around the center point. In this case, the SIN goes up from 0 to the max level and then a following MULT with POT1 controls the excursion in just one direction. So you can use that directly for the delay time control to the servo without worrying about what happens if I go < 0.

Then I use Pot 2 mixed (added) with this scaled LFO to set, not the center point, but the lowest point of the LFO swing.

I didn't put too much effort into it and you may need to tweak the SOFs or whatever to give you more of what you are after.

The following code was generated by SpinCAD and is not the way you would necessarily go about it if you were writing the whole thing by hand. But I think the overall concepts still apply.

Code: Select all

; Patch Name: manual width control chorus-flanger.spcd
; SpinCAD Designer version: 956
; Pot 0: LFO speed
; Pot 1: LFO width
; Pot 2: delay minimum point
; 
; 
; ----------------------------
;------ Input
;------ Pot 2
;------ Pot 0
;------ Pot 1
;------ Scale/Offset
RDAX POT2,1.0000000000
SOF 0.4200000000,0.0000000000
WRAX REG0,0.0000000000
;------ Scale/Offset
RDAX POT0,1.0000000000
SOF 0.7500000000,0.2500000000
WRAX REG1,0.0000000000
;------ Scale/Offset
RDAX POT1,1.0000000000
SOF 0.9600000000,0.0400000000
WRAX REG2,0.0000000000
;------ LFO 0
SKP RUN ,1
WLDS 0,100,5173
RDAX REG1,0.1956947162
WRAX SIN0_RATE,0.0000000000
CHO RDAL,0
SOF 0.5000000000,0.5000000000
WRAX REG3,0.0000000000
;------ Multiply
RDAX REG3,1.0000000000
MULX REG2
WRAX REG4,0.0000000000
;------ Volume
RDAX ADCL,0.6309573445
WRAX REG5,0.0000000000
;------ Mixer 2:1
RDAX REG4,1.0000000000
WRAX REG6,0.0000000000
RDAX REG0,1.0000000000
RDAX REG6,1.0000000000
WRAX REG6,0.0000000000
;------ Feedback Output
;------ Servo Flanger
SKP RUN ,1
WLDR 0, 0, 4096
CLR
RDAX REG7,0.5000000000
RDAX REG5,1.0000000000
WRA 0,0.0
CHO RDAL,2
RDAX REG6,-0.2500000000
WRAX RMP0_RATE,0.0000000000
CHO RDA,2,REG | COMPC,0
CHO RDA,2,0,1
RDFX REG9,0.2500000000
WRLX REG9,-1.0000000000
WRAX REG8,0.0000000000
CLR
OR $007FFF00
SOF 0.0029687500,0.0001867676
WRAX ADDR_PTR,0.0000000000
RMPA 1.0
WRAX REG10,0.0000000000
;------ Mixer 2:1
RDAX REG8,1.0000000000
RDAX REG10,1.0000000000
WRAX REG11,0.0000000000
;------ Phase_Invert
RDAX REG8,-1.0000000000
WRAX REG12,0.0000000000
;------ Output
RDAX REG11,1.0000000000
RDAX REG11,1.0000000000
WRAX DACL,1.0000000000
WRAX DACR,0.0000000000
;------ FB In 1
RDAX REG12,1.0000000000
WRAX REG7,0.0000000000
Aaron
Posts: 54
Joined: Wed Mar 04, 2015 8:10 pm
Location: Oklahoma

Post by Aaron »

Thanks Larry! I actually just implemented this same concept a bit ago. I was finally able to figure out the scaling for the servo delay thanks to your findings. I have limited the delay time pot to go from ~ 3ms to 27ms and have an lfo which I just added into the "mpos" register. It is working exactly as I had hoped.

Code: Select all

skp	run,START			;
wldr	rmp0,0,1024			;initialize ramp for delay servo
wlds	sin0,0,98			;initialize sin0 for modulation
rdax	pot0,1				;get pot0
sof	0.1,0.0125			;scale for 3ms to 27ms
wrax	pot0fil,0				;save to pot0fill


START:

cho	rdal,rmp0			;get value from rmp0
rdax	offset,-1				;subtract offset
wrax	rmp0_rate,0			;save to ramp rate, clear ACC

ldax	pot1				;load pot1
sof	0.0441,0.0049			;scale for 0.1Hz to 1Hz
wrax	sin0_rate,0			;save to sin0 rate, clear ACC

cho	rdal,sin0				;get sin0 value
skp	neg,LOW				;if sin0 value is negative do LOW
sof	0,0.0125			;positive output scaled at 3ms
skp	gez,OUT				;if sin0 value is >=0 then do OUT
LOW:
sof	0,0				;clear ACC
OUT:
wrax	lfo,0				;save to lfo, clear ACC


rdax	adcl,1				;get left input
wra	delayl,0				;save to delayl, clear ACC

rdax	pot0,1				;read pot0
sof	0.1,0.0125			;scale for 3ms to 27ms
rdax	lfo,1				;add modulation
rdfx	pot0fil,0.003827			;filter pot for smoother transistions
wrlx	pot0fil,-1			;
wrax	pot0fil,1				;save to pot0fil
wrax	offset,0				;save to offset, clear ACC

cho	rda,rmp0,reg|compc,delayl		;output of delayl
cho	rda,rmp0,0,delayl+1		;
rdax	adcl,1				;add left input				
wrax	dacl,0				;write to left out, clear ACC

I really appreciate all of the help! I tried using a square wave here just to see what it would sound like. It gives it a fairly unique feel, a bit more usable than I would have expected. Still needs some fine tuning but the concept definitely works.
Post Reply