Page 3 of 3

Posted: Wed Mar 09, 2011 10:08 pm
by frank
Ah, well, that is not what I thought you were trying to do, I thought you were trying to make it fade out over time in playback mode. Adjusting the delay length involves some deeper understanding of memory addressing in the FV-1.

So, when I said the problem is here:
wrax reg0,1 ; write the value to reg0, save it for later

I thought you wanted to fade out and the solution to do that is to change the line to:
wrax reg0,0 ; write the value to reg0, save it for later

The "1" coefficient is keeping the value in the accumulator so the next line:
rda delL#,1 ; Read tail of left delay

Is adding the accumulator to the value read from the end of the delay so it was constantly increasing and saturating the output.

Posted: Thu Mar 10, 2011 11:21 am
by soundsubs
see, this makes perfect sense to me when you put it that way. thanks!

for the operation "adjustment of the delay length which is sustained" it shouldnt be any different than a typical delay adjustment length code snippet.
i'll see if i can dig that up and burn it when im back home.

Posted: Fri Mar 11, 2011 2:03 pm
by soundsubs
Tried the following:

Code: Select all

; this is borrowed heavily from the delay/play alg posted by frank
; meant to be a "freeze" effect where it samples input and 
; outputs a shortened loop of the input audio, near a single cycle. 
; If POT0 is 0 to 0.5 we are in record mode 
; If 0.5 to 0.999 we are in playback mode 
; 
delL mem 4096 		; Define delay as really really small 
ldax pot0 		; Read in POT0 
sof 1.0,-0.5 		; Add -0.5 to the POT0 value so it ranges -0.5 to +0.5 
skp gez,play 		; If ACC is >=0 we are in playback mode so jump to play 
ldax adcl 		; Read in ADC left 
wra delL,1.0 		; Write to left delay line 
wrax dacl,0 		; and to DAC left 
wra delL#,0 		; write 0 at end of delay line to limit record length 
skp zro, end 		; Jump to end 
; 
; Play back mode 
play: 
clr ; Clear ACC 
rda delL#,1.0 		; Read tail of left delay 
wra delL,1.0 		; Write to head of delay 
wrax dacl,0 		; Write it to DAC left 
wra delL#,0 		; write a 0 to end of delay, not really needed but will make sure rest of memory is 0 if you add other functions 
;
;get address pointer from pot1: 
;
rdax   pot1,1 		; Read value of Pot1, multiply by 1
and   %01111110_00000000_00000000   ;don't make jumps too small 
sof   61/64,3/64         	;50 ms to 1 second 
wrax   addr_ptr,0 
; 
end:
....hoping that POT1 would adjust buffer amount, but it doesnt.
do i need to have the POT1 portion elsewhere in the code?

thanks in advance.

Posted: Sat Mar 12, 2011 6:11 am
by slacker
The way you've done the code for the pot it's just stuck at the end of the program and doesn't do anything.
What the code does is read the value from the pot and writing it to the delay memory address pointer. In order to make it do anything you then need to read from the address pointer instead of reading from the tail of the delay.

I think this should work, it will set the buffer length anywhere from 0 to 4096 samples. It will probably won't work if you change the buffer size whilst it's playing back, you'd need to set it and then record another loop to hear the effect.

Code: Select all

; this is borrowed heavily from the delay/play alg posted by frank
; meant to be a "freeze" effect where it samples input and
; outputs a shortened loop of the input audio, near a single cycle.
; If POT0 is 0 to 0.5 we are in record mode
; If 0.5 to 0.999 we are in playback mode
;
delL mem 4096       ; Define delay as really really small
ldax pot0       ; Read in POT0
sof 1.0,-0.5       ; Add -0.5 to the POT0 value so it ranges -0.5 to +0.5
skp gez,play       ; If ACC is >=0 we are in playback mode so jump to play
ldax adcl       ; Read in ADC left
wra delL,1.0       ; Write to left delay line
wrax dacl,0       ; and to DAC left
wra delL#,0       ; write 0 at end of delay line to limit record length
skp zro, end       ; Jump to end
;
; Play back mode
play:
clr ; Clear ACC

rdax   pot1,0.125       ; Read value of Pot1, divide by 8 to scale from 0 to 4096
wrax   addr_ptr,0
rmpa 1               ; Read from address pointer
wra delL,1.0       ; Write to head of delay
wrax dacl,0       ; Write it to DAC left
wra delL#,0       ; write a 0 to end of delay, not really needed but will make sure rest of memory is 0 if you add other functions
;
end:
I think that's correct, I'm not 100% sure about scaling the pot, I've only just started messing with this stuff.

Posted: Sat Mar 12, 2011 9:22 am
by soundsubs
Thanks slacker!

this is ALMOST working perfectly:

Code: Select all

