tap tempo snippet

Algorithm development and general DSP issues

Moderator: frank

slacker
Posts: 116
Joined: Tue Feb 01, 2011 1:13 pm

Post by slacker »

The way the code works is low has to be below 1.65 volts and high has to be above 1.65 volts. It then has to stay high or low for 50 clock cycles before it will switch, less than that and the code ignores it.

You can try changing the high to low point by changing sof line below, change the -0.5 to -0.9 and low will then be anything below 3 volts. I don't know how well this will work.

Code: Select all

;Switch Debouncing and pot filtering work around

 ldax   pot2   ;read pot2
 sof 1,-0.5   ;level shift to -0.5 to 0.5 
Mcfly
Posts: 46
Joined: Fri Mar 08, 2013 2:38 pm
Location: Argentina

tap tempo snippet

Post by Mcfly »

Slacker, one more question. What if i'm not using the whole delay mem (let's say just 22938, or max delay time=700ms). Do i need to modify the tap tempo code to fit the 700ms limit?
slacker
Posts: 116
Joined: Tue Feb 01, 2011 1:13 pm

Post by slacker »

If you want a smaller maximum delay you need to change the following part of the code.

Code: Select all

LOW:
 sof 0,0.064       
 wrax rmp0_rate,0      ;set rmp0 rate to 1Hz
 cho rdal,rmp0      ;read value of rmp0
 
The sof 0,0.064 sets up a 1Hz ramp to give delay time up to 1 second, so for 700ms you change the sof command to

Code: Select all

sof 0,0.089285


This gives a ramp 700ms long. The formula to calculate the sof command for different delays is 1/delay time in seconds/16 so for 700ms 1/0.7/16 = 0.089285.....

Then in the delay section you need to change this part

Code: Select all

wra delay,0      ;write to head of delay
 ldax taptempo      ;read taptempo register
 wrax addr_ptr,0      ;write to delay address pointer 
After the ldax taptempo line add

Code: Select all

sof 0.7,0
This scales the taptempo value to what ever delay length you want, in this case 700ms.

If you're using the LED flashing code you'll need to change the sof command there as well so the flashing matches the tap tempo.

Hope that makes sense
Mcfly
Posts: 46
Joined: Fri Mar 08, 2013 2:38 pm
Location: Argentina

Post by Mcfly »

slacker wrote:If you want a smaller maximum delay you need to change the following part of the code.

Code: Select all

LOW:
 sof 0,0.064       
 wrax rmp0_rate,0      ;set rmp0 rate to 1Hz
 cho rdal,rmp0      ;read value of rmp0
 
The sof 0,0.064 sets up a 1Hz ramp to give delay time up to 1 second, so for 700ms you change the sof command to

Code: Select all

sof 0,0.089285


This gives a ramp 700ms long. The formula to calculate the sof command for different delays is 1/delay time in seconds/16 so for 700ms 1/0.7/16 = 0.089285.....

Then in the delay section you need to change this part

Code: Select all

wra delay,0      ;write to head of delay
 ldax taptempo      ;read taptempo register
 wrax addr_ptr,0      ;write to delay address pointer 
After the ldax taptempo line add

Code: Select all

sof 0.7,0
This scales the taptempo value to what ever delay length you want, in this case 700ms.

If you're using the LED flashing code you'll need to change the sof command there as well so the flashing matches the tap tempo.

Hope that makes sense
Thanks a lot Slacker, it is working perfectly!
slacker
Posts: 116
Joined: Tue Feb 01, 2011 1:13 pm

Post by slacker »

Cool.
Mcfly
Posts: 46
Joined: Fri Mar 08, 2013 2:38 pm
Location: Argentina

Post by Mcfly »

slacker wrote:Cool.
Hey Slacker I have another problem, this time with the led rate indicator.

When i use it with full memory it works ok, but when i'm using it with 700 ms, a horrible noise is present (an oscillation). Even if i don't write led register to any DAC.

For 700 ms i'm using:

Code: Select all

;Taptempo rate indicator, creates a square wave at the tap tempo rate 
sof 0,0.089285  
wrax rmp1_rate,0      ;set rmp1 rate to 1Hz 
cho rdal,rmp1      ;read value of rmp1 
sof -2,0.999      ;level shift to 0 - 1 rising ramp 
sof 1,0.001 
rdax taptempo,-0.5   ;deduct half of the taptempo value 
skp neg,ENDLED      ;if negative skip to ENDLED 
jam rmp1      ;else reset ramp1 
ldax led         ;and invert value of led register, creates square wave at taptempo rate 
sof -1,0 
wrax led,0 
ENDLED: 
Thanks for your help!
Mcfly
Posts: 46
Joined: Fri Mar 08, 2013 2:38 pm
Location: Argentina

Post by Mcfly »

Mcfly wrote:
slacker wrote:Cool.
Hey Slacker I have another problem, this time with the led rate indicator.

