SpinCAD Designer release 0.98-1037 - fixed Drum Delay block

Digital Larry

Active member

Build 1036 included a "Drum Delay" block which wasn't quite working properly. At the heart of the matter is the fact that SpinCAD Builder doesn't handle SKP instructions properly when there are extra directives like @isPinConnected between the SKP instruction and the target label. So I generated the JAVA from SpinCAD Builder and then edited the Java to make it work correctly. Had to rearrange things a little as well, but you don't really care about that.

So here's what it does. It is a 4-tap delay.
The first control input is Delay Time like all the other delay blocks.
The second control input is "Heads". At 0, only tap 1 comes out. At 0.25, tap 2 also comes out. At 0.5, tap 3 comes out, and yes you guessed it, at 0.75, all 4 taps are active. If "Heads" is not connected, all 4 taps are active. I'm not sure why you'd want to do that though.
The third control is feedback gain like all the other delay blocks.

The attached patch is stereo and you can hear the delays go from left to right, or the other way, depending on how your speakers are hooked up. Rename the WAV file to .spcd (this board will not allow an spcd or zip file to be uploaded).

I think it works! Give it a shot and let me know if you find any problems.

1709345950862.png
 

Attachments

  • drum-delay-stereo.wav
    11.5 KB
I kinda forgot how fun this could be. You can work so fast that it's not a big deal to come up with something crazy that you might only use once.

1709363317034.png
 
That's awesome Thanks Larry!! Indeed Spincad is so much fun, me & my band mate are just coming up with some wild patches that we've never thought of!
 
Last edited:
Here's another fun variation on the above. I set the mixer gains all back to 0 dB. The LFO is generating a quadrature output (0, 90, 180, 270 degrees) sine wave offset to (0 - 1.0), pairs of which 90 degrees apart are going to left/right mixer gain controls for each tap. This gives a panning side-to-side effect.

1709396453539.png

It's not quite "flying around your head" though. On two of the taps, I added an LPF that is also sweeping up and down although I'm not sure if I got the phase right. The idea being, that when the L/R levels are equal, the source appears to be in front of you. Or at least somewhere on the plane that would slice you into two symmetrical pieces. Now if we can make the filter be brightest at one such crossing, and darkest at another, I believe that the "flying around your head" illusion would be stronger.

Little more thought on this. The place where sin and cos cross is at 45 degrees. If I add sin + cos, I get a sine wave with peak value square root of two (1.414) 45 degrees lagged from the cosine wave. However, I'm not sure I would be able to optimize the ASM far enough to make that happen. Someone want to give it a try? ;)

1709400608527.png

This patch demonstrates something else. As shown it generates 129 instructions which won't assemble in the SpinASM IDE. However I show how to optimize it to remove one instruction. The most likely places where this can happen are when:
  • two blocks are connected
  • the destination only has one input
  • the source only goes to one destination.
I think the smoother after the Scale/Offset connected to Pot0 is a good candidate.

1709396357089.png

In the Spin ASM, I have moved the Smoother block to be just after the Scale/Offset block.

Note that because of the registers SpinCAD uses to connect blocks, you can move blocks around indiscriminately in SpinCAD generated ASM and it will still work. Well, "indiscriminately" might be overstating it because some things do want to be calculated before others. In this case, moving that block does not disturb any order of calculation concerns.

Next, I realize that this pair of instructions:

WRAX REG1, 0.0
RDAX REG1, 1.0


can be replaced by

WRAX REG1, 1.0

and so I do that. This saves 1 instruction and the program assembles now!

In fact, because the source only goes to one destination, I could have also removed:

WRAX REG1, 0.0

but I didn't since I only needed one instruction freed up.

Rename drum-delay-stereo-rotating.spcd.wav to drum-delay-stereo-rotating.spcd to load into SpinCAD Designer.
Rename drum-delay-stereo-spinning.spn.txt to drum-delay-stereo-spinning.spn to load into SpinASM IDE.
 

Attachments

  • drum-delay-stereo-spinning.spn.txt
    6.5 KB · Views: 1
  • drum-delay-stereo-rotating.spcd.wav
    15.7 KB
Last edited:
Hey Larry I managed to setup Eclipse today to try and add a new block & since I always wanted to mess with reversed buffers, so I decided to make the reverse reverb from Fv-1 programs repo but I failed miserably :ROFLMAO:

here is my snippet:

Code:
@name Reverse_Reverb
@color "0x7100fc"
@audioInput adcl Input_Left
@audioInput adcr Input_Right
@audioOutput dacl Output_Left
@audioOutput dacr Output_Right


@controlInput pdel Pre_Delay
@controlInput rdel Decay_Time
@controlInput dfil Damping



equ pdel 300
@sliderLabel pdel Predelay_Length 0 300 300 99 0 // Predelay length control
equ rdel 700
@sliderLabel rdel Reverse_Delay_Length 0 700 700 1 0 // Reverse delay length control

mem pdel 9900 // Predelay buffer, 300ms
mem rdel 18000 // Reverse delay buffer
mem ap1 1234 // All-pass filter 1 delay buffer
mem ap2 957 // All-pass filter 2 delay buffer
mem ap3 765 // All-pass filter 3 delay buffer
mem ap4 321 // All-pass filter 4 delay buffer