; this is borrowed heavily from the delay/play alg posted by frank 
; meant to be a "freeze" effect where it samples input and 
; outputs a shortened loop of the input audio, near a single cycle. 
; If POT0 is 0 to 0.5 we are in record mode 
; If 0.5 to 0.999 we are in playback mode 
; 
delL mem 8148       	; Define delay as small 
ldax pot0       		; Read in POT0 
sof 1.0,-0.5       		; Add -0.5 to the POT0 value so it ranges -0.5 to +0.5 
skp gez,play       		; If ACC is >=0 we are in playback mode so jump to play 
ldax adcl       		; Read in ADC left 
wra delL,1.0       		; Write to left delay line 
wrax dacl,0       		; and to DAC left 
wra delL#,0       		; write 0 at end of delay line to limit record length 
skp zro, end       		; Jump to end 
; 
; Play back mode 
play: 
clr 			; Clear ACC 

rdax   pot1,0.5       	; Read value of Pot1, divide by 2 to scale from 0 to 8148 
and   %01111111_10000000_00000000 
sof  243/256,13/256         ;50 ms to 1 second 
wrax   addr_ptr,0 
rmpa 1               		; Read from address pointer 
wra delL,1.0       		; Write to head of delay 
wrax dacl,0       		; Write it to DAC left 
wra delL#,0       		; write a 0 to end of delay, not really needed but will make sure rest of memory is 0 if you add other functions 
; 
end:



it will even "hold" the buffer while i move POT1! this makes for really interesting effects that happen while the buffer is moving around.
the only issue is that when POT1 is above about 45%, the buffer is silent.
any ideas?

Posted: Sat Mar 12, 2011 9:57 am
by slacker
I think your pot scaling is wrong, the maximum length is 32767 so to get to 8148 you need to deivide by 4 not 2. What's probably happening now is once you get past half way you'e gone outside the buffer.

Posted: Sat Mar 12, 2011 4:50 pm
by soundsubs
ok here it is:

Code: Select all

; this is borrowed heavily from the delay/play alg posted by frank 
; meant to be a "freeze" effect where it samples input and 
; outputs a shortened loop of the input audio, near a single cycle. 
; If POT0 is 0 to 0.5 we are in record mode 
; If 0.5 to 0.999 we are in playback mode 
; 
delL mem 8148       	; Define delay as small 
ldax pot0       		; Read in POT0 
sof 1.0,-0.5       		; Add -0.5 to the POT0 value so it ranges -0.5 to +0.5 
skp gez,play       		; If ACC is >=0 we are in playback mode so jump to play 
ldax adcl       		; Read in ADC left 
wra delL,1.0       		; Write to left delay line 
wrax dacl,0       		; and to DAC left 
wra delL#,0       		; write 0 at end of delay line to limit record length 
skp zro, end       		; Jump to end 
; 
; Play back mode 
play: 
clr 			; Clear ACC 
rdax   pot1,1       		; Read value of POT1, multiply by 1 to get a positive integer
mulx   pot1		; multiply the value in POT1 by itself
mulx   pot1		; multiply the value by itself again
and   %01111111_10000000_00000000 
sof  243/256,13/256         ; 50 ms to 1 second 
wrax   addr_ptr,0 
rmpa 1               		; Read from address pointer 
wra delL,1.0       		; Write to head of delay 
wrax dacl,0       		; Write it to DAC left 
; 
end:

this will take the input, loop it infinitely if POT0 is above halfway
POT1 controls Loop buffer length.

lots and lots of fun here.


....now, to figure out the livecut algorithm.

Posted: Wed Mar 16, 2011 8:57 am
by jovesdies
Hi,
I think that there is a better way to do "freeze" effect.
The problem with the posted code is the "click" sound due to the fact that the recorded sample doesn't start and stop at the same point.

Now, we can use the delay program with infinite feedback with this setup:
left channel for "freeze" effect only, right channel for clean, direct signal.
Set the initial feedback short and connect a momentary switch to the feedback pot so when the switch is pressed we turn the pot to max (infinite feedback). then we must tell the program to don't read anymore from left channel. In this way we can play over the feedback signal recorded.
Now, I don't know where to start to program but if there is anyone who can ....

Posted: Sun Nov 25, 2012 6:33 am
by Alex MAK
Hi guys! This code works for me is not correct, it's like a tremolo effect. How can you get rid of this artifact? Thank you! Alex.

Posted: Mon Nov 26, 2012 2:13 pm
by slacker
The code Soundsubs posted should work fine, it does not give a smooth infinite sustain sound though, it just loops short sections of audio. If you want to make it smoother you could try adding some reverb after it.
Or you could use a reverb program instead like Sean Costello suggested on the first page of this thread, the Reverb+HP+LP code in the free DSP programs section does this, works really well.

Posted: Mon Nov 26, 2012 11:16 pm
by Alex MAK
Thank you! I'll try it :)

Posted: Fri Aug 05, 2016 6:50 am
by MacroMachines
The best thing I've found so far is to use this rec/play but with a few allpass delays in the circulating locked feedback buffer, it blurs the loop from being a ridged stutter to being more of a spectral feeling hold.

Posted: Tue Dec 06, 2016 11:02 pm
by MacroMachines
Ive also been playing with a combination of the tap tempo/ flip flop code in other threads to create a zero crossing repeater. I would love to figure out a way to have start and end points of a loop able to snap to the nearest zero cross, but its a bit tricky. This would be good for both pitch shifting and sustain.