Need a 3th RAMP LFO for sample interpolation

Software questions and issues with the FV-1

Moderator: frank

Post Reply
Felix
Posts: 5
Joined: Sat Dec 27, 2008 3:13 am

Need a 3th RAMP LFO for sample interpolation

Post by Felix »

Hi,
I want to interpolate between two samples (bulding a continously varying delay). Best way should be using the RAMP LFO. At my application I need a 3th Delay and the two RAMP LFOs and SIN LFOs are already blocked for Delay 1&2. I found at in the OEM1_6Flanger a part, wich do the interpolation "diskret". But this programm needs 31 operations (of 128); thats to much !!!

Questions:
Is there another way for sample interpolation ?
How do the calc. for the pointer works (in both ways, using RAMP or diskret)

This is my example:

equ temp reg0 ;temp. Register
equ sample1 reg1
equ sample2 reg2
equ X_Fade reg3

Delay mem 32767 ;DelayLine

skp RUN,START
wldr rmp0,0,4096 ;DelayMemory=4096->max 125ms
wlds sin1,0,0

START:

ldax adcl
wra Delay,0

rdax pot0,0.5 ;read pot0 and scale to 0...0.5
wrax temp,0 ;save it, clear the ACC

;--------------------------------------------------------------------------------------
;calc. the Pointer - it works but i dont' know why
;--------------------------------------------------------------------------------------
cho rdal,rmp0 ;
rdax temp,-1 ;????
wrax rmp0_rate,0 ;

;--------------------------------------------------------------------------------------
;Use Chorus-Fuction and RAMP0-LFO as sample interpolator
;--------------------------------------------------------------------------------------
cho rda,rmp0,reg|compc,Delay ;Sample from Delay1 read,
cho rda,rmp0,0,Delay+1 ;Interpol. with Sample Delay+1
wrax dacr,0 ;output right, and clear ACC


;--------------------------------------------------------------------------------------
;Using SIN-LFO for interpolation. the next 5 lines do the same as above, ;but
;produce "glitches" when rotation the pot0 - why ????
;--------------------------------------------------------------------------------------
;rdax temp,1
;wrax sin1_range,0

;cho rda,sin1,cos|reg|compc,Delay
;cho rda,sin1,cos,Delay+1
;wrax dacl,0

;--------------------------------------------------------------------------------------
;found the following code in the OEM-Flanger,
;It makes sample interpolation without the CHO instruction
;produce also "glitches" when rotation the pot0 - why ????
;--------------------------------------------------------------------------------------
rdax temp,0.25 ;pot0 value, scale it cause addr_ptr ist 32768
;samples wide
;now pot0 produce a value from 0...0.125 =
;0....4096 samples
wrax addr_ptr,0 ;put into Addr_ptr
rmpa 1 ;read the sample
wrax sample1,0 ;save it, and clear ACC

or %00000000_00000001_00000000 ;put 1 into to ACC
rdax temp,0.25 ;add pot0 value
wrax addr_ptr,0 ;put into Addr_ptr
rmpa 1 ;read the next sample
wrax sample2,0 ;store it

;now derive an interpolation coefficient from LSBs of pointer:

rdax temp,0.25 ;the pot value
and %00000000_00000000_11111111 ;dont'know exactly what
;happens here, thing it blank out the
;"integer-part"
sof -2,0 ;this looks like a shifter,
sof -2,0 ;14 Bits
sof -2,0
sof -2,0
sof -2,0
sof -2,0
sof -2,0
sof -2,0
sof -2,0
sof -2,0
sof -2,0
sof -2,0
sof -2,0
sof -2,0
sof 1.9999,0 ;one more Bit ???
wrax X_Fade,0 ;store the X-Fade coefficient

;now interpolate between the two adjacent delay taps:

rdax sample2,1
rdax sample1,-1
mulx X_Fade ;crossfade with interpolation
rdax sample1,1
wrax dacl,0 ;Do you hear the glitches ???



;------ ENDE --------
frank
Posts: 1244
Joined: Wed Oct 19, 2005 12:26 pm
Contact:

Post by frank »

Hi Felix,

In answer to your direct questions, the example using 31 instructions is about the best I have seen, it takes a lot of instructions to generate a ramp, find the pointers, generate the coefficient, etc.

How the calculations work is simple to describe but a bit complex to implement.

Basically we have a value that is incremented by a fixed amount each sample period, this creates the upward sloping ramp. We allow it to rollover to drop back to zero when it passes it's high threshold (i.e. 1101 -> 1110 -> 1111 -> 0000) so this gives it the ramp shape (steady rise then sudden drop to zero).