equ f1 reg0 // Filter 1
equ f2 reg1 // Filter 2
equ f3 reg2 // Filter 3
equ f4 reg3 // Filter 4
equ pdlo reg4 // Predelay output
equ dfil reg5 // Delay filter control
equ kfil reg6 // Filter coefficient
equ dacl reg7
equ dacr reg8

@isPinConnected Input_Right
rdax    adcr,0.5        ;get right input
@endif

@isPinConnected Input_Left
rdax    adcl,0.5        ;get left input

@endif

wra pdel, 0 ; Write to predelay buffer
;get predelay output into pdlo:


rdax    pot0,0.3        ;get pot0 (to 0.3 of memory range)
rdfx    dfil,0.001    ;filter delay control
wrax    dfil,1        ;write delay control filter
wrax    addr_ptr,0    ;write to address pointer
rmpa    1        ;read delay from address pointer
wrax    pdlo,0        ;write result to pdlo
wra    rdel,0        ;clear reverse delay input

;now write the pdlo register to the reverse delay, depending on pot1:


rdax     pot1,1

skp    zro,wr1
sof    1,-0.125
skp    neg,wr2
sof    1,-0.125
skp    neg,wr3
sof    1,-0.125
skp    neg,wr4
sof    1,-0.125
skp    neg,wr5
sof    1,-0.125
skp    neg,wr6
sof    1,-0.125
skp    neg,wr7
skp    run,wr8

wr1:
ldax    pdlo
wra    rdel+14000,0
skp    zro,wr9

wr2:
ldax    pdlo
wra    rdel+12000,0
skp    zro,wr9

wr3:
ldax    pdlo
wra    rdel+10000,0
skp    zro,wr9

wr4:
ldax    pdlo
wra    rdel+8000,0
skp    zro,wr9

wr5:
ldax    pdlo
wra    rdel+6000,0
skp    zro,wr9

wr6:
ldax    pdlo
wra    rdel+4000,0
skp    zro,wr9

wr7:
ldax    pdlo
wra    rdel+2000,0
skp    zro,wr9

wr8:
ldax    pdlo
wra    rdel,0           

wr9:

;prepare filter coefficient from pot2:

rdax    pot2,1


sof    0.8,0.1        ;treble increases CW
wrax    kfil,0

;do reverse reverb taps with interspersed filtering and allpasses:

rda    rdel+1,0.05
rda    rdel+303,-0.05
rda    rdel+569,0.06
rda    rdel+911,0.07
rda    rdel+1256,-0.008
rda    rdel+1478,0.008
rda    rdel+1818,-0.01
rda    rdel+2089,0.01
rda    rdel+2358,-0.011
rda    rdel+2710,0.012
rda    rdel+3018,0.0135
rda    rdel+3345,-0.012
rda    rdel+3567,-0.015
rda    rdel+3922,0.02
rda    rdel+4167,-0.02

rdax    f1,-1
mulx    kfil
rdax    f1,1
wrax    f1,1
rda    ap1#,0.5
wrap    ap1,-0.5

rda    rdel+4522,-0.029
rda    rdel+4754,0.04
rda    rdel+5156,-0.034
rda    rdel+5342,-0.04
rda    rdel+5657,0.035
rda    rdel+6008,0.04
rda    rdel+6283,-0.04
rda    rdel+6623,-0.045
rda    rdel+6845,-0.055
rda    rdel+7219,0.06
rda    rdel+7487,-0.06
rda    rdel+7832,-0.05
rda    rdel+8065,0.07

rdax    f2,-1
mulx    kfil
rdax    f2,1
wrax    f2,1
rda    ap2#,0.5
wrap    ap2,-0.5

rda    rdel+8404,0.08
rda    rdel+8713,-0.07
rda    rdel+8967,-0.08
rda    rdel+9307,0.08
rda    rdel+9576,-0.09
rda    rdel+9924,-0.09
rda    rdel+10298,-0.11
rda    rdel+10578,0.1
rda    rdel+10835,0.12
rda    rdel+11207,-0.1
rda    rdel+11523,-0.14
rda    rdel+11765,-0.18
rda    rdel+12113,0.16
rda    rdel+12324,-0.13
rda    rdel+12735,-0.17

rdax    f3,-1
mulx    kfil
rdax    f3,1
wrax    f3,1
rda        ap3#,0.5
wrap    ap3,-0.5

rda    rdel+13003,0.19
rda    rdel+13267,-0.14
rda    rdel+13610,0.16
rda    rdel+13945,-0.18
rda    rdel+14130,0.2
rda    rdel+14550,-0.25
rda    rdel+14800,-0.25

rdax    f4,-1
mulx    kfil
rdax    f4,1
wrax    f4,1
rda    ap4#,0.5
wrap    ap4,-0.5

rda    rdel+16000,1
wrax    dacl,1
@setOutputPin Output_Left dacl

wrax    dacr,0
@setOutputPin Output_Right dacr

