Trying to understand basic delay code

Software questions and issues with the FV-1

Moderator: frank

Post Reply
Alefal
Posts: 5
Joined: Mon Jul 09, 2018 3:41 am
Contact:

Trying to understand basic delay code

Post by Alefal »

Hello,

I try to understand the single delay bloc code from SpinCAD Designer. I already read all the FV-1 Datasheet, AN0001..
I understood that to get a delay effect we need to but a sample at the beginning of a delay line (= portion of the delay ram ?) and then read at another adress in the delay ram so the time if the repeats is related to the adress we read.
But there still some things I don't get/I'm not sure if it's working like I think it really is:

- Is each spinasm code running in a kind of infinite loop ? (if I understood the code we write is only for 1 audio sample )
- How the sample is moving into the delay ram ?
- Why are we writing the sample + all the ACC in the adress 0 of the delay ram and not just writing the sample itself ?
- How the repeats are created ?
- Are the 'lines which are useless to me' really useless ? (I tried to delet them and it still works so I assume these are automatically SpinCAD generated code lines to prevent that the ACC is really empty before doing some operations)
- If I want to get a 1000 ms delay can I just replace the lines 5 and 6 by SOF 0.0,1.0 ? What the point of having 2 lines here since we could just directly write SOF 0.0,0.25 ?

Here's the code with my comments.

Code: Select all

;Delay Analysis

;These two lines are useless
RDAX ADCL,0.5000000000 ;1 Read left ADC and put the half of the sample into the ACC
WRAX REG1,0.0000000000 ;2 Write the value of ACC into REG1 and clear the ACC

