Phaser/allpass filter code

Algorithm development and general DSP issues

Moderator: frank

seancostello
Posts: 74
Joined: Mon Sep 11, 2006 10:04 pm

Post by seancostello »

mdroberts1243 wrote: I don't understand the 'post' processing chorus stuff that is done in a lot of the reverb example programmes... is that explained anywhere? I'm trying to implement the modulated output taps directly in the allpass as shown in a lot of reverb flow-diagrams instead.
It's not really post-processing, so much as a decision about where to place the modulation code in the code listing. You could construct an allpass filter by writing into a delay, reading out a modulated tap, and then putting feedforward and feedback paths around the structure, but this would take more cycles than the 2-cycle allpasses that the FV-1 can perform. So, the Spin Semi examples modulate the allpass delays by the following process:

- Calculate the allpass delay using the 2-cycle method;
- Perform a modulated read from somewhere in the "middle" of the delay memory INSIDE of the allpass delay;
- Write the result back into the allpass delay memory.

In order to do this, you need to allow room for the modulation width. Otherwise, you might write to a location that precedes where you read from in time, and you will create an unstable feedback loop. So, if you read from location N, and your modulation width is M, you should write to a memory location that is greater than or equal to N+M. Don't forget to incorporate this modulation width room into the delay length of your allpasses.

Sean Costello
mdroberts1243
Posts: 18
Joined: Tue Jul 22, 2008 3:54 pm
Location: Ottawa, Canada
Contact:

Post by mdroberts1243 »

Thanks Frank & Sean!

Sean, is the chorus modification of the 'interior' values equivalent to reading from a variable end-point like the Dattorro paper block diagram does? Could I simplify my implementation of the Plate (separate thread) by using the two-step AP where possible and then doing a chorus modification at the end of the code?
-mark
My blog: http://tubenexus.com
MacroMachines
Posts: 71
Joined: Fri Dec 12, 2014 10:45 pm
Location: Detroit,MI
Contact:

Post by MacroMachines »

seancostello wrote:

- Calculate the allpass delay using the 2-cycle method;
- Perform a modulated read from somewhere in the "middle" of the delay memory INSIDE of the allpass delay;
- Write the result back into the allpass delay memory.

In order to do this, you need to allow room for the modulation width. Otherwise, you might write to a location that precedes where you read from in time, and you will create an unstable feedback loop. So, if you read from location N, and your modulation width is M, you should write to a memory location that is greater than or equal to N+M. Don't forget to incorporate this modulation width room into the delay length of your allpasses.

Sean Costello
Do you possibly have an example of this I could reference? I think I understand the structure but not confident I understand the implementation.
http://MacroMachines.net
Digital Control for your Analog Soul.
MacroMachines
Posts: 71
Joined: Fri Dec 12, 2014 10:45 pm
Location: Detroit,MI
Contact:

Post by MacroMachines »

Im working on a version so I can set the all pass delay time and coefficient dynamically, Im currently looking for a good way to scale the value for addr_ptr. Im assuming something like:

SOF maxLength/32767, offset.

Is there any comprehensive example of how to work with variable delay times? The best I have found so far is the OEM_5 which is an analog style echo and also features manual interpolation which appears to require a fair number of SOF opcodes to scale up the interpolation coefficient. Are there any other methods for interpolation of a variable delay line that might take less ops? I have read the application notes on the ramp and tried the technique in there but it doesn't appear to work with adds_ptr and is causing some very odd results in my tests.

Code: Select all

mem	delay		2000
equ	temp		reg0
equ	coefficient	pot0
equ	time		pot1

rdax	time,	1
wrax	addr_ptr,	0


rdax	adcl,	1
wrax 	temp, 	0 
rmpa	1
;rda 	delay#, 	1 	; allpass with WRAP replaced to use variable coefficient 
mulx 	coefficient 
rdax 	temp,	1 	; add input *NEW* 
wra 	delay, 	-1 	; store to delay and then negate ACC 
mulx 	coefficient 	; apply 'negative' coefficient 
rmpa	1
;rda 	delay#, 	1 	; add in the end entry in the delay


wrax	dacl,	1
wrax	dacr,	0
http://MacroMachines.net
Digital Control for your Analog Soul.
Post Reply