it seems to cause error in the compiled java
 
Last edited:
Here's another fun variation on the above. I set the mixer gains all back to 0 dB. The LFO is generating a quadrature output (0, 90, 180, 270 degrees) sine wave offset to (0 - 1.0), pairs of which 90 degrees apart are going to left/right mixer gain controls for each tap. This gives a panning side-to-side effect.

View attachment 69794

It's not quite "flying around your head" though. On two of the taps, I added an LPF that is also sweeping up and down although I'm not sure if I got the phase right. The idea being, that when the L/R levels are equal, the source appears to be in front of you. Or at least somewhere on the plane that would slice you into two symmetrical pieces. Now if we can make the filter be brightest at one such crossing, and darkest at another, I believe that the "flying around your head" illusion would be stronger.

Little more thought on this. The place where sin and cos cross is at 45 degrees. If I add sin + cos, I get a sine wave with peak value square root of two (1.414) 45 degrees lagged from the cosine wave. However, I'm not sure I would be able to optimize the ASM far enough to make that happen. Someone want to give it a try? ;)

View attachment 69800

This patch demonstrates something else. As shown it generates 129 instructions which won't assemble in the SpinASM IDE. However I show how to optimize it to remove one instruction. The most likely places where this can happen are when two blocks are connected and the source only goes to one destination. I think the smoother after the Scale/Offset connected to Pot0 is a good candidate.

View attachment 69793

In the Spin ASM, I have moved the Smoother block to be just after the Scale/Offset block.

Note that because of the registers SpinCAD uses to connect blocks, you can move blocks around indiscriminately in SpinCAD generated ASM and it will still work. Well, "indiscriminately" might be overstating it because some things do want to be calculated before others. In this case, moving that block does not disturb any order of calculation concerns.

Next, I realize that this pair of instructions:

WRAX REG1, 0.0
RDAX REG1, 1.0


can be replaced by

WRAX REG1, 1.0

and so I do that. This saves 1 instruction and the program assembles now!

In fact, because the source only goes to one destination, I could have also removed:

WRAX REG1, 0.0

but I didn't since I only needed one instruction freed up.

Rename drum-delay-stereo-rotating.spcd.wav to drum-delay-stereo-rotating.spcd to load into SpinCAD Designer.
Rename drum-delay-stereo-spinning.spn.txt to drum-delay-stereo-spinning.spn to load into SpinASM IDE.
That's pretty cool I started to mess tinker a bit in SpinASM coding with the exported code from Spincad that's good to know similar to your hacks on your Spincad wiki page!
 
Hey Larry I managed to setup Eclipse today to try and add a new block & since I always wanted to mess with reversed buffers, so I decided to make the reverse reverb but I failed miserably :ROFLMAO:

here is my snippet:

Code:
@name Reverse_Reverb
@color "0x7100fc"
@audioInput adcl Input_Left
@audioInput adcr Input_Right
@audioOutput dacl 'Output_Left'
@audioOutput dacr 'Output_Right'


@controlInput input0 Pre_Delay
@controlInput input1 Decay_Time
@controlInput input2 Damping



equ pdel 1200
@sliderLabel pdel Predelay_Length 0 3000 3000 9900 0 // Predelay length control
equ rdel 16384
@sliderLabel rdel Reverse_Delay_Length 0 32767 16384 1 0 // Reverse delay length control

mem pdel 9900 // Predelay buffer, 300ms
mem rdel 18000 // Reverse delay buffer
mem ap1 1234 // All-pass filter 1 delay buffer
mem ap2 957 // All-pass filter 2 delay buffer
mem ap3 765 // All-pass filter 3 delay buffer
mem ap4 321 // All-pass filter 4 delay buffer

equ f1 reg0 // Filter 1
equ f2 reg1 // Filter 2
equ f3 reg2 // Filter 3
equ f4 reg3 // Filter 4
equ pdlo reg4 // Predelay output
equ dfil reg5 // Delay filter control
equ kfil reg6 // Filter coefficient



rdax    adcr,0.5        ;get right input



rdax    adcl,0.5        ;get left input


wra pdel, 0 ; Write to predelay buffer
;get predelay output into pdlo:


rdax    pot0,0.3        ;get pot0 (to 0.3 of memory range)
rdfx    dfil,0.001    ;filter delay control
wrax    dfil,1        ;write delay control filter
wrax    addr_ptr,0    ;write to address pointer
rmpa    1        ;read delay from address pointer
wrax    pdlo,0        ;write result to pdlo
wra    rdel,0        ;clear reverse delay input

;now write the pdlo register to the reverse delay, depending on pot1:


rdax     pot1,1

skp    zro,wr1
sof    1,-0.125
skp    neg,wr2
sof    1,-0.125
skp    neg,wr3
sof    1,-0.125
skp    neg,wr4
sof    1,-0.125
skp    neg,wr5
sof    1,-0.125
skp    neg,wr6
sof    1,-0.125
skp    neg,wr7
skp    run,wr8

wr1:
ldax    pdlo
wra    rdel+14000,0
skp    zro,wr9