SOF 0.0000000000,0.4500000000 ;3 Put 0.45 into the ACC
WRAX REG1,0.0000000000 ;4 Write the value of ACC into REG1 and clear ACC
SOF 0.0000000000,0.9990000000 ;5 Put 0.999 into ACC 
SOF 0.2500000000,0.0000305176 ;6 ACC*0.25 + 0.0000305176
WRAX ADDR_PTR,0.0000000000 ;7 Write ACC into ADDR_PTR and clear ACC
RMPA 1.0 ;8 Read from the RAM (so RAMADDRESS = ADDR_PTR, (so the value of ADDR_PTR contain the time since we're reading at this adress), 
	;multiply the value by C (if C>1 we start to have self oscillation of the delay)
WRAX REG0,1.0000000000 ;9 write ACC into REG0 and keep the value into ACC too
MULX REG1 ;10 Multiply ACC with REG1 value and put the result into ACC
RDAX ADCL,0.5000000000 ;11 Read left ADC and put the half of the sample into the ACC and add it with the old ACC value
WRA 0,0.0 ;12 Write ACC into the RAM at the @0 and clear ACC

;These two lines are useless
RDAX REG0,1.0000000000 ;13 Put REG0 value into ACC and keep ACC value 
WRAX REG0,0.0000000000 ;14 Write REG0 value into ACC and clear ACC

;------ Output
RDAX REG0,1.0000000000 ;15 Read REG0 value and put it into ACC
WRAX DACR,0.0000000000 ;16 Write ACC into right channel DAC and clear ACC
I'm sorry these are really basic questions but I couldn't find any answers about how the delay ram is really working in the FV-1.
I have already some knowledge in uP, uC and programing but it's the first time for me with DSP stuff so if you know any good books which can help me to understand how the delay ram is working I would be really interested!

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

Re: Trying to understand basic delay code

Post by frank »

Alefal wrote: Tue Jul 10, 2018 6:23 am - Is each spinasm code running in a kind of infinite loop ? (if I understood the code we write is only for 1 audio sample )
Basically, yes. The program is run on every sample
Alefal wrote: Tue Jul 10, 2018 6:23 am - How the sample is moving into the delay ram ?
The lines:
RDAX ADCL,0.5000000000 ;11 Read left ADC and put the half of the sample into the ACC and add it with the old ACC value
WRA 0,0.0
Are reading in the sample*0.5, adding to the current acc and writing to delay RAM
Alefal wrote: Tue Jul 10, 2018 6:23 am - Why are we writing the sample + all the ACC in the adress 0 of the delay ram and not just writing the sample itself ?
Depends on the desired effect, often this is done to create repeats, a filter, etc..
Alefal wrote: Tue Jul 10, 2018 6:23 am - How the repeats are created ?
Generally read the end of the delay line, multiply it by < 1.0 and add in the input then write result to head of delay.
Alefal wrote: Tue Jul 10, 2018 6:23 am - Are the 'lines which are useless to me' really useless ? (I tried to delet them and it still works so I assume these are automatically SpinCAD generated code lines to prevent that the ACC is really empty before doing some operations)
- If I want to get a 1000 ms delay can I just replace the lines 5 and 6 by SOF 0.0,1.0 ? What the point of having 2 lines here since we could just directly write SOF 0.0,0.25 ?
Best to ask these at the SpinCAD site so they can explain why they made certain decisions
Alefal wrote: Tue Jul 10, 2018 6:23 am I'm sorry these are really basic questions but I couldn't find any answers about how the delay ram is really working in the FV-1.
I have already some knowledge in uP, uC and programing but it's the first time for me with DSP stuff so if you know any good books which can help me to understand how the delay ram is working I would be really interested!
Look up "circular buffers" as applied to DSP and that will make things clearer, in the FV-1 we use a down counter that is decremented by 1 each sample period and is added to the address in the instruction so the physical address is always moving due to the down counter.
Frank Thomson
Experimental Noize
Alefal
Posts: 5
Joined: Mon Jul 09, 2018 3:41 am
Contact:

Re: Trying to understand basic delay code

Post by Alefal »

Thanks a lot for your reply, this already makes things clearer. I will read some stuff about circular buffers.
potul
Posts: 76
Joined: Tue Sep 26, 2017 12:33 am

Re: Trying to understand basic delay code

Post by potul »

Alefal wrote: Tue Jul 10, 2018 6:23 am
- How the repeats are created ?
I honestly think this block is wrong.... feedback control is not doing anything. I use the "Coarse Delay" instead.

- If I want to get a 1000 ms delay can I just replace the lines 5 and 6 by SOF 0.0,1.0 ? What the point of having 2 lines here since we could just directly write SOF 0.0,0.25 ?
The reason for having 2 lines is the way SpinCAD is replacing some instructions depending on what is connected to the pins. If you connect a pot to the "time" pin you will see one of this lines gets replaced by a RDAX reading the Pot value. This additional sentence is replacing this when there is nothing connected to the pin.
Digital Larry
Posts: 338
Joined: Mon Nov 12, 2012 1:12 pm
Contact:

Re: Trying to understand basic delay code

Post by Digital Larry »

Please do ask questions about SpinCAD over at my forum. I am not a Spin employee. Sometimes I can't even remember why I did certain things, especially on the earliest blocks I developed, but I'll try. At one point I probably thought, "I know! I'll put some really stupid nonsensical things in my code that don't do anything, so I can see if anyone uses it or asks why!"

FYI my go-to delay block is the triple-tap delay. It only generates code for the taps which you have connected and has an external feedback loop.

In some cases SpinCAD generates code which is somewhat incomprehensible to those familiar with writing Spin ASM. Lots of times in Spin ASM you can make simplifying assumptions, for example if the delay buffer begins at zero, but in SpinCAD no such assumptions are made, so pointer arithmetic can look a little baffling. No explicit buffer references are made as far as I remember.
Alefal
Posts: 5
Joined: Mon Jul 09, 2018 3:41 am
Contact:

Re: Trying to understand basic delay code

Post by Alefal »

Thanks for your replies.

Digital Larry, I'm sorry, I will post specific SpinCAD questions on the SpinCAD forum next time.
My questions were more related to the spinasm part and the delay ram that's why I posted here.
Alefal
Posts: 5
Joined: Mon Jul 09, 2018 3:41 am
Contact:

Re: Trying to understand basic delay code

Post by Alefal »

I'm still stuggling a bit with the full understanding of the delay ram
So if I understood well, the delay ram IS a circular buffer ?
With a 32kHz clock we get a 1/32kHz sample rate so if we set a 32k (bits?) delay line, we will get 1000ms, so the maximum delay time. Is that correct to think about just making a cross-multiplication to get a precise delay time ?

I have a more precise question about the ping pong delay code, because i don't really get how you set the delay line, I mean the value you wrote inside the delay ram. I don't get why you multiply ping_len and pong_len by 256. Why do we want to alligned the delay length to ACC[22:8] ?And what ACC[22:8] means ? I studied some programming languages and to me this [A:B] means that we take the bits between A and B in a table but i'm a bit confused about going from the 22nd bit to the 8th.. This means nothing to me

Code: Select all

; Smooth POT0
clr				; Clear the ACC
or 	ping_len*256		; Put delay length into ACC alligned to ACC[22:8]
mulx 	pot0			; Multiply by POT0, new target value
rdfx 	ping_addr, smooth		; Smooth it
wrax 	ping_addr, 0		; Save it
or	ping*256			; Load ping base address
rdax	ping_addr,1.0		; add pointer offset
wrax 	addr_ptr, 0		; Write it to the address pointer register
rmpa 	1			; Read from memory
wrax	ping_data,0		; Write data from delay output to register

; Smooth POT1
or 	pong_len*256		; Put delay length into ACC alligned to ACC[22:8]
mulx 	pot1			; Multiply by POT1, new target value
rdfx 	pong_addr, smooth		; Smooth it
wrax 	pong_addr, 0		; Save it
or	pong*256			; Load pong base address
rdax	pong_addr,1.0		; add pointer offset
wrax 	addr_ptr, 0		; Write it to the address pointer register
rmpa 	1			; Read from memory
wrax	pong_data,0		; Write data from delay output to register
frank
Posts: 1244
Joined: Wed Oct 19, 2005 12:26 pm
Contact:

Re: Trying to understand basic delay code

Post by frank »

Yes, the entire delay RAM is a circular buffer. You can break it up into smaller parts depending on program needs but you do not need to concern yourself with the details just define memory areas and use them.

32K samples, each sample is a 14-bit compressed value. Data compression/decompression happens automatically and you do not need to do anything. Just read and write to the memory.

RMAP uses bits [22:8] in the addr_ptr register as the memory address to read from. If you are not use to bit fields and bit masks I suggest you read up on basic microprocessor programming in assembly. Forget everything you know about high level languages and start with basic digital logic bit-wise AND/OR/NOT, basic assembly languages and syntax, etc.
Frank Thomson
Experimental Noize
Alefal
Posts: 5
Joined: Mon Jul 09, 2018 3:41 am
Contact:

Re: Trying to understand basic delay code

Post by Alefal »

Thanks for your reply

I have another question about the circular buffer. Since we always write the sample at the same adress (which is the begining of the delay line) and read the dealy the sample at the same adress (end of the delay line), how can the sample goes from the begining to the end ? Does this would mean the sample is automatically changing of adress everytime we add another sample in the delay ram until it reaches the end of the delay line ?
I know I do not need this to program the delay but I really like to understand in depth what's happening with the samples.

Thanks, i will look for basic up and digital logic stuff, any books or websites recommendations are welcomed too.
frank
Posts: 1244
Joined: Wed Oct 19, 2005 12:26 pm
Contact:

Re: Trying to understand basic delay code

Post by frank »

As I noted in an earlier reply the address in the instruction is added to a down counter that is decremented once each sample period and the result is the physical address. This counter creates the circular buffer as it rolls over after 32K sample periods.

No specific books but you will need to understand bit level manipulation and operations, saturating and non-saturating math, etc. It is a different way of thinking about programming versus languages like C++.
Frank Thomson
Experimental Noize
Post Reply