When i use it with full memory it works ok, but when i'm using it with 700 ms, a horrible noise is present (an oscillation). Even if i don't write led register to any DAC.

For 700 ms i'm using:

Code: Select all

;Taptempo rate indicator, creates a square wave at the tap tempo rate 
sof 0,0.089285  
wrax rmp1_rate,0      ;set rmp1 rate to 1Hz 
cho rdal,rmp1      ;read value of rmp1 
sof -2,0.999      ;level shift to 0 - 1 rising ramp 
sof 1,0.001 
rdax taptempo,-0.5   ;deduct half of the taptempo value 
skp neg,ENDLED      ;if negative skip to ENDLED 
jam rmp1      ;else reset ramp1 
ldax led         ;and invert value of led register, creates square wave at taptempo rate 
sof -1,0 
wrax led,0 
ENDLED: 
Thanks for your help!
I was wrong, code works perfectly!
Alex MAK
Posts: 89
Joined: Fri Nov 05, 2010 1:00 pm

Post by Alex MAK »

Hi, guys! Please tell me how to implement the code in a single control "TIME" a potentiometer and click "Tap Tempo" at the same time. Thank you! Best regards, Alex!
Digital Larry
Posts: 338
Joined: Mon Nov 12, 2012 1:12 pm
Contact:

Post by Digital Larry »

Hi Slacker,

I'm ready to make a tap-tempo block in SpinCAD Designer if you like. I'd need your help in extracting/abstracting values that would go into the control panel and seeing how it might become more general purpose (e.g. be able to link to a delay block, SIN/COS LFO, ramp LFO, etc.).

I haven't tried any of it myself so I'm not 100% sure what it's capable of.

Up to you! California weather is pretty hot these days and I'm not as ambitious in the evenings as I was earlier in the year.

Thanks!

DL
Alex MAK
Posts: 89
Joined: Fri Nov 05, 2010 1:00 pm

Post by Alex MAK »

Guys, please tell me how to bind this piece of code to a large code. Thank you! Sincerely, Alex.

Code: Select all

clr 
rdax   pot2,   1 
and      %01100000_00000000_00000000       
skp   zro,   POT 
sof   1,   -0.25 
skp   zro,   POT 
sof   1,   -0.25 
skp   zro,   POT 
clr 
skp   zro,   TAP
slacker
Posts: 116
Joined: Tue Feb 01, 2011 1:13 pm

Post by slacker »

Alex - what do you want this to do? Do you want one pot to be the time and another to be the tap tempo?

Digital Larry - leave it with me I post some code over on your forum.
Alex MAK
Posts: 89
Joined: Fri Nov 05, 2010 1:00 pm

Post by Alex MAK »

Hi, Slacker! I want to use POT2 for TAP TEMPO and the same POT2 used to control potentiometer. I just want an option if POT2 for Tap Tempo and POT1 potentiometer. Thank you! Best regards, Alex!
slacker
Posts: 116
Joined: Tue Feb 01, 2011 1:13 pm

Post by slacker »

Sorry I'm still not exactly sure what you want. I can make the code so POT1 would control the delay time but if this was turned all the way down then POT2 will act as a tap tempo.
I can't make one pot control the delay time and do tap tempo, you'll have to figure out a way to do that yourself, unless someone else has already done it.
Alex MAK
Posts: 89
Joined: Fri Nov 05, 2010 1:00 pm

Post by Alex MAK »

Slacker, I like your version. How is it possible to implement the code? Thank you! Sincerely, Alex.
slacker
Posts: 116
Joined: Tue Feb 01, 2011 1:13 pm

Post by slacker »

Here you go, if pot1 is turned all the way down the delay is controlled by the taptempo, otherwise pot 1 controls the delay time. Delay level is fixed at 50%.
The new code is between ";Pot control on POT1" and "DODELAY" hopefully it's self explanatory.

I haven't tested this but it should work.

Code: Select all

;tap tempo delay
;mono input (ADCL) mono output (DACL)
;a 0 - 0.99 square wave at the tap tempo rate is send to DACR. This can be used to flash a LED using a suitable driver. 
;Pot 2 is used as a tap tempo switch input. This should be a momentary switch, transition can be high to low or low to high.
;see guitar amp application note for examples of switch hookup.  
;pot 0 = feedback
;pot 1 = set below 0.05 delay is taptempo controlled, above 0.05 pot1 sets delay time

;set up registers and equates

equ  db reg0		;debounce
equ  mom reg1		;momentary output of switch +1 high, -1 Low
equ  latch reg2		;latched output of switch +1 high, -1 low
equ ramp reg3		;current value of rmpo, scaled to 0 to 1
equ taptempo reg4	;taptempo value, 0 to 1
equ fback reg5		;feedback
equ delayout reg6		;delay output
equ clip reg7		;clipping
equ led reg8		;taptempo LED