wr2:
ldax    pdlo
wra    rdel+12000,0
skp    zro,wr9

wr3:
ldax    pdlo
wra    rdel+10000,0
skp    zro,wr9

wr4:
ldax    pdlo
wra    rdel+8000,0
skp    zro,wr9

wr5:
ldax    pdlo
wra    rdel+6000,0
skp    zro,wr9

wr6:
ldax    pdlo
wra    rdel+4000,0
skp    zro,wr9

wr7:
ldax    pdlo
wra    rdel+2000,0
skp    zro,wr9

wr8:
ldax    pdlo
wra    rdel,0     

wr9:

;prepare filter coefficient from pot2:

rdax    pot2,1


sof    0.8,0.1        ;treble increases CW
wrax    kfil,0

;do reverse reverb taps with interspersed filtering and allpasses:

rda    rdel+1,0.05
rda    rdel+303,-0.05
rda    rdel+569,0.06
rda    rdel+911,0.07
rda    rdel+1256,-0.008
rda    rdel+1478,0.008
rda    rdel+1818,-0.01
rda    rdel+2089,0.01
rda    rdel+2358,-0.011
rda    rdel+2710,0.012
rda    rdel+3018,0.0135
rda    rdel+3345,-0.012
rda    rdel+3567,-0.015
rda    rdel+3922,0.02
rda    rdel+4167,-0.02

rdax    f1,-1
mulx    kfil
rdax    f1,1
wrax    f1,1
rda    ap1#,0.5
wrap    ap1,-0.5

rda    rdel+4522,-0.029
rda    rdel+4754,0.04
rda    rdel+5156,-0.034
rda    rdel+5342,-0.04
rda    rdel+5657,0.035
rda    rdel+6008,0.04
rda    rdel+6283,-0.04
rda    rdel+6623,-0.045
rda    rdel+6845,-0.055
rda    rdel+7219,0.06
rda    rdel+7487,-0.06
rda    rdel+7832,-0.05
rda    rdel+8065,0.07

rdax    f2,-1
mulx    kfil
rdax    f2,1
wrax    f2,1
rda    ap2#,0.5
wrap    ap2,-0.5

rda    rdel+8404,0.08
rda    rdel+8713,-0.07
rda    rdel+8967,-0.08
rda    rdel+9307,0.08
rda    rdel+9576,-0.09
rda    rdel+9924,-0.09
rda    rdel+10298,-0.11
rda    rdel+10578,0.1
rda    rdel+10835,0.12
rda    rdel+11207,-0.1
rda    rdel+11523,-0.14
rda    rdel+11765,-0.18
rda    rdel+12113,0.16
rda    rdel+12324,-0.13
rda    rdel+12735,-0.17

rdax    f3,-1
mulx    kfil
rdax    f3,1
wrax    f3,1
rda    ap3#,0.5
wrap    ap3,-0.5

rda    rdel+13003,0.19
rda    rdel+13267,-0.14
rda    rdel+13610,0.16
rda    rdel+13945,-0.18
rda    rdel+14130,0.2
rda    rdel+14550,-0.25
rda    rdel+14800,-0.25

rdax    f4,-1
mulx    kfil
rdax    f4,1
wrax    f4,1
rda    ap4#,0.5
wrap    ap4,-0.5

rda    rdel+16000,1
wrax    dacl,1
@setOutputPin 'Output_Left' dacl
wrax    dacr,0
@setOutputPin 'Output_Right' dacr

it seems to cause error in the compiled java in here

Code:
            sfxb.writeRegister(dacl, 1);
            this.getPin("Output_Left").setRegister(dacl);
            sfxb.writeRegister(dacr, 0);
            this.getPin("Output_Right").setRegister(dacr);

            }
Hi Ted,

I wouldn't consider that failing miserably.

I actually didn't remember how it was done so I opened up "grepWin"


and searched my workspace for "SetOutputPin".

In allpass.spincad (for example) we have:

@audioOutput output1 Output

matched with

@setOutputPin Output output1

Whereas you have:

@audioOutput dacl 'Output_Left'
matched with
@setOutputPin 'Output_Left' dacl

I suggest that you NOT use dacl, dacr, adcl, adcr for your pin variables. These are reserved keywords in the SpinASM language. Instead, just come up with a unique descriptive variable name.

Similarly, you should replace direct references to "potx" with the control variables you have defined.

@controlInput pdel Pre_Delay
@controlInput rdel Decay_Time
@controlInput dfil Damping

Replace pot0 throughout your code with pdel, etc.

Does this help?
 
Last edited:
awesome thanks that fixed the issue when I added these two not sure if it's correct even
equ outputl reg7
equ outputr reg8

& now I have another 2 problems:

1- no sound :unsure: when I connect the block with in/out + pot connected
2- I think I implemented @sliderLabel in the wrong way since now I cannot adjust the delay RAM properly
Code:
@name Reverse_Reverb
@color "0x7100fc"
@audioInput inputl Input_Left
@audioInput inputr Input_Right
@audioOutput outputl Output_Left
@audioOutput outputr Output_Right


@controlInput input0 Pre_Delay
@controlInput input1 Decay_Time
@controlInput input2 Damping



