Spin Semiconductor Forum Index Spin Semiconductor
Support forum
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

freeverb implementation

 
Post new topic   Reply to topic    Spin Semiconductor Forum Index -> Algorithm development
View previous topic :: View next topic  
Author Message
basilrush



Joined: 01 Nov 2011
Posts: 2
Location: United Kingdom

PostPosted: Tue Nov 01, 2011 11:37 am    Post subject: freeverb implementation Reply with quote

Now, maybe it's already been done, but I needed a little project to get going. I've ported the freeverb code from C to FV-1. It sounds quite nice, but need to do some more testing and perhaps compare against the real thing. I suspect that I've ended up doing slightly different allpass filters.

However, I've also run out of space for more instructions and it'd be good to make the damping variable too. Any optimisations anyone can suggest? I had to leave out the last allpass on the right channel...

Code:
Code:



equ comb1filt 32
equ comb2filt 33
equ comb3filt 34
equ comb4filt 35
equ comb5filt 36
equ comb6filt 37
equ comb7filt 38
equ comb8filt 39

equ combR1filt 32+12
equ combR2filt 33+12
equ combR3filt 34+12
equ combR4filt 35+12
equ combR5filt 36+12
equ combR6filt 37+12
equ combR7filt 38+12
equ combR8filt 39+12

equ combfeedback pot0
equ stereospread 23
equ filtco 0.5
equ allpassamt 0.5
mem comb1 1116
mem comb2 1188
mem comb3 1277
mem comb4 1356
mem comb5 1422
mem comb6 1491
mem comb7 1557
mem comb8 1617

mem combR1 1116+stereospread
mem combR2 1188+stereospread
mem combR3 1277+stereospread
mem combR4 1356+stereospread
mem combR5 1422+stereospread
mem combR6 1491+stereospread
mem combR7 1557+stereospread
mem combR8 1617+stereospread

mem allpass1 556
mem allpass2 441
mem allpass3 341
mem allpass4 225

mem allpassR1 556+stereospread
mem allpassR2 441+stereospread
mem allpassR3 341+stereospread
mem allpassR4 225+stereospread

; LEFT CHANNEL

;* NOW do freeverb style comb with lowpass filters, sum outputs
; output = delay output
; delay-input = [filteredoutput * feedback + input]

; get delay and one pole low pass
rda comb1#, 1-filtco ; read delay output
rdax comb1filt, filtco ; filter using one sample delay
wrax comb1filt, 1 ; store one sample delay, scale by feedback amount
mulx combfeedback
rdax adcl, 0.5 ; add the input
wra comb1, 0 ; write to the buffer

rda comb2#, 1-filtco ; read delay output
rdax comb2filt, filtco ; filter using one sample delay
wrax comb2filt, 1 ; store one sample delay, scale by feedback amount
mulx combfeedback
rdax adcl, 0.5 ; add the input
wra comb2, 0 ; write to the buffer

rda comb3#, 1-filtco ; read delay output
rdax comb3filt, filtco ; filter using one sample delay
wrax comb3filt, 1 ; store one sample delay, scale by feedback amount
mulx combfeedback
rdax adcl, 0.5 ; add the input
wra comb3, 0 ; write to the buffer

rda comb4#, 1-filtco ; read delay output
rdax comb4filt, filtco ; filter using one sample delay
wrax comb4filt, 1 ; store one sample delay, scale by feedback amount
mulx combfeedback
rdax adcl, 0.5 ; add the input
wra comb4, 0 ; write to the buffer

rda comb5#, 1-filtco ; read delay output
rdax comb5filt, filtco ; filter using one sample delay
wrax comb5filt, 1 ; store one sample delay, scale by feedback amount
mulx combfeedback
rdax adcl, 0.5 ; add the input
wra comb5, 0 ; write to the buffer

rda comb6#, 1-filtco ; read delay output
rdax comb6filt, filtco ; filter using one sample delay
wrax comb6filt, 1 ; store one sample delay, scale by feedback amount
mulx combfeedback
rdax adcl, 0.5 ; add the input
wra comb6, 0 ; write to the buffer

rda comb7#, 1-filtco ; read delay output
rdax comb7filt, filtco ; filter using one sample delay
wrax comb7filt, 1 ; store one sample delay, scale by feedback amount
mulx combfeedback
rdax adcl, 0.5 ; add the input
wra comb7, 0 ; write to the buffer

rda comb8#, 1-filtco ; read delay output
rdax comb8filt, filtco ; filter using one sample delay
wrax comb8filt, 1 ; store one sample delay, scale by feedback amount
mulx combfeedback
rdax adcl, 0.5 ; add the input
wra comb8, 0 ; write to the buffer

; RIGHT CHANNEL

;* NOW do freeverb style combR with lowpass filters, sum outputs
; output = delay output
; delay-input = [filteredoutput * feedback + input]