This value can be though of as having an integer and a fractional portion, the integer portion is used as the address pointer and the fractional portion is the interpolation coefficient.

In the code you have:
and %00000000_00000000_11111111
and you are correct in your comments, it is getting rid of the integer part. The sof instructions that follow are just moving the fractional part into the correct position to do a multiply later.

Now, you can see why we created the two ramp generators in the chip, lots of things going on, lots of instructions if done in software. But do you really need them for a continuously variable delay? Depending on what you really want to do, maybe not. If your delay is just a variable length controlled by a pot input so it only changes when a user turns the pot and sits at a fixed setting otherwise, I wouldn't bother with interpolation. Just low-pass filter the pot value to avoid zipper noise and use the result as the pointer.
Frank Thomson
Experimental Noize
Felix
Posts: 5
Joined: Sat Dec 27, 2008 3:13 am

Post by Felix »

Hello Frank,

thanks for your fast answer. I have one question about "shifting bits" in the OEM1_6_Flanger Programm. Lets have a look at the following code:

and %00000000_00000000_11111111 ;keep fractional-part in acc
sof -2,0 ;this looks like a shifter,
sof -2,0 ;14 Bits to the left
sof -2,0
sof -2,0
sof -2,0
sof -2,0
sof -2,0
sof -2,0
sof -2,0
sof -2,0
sof -2,0
sof -2,0
sof -2,0
sof -2,0
sof 1.9999,0 ;and at last one more Bit to the left
wrax X_Fade,0 ;store the X-Fade coefficient

rdax sample2,1
rdax sample1,-1
mulx X_Fade ;crossfade with interpolation
rdax sample1,1
wrax dacl,0

From my point of view, we shift the lowerByte 15 bits to the left. If we are having an "S1.14 Fromat" for the crossfade coefficient, we find BitNo 7 at position 22, the Integer bit. I think we will have one "sof instruction" to much in the code.
But deleting one sof will have no audible effect.
Please remember that the prog. is orginal taken from your website.
Is there a software simulator/emulator available / planed so that we can step trough the code and watching the registers ?

At last i would like congratulate all Spin designers for this chip.
I never worked with audio dsp's any time before, but with this chip it is
quiet easy to make your own effects.

Thanks - and have a happy new year
frank
Posts: 1244
Joined: Wed Oct 19, 2005 12:26 pm
Contact:

Post by frank »

From my point of view, we shift the lowerByte 15 bits to the left. If we are having an "S1.14 Fromat" for the crossfade coefficient, we find BitNo 7 at position 22, the Integer bit. I think we will have one "sof instruction" to much in the code.
The MULX instruction treats the register value as a S0.15 format so we do want the 15 bit shift here.
Is there a software simulator/emulator available / planed so that we can step trough the code and watching the registers ?
Not at this time, all logic simulations were done in Verilog during development. I don't know if there will be a simulator released but elmood appears to be working on one http://www.spinsemi.com/forum/viewtopic.php?t=98 so you may check with him on status and if he plans to share it.
At last i would like congratulate all Spin designers for this chip.
Thanks, Keith and I did the entire chip design so we were the only designers. Basically I did the digital design and simulation and Keith did the analog design and simulation.
Frank Thomson
Experimental Noize
Zetopan
Posts: 7
Joined: Tue Jan 13, 2009 1:05 pm

Post by Zetopan »

Since SOF only allows a maximum multiplier of -2.0 it takes a lot of (paired)
SOF instructions to implement (even numbered) left shifts. Why not take
the LOG, adding N during the LOG, and then take the EXP to multiply by a
factor of 2^N?

Since the assumed format for a LOG output is S4.19 we can multiply by up
to 2^15 for each LOG and EXP instruction pair. However, the bad news is
that the input to the LOG can only be as small as 0.00001526. If you do
the math that value is equivalent to $000080. Thus for precision reasons
the first 8 shifts would need to be done using SOFs, but the remaining 6
could be done with a LOG EXP pair instead of 6 more SOF instructions.
Alternatively, 7 SOFs, an ABS and a LOG EXP pair would also perform the
same scaling, but the number of instructions is the same and you would
gain a bit more precision with the 8 SOF version.


AND $0000FF ; Extract the lowest byte
SOF -2.0, 0.0 ; and scale by 2^8
SOF -2.0, 0.0
SOF -2.0, 0.0
SOF -2.0, 0.0
SOF -2.0, 0.0
SOF -2.0, 0.0
SOF -2.0, 0.0
SOF -2.0, 0.0
LOG 1.0, 6.0 ; Finish scaling by 2^14
EXP 1.0, 0.0
Post Reply