equ pdel 99
@sliderLabel pdel Predelay_Length 0 3000 3000 9900 0 // Predelay length control
equ rdel 18000
@sliderLabel rdel Reverse_Delay_Length 0 32767 18000 1 0  // Reverse delay length control

@getBaseAddress
mem pdel 9900 // Predelay buffer, 300ms
mem rdel 18000 // Reverse delay buffer
mem ap1 1234 // All-pass filter 1 delay buffer
mem ap2 957 // All-pass filter 2 delay buffer
mem ap3 765 // All-pass filter 3 delay buffer
mem ap4 321 // All-pass filter 4 delay buffer

equ f1 reg0 // Filter 1
equ f2 reg1 // Filter 2
equ f3 reg2 // Filter 3
equ f4 reg3 // Filter 4
equ pdlo reg4 // Predelay output
equ dfil reg5 // Delay filter control
equ kfil reg6 // Filter coefficient


 //not sure about these 2
equ outputl reg7
equ outputr reg8


//@isPinConnected Input_Right
rdax    inputr,0.5        ;get right input
//@endif

//@isPinConnected Input_Left
rdax    inputl,0.5        ;get left input
//@endif
wra pdel, 0 ; Write to predelay buffer
;get predelay output into pdlo:

//@isPinConnected input0
rdax    input0,0.3        ;get pot0 (to 0.3 of memory range)
//@endif
rdfx    dfil,0.001    ;filter delay control
wrax    dfil,1        ;write delay control filter
wrax    addr_ptr,0    ;write to address pointer
rmpa    1        ;read delay from address pointer
wrax    pdlo,0        ;write result to pdlo
wra    rdel,0        ;clear reverse delay input

;now write the pdlo register to the reverse delay, depending on pot1:

//@isPinConnected input1
rdax     input1,1
//@endif
skp    zro,wr1
sof    1,-0.125
skp    neg,wr2
sof    1,-0.125
skp    neg,wr3
sof    1,-0.125
skp    neg,wr4
sof    1,-0.125
skp    neg,wr5
sof    1,-0.125
skp    neg,wr6
sof    1,-0.125
skp    neg,wr7
skp    run,wr8

wr1:
ldax    pdlo
wra    rdel+14000,0
skp    zro,wr9

wr2:
ldax    pdlo
wra    rdel+12000,0
skp    zro,wr9

wr3:
ldax    pdlo
wra    rdel+10000,0
skp    zro,wr9

wr4:
ldax    pdlo
wra    rdel+8000,0
skp    zro,wr9

wr5:
ldax    pdlo
wra    rdel+6000,0
skp    zro,wr9

wr6:
ldax    pdlo
wra    rdel+4000,0
skp    zro,wr9

wr7:
ldax    pdlo
wra    rdel+2000,0
skp    zro,wr9

wr8:
ldax    pdlo
wra    rdel,0         

wr9:

;prepare filter coefficient from pot2:
//@isPinConnected input2
rdax    input2,1
//@endif

sof    0.8,0.1        ;treble increases CW
wrax    kfil,0

;do reverse reverb taps with interspersed filtering and allpasses:

rda    rdel+1,0.05
rda    rdel+303,-0.05
rda    rdel+569,0.06
rda    rdel+911,0.07
rda    rdel+1256,-0.008
rda    rdel+1478,0.008
rda    rdel+1818,-0.01
rda    rdel+2089,0.01
rda    rdel+2358,-0.011
rda    rdel+2710,0.012
rda    rdel+3018,0.0135
rda    rdel+3345,-0.012
rda    rdel+3567,-0.015
rda    rdel+3922,0.02
rda    rdel+4167,-0.02

rdax    f1,-1
mulx    kfil
rdax    f1,1
wrax    f1,1
rda    ap1#,0.5
wrap    ap1,-0.5

rda    rdel+4522,-0.029
rda    rdel+4754,0.04
rda    rdel+5156,-0.034
rda    rdel+5342,-0.04
rda    rdel+5657,0.035
rda    rdel+6008,0.04
rda    rdel+6283,-0.04
rda    rdel+6623,-0.045
rda    rdel+6845,-0.055
rda    rdel+7219,0.06
rda    rdel+7487,-0.06
rda    rdel+7832,-0.05
rda    rdel+8065,0.07

rdax    f2,-1
mulx    kfil
rdax    f2,1
wrax    f2,1
rda    ap2#,0.5
wrap    ap2,-0.5

rda    rdel+8404,0.08
rda    rdel+8713,-0.07
rda    rdel+8967,-0.08
rda    rdel+9307,0.08
rda    rdel+9576,-0.09
rda    rdel+9924,-0.09
rda    rdel+10298,-0.11
rda    rdel+10578,0.1
rda    rdel+10835,0.12
rda    rdel+11207,-0.1
rda    rdel+11523,-0.14
rda    rdel+11765,-0.18
rda    rdel+12113,0.16
rda    rdel+12324,-0.13
rda    rdel+12735,-0.17