; get delay and one pole low pass
rda combR1#, 1-filtco ; read delay output
rdax combR1filt, filtco ; filter using one sample delay
wrax combR1filt, 1 ; store one sample delay, scale by feedback amount
mulx combfeedback
rdax adcl, 0.5 ; add the input
wra combR1, 0 ; write to the buffer

rda combR2#, 1-filtco ; read delay output
rdax combR2filt, filtco ; filter using one sample delay
wrax combR2filt, 1 ; store one sample delay, scale by feedback amount
mulx combfeedback
rdax adcl, 0.5 ; add the input
wra combR2, 0 ; write to the buffer

rda combR3#, 1-filtco ; read delay output
rdax combR3filt, filtco ; filter using one sample delay
wrax combR3filt, 1 ; store one sample delay, scale by feedback amount
mulx combfeedback
rdax adcl, 0.5 ; add the input
wra combR3, 0 ; write to the buffer

rda combR4#, 1-filtco ; read delay output
rdax combR4filt, filtco ; filter using one sample delay
wrax combR4filt, 1 ; store one sample delay, scale by feedback amount
mulx combfeedback
rdax adcl, 0.5 ; add the input
wra combR4, 0 ; write to the buffer

rda combR5#, 1-filtco ; read delay output
rdax combR5filt, filtco ; filter using one sample delay
wrax combR5filt, 1 ; store one sample delay, scale by feedback amount
mulx combfeedback
rdax adcl, 0.5 ; add the input
wra combR5, 0 ; write to the buffer

rda combR6#, 1-filtco ; read delay output
rdax combR6filt, filtco ; filter using one sample delay
wrax combR6filt, 1 ; store one sample delay, scale by feedback amount
mulx combfeedback
rdax adcl, 0.5 ; add the input
wra combR6, 0 ; write to the buffer

rda combR7#, 1-filtco ; read delay output
rdax combR7filt, filtco ; filter using one sample delay
wrax combR7filt, 1 ; store one sample delay, scale by feedback amount
mulx combfeedback
rdax adcl, 0.5 ; add the input
wra combR7, 0 ; write to the buffer

rda combR8#, 1-filtco ; read delay output
rdax combR8filt, filtco ; filter using one sample delay
wrax combR8filt, 1 ; store one sample delay, scale by feedback amount
mulx combfeedback
rdax adcl, 0.5 ; add the input
wra combR8, 0 ; write to the buffer


;LEFT CHANNEL

;* NOW sum outputs
rda comb1#, 1
rda comb2#, 1
rda comb3#, 1
rda comb4#, 1
rda comb5#, 1
rda comb6#, 1
rda comb7#, 1
rda comb8#, 1

; feed through allpass filters in series

; get delay -> add to -1*acc ->

rda allpass1#, -allpassamt
wrap allpass1, allpassamt
rda allpass2#, -allpassamt
wrap allpass2, allpassamt
rda allpass3#, -allpassamt
wrap allpass3, allpassamt
rda allpass4#, -allpassamt
wrap allpass4, allpassamt


;** OUTPUT
wrax dacl, 0

; RIGHT CHANNEL

;* NOW sum outputs
rda combR1#, 1
rda combR2#, 1
rda combR3#, 1
rda combR4#, 1
rda combR5#, 1
rda combR6#, 1
rda combR7#, 1
rda combR8#, 1

; feed through allpass filters in series

; get delay -> add to -1*acc ->

rda allpassR1#, -allpassamt
wrap allpassR1, allpassamt
rda allpassR2#, -allpassamt
wrap allpassR2, allpassamt
rda allpassR3#, -allpassamt
wrap allpassR3, allpassamt
;rda allpassR4#, -allpassamt
;wrap allpassR4, allpassamt

;** OUTPUT
wrax dacr, 0
Back to top
View user's profile Send private message
frank



Joined: 19 Oct 2005
Posts: 972

PostPosted: Tue Nov 01, 2011 3:52 pm    Post subject: Reply with quote

That is some nice code. Nothing is jumping out at me where you could save a few instructions, will continue to look...
_________________
Frank Thomson
Experimental Noize
Back to top
View user's profile Send private message Visit poster's website
basilrush



Joined: 01 Nov 2011
Posts: 2
Location: United Kingdom

PostPosted: Tue Nov 01, 2011 10:52 pm    Post subject: Reply with quote

Cheers - it sounds pretty good still even with the missing all pass at the end.

It'd be nice to make the filter in the comb filters variable too but I just can't see how that's possible within the instruction limit.

Actually, it's pretty ugly to do even one of the comb filters. I had a punt at it last night. Unfortunately putting a tone control on the end just doesn't sound the same as adjusting the filter co-efficient inside the comb filter.

Still, any bright ideas gratefully received.