equ count 0.01		;debounce counter
equ delaytime 330		;initial delay time in milli seconds

mem delay 32767

skp run,START
wldr rmp0,0,4096	;set up rmp0
wldr rmp1,0,4096	;set up rmp1
sof 0,0.99		
wrax latch,1		;set latch = 1 high
wrax led,0		;set led = 1 high
sof 0,delaytime/1000	;set initial delay time
wrax ramp,0

START:

;Switch Debouncing and pot filtering work around

ldax   pot2	;read pot2
sof 1,-0.5	;level shift to -0.5 to 0.5
skp neg,DOWN	;if negative jump to DOWN
ldax db		;else high, read db
sof 1,count	;add count
wrax db,0	;write new value to db
skp zro,ENDDB	;jump to ENDDB
DOWN:
ldax db		;read db
sof 1,-count	;deduct count
wrax db,0	;write new value to db

ENDDB:

;latching switch, falling edge triggered flipflop
;Output of debounce routine of < -0.9 is low, > 0.9 is high, values in between
;are ignored and the switch does nothing, Schmitt trigger action.


ldax db			;read db
absa			;get absolute value
sof 1,-0.9		;deduct 0.9 so only values < -0.9 or > 0.9 give a positive result
skp neg,ENDSWITCH	;if negative then jump to ENDSWITCH
ldax db			;read db
sof 1,-0.9		;deduct 0.9
skp neg,LO		;if negative jump to LO, output of debounce is low 
sof 0,0.999		;else output of debounce is high
wrax mom,0		;set mom to 1 (high)
skp zro,ENDSWITCH	;jump to ENDSWITCH
LO:
ldax mom		;read mom
skp neg,ENDSWITCH	;if it's negative then debounce was already low last time so do nothing, jump to ENDSWITCH
sof 0,-0.999		;else mom was high last time so switch has only just been pressed (falling edge)
wrax mom,0		;set mom to -1 (low)
ldax latch		;read latch
sof -1,0			;invert, high becomes low, low becomes high
wrax latch,0		;write to value to latch

ENDSWITCH:

;tap tempo, uses rmp0 as a 1 Hz rising ramp, runs whilst latch is low and is sampled and held when latch is high

ldax latch		;read latch
skp neg,LOW		;if negative jump to LOW
jam rmp0		;else latch is high, jam rmp0 (reset to 0)
ldax ramp		;read ramp, will contain last value of rmp0 before latch went high	
wrax taptempo,0		;write to taptempo
skp zro,ENDTT		;jump to ENDTT
LOW:
sof 0,0.0625		
wrax rmp0_rate,0		;set rmp0 rate to 1Hz
cho rdal,rmp0		;read value of rmp0
sof -2,0.999
sof 1,0.001		;level shift to 0 to 1 rising ramp
wrax ramp,1		;write to ramp
sof 1,-0.999		;deduct 0.999 from ramp		
skp neg,ENDTT		;if answer is positive then second tap hasn't happened with 0.999 ms of first			
ldax taptempo		;so keep last value of taptempo
wrax ramp,0		
sof 0,0.999		;and reset latch high
wrax latch,0
ENDTT:

;Taptempo rate indicator, creates a square wave at the tap tempo rate
sof 0,0.0625		
wrax rmp1_rate,0		;set rmp1 rate to 1Hz
cho rdal,rmp1		;read value of rmp1
sof -2,0.999		;level shift to 0 - 1 rising ramp
sof 1,0.001
rdax taptempo,-0.5	;deduct half of the taptempo value
skp neg,ENDLED		;if negative skip to ENDLED
jam rmp1		;else reset ramp1
ldax led			;and invert value of led register, creates square wave at taptempo rate
sof -1,0
wrax led,0
ENDLED:

;Pot control on POT1

ldax pot1		;read pot1
sof 1,-0.05		;shift down now -0.05 to 0.95
skp neg,DODELAY		;if negative skip to delay, taptempo mode
ldax pot1		;else read pot1
sof 1/0.95,-0.05/0.95 	;scale to 0 to 1
wrax taptempo,0		;and write to taptempo register, pot controls delay time

DODELAY:

clr
rdax fback,1		;read feedback register, scaled to 0.95%
rdax adcl,1		;mix with input from ADCL
wra delay,0		;write to head of delay
ldax taptempo		;read taptempo register
wrax addr_ptr,0		;write to delay address pointer
rmpa 1			;read from delay address set by pointer
wrax delayout,1		;write to delayout register

mulx pot0		;mulx with pot0, feedback level control
wrax clip,-0.33333	;soft clip, using cube distortion snippet
mulx clip
mulx clip
rdax clip,1
wrax fback,0		;write to feedback register

rdax delayout,0.5		;read delayout register
rdax adcl,1		;mix with input from ADCL
wrax dacl,0		;write to DACL

ldax led			;read led register
wrax dacr,0		;write to DACR, flashes LED attached to DACR
Post Reply