rdax    f3,-1
mulx    kfil
rdax    f3,1
wrax    f3,1
rda    ap3#,0.5
wrap    ap3,-0.5

rda    rdel+13003,0.19
rda    rdel+13267,-0.14
rda    rdel+13610,0.16
rda    rdel+13945,-0.18
rda    rdel+14130,0.2
rda    rdel+14550,-0.25
rda    rdel+14800,-0.25

rdax    f4,-1
mulx    kfil
rdax    f4,1
wrax    f4,1
rda    ap4#,0.5
wrap    ap4,-0.5

rda    outputl+16000,1
wrax    outputl,1
@setOutputPin Output_Left outputl
wrax    outputr,0
@setOutputPin Output_Right outputr

also, the SpinAsm code coming out from spincad looks suspicious

Code:
; Untitled
; null
; Pot 0:
; Pot 1:
; Pot 2:
;
;
; ----------------------------
;------ Input
;------ Pot 0
;------ Pot 1
;------ Pot 2
;------ Reverse_Reverb
RDAX ADCR,0.5000000000
RDAX ADCL,0.5000000000
WRA 0,0.0
RDAX POT0,0.3000000000
RDFX REG5,0.0010000000
WRAX REG5,1.0000000000
WRAX ADDR_PTR,0.0000000000
RMPA 1.0
WRAX REG4,0.0000000000
WRA 9901,0.0
RDAX POT1,1.0000000000
SKP ZRO,13
SOF 1.0000000000,-0.1250000000
SKP NEG,14
SOF 1.0000000000,-0.1250000000
SKP NEG,15
SOF 1.0000000000,-0.1250000000
SKP NEG,16
SOF 1.0000000000,-0.1250000000
SKP NEG,17
SOF 1.0000000000,-0.1250000000
SKP NEG,18
SOF 1.0000000000,-0.1250000000
SKP NEG,19
SKP RUN ,21
LDAX REG4
WRA 23901,0.0
SKP ZRO,20
LDAX REG4
WRA 21901,0.0
SKP ZRO,17
LDAX REG4
WRA 19901,0.0
SKP ZRO,14
LDAX REG4
WRA 17901,0.0
SKP ZRO,11
LDAX REG4
WRA 15901,0.0
SKP ZRO,8
LDAX REG4
WRA 13901,0.0
SKP ZRO,5
LDAX REG4
WRA 11901,0.0
SKP ZRO,2
LDAX REG4
WRA 9901,0.0
RDAX POT2,1.0000000000
SOF 0.8000000000,0.1000000000
WRAX REG6,0.0000000000
RDA 9902,0.05
RDA 10204,-0.05
RDA 10470,0.06
RDA 10812,0.07
RDA 11157,-0.008
RDA 11379,0.008
RDA 11719,-0.01
RDA 11990,0.01
RDA 12259,-0.011
RDA 12611,0.012
RDA 12919,0.0135
RDA 13246,-0.012
RDA 13468,-0.015
RDA 13823,0.02
RDA 14068,-0.02
RDAX REG0,-1.0000000000
MULX REG6
RDAX REG0,1.0000000000
WRAX REG0,1.0000000000
RDA 29136,0.5
WRAP 27902,-0.5
RDA 14423,-0.029
RDA 14655,0.04
RDA 15057,-0.034
RDA 15243,-0.04
RDA 15558,0.035
RDA 15909,0.04
RDA 16184,-0.04
RDA 16524,-0.045
RDA 16746,-0.055
RDA 17120,0.06
RDA 17388,-0.06
RDA 17733,-0.05
RDA 17966,0.07
RDAX REG1,-1.0000000000
MULX REG6
RDAX REG1,1.0000000000
WRAX REG1,1.0000000000
RDA 30094,0.5
WRAP 29137,-0.5
RDA 18305,0.08
RDA 18614,-0.07
RDA 18868,-0.08
RDA 19208,0.08
RDA 19477,-0.09
RDA 19825,-0.09
RDA 20199,-0.11
RDA 20479,0.1
RDA 20736,0.12
RDA 21108,-0.1
RDA 21424,-0.14
RDA 21666,-0.18
RDA 22014,0.16
RDA 22225,-0.13
RDA 22636,-0.17
RDAX REG2,-1.0000000000
MULX REG6
RDAX REG2,1.0000000000
WRAX REG2,1.0000000000
RDA 30860,0.5
WRAP 30095,-0.5
RDA 22904,0.19
RDA 23168,-0.14
RDA 23511,0.16
RDA 23846,-0.18
RDA 24031,0.2
RDA 24451,-0.25
RDA 24701,-0.25
RDAX REG3,-1.0000000000
MULX REG6
RDAX REG3,1.0000000000
WRAX REG3,1.0000000000
RDA 31182,0.5
WRAP 30861,-0.5
 
Hi Ted,

Well I won't say that you're not ambitious! Here's what I see.

I meant to say outputl, not output1 in the comment.

1709418569890.png
Another point, not that I think it is the problem here.

Typically I use @isPinConnected Input where Input is the first audio input pin to control code generation for the entire block. In other words, if you don't connect the first audio input, what exactly are you trying to do? In your code (although commented out at present) you are just inserting or removing this one instruction.

