' ******************************************************************** ' * PIC firmware for player piano pp2 pedal * ' * coded by dr.Godfried-Willem Raes * ' * http://www.logosfoundation.org/instrum_gwr/playerpiano/picworks * ' * source code development directory: * ' * pp2-pedal-V3.bas * ' ******************************************************************** ' 02.02.2016: PCB designed ' 04.02.2016: Board etched and soldered. Start coding. ' This board is placed inside the power supply chassis. ' It connects to the pedal with a 5-pole din chord using ' a quad optocoupler ' Measurement and debug with Tektronix scope. ' 06.02.2016: Back_lite works fine, yellow lite has a problem... ' bug found: we had PORTA.3 for loop speed measurement ' changed yo PORTA.2 ' Added: support for Ctrl #68: pedal release speed. ' requires an extra timer ' Works fine on the led debug board. Checked with tektronix. Include "18F2525.inc" ' (40MHz) ' Mapping defines for midi-events on pin outputs and inputs: $define Yellow_Lite PORTA.3 ' on front of power supply module $define back_lite PORTA.4 ' back side of power supply module $define Blue_Lite PORTC.0 ' on pedal $define Amber_Lite PORTC.3 ' on pedal $define Hold_Voltage PORTC.1 ' pwm pedal solenoid hold $define Velo_Voltage PORTC.2 ' pwm pedal solenoid velo $define blue_led PORTC.4 $define yellow_led PORTC.5 $define green_led PORTB.2 $define analog0 PORTA.0 ' option $define analog1 PORTA.1 ' option 'red LED for debug: $define Debug_Led PORTB.5 ' for testing - red led - watchdog Declare All_Digital = True ' makes all analog pins, digital for I/O ' configure the input and output pins: Clear SSPCON1.5 'RC3 must be available for I/O TRISA = %01000011 'bits set to 0 are output, 1 = input TRISB = %11100000 'ICD on B7, B6,B5 TRISC = %11000000 'RC1 en RC2 zijn pwm outputs and must be set to output 'RC6 en RC7 zijn USART I/O and must be set to input 'constant definitions: Symbol fPWM = 4000 ' limited by the speed of the optocouplers Symbol lite3 = 127 ' amber light pedal Symbol lite2 = 126 ' blue light pedal Symbol Lite1 = 125 ' yellow spotlite Symbol Lite0 = 124 ' backlight Symbol U_Hold = 255 ' default hold voltage Symbol U_Velo = 255 ' default velo voltage Symbol Timeunit = 516 ' = Maxtime / 127 = 11ms Symbol Maxtime = 65537 'initialisations for the midi input parser: Symbol Midichannel = 0 ' Piano_Channel Symbol NoteOff_Status = 128 + Midichannel ' 2 bytes follow Symbol NoteOn_Status = 144 + Midichannel Symbol Keypres_Status = 160 + Midichannel Symbol Control_Status = 176 + Midichannel Symbol ProgChange_Status = 192 + Midichannel ' 1 byte message Symbol Aftertouch_Status = 208 + Midichannel ' 1 byte follows Symbol Pitchbend_Status = 224 + Midichannel ' lsb msb follow ' Setup the USART Declare Hserial_Baud = 31250 ' Set baud rate for the USART to MIDI specs. Declare Hserial_TXSTA = 0x24 ' instead of the normal 0x20 - ?? 0x24 ' Declare Hserial_Clear = On ' should clear on errors. Bytes get lost of course... ' Create variables: ' Dim Cnt As Dword System '32 bit counter ' Dim CntHw As Cnt.Word1 ' Word System 'used in the timer0 interrupt, where it is incremented ' Dim CntLw As TMR0L.Word 'this is the trick to read both TMR0L and TMR0H 'it makes Cntlw the low word of cnt, when we use cnt.word0=CntLw ' Dim Tim1 As TMR1L.Word 'not used here ' Dim Tim2 As TMR2 'not used here ' Dim Cnt3 As Dword System ' Dim Cnt3Hw As Cnt3.Word1 ' Dim Tim3 As TMR3L.Word ' same trick for timer3 ' Dim Sr as TMR0L.7 '512 S/s - this works but these DO NOT WORK!!!: ' Dim Sr as CntLw.Byte1 does not ' Dim Sr As TMR0H.0 'sampling rate bit, 256 S/s ' DIM Sr as CntLw.8 ' As TMR0H.1 would be 128 S/s ' As TMR0H.2 would be 64 S/s ' As TMR0H.3 would be 32 S/s ' As TMR0H.4 would be 16 S/s Dim Bytein As Byte System ' midi byte read from buffer Dim StBit As Bytein.7 ' highest bit of ByteIn Dim i As Byte System ' general purpose counter ' midi variables Dim statusbyte As Byte System Dim noteUit As Byte System ' note off + release value Dim release As Byte System Dim noteAan As Byte System ' note on + release value Dim velo As Byte System Dim notePres As Byte System ' note pressure + pressure value Dim pres As Byte System Dim Ctrl As Byte System ' continuous controller + value Dim value As Byte System Dim prog As Byte System ' program change + program-byte ' Dim aft As Byte System ' channel aftertouch ' Dim pblsb As Byte System ' pitch bend lsb ' Dim pbmsb As Byte System ' pitch bend msb ' Dim veltim As Dword System ' 32 bit velo Dim veltim0 As Dword System ' faster, replaces the arrays Dim veltim1 As Dword System Dim veltim2 As Word System Dim veltim3 As Word System Dim veltim4 As Word System ' for attack control of solenoid - pulse duration Dim Velflags As Byte System ' so we can have only 8 tasks ' Dim CC66 As Byte System ' global on/off switch ' Dim PowerOn As CC66.0 ' handled on the hub board. Dim notes As Word System ' for note repetition mechanism Dim Rate0 As Word System Dim Rate1 As Word System Dim Rate2 As Word System Dim Rate3 As Word System ' Dim velo0 As Word System ' Dim velo1 As Word System ' Dim velo2 As Word System ' Dim velo3 As Word System ' Dim velo4 As Word System Dim Pres0 As Byte System 'indexes for durations lookup Dim pres1 As Byte System Dim pres2 As Byte System Dim pres3 As Byte System Dim CC64 As Byte System Dim CC65 As Byte System Dim CC66 As Byte System Dim CC67 As Byte System Dim CC68 As Byte System Dim relstep As Float Dim pwmval As Float Dim time As Dword System ' 32-bit, incremented in loopcounter Dim maxtim As time.31 ' overflow bit, will cause timer reset after 1h45 Dim t As Byte System ' loopcounter, running at 4 times time-clock Dim tog As Byte System Dim tg As tog.0 ' divide by 4 bit Dim TimVals[6] As Dword ' lijst met timer waarden - de kleinste is eerst aan de beurt Dim Nxt As Dword System ' waarde voor de eerstvolgende timer Dim idx As Byte System ' index voor de eerstvolgende timer Dim Ringbuffer[256] As Byte 'System '----------------------------------------------------------------------------------------- ' Load the USART Interrupt handler and buffer read subroutines into memory Include "pp2_Irq_Pow.inc" ' for UART,Timer0, Timer3 Interrupt 'Clear ' clear all RAM '----------------------------------------------------------------------------------------- Dim vels[128] As Word ' velocity lookup table for the pedal Dim Dur[128] As Word ' duration lookup for repetitions ' Main program starts here MAIN: High Debug_Led DelayMS 10 ' wait for stability Low Debug_Led Low blue_led ' pedal indicator: on is pedal down Low green_led ' CC66 Low yellow_led ' Low PortA ' Low PortB HPWM 2, 0, fPWM ' hold off HPWM 1, 0, fPWM ' velo off Low back_lite ' portA.4 Low Yellow_Lite ' PORTA.3 Low Blue_Lite Low Amber_Lite Clear notes Clear Velflags Set TimVals Clear Pres0 Clear Rate0 Clear pres1 Clear Rate1 Clear pres2 Clear Rate2 Clear pres3 Clear Rate3 Clear CC64 CC65 = U_Velo CC67 = U_Hold Clear CC66 Clear CC68 relstep = 0 pwmval = CC67 Init_Usart_Interrupt ' Initiate the USART serial buffer interrupt ' this procedure is in the include file Clear_Serial_Buffer ' Clear the serial buffer and reset its pointers ' in the include as well ' Configure Timer0 for: ' Clear TMR0L and TMR0H registers ' Interrupt on Timer0 overflow ' 16-bit operation ' Internal clock source 40MHz ' 1:256 Prescaler : thus 40MHz / 256 = 156.250kHz ' 6.4 us per clock-tick ' Opentimer0 (Timer_INT_On & T0_16BIT & T0_SOURCE_INT & T0_PS_1_256) ' replacing above macro with in-line coding: Clear T1CON Clear IntConBits_T0IF ' clear interrupt flag Set INTCONBITS_T0IE ' enable interrupt on overflow T0CON = %10000111 ' bit 7 = enable/disable ' bit 6 = 1=8 bot, 0=16 bit ' bit 5 = 1 pin input, 0= Internal Clk0 ' bit 4 = HL or LH transition when bit5 =1 ' bit 3 = 1= bypass prescaler, 0= input from prescaler ' bit 2-0 = prescaler select: 111= 1:256 ' Setup the High priorities for the interrupts ' TIMER1: if enabled, all midi-in is blocked, so it must interfere with the UART ' Configure Timer1 for: ' Clear TMR1L and TMR1H registers ' Interrupt on Timer1 overflow ' 16-bit read/write mode ' Internal clock source ' 1:8 Prescaler ' OpenTimer1(TIMER_INT_ON & T1_16BIT_RW & T1_SOURCE_INT & T1_PS_1_8) ' dit kompileert o.k. ' TIMER2: if enabled, the UART stops working... ' Opentimer2 (Timer_Int_On & T2_POST_1_16 & T2_PS_1_16) ' dit lukt... maar de timer is nodig voor de UART... ' TIMER3: ' Configure Timer3 for: ' Interrupt on Timer3 overflow ' 16-bit read/write mode ' Internal clock source ' 1:8 Prescaler ' Don’t sync external clock input ' T3_OSC1En_On () ' macro ' OpenTimer3(TIMER_INT_ON & T3_16BIT_RW & T3_SOURCE_INT & T3_PS_1_8 & T3_SYNC_EXT_OFF) ' fout, but == voorbeeld??? ' Opentimer3 (Timer_Int_On & T3_16BIT_RW & T3_SOURCE_INT & T3_PS_1_8 & T3_SYNC_EXT_OFF & T3_SOURCE_CCP) ' fout ' OpenTimer3 (Timer_INT_ON & T3_16BIT_RW & T3_PS_1_8 & T3_SYNC_EXT_OFF) ' fout ' OpenTimer3 (0xFFFF & Timer_INT_On & T3_16BIT_RW) ' OpenTimer3(T3_8BIT_RW & T3_SOURCE_EXT & T3_PS_1_1 & T3_SYNC_EXT_OFF) ' copied from manual, fout!!! ' OpenTimer3(TIMER_INT_OFF & T3_16BIT_RW & T3_SOURCE_INT & T3_PS_1_8) ' doing it this way seems to work: Clear T3CON Clear PIR2BITS_TMR3IF ' clear IRQ flag Set PIE2BITS_TMR3IE ' irq on 'T3_OSC1En_On () ' macro - sets T3CON ' Clear Tim3 ' Clear TMR3L And TMR3H registers Set RCONbits_IPEN ' Enable priority interrupts Clear IPR2bits_TMR3IP ' Set Timer3 as a low priority interrupt source ' we can also set T3Con in one instruction as: T3CON = %10110001 ' oef, now it works... ' bit 7 = 16 bit mode ' bit 6,3 = 0, 0 ' bit 5,4 = 1:8 prescale ' bit 2 = 0 ' bit 1 = 0 Internal clock = Fosc/4 ' bit 0 : 1= enable timer 3, 0= disable ' maximum count = 52.42ms, 1 tick =0.8uS, freq.=19Hz ' Set up priority interrupts. IPR1bits_TMR1IP = 0 ' Set Timer1 as a low priority interrupt source INTCONbits_PEIE = 1 ' Enable peripheral interrupts INTCONbits_GIE = 1 ' Enable global interrupts ' Open the ADC: ' not used on this board. ' Fosc/32 ' Right justified for 10-bit operation ' Tad value of 0 ' Vref+ at Vcc : Vref- at Gnd ' Make AN0 an analogue input ' OpenADC(ADC_FOSC_32 & ADC_RIGHT_JUST & ADC_0_TAD, ADC_REF_VDD_VSS, ADC_1ANA) GoSub Dur_Lookup ' for flashing light only GoSub Vels_Lookup ' start the main program loop: LOOP: ' Create an infinite loop Inc t ' byte If t.1 = tg Then Btg tg Inc time ' dword EndIf Bytein = HRSIn ' Read data from the serial buffer, with no timeout ' Start the midi parser. Midi_Parse: If Bytein > Control_Status Then ' here higher statusses are not implemented. If Bytein > 253 Then '254 = midiclock, 255= reset 'midiclock can interrupt all other msg's... '255 had to be intercepted since thats what we 'get when no new byte flows in. Else Clear statusbyte 'reset the status byte End If GoTo Check_Timers 'throw away... EndIf If StBit =1 Then 'should be faster than If Bytein > 127 Then 'status byte received, bit 7 is set Clear statusbyte 'if on another channel, the statusbyte needs a reset Select Bytein 'eqv to Select case ByteIn Case NoteOff_Status statusbyte = Bytein Set noteUit 'reset value. Cannot be 0 !!! Set release '0 is a valid midi note! Case NoteOn_Status statusbyte = Bytein Set noteAan '= 255 Set velo '= 255 Case Keypres_Status 'only used for flashing lite statusbyte = Bytein notePres = 255 pres = 255 Case Control_Status ' controllers and switches statusbyte = Bytein Set Ctrl Set value ' Case ProgChange_Status ' used for different lookup tables ' statusbyte = Bytein ' prog = 255 ' Case Aftertouch_Status ' statusbyte = Bytein ' Set aft ' Case Pitchbend_Status ' not on this board. ' statusbyte = Bytein ' pblsb = 255 ' pbmsb = 255 End Select Else 'midi byte is 7 bits Select statusbyte Case 0 'not a message for this channel GoTo Check_Timers 'disregard Case NoteOff_Status If noteUit = 255 Then noteUit = Bytein Else release = Bytein 'message complete, so we can do the action... Select noteUit Case Lite0 Low back_lite ' back panel PS Clear Velflags.0 Clear notes.0 Set TimVals[0] Case Lite1 Low Yellow_Lite ' front panel PS Clear Velflags.1 Clear notes.1 Set TimVals[1] Case lite2 Low Blue_Lite ' pedal Clear Velflags.2 Clear notes.2 Set TimVals[2] Case lite3 Low Amber_Lite ' pedal Clear Velflags.3 Clear notes.3 Set TimVals[3] Case Else Set noteUit GoTo Check_Timers End Select Set noteUit ' reset GoTo resort ' mandatory, as we changed timers! EndIf GoTo Check_Timers Case NoteOn_Status If noteAan = 255 Then noteAan = Bytein Else velo = Bytein If velo = 0 Then Select noteAan Case Lite0 Low back_lite Clear Velflags.0 Clear notes.0 Set TimVals[0] Case Lite1 Low Yellow_Lite Clear Velflags.1 Clear notes.1 Set TimVals[1] Case lite2 Low Blue_Lite Clear Velflags.2 Clear notes.2 Set TimVals[2] Case lite3 Low Amber_Lite Clear Velflags.3 Clear notes.3 Set TimVals[3] Case Else Set noteAan GoTo Check_Timers End Select Set noteAan GoTo resort ' mandatory as we changed timers Else Select noteAan Case Lite0 High back_lite If velo < 127 Then Set Velflags.0 Rate0 = Dur[velo] TimVals[0] = time + Rate0 Set notes.0 Else Clear Velflags.0 Clear notes.0 Set TimVals[0] EndIf Case Lite1 High Yellow_Lite If velo < 127 Then Set Velflags.1 Rate1 = Dur[velo] TimVals[1] = time + Rate1 Set notes.1 Else Clear Velflags.1 Clear notes.1 Set TimVals[1] EndIf Case lite2 High Blue_Lite If velo < 127 Then Set Velflags.2 Rate2 = Dur[velo] TimVals[2] = time + Rate2 Set notes.2 Else Clear Velflags.2 Clear notes.2 Set TimVals[2] EndIf Case lite3 High Amber_Lite If velo < 127 Then Set Velflags.3 Rate3 = Dur[velo] TimVals[3] = time + Rate3 Set notes.3 Else Clear Velflags.3 Clear notes.3 Set TimVals[3] EndIf Case Else Set noteAan GoTo Check_Timers End Select Set noteAan '= 255 'reset !!! GoTo resort EndIf EndIf GoTo Check_Timers Case Keypres_Status 'used for note repetitions If notePres = 255 Then notePres = Bytein Else pres = Bytein GoSub KeyPres EndIf GoTo Check_Timers Case Control_Status If Ctrl = 255 Then Ctrl = Bytein Else value = Bytein Select Ctrl Case 64 ' velo value for the pulse duration ' start the velo-timer: CC64 = value If value > 0 Then ' pedal down Set blue_led Clear Velflags.5 ' clear release timer Set Velflags.4 ' set the timer bit HPWM 2, 0, fPWM ' hold voltage OFF TimVals[4] = time + vels[value] ' program the timer HPWM 1, CC65, fPWM ' velo pulse start Else ' here we should added a procedure for slow release Clear Velflags.4 ' cancel timer flag HPWM 1, 0, fPWM ' velo off Set TimVals[4] ' erase timer program value ' if CC68 is set If CC68 = 0 Then Clear blue_led HPWM 2, 0, fPWM ' hold voltage off Clear Velflags.5 Set TimVals.5 Else pwmval = CC67 - relstep ' CC67 must be > 0 HPWM 2, pwmval, fPWM ' set a slow release timer: TimVals[5] = time + Timeunit ' 516 Set Velflags.5 EndIf EndIf Set Ctrl GoTo resort Case 65 ' sets the pwm value for the velocity (attack force) CC65 = value << 1 ' make 8-bit If CC65 > 0 Then Set yellow_led If value = 127 Then Set CC65 ' make 255 Else Clear yellow_led EndIf Case 66 'on/off for the robot If value = 0 Then GoSub PowerDown ' low green_led Else CC67 = U_Hold ' reset to default Set CC66 CC65 = U_Velo ' reset to default Clear CC68 ' no soft release on startup High green_led ' on board indicator EndIf Case 67 ' sets the force required to hold the pedal down CC67 = value << 1 If value = 127 Then Set CC67 ' range is 0, 2-255 Case 68 ' set the time for pedal slow release CC68 = value If CC67 > 0 Then If CC68 > 0 Then relstep = CC67 / CC68 ' floating point Else relstep = 0 EndIf Else Clear CC68 ' CC68 on with CC67 off makes no sense relstep = 0 EndIf Case 123 Clear back_lite Clear Yellow_Lite Clear Blue_Lite Clear Amber_Lite HPWM 1, 0, fPWM HPWM 2, 0, fPWM Clear Velflags Clear notes Set TimVals Set Ctrl GoTo resort End Select Set Ctrl 'mandatory reset EndIf GoTo Check_Timers Case Else GoTo Check_Timers ' no sorting End Select EndIf resort: GoSub SortTimers ' so we resort only if an incoming midi command changed something Check_Timers: If idx < 6 Then ' we moeten alleen checken wanneer er een timer loopt If time >= Nxt Then ' nagaan of de eerstvolgende timer afgelopen is... ' in dit geval is de eerste timer afgelopen en moeten we de juiste aktie ondernemen: Set Nxt.31 ' timer reset, is immers afgelopen ' aan de hand van idx weten we welke timer dit is Select idx Case 0 ' Lite0 If notes.0 = 0 Then ' in dit geval zijn er geen repeats Clear Velflags.0 ' cancel timer Set TimVals[0] ' set to infinite= disable Clear back_lite Else ' in dit geval moet de noot worden herhaald: If Velflags.0 = 1 Then Btg back_lite TimVals[0] = time + Rate0 EndIf EndIf Case 1 ' Lite1 yellow If notes.1 = 0 Then ' in dit geval zijn er geen repeats Clear Velflags.1 ' cancel timer Set TimVals[1] ' set to infinite= disable Clear Yellow_Lite Else ' in dit geval moet de noot worden herhaald: If Velflags.1 = 1 Then Btg Yellow_Lite TimVals[1] = time + Rate1 EndIf EndIf Case 2 ' Lite2 blue pedal If notes.2 = 0 Then ' in dit geval zijn er geen repeats Clear Velflags.2 ' cancel timer Set TimVals[2] ' set to infinite= disable Clear Blue_Lite Else ' in dit geval moet de noot worden herhaald: If Velflags.2 = 1 Then Btg Blue_Lite TimVals[2] = time + Rate2 EndIf EndIf Case 3 ' Lite3 amber pedal If notes.3 = 0 Then ' in dit geval zijn er geen repeats Clear Velflags.3 ' cancel timer Set TimVals[3] ' set to infinite= disable Clear Amber_Lite Else ' in dit geval moet de noot worden herhaald: If Velflags.3 = 1 Then Btg Amber_Lite TimVals[3] = time + Rate3 EndIf EndIf Case 4 ' velocity pulse Clear Velflags.4 ' no repeats here! Set TimVals[4] ' cancel timer HPWM 1, 0, fPWM ' velo-off HPWM 2, CC67, fPWM ' hold ON Case 5 ' slow release procedure for pedal pwmval = pwmval - relstep ' float! If pwmval > 0.015 Then HPWM 2, pwmval, fPWM ' reload timer TimVals[5] = time + Timeunit Else Clear blue_led Clear Velflags.5 Set TimVals[5] HPWM 2, 0, fPWM EndIf 'Case Else ' ' in dit geval is idx geset ' GoTo jumpout End Select GoSub SortTimers ' find a new nxt and idx EndIf ' beveiliging tegen overflow crashes... If maxtim = 1 Then Clear time Clear Velflags Clear notes Set TimVals EndIf Else ' idx > 1, no timers running, so to avoid overflows, we can reset the loop timer If maxtim = 1 Then Clear time ' 16.06.2015 EndIf Btg PORTA.2 ' average loop-speed: 4.8 microseconds,(Tektronix measurement, 01.02.2016) GoTo LOOP SortTimers: 'look up the next smallest timer value in the Timvals array ' zoek de de volgende kleinste timer waarde: Set idx ' makes it 255 Set Nxt.31 ' nxt is set on entry. - for speed, we just set the highest bit For i = 0 To 5 If TimVals[i] < Nxt Then Nxt = TimVals[i] ' 6 dword comparisons idx = i EndIf Next i Return KeyPres: ' used for auto-repeat in , here only for the lights Select notePres Case Lite0 ' backlite Pres0 = pres If Pres0 > 0 Then Rate0 = Dur[Pres0] ' note that we set notes.0 only on reception of a note-on ' this way we can program the repeats prior to playing. Else Clear Rate0 Clear notes.0 ' we have to cancel running timers here: Clear Velflags.0 Set TimVals[0] Clear back_lite GoSub SortTimers EndIf Case Lite1 ' yellow spot pres1 = pres If pres1 > 0 Then Rate1 = Dur[pres1] Else Clear Rate1 Clear notes.1 ' we have to cancel running timers here: Clear Velflags.1 Set TimVals[1] Clear Yellow_Lite GoSub SortTimers EndIf Case lite2 ' blue lite pres2 = pres If pres2 > 0 Then Rate2 = Dur[pres2] Else Clear Rate2 Clear notes.2 ' we have to cancel running timers here: Clear Velflags.2 Set TimVals[2] Clear Blue_Lite GoSub SortTimers EndIf Case lite3 ' amber lite pres3 = pres If pres3 > 0 Then Rate3 = Dur[pres3] Else Clear Rate3 Clear notes.3 ' we have to cancel running timers here: Clear Velflags.3 Set TimVals[3] Clear Amber_Lite GoSub SortTimers EndIf EndSelect ' we do not need to resort here if pres changed ' as timers are only reprogrammed after reception of a note-on ' however on note-pressure zero we perform a full noteoff. Set notePres '= 255 Return ProgChange: Set prog 'this is not realy required Return 'Pitchbend: ' Set pblsb 'Return 'Aftertouch: ' Set aft ' reset 'Return 'Controller: ' Set Ctrl 'mandatory reset 'Return PowerDown: ' must perform a controller reset!!! Low blue_led Low green_led Low yellow_led HPWM 1, 0, fPWM ' velo off HPWM 2, 0, fPWM ' hold off Low back_lite Low Yellow_Lite Low Blue_Lite Low Amber_Lite Clear notes ' cancel all repetition flags Clear Velflags ' cancel all timers Set TimVals CC65 = U_Velo CC67 = U_Hold Clear CC68 ' no soft release on start-up ' we should also reset programmed repeat frequencies. Clear Rate0 Clear Pres0 Clear Rate1 Clear pres1 Clear Rate2 Clear pres2 Clear Rate3 Clear pres3 GoSub SortTimers Return Dur_Lookup: Set Dur[0] ' 0-index not used ' durations for note repetition on pp2 ' the dur values are for a half period ! ' the frequencies are for the full period. Dur[1]= 23674 ' freq= 2.01144916866806 Dur[2]= 22917 ' freq= 2.07789185404056 Dur[3]= 22548 ' freq= 2.11189673669716 Dur[4]= 22185 ' freq= 2.14645245071208 Dur[5]= 21827 ' freq= 2.18165792912666 Dur[6]= 21475 ' freq= 2.21741781695216 Dur[7]= 21129 ' freq= 2.25372935865624 Dur[8]= 20789 ' freq= 2.29058865837932 Dur[9]= 20454 ' freq= 2.32810441082662 Dur[10]= 20124 ' freq= 2.36628143604888 Dur[11]= 19800 ' freq= 2.4050024050024 Dur[12]= 19481 ' freq= 2.44438414963542 Dur[13]= 19167 ' freq= 2.48442884223132 Dur[14]= 18858 ' freq= 2.52513774626406 Dur[15]= 18554 ' freq= 2.56651113609182 Dur[16]= 18255 ' freq= 2.60854821249234 Dur[17]= 17961 ' freq= 2.65124701403305 Dur[18]= 17672 ' freq= 2.69460432430102 Dur[19]= 17387 ' freq= 2.73877308443364 Dur[20]= 17107 ' freq= 2.78360014140689 Dur[21]= 16831 ' freq= 2.82924648678318 Dur[22]= 16560 ' freq= 2.87554635380722 Dur[23]= 16293 ' freq= 2.92266909832736 Dur[24]= 16030 ' freq= 2.97062056263553 Dur[25]= 15772 ' freq= 3.01921427967586 Dur[26]= 15518 ' freq= 3.06863304672301 Dur[27]= 15268 ' freq= 3.11887919957084 Dur[28]= 15022 ' freq= 3.16995390887016 Dur[29]= 14780 ' freq= 3.22185707842 Dur[30]= 14542 ' freq= 3.27458723827862 Dur[31]= 14307 ' freq= 3.32837405598991 Dur[32]= 14077 ' freq= 3.38275538957502 Dur[33]= 13850 ' freq= 3.43819838404676 Dur[34]= 13627 ' freq= 3.49446302333952 Dur[35]= 13407 ' freq= 3.55180484963434 Dur[36]= 13191 ' freq= 3.60996494724036 Dur[37]= 12978 ' freq= 3.66921310055845 Dur[38]= 12769 ' freq= 3.7292699208276 Dur[39]= 12564 ' freq= 3.79011840329892 Dur[40]= 12361 ' freq= 3.85236207580678 Dur[41]= 12162 ' freq= 3.91539612062552 Dur[42]= 11966 ' freq= 3.97952930127424 Dur[43]= 11773 ' freq= 4.04476748654104 Dur[44]= 11583 ' freq= 4.11111522222633 Dur[45]= 11397 ' freq= 4.17820896894337 Dur[46]= 11213 ' freq= 4.24677139204919 Dur[47]= 11032 ' freq= 4.3164473911392 Dur[48]= 10855 ' freq= 4.38683073413612 Dur[49]= 10680 ' freq= 4.45871232388086 Dur[50]= 10508 ' freq= 4.53169467253974 Dur[51]= 10338 ' freq= 4.60621470487982 Dur[52]= 10172 ' freq= 4.68138494092092 Dur[53]= 10008 ' freq= 4.75809828327814 Dur[54]= 9846 ' freq= 4.83638509232659 Dur[55]= 9688 ' freq= 4.91526090204868 Dur[56]= 9532 ' freq= 4.99570369482245 Dur[57]= 9378 ' freq= 5.07774020250028 Dur[58]= 9227 ' freq= 5.16083750070962 Dur[59]= 9078 ' freq= 5.24554391044807 Dur[60]= 8932 ' freq= 5.33128611946346 Dur[61]= 8788 ' freq= 5.41864447189891 Dur[62]= 8646 ' freq= 5.50763909542536 Dur[63]= 8507 ' freq= 5.59763108252588 Dur[64]= 8370 ' freq= 5.68925300108096 Dur[65]= 8235 ' freq= 5.78251944372163 Dur[66]= 8102 ' freq= 5.87744354715473 Dur[67]= 7972 ' freq= 5.97328745848565 Dur[68]= 7843 ' freq= 6.07153482328798 Dur[69]= 7717 ' freq= 6.17066834508846 Dur[70]= 7593 ' freq= 6.2714404871655 Dur[71]= 7470 ' freq= 6.37470516988589 Dur[72]= 7350 ' freq= 6.47878198898607 Dur[73]= 7231 ' freq= 6.58540279616203 Dur[74]= 7115 ' freq= 6.692768463675 Dur[75]= 7000 ' freq= 6.80272108843537 Dur[76]= 6888 ' freq= 6.91333443946684 Dur[77]= 6777 ' freq= 7.02656745153425 Dur[78]= 6667 ' freq= 7.14250001785625 Dur[79]= 6560 ' freq= 7.25900116144019 Dur[80]= 6454 ' freq= 7.37822243865008 Dur[81]= 6350 ' freq= 7.49906261717285 Dur[82]= 6248 ' freq= 7.62148649472593 Dur[83]= 6147 ' freq= 7.74671345681595 Dur[84]= 6048 ' freq= 7.87351977828168 Dur[85]= 5951 ' freq= 8.00185643069192 Dur[86]= 5855 ' freq= 8.13305680940181 Dur[87]= 5760 ' freq= 8.26719576719577 Dur[88]= 5668 ' freq= 8.40138454817354 Dur[89]= 5576 ' freq= 8.54000136640022 Dur[90]= 5486 ' freq= 8.68010346683332 Dur[91]= 5398 ' freq= 8.82160941442157 Dur[92]= 5311 ' freq= 8.96611704369189 Dur[93]= 5225 ' freq= 9.11369332421964 Dur[94]= 5141 ' freq= 9.26260408851344 Dur[95]= 5058 ' freq= 9.41460016193112 Dur[96]= 4977 ' freq= 9.56782150272204 Dur[97]= 4897 ' freq= 9.72412653033441 Dur[98]= 4818 ' freq= 9.88357152740714 Dur[99]= 4740 ' freq= 10.0462125778581 Dur[100]= 4664 ' freq= 10.2099158702932 Dur[101]= 4589 ' freq= 10.3767809150245 Dur[102]= 4515 ' freq= 10.546854400675 Dur[103]= 4442 ' freq= 10.7201818142836 Dur[104]= 4370 ' freq= 10.89680723548 Dur[105]= 4300 ' freq= 11.0741971207087 Dur[106]= 4231 ' freq= 11.2547973573736 Dur[107]= 4162 ' freq= 11.4413857806458 Dur[108]= 4095 ' freq= 11.6285830571545 Dur[109]= 4029 ' freq= 11.8190736210096 Dur[110]= 3964 ' freq= 12.012877805007 Dur[111]= 3901 ' freq= 12.206882240207 Dur[112]= 3838 ' freq= 12.4072557631703 Dur[113]= 3776 ' freq= 12.6109765940274 Dur[114]= 3715 ' freq= 12.8180478113183 Dur[115]= 3655 ' freq= 13.0284672008338 Dur[116]= 3596 ' freq= 13.2422268128608 Dur[117]= 3538 ' freq= 13.4593124983176 Dur[118]= 3481 ' freq= 13.6797034240298 Dur[119]= 3425 ' freq= 13.9033715676051 Dur[120]= 3370 ' freq= 14.1302811925957 Dur[121]= 3316 ' freq= 14.3603883048998 Dur[122]= 3262 ' freq= 14.5981139236811 Dur[123]= 3210 ' freq= 14.8345942738466 Dur[124]= 3158 ' freq= 15.0788624506167 Dur[125]= 3107 ' freq= 15.3263751590111 Dur[126]= 3057 ' freq= 15.5770518871598 Dur[127]= 3008 ' freq= 15.8308004052685 Return Vels_Lookup: ' velo lookup scale prog.change 1 Same range as 0 but logarithmic vels[1]= 52 ' duur= .000546 vels[2]= 56 ' duur= .000588 vels[3]= 58 ' duur= .000609 vels[4]= 60 ' duur= .00063 vels[5]= 62 ' duur= .000651 vels[6]= 64 ' duur= .000672 vels[7]= 66 ' duur= .000693 vels[8]= 69 ' duur= .0007245 vels[9]= 71 ' duur= .0007455 vels[10]= 73 ' duur= .0007665 vels[11]= 76 ' duur= .000798 vels[12]= 79 ' duur= .0008295 vels[13]= 81 ' duur= .0008505 vels[14]= 84 ' duur= .000882 vels[15]= 87 ' duur= .0009135 vels[16]= 90 ' duur= .000945 vels[17]= 94 ' duur= .000987 vels[18]= 97 ' duur= .0010185 vels[19]= 100 ' duur= .00105 vels[20]= 104 ' duur= .001092 vels[21]= 107 ' duur= .0011235 vels[22]= 111 ' duur= .0011655 vels[23]= 115 ' duur= .0012075 vels[24]= 119 ' duur= .0012495 vels[25]= 123 ' duur= .0012915 vels[26]= 128 ' duur= .001344 vels[27]= 132 ' duur= .001386 vels[28]= 137 ' duur= .0014385 vels[29]= 142 ' duur= .001491 vels[30]= 147 ' duur= .0015435 vels[31]= 152 ' duur= .001596 vels[32]= 157 ' duur= .0016485 vels[33]= 163 ' duur= .0017115 vels[34]= 168 ' duur= .001764 vels[35]= 174 ' duur= .001827 vels[36]= 180 ' duur= .00189 vels[37]= 187 ' duur= .0019635 vels[38]= 193 ' duur= .0020265 vels[39]= 200 ' duur= .0021 vels[40]= 207 ' duur= .0021735 vels[41]= 214 ' duur= .002247 vels[42]= 222 ' duur= .002331 vels[43]= 230 ' duur= .002415 vels[44]= 238 ' duur= .002499 vels[45]= 246 ' duur= .002583 vels[46]= 255 ' duur= .0026775 vels[47]= 264 ' duur= .002772 vels[48]= 273 ' duur= .0028665 vels[49]= 283 ' duur= .0029715 vels[50]= 293 ' duur= .0030765 vels[51]= 303 ' duur= .0031815 vels[52]= 314 ' duur= .003297 vels[53]= 325 ' duur= .0034125 vels[54]= 336 ' duur= .003528 vels[55]= 348 ' duur= .003654 vels[56]= 360 ' duur= .00378 vels[57]= 373 ' duur= .0039165 vels[58]= 386 ' duur= .004053 vels[59]= 400 ' duur= .0042 vels[60]= 414 ' duur= .004347 vels[61]= 428 ' duur= .004494 vels[62]= 443 ' duur= .0046515 vels[63]= 459 ' duur= .0048195 vels[64]= 475 ' duur= .0049875 vels[65]= 492 ' duur= .005166 vels[66]= 509 ' duur= .0053445 vels[67]= 527 ' duur= .0055335 vels[68]= 545 ' duur= .0057225 vels[69]= 564 ' duur= .005922 vels[70]= 584 ' duur= .006132 vels[71]= 605 ' duur= .0063525 vels[72]= 626 ' duur= .006573 vels[73]= 648 ' duur= .006804 vels[74]= 671 ' duur= .0070455 vels[75]= 695 ' duur= .0072975 vels[76]= 719 ' duur= .0075495 vels[77]= 744 ' duur= .007812 vels[78]= 770 ' duur= .008085 vels[79]= 798 ' duur= .008379 vels[80]= 826 ' duur= .008673 vels[81]= 855 ' duur= .0089775 vels[82]= 885 ' duur= .0092925 vels[83]= 916 ' duur= .009618 vels[84]= 948 ' duur= .009954 vels[85]= 981 ' duur= .0103005 vels[86]= 1016 ' duur= .010668 vels[87]= 1052 ' duur= .011046 vels[88]= 1089 ' duur= .0114345 vels[89]= 1127 ' duur= .0118335 vels[90]= 1166 ' duur= .012243 vels[91]= 1207 ' duur= .0126735 vels[92]= 1250 ' duur= .013125 vels[93]= 1294 ' duur= .013587 vels[94]= 1339 ' duur= .0140595 vels[95]= 1386 ' duur= .014553 vels[96]= 1435 ' duur= .0150675 vels[97]= 1486 ' duur= .015603 vels[98]= 1538 ' duur= .016149 vels[99]= 1592 ' duur= .016716 vels[100]= 1648 ' duur= .017304 vels[101]= 1706 ' duur= .017913 vels[102]= 1766 ' duur= .018543 vels[103]= 1828 ' duur= .019194 vels[104]= 1892 ' duur= .019866 vels[105]= 1959 ' duur= .0205695 vels[106]= 2028 ' duur= .021294 vels[107]= 2099 ' duur= .0220395 vels[108]= 2173 ' duur= .0228165 vels[109]= 2249 ' duur= .0236145 vels[110]= 2328 ' duur= .024444 vels[111]= 2410 ' duur= .025305 vels[112]= 2495 ' duur= .0261975 vels[113]= 2583 ' duur= .0271215 vels[114]= 2674 ' duur= .028077 vels[115]= 2768 ' duur= .029064 vels[116]= 2865 ' duur= .0300825 vels[117]= 2966 ' duur= .031143 vels[118]= 3070 ' duur= .032235 vels[119]= 3178 ' duur= .033369 vels[120]= 3290 ' duur= .034545 vels[121]= 3405 ' duur= .0357525 vels[122]= 3525 ' duur= .0370125 vels[123]= 3649 ' duur= .0383145 vels[124]= 3777 ' duur= .0396585 vels[125]= 3910 ' duur= .041055 vels[126]= 4048 ' duur= .042504 vels[127]= 4190 ' duur= .043995 Return '[EOF]