tap tempo snippet

Algorithm development and general DSP issues

Moderator: frank

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

Post by frank »

Sweetalk wrote:Nice idea, i'll try that. I'm really close to sync the sine but it's really hard to do that and I don't think that I understand really well the coef of the sine lfo that appears on the AN0001. They're really different to the ones on some example codes, it's confusing :roll:
First, sorry for the delay in getting to this. I did see the posting a few days back but things are always crazy this time of year and kept getting pulled for other issues.

So, the coefficients are handled slightly differently depending if you are using them in a WLDR/WLDS or a WRAX instruction. Basically in WLDR/WLDS they expect an integer value while WRAX expects a fractional value. To convert an integer to the equivalent fractional just divide the desired integer value by the max allowed for a control value plus 1.

For example, lets say you calculate C for the ramp to be 10000 but you want to use it in a WRAX instruction so you can update it based on a pot. The max allowed value for C is 32767 so the fractional value to use in a WRAX would be 10000/(32767+1) = 0.305176

If this doesn't address your question please paste the code that you are seeing that seems to be wrong and I'll try to check it and see if we made a mistake or if there is a reason we did a strange thing to the numbers.
Frank Thomson
Experimental Noize
Sweetalk
Posts: 141
Joined: Thu Oct 15, 2009 5:13 am

Post by Sweetalk »

frank wrote:
Sweetalk wrote:Nice idea, i'll try that. I'm really close to sync the sine but it's really hard to do that and I don't think that I understand really well the coef of the sine lfo that appears on the AN0001. They're really different to the ones on some example codes, it's confusing :roll:
First, sorry for the delay in getting to this. I did see the posting a few days back but things are always crazy this time of year and kept getting pulled for other issues.

So, the coefficients are handled slightly differently depending if you are using them in a WLDR/WLDS or a WRAX instruction. Basically in WLDR/WLDS they expect an integer value while WRAX expects a fractional value. To convert an integer to the equivalent fractional just divide the desired integer value by the max allowed for a control value plus 1.

For example, lets say you calculate C for the ramp to be 10000 but you want to use it in a WRAX instruction so you can update it based on a pot. The max allowed value for C is 32767 so the fractional value to use in a WRAX would be 10000/(32767+1) = 0.305176

If this doesn't address your question please paste the code that you are seeing that seems to be wrong and I'll try to check it and see if we made a mistake or if there is a reason we did a strange thing to the numbers.
Thanks Frank, I'll check this out as soon as I can.
ice-nine
Posts: 192
Joined: Thu May 24, 2012 9:03 am

Post by ice-nine »

slacker wrote:I think this will work, change these lines

Code: Select all

ldax taptempo      ;read taptempo register
wrax addr_ptr,0      ;write to delay address pointer
to this

Code: Select all

ldax taptempo      ;read taptempo register
 sof 3/4,0          ;multiply tapped tempo by 3/4 
wrax addr_ptr,0      ;write to delay address pointer
The sof line could be replaced by something more complicated, maybe a pot skip routine to let you select different divisions.

I have looked at the maths for note divisions and would like to ask if these would be correct with the following.


sof 3/4,0 ;multiply tapped tempo by 3/4 (as Slackers post)
sof 2/3,0 :Dotted 1/8th
sof 1/2,0 ;8th note
sof 1/3,0 ;8th triplet
sof 1/4,0 ;16th note

Also what type of footswitch is needed for the tap delay, I have a SPST momentary switch connected should I be using a SPDT so that it switches between hi/low rather than just pulling to ground ?

Thanks for the code Ian it's great for me to work with code others have written and try to learn from it.
slacker
Posts: 116
Joined: Tue Feb 01, 2011 1:13 pm

Post by slacker »

I think those divisions are right.
I use a SPST momentary, using the method we talked about here you have to turn the pot all the way up for it to work consistently. If you only want to use that pin for tap tempo, use a resistor from the pin to 3.3 Volts to pull it up and SPST to pull the pin to ground. The code doesn't actually care which way the transition goes so long as it goes between high and low.

Look forward to seeing what you come up with.
ice-nine
Posts: 192
Joined: Thu May 24, 2012 9:03 am

Post by ice-nine »

Yes, I wired the pot/switch combination up the way we discussed in the hardware thread, but I think the problem would be that I also put a resistor on both ends of the pot. I expect this is not allowing the pin to get close enough to the +rail to work.

Sorry a little off topic in the software area. Thanks for the pointers.
slacker
Posts: 116
Joined: Tue Feb 01, 2011 1:13 pm

Post by slacker »

I think it should work with resistors limiting the pot travel, so long as the high voltage is above half the supply. Making the "count" value bigger might help if high isn't 3.3 Volts, might need some experimenting, too big and you might get switch bounce.

I discovered a small error in the code recently. The sof 0.064 instructions to set the ramp speed should be sof 0.0625, 0.064 is slightly over 1Hz, probably doesn't make any practical difference.

These are wrong as well

Code: Select all

wldr rmp0,0.064,4096   ;set up rmp0
wldr rmp1,0.064,4096   ;set up rmp1 
The 0.064 should be the coefficient value not the decimal, so it should be 2047.9375 or however many decimal places you want. These get overridden by the sof 0.0625 instructions anyway so it doesn't really matter.
ice-nine
Posts: 192
Joined: Thu May 24, 2012 9:03 am