1709419903284.png
So what does it mean when that instruction isn't there because the pin isn't connected? You have all the rest of the instructions but no place to get input. You approach would actually be OK if one or the other input was connected but you would get a lot of code generated if they both weren't connected. Anyway I think my assumption all along is that you are gonna connect the first input, and that @isPinConnected will wrap ALL the code. It's challenging to be super clever and come up with alternatives for every possible way things could be connected. You will probably see some of these nested inside each other in some of the code. That starts to get real headache inducing.

See reverb_plate.spincad for example.

1709419796534.png

the @endif for this is all the way at the bottom.

1709419852984.png
 

Attachments

  • 1709419711747.png
    1709419711747.png
    4.4 KB · Views: 3
Last edited:
Thanks Larry, that was very helpful! I started to realize how ambitious this one is 😂 ..probably I should've started with a simpler one... anyway I'm understanding some asm code on the way so that's fine.

the @isPinConnected I commented it by mistake

here is what I got till now still no sound But I guess I'm getting there

Code:
@name Reverse_Reverb
@color "0x7100fc"
@audioInput inputl 'Input_Left'
@audioInput inputr 'Input_Right'
@audioOutput outputl 'Output_Left'
@audioOutput outputr 'Output_Right'


@controlInput input0 'Pre_Delay'
@controlInput input1 'Decay_Time'
@controlInput input2 'Damping'

equ inputGainl 1.0
@sliderLabel inputGainl 'Input Gain L'  -24 0 0 1.0 1 DBLEVEL
equ inputGainr 1.0
@sliderLabel inputGainr 'Input Gain R'  -24 0 0 1.0 1 DBLEVEL

equ pre 3000
@sliderLabel pre 'Pre_Delay' 0 9900 3000 1 0 // Predelay length control
equ decay 18000
@sliderLabel decay 'Decay_Time' 0 32767 18000 1 0  // Reverse delay length control

@getBaseAddress
mem pdel pre // Predelay buffer, 300ms
mem rdel decay // Reverse delay buffer
mem ap1 1234 // All-pass filter 1 delay buffer
mem ap2 957 // All-pass filter 2 delay buffer
mem ap3 765 // All-pass filter 3 delay buffer
mem ap4 321 // All-pass filter 4 delay buffer

equ f1 reg0 // Filter 1
equ f2 reg1 // Filter 2
equ f3 reg2 // Filter 3
equ f4 reg3 // Filter 4
equ input0 reg4 // Predelay output
equ input2 reg5 // Delay filter control
equ kfil reg6 // Filter coefficient
equ input1 reg9


 //not sure about these 2
equ outputl reg7
equ outputr reg8


@isPinConnected 'Input_Right'
rdax    inputr,inputGainr    ;get right input
@endif

@isPinConnected 'Input_Left'
rdax    inputl,inputGainl    ;get left input
@endif
wra pdel, 0 ; Write to predelay buffer
;get predelay output into input0:

@isPinConnected 'Pre_Delay'
rdax    input0,0.3        ;get pot0 (to 0.3 of memory range)
@endif
rdfx    input2,0.001    ;filter delay control
wrax    input2,1        ;write delay control filter
wrax    addr_ptr,0    ;write to address pointer
rmpa    1        ;read delay from address pointer
wrax    input0,0        ;write result to input0
wra    rdel,0        ;clear reverse delay input

;now write the input0 register to the reverse delay, depending on pot1:

@isPinConnected 'Decay_Time'
rdax     input1,1
//@endif

skp    zro,wr1
sof    1,-0.125
skp    neg,wr2
sof    1,-0.125
skp    neg,wr3
sof    1,-0.125
skp    neg,wr4
sof    1,-0.125
skp    neg,wr5
sof    1,-0.125
skp    neg,wr6
sof    1,-0.125
skp    neg,wr7
skp    run,wr8

wr1:
@isPinConnected 'Pre_Delay'
ldax    input0
wra    rdel+14000,0
skp    zro,wr9
@endif
@isPinConnected 'Pre_Delay'
wr2:
ldax    input0
wra    rdel+12000,0
skp    zro,wr9
@endif
@isPinConnected 'Pre_Delay'
wr3:
ldax    input0
wra    rdel+10000,0
skp    zro,wr9
@endif
@isPinConnected 'Pre_Delay'
wr4:
ldax    input0
wra    rdel+8000,0
skp    zro,wr9
@endif
@isPinConnected 'Pre_Delay'
wr5:
ldax    input0
wra    rdel+6000,0
skp    zro,wr9
@endif
@isPinConnected 'Pre_Delay'
wr6:
ldax    input0
wra    rdel+4000,0
skp    zro,wr9
@endif
@isPinConnected 'Pre_Delay'
wr7:
ldax    input0
wra    rdel+2000,0
skp    zro,wr9
@endif
@isPinConnected 'Pre_Delay'
wr8:
ldax    input0
wra    rdel,0         
@endif
wr9:

;prepare filter coefficient from pot2:
@isPinConnected 'Damping'
rdax    input2,1
@endif