I suppose I could try running the first four comb filters in mono and then splitting the sound - I imagine the stereo would be pretty good still and I'd recover some 20 or so instructions to play with.
Back to top
View user's profile Send private message
MacroMachines



Joined: 12 Dec 2014
Posts: 70
Location: Detroit,MI

PostPosted: Sun Jul 31, 2016 5:58 pm    Post subject: Reply with quote

I did a version in audulus where I used the comb sum for the left chanel and the all pass output for the right and it sounds great, here is a version like that:

Code:
equ combfeedback pot0
equ filtco 0.5
equ allpassamt 0.5

equ comb1filt 32
equ comb2filt 33
equ comb3filt 34
equ comb4filt 35
equ comb5filt 36
equ comb6filt 37
equ comb7filt 38
equ comb8filt 39

mem comb1 1116
mem comb2 1188
mem comb3 1277
mem comb4 1356
mem comb5 1422
mem comb6 1491
mem comb7 1557
mem comb8 1617

mem allpass1 556
mem allpass2 441
mem allpass3 341
mem allpass4 225



; LEFT CHANNEL ____________________________________
;* NOW do freeverb style comb with lowpass filters, sum outputs
; output = delay output
; delay-input = [filteredoutput * feedback + input]
; get delay and one pole low pass

rda comb1#, 1-filtco       ; read delay output
rdax comb1filt, filtco       ; filter using one sample delay
wrax comb1filt, 1       ; store one sample delay, scale by feedback amount
mulx combfeedback
rdax adcl, 0.5       ; add the input
wra comb1, 0       ; write to the buffer

rda comb2#, 1-filtco ; read delay output
rdax comb2filt, filtco ; filter using one sample delay
wrax comb2filt, 1 ; store one sample delay, scale by feedback amount
mulx combfeedback
rdax adcl, 0.5 ; add the input
wra comb2, 0 ; write to the buffer

rda comb3#, 1-filtco ; read delay output
rdax comb3filt, filtco ; filter using one sample delay
wrax comb3filt, 1 ; store one sample delay, scale by feedback amount
mulx combfeedback
rdax adcl, 0.5 ; add the input
wra comb3, 0 ; write to the buffer

rda comb4#, 1-filtco ; read delay output
rdax comb4filt, filtco ; filter using one sample delay
wrax comb4filt, 1 ; store one sample delay, scale by feedback amount
mulx combfeedback
rdax adcl, 0.5 ; add the input
wra comb4, 0 ; write to the buffer

rda comb5#, 1-filtco ; read delay output
rdax comb5filt, filtco ; filter using one sample delay
wrax comb5filt, 1 ; store one sample delay, scale by feedback amount
mulx combfeedback
rdax adcl, 0.5 ; add the input
wra comb5, 0 ; write to the buffer

rda comb6#, 1-filtco ; read delay output
rdax comb6filt, filtco ; filter using one sample delay
wrax comb6filt, 1 ; store one sample delay, scale by feedback amount
mulx combfeedback
rdax adcl, 0.5 ; add the input
wra comb6, 0 ; write to the buffer

rda comb7#, 1-filtco ; read delay output
rdax comb7filt, filtco ; filter using one sample delay
wrax comb7filt, 1 ; store one sample delay, scale by feedback amount
mulx combfeedback
rdax adcl, 0.5 ; add the input
wra comb7, 0 ; write to the buffer

rda comb8#, 1-filtco ; read delay output
rdax comb8filt, filtco ; filter using one sample delay
wrax comb8filt, 1 ; store one sample delay, scale by feedback amount
mulx combfeedback
rdax adcl, 0.5 ; add the input
wra comb8, 0 ; write to the buffer



;LEFT CHANNEL

;* NOW sum outputs
rda comb1#, 1
rda comb2#, 1
rda comb3#, 1
rda comb4#, 1
rda comb5#, 1
rda comb6#, 1
rda comb7#, 1
rda comb8#, 1

;** OUTPUT
wrax dacl, 1
; feed through allpass filters in series

; get delay -> add to -1*acc ->

rda allpass1#, -allpassamt
wrap allpass1, allpassamt
rda allpass2#, -allpassamt
wrap allpass2, allpassamt
rda allpass3#, -allpassamt
wrap allpass3, allpassamt
rda allpass4#, -allpassamt
wrap allpass4, allpassamt



; RIGHT CHANNEL

;** OUTPUT
wrax dacr, 0





Also you could use a temp register for continual summing each comb into one register and that might save some instructions.
_________________
http://MacroMachines.net
Digital Control for your Analog Soul.
Back to top
View user's profile Send private message Visit poster's website AIM Address
Display posts from previous:   
Post new topic   Reply to topic    Spin Semiconductor Forum Index -> Algorithm development All times are GMT - 8 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group