Post by ice-nine »

I have noticed a couple of things that don't seem to be working the way I was expecting but most likely my fault.
I have swapped which pots control which setting as the layout on my hardware works for me that way but maybe I haven't done in correctly.

Im using pot0 to control the delay/tap input, pot 1 stays the same for level and pot2 for feedback.
The lines I have changed are

Code: Select all

ldax   pot2   ;read pot2 
to

Code: Select all

 
Idax  pot0    ;read pot0
and

Code: Select all

mulx pot0    ;mulx with pot0, feedback level control
to

Code: Select all

mulx pot2    ;mulx with pot2, feedback level control
It looks like this is all that needed changing but if I have missed something this may be causing the problem.

I have noticed that the delay time is nearer 0.5 seconds rather than 1 second, is this correct? Also the pot controls the delay but the switch can only change the delay from min/max when either held pressed or released just like a pot on min or max. Pretty stumped on this one.
slacker
Posts: 116
Joined: Tue Feb 01, 2011 1:13 pm

Post by slacker »

Those changes look right to me. Are you using the latest version of the code the one from 18 September 2011, the earlier ones have an error and the delay time doesn't match the tapped tempo.

Not sure why your switch isn't working, have you made some other changes to the code? The pot used for tap tempo doesn't control the delay time in my code.
ice-nine
Posts: 192
Joined: Thu May 24, 2012 9:03 am

Post by ice-nine »

slacker wrote:Did you use the latest version? The first and second versions I posted have an error in them and the delay doesn't match the tapped tempo.

In the latest one the delay time should match the tap tempo, and it seems to work for me, I haven't tested it though so there might still be some error. I'll see if I can do some tests but if you could try it with a click track and let me know what you find that would be great.
I had made no other code alterations, I have been using the code dated Sun Sep 18, 2011 and have just re-tried it without any alterations of any kind. The pot is definitely still changing the delay time. while the other 2 pots control delay level and feedback.

With this code should the pot2 be having no effect on the delay time at all ?
slacker
Posts: 116
Joined: Tue Feb 01, 2011 1:13 pm

Post by slacker »

Pot 2 should act like a switch, if you turn it up and down fast enough it should set the tap tempo. It doesn't directly control the delay time.

I wonder is there's something wrong with your switch or wiring. I would check that when the switch is not pressed you have 3.3 Volts on the Pot2 pin on the FV-1 and that when the switch is pressed and held you get zero Volts.

If tapping it at different speeds then doesn't change the tempo I'm not sure what's wrong.
ice-nine
Posts: 192
Joined: Thu May 24, 2012 9:03 am

Post by ice-nine »

As a last ditch attempt to troubleshoot this, I have removed the switch and left the 3 pots wired in as normal, on another pc I have assembled the code and tested on the hardware. Same result pot 2 definitely adjusts the delay time.

Should the pot have no effect at all on the delay time.

Here is the code I have tried (just in case i'm using the wrong code)

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 = delay level 

 ;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.064,4096   ;set up rmp0 
 wldr rmp1,0.064,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.064       
 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.064       
 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: 

 ;delay 

 clr 
 rdax fback,0.95      ;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,1      ;read delayout register 
 mulx pot1      ;mulx with pot1, delay level control 
 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
Thanks for taking the time to try and help me, I know it can be hard to trouble shoot this way.
slacker
Posts: 116
Joined: Tue Feb 01, 2011 1:13 pm

Post by slacker »

ice-nine wrote: Should the pot have no effect at all on the delay time.
If you slowly turn the pot it shouldn't do anything, the position of the pot shouldn't change the delay time at all. If you turn it back and forth repeatedly so it goes from one end to the other in less than a second, then the code might occasionally read the high/low transitions the same as it would for a switch and the delay time will change.
Thanks for taking the time to try and help me, I know it can be hard to trouble shoot this way.
No problem, be nice to figure out what's going on.
ice-nine
Posts: 192
Joined: Thu May 24, 2012 9:03 am

Post by ice-nine »

Thanks for sticking with this, I have solved the problem and after checking everything over and over and knowing the code and the circuit were 100% fine I knew the problem had to be else where. I suspected my PC was not saving the compiled hex properly. To cut a long story short, I set up a spare laptop last night and all compiled perfectly, and now I have a working tap tempo to play around with. :D
slacker
Posts: 116
Joined: Tue Feb 01, 2011 1:13 pm

Post by slacker »

Glad you got it sorted, weird one that not your usual debug.
Mcfly
Posts: 46
Joined: Fri Mar 08, 2013 2:38 pm
Location: Argentina

tap tempo snippet

Post by Mcfly »

ice-nine wrote:Yes, I wired the pot/switch combination up the way we discussed in the hardware thread, but I think the problem would be that I also put a resistor on both ends of the pot. I expect this is not allowing the pin to get close enough to the +rail to work.

Sorry a little off topic in the software area. Thanks for the pointers.
I put a resistor on both ends of the pot also, and my switch for the tap goes from no connection to 3,3v. This way I can use this momentary switch to set the reverb level to max in another program.
My question is, how much has to be the voltage diference beetwen high to low to get a nice tap recognition?. Will it work this way? high=3,3v and low=3v.
:?:
Post Reply