sof    0.8,0.1        ;treble increases CW
wrax    kfil,0

;do reverse reverb taps with interspersed filtering and allpasses:

rda    rdel+1,0.05
rda    rdel+303,-0.05
rda    rdel+569,0.06
rda    rdel+911,0.07
rda    rdel+1256,-0.008
rda    rdel+1478,0.008
rda    rdel+1818,-0.01
rda    rdel+2089,0.01
rda    rdel+2358,-0.011
rda    rdel+2710,0.012
rda    rdel+3018,0.0135
rda    rdel+3345,-0.012
rda    rdel+3567,-0.015
rda    rdel+3922,0.02
rda    rdel+4167,-0.02

rdax    f1,-1
mulx    kfil
rdax    f1,1
wrax    f1,1
rda    ap1#,0.5
wrap    ap1,-0.5

rda    rdel+4522,-0.029
rda    rdel+4754,0.04
rda    rdel+5156,-0.034
rda    rdel+5342,-0.04
rda    rdel+5657,0.035
rda    rdel+6008,0.04
rda    rdel+6283,-0.04
rda    rdel+6623,-0.045
rda    rdel+6845,-0.055
rda    rdel+7219,0.06
rda    rdel+7487,-0.06
rda    rdel+7832,-0.05
rda    rdel+8065,0.07

rdax    f2,-1
mulx    kfil
rdax    f2,1
wrax    f2,1
rda    ap2#,0.5
wrap    ap2,-0.5

rda    rdel+8404,0.08
rda    rdel+8713,-0.07
rda    rdel+8967,-0.08
rda    rdel+9307,0.08
rda    rdel+9576,-0.09
rda    rdel+9924,-0.09
rda    rdel+10298,-0.11
rda    rdel+10578,0.1
rda    rdel+10835,0.12
rda    rdel+11207,-0.1
rda    rdel+11523,-0.14
rda    rdel+11765,-0.18
rda    rdel+12113,0.16
rda    rdel+12324,-0.13
rda    rdel+12735,-0.17

rdax    f3,-1
mulx    kfil
rdax    f3,1
wrax    f3,1
rda    ap3#,0.5
wrap    ap3,-0.5

rda    rdel+13003,0.19
rda    rdel+13267,-0.14
rda    rdel+13610,0.16
rda    rdel+13945,-0.18
rda    rdel+14130,0.2
rda    rdel+14550,-0.25
rda    rdel+14800,-0.25

rdax    f4,-1
mulx    kfil
rdax    f4,1
wrax    f4,1
rda    ap4#,0.5
wrap    ap4,-0.5

rda    redel+16000,1
@setOutputPin 'Output_Left' outputl
wrax    outputl,1

@setOutputPin 'Output_Right' outputr
wrax    outputr,0


@endif
 
rda redel+16000,1
====
"redel" is not valid.
--------------
Also, in every case I can see, I put the "SetOutputPin" statement after the last reference to the variable. I'm not sure if it matters but it might.
--------------
I think what we're seeing is that SpinCAD Builder doesn't have a lot of error checking. I did mostly write it for myself after all. It's been about ten years and you're the first person who's ever asked me anything about it.

I made the above changes and it still does not work. Also even with just input and output connections it goes over the 128 instruction limit and generates more errors. This heavily suggests its utility as a block in SpinCAD is almost zero because what else can you combine with it? Nothing. Please forgive me if I don't spend a lot of time trying to debug this for you.

I would suggest that you spend more time looking at the existing blocks of different kinds and see what impact changing things has. I don't mean to discourage you, but I spent several years learning both Spin ASM and Java before I felt like I had a handle on it.

1709425110294.png
 
Last edited:
Thanks Larry.. yes I'll do that, also probably I started with the wrong block probably I should've made a simpler block as a start.

Anyways I won't bother you again will share the blocks over here once I have some success :)
 
Thanks Larry.. yes I'll do that, also probably I started with the wrong block probably I should've made a simpler block as a start.

Anyways I won't bother you again will share the blocks over here once I have some success :)
No worries Ted. I am just getting back into this myself after many years not paying attention to it, simply because people here such as yourself showed some interest, which I appreciate. SpinCAD Designer is the "kiddie pool", whereas SpinCAD Builder is... something else much closer to the real deep end or the ocean. Personally, I vastly prefer the kiddie pool! :cool:

Also keep in mind:
- There are a number of known issues with SpinCAD Builder/Designer, see the "issues" list at Github.
- There are probably some unknown issues with SpinCAD Designer - these I would like to hear about. Maybe I'll fix them, maybe I won't.
- Some Spin algorithms depend on e.g. a memory block starting at zero and being a specific size. Or multiple flags to the SKP instruction. These won't work in SpinCAD Builder without being rewritten and I am not signing up for that. Unless you are pretty good at Spin ASM you won't be able to recognize these sorts of things.
- Working on reverbs or huge algorithms, I'd suggest doing that directly in Spin ASM as you're not going to gain much benefit from the GUI.
- Learn how to use the hybrid approach - which it sounds like you already are.

Thx!

DL
 
Last edited:
Back
Top