From e6b068cee5a2c84650c97cb6c7b81bea3ef63245 Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Wed, 26 Apr 2017 10:23:13 -0700 Subject: [PATCH] Release 1.0 --- src/samplesrc/a2pwm/hilopwm.pla | 263 +++++++++++++++++--------------- src/samplesrc/a2pwm/lfo.po | Bin 143360 -> 143360 bytes src/samplesrc/a2pwm/util.pla | 8 +- 3 files changed, 148 insertions(+), 123 deletions(-) diff --git a/src/samplesrc/a2pwm/hilopwm.pla b/src/samplesrc/a2pwm/hilopwm.pla index c4e937c..2fd6a22 100755 --- a/src/samplesrc/a2pwm/hilopwm.pla +++ b/src/samplesrc/a2pwm/hilopwm.pla @@ -1,14 +1,13 @@ const inbuff = $200 const freemem = $0002 -const iobuffer = 0x1800 +const iobuffer = $1C00 const NMACROS = 7 const FALSE = 0 const TRUE = !FALSE // -// Macro sequence structure +// Patch state // -struc t_macro - byte absStart +struc t_state byte durAtk byte durDcy byte durSus @@ -16,14 +15,23 @@ struc t_macro word rateAtk word rateDcy word rateRel - byte idxOctave - byte perLFO + byte octave + byte LFO byte idxLFO - byte[256] sequence end +// +// Macro sequence structure +// +struc t_macro + byte absStart + byte stateStart[t_state] + byte sequence[256] +end +byte current[t_state] // Current state word macros // Pointer to macros byte record[t_macro] // Recording buffer word recording = FALSE // Recording key/flag +byte playing = 0 // Keep track of active macros // // System variables. // @@ -45,27 +53,9 @@ byte keymacro[] = 'Z', 'X', 'C', 'V', 'B', 'N', 'M' // byte keyrecord[] = $1A, $18, $03, $16, $02, $0E, $0D // -// Which octave are we in -// -byte octave = 1 -// -// FLO period and waveform -// -byte LFO, LFOmap -// // Note duration // -byte duration = 22 -// -// Envelope parameters -// -byte atkLen = 2 -byte dcyLen = 0 -byte susLen = 4 -byte relLen = 16 -word atkRate = $07FF -word dcyRate = $0000 -word relRate = $00FF +byte duration = 16 // // Patch filename // @@ -80,33 +70,35 @@ include "util.pla" // def loadPatch byte refnum - + refnum = open(@patch, iobuffer) if refnum read(refnum, macros, t_macro * NMACROS) // Macros - read(refnum, @octave, @patch - @octave) // Initial values + read(refnum, @current, t_state) // Initial values close(refnum) fin + return refnum <> 0 end def savePatch byte refnum - + destroy(@patch) create(@patch, $C3, $06, $00) // full access, BIN file refnum = open(@patch, iobuffer) if refnum write(refnum, macros, t_macro * NMACROS) // Macros - write(refnum, @octave, @patch - @octave) // Initial values + write(refnum, @current, t_state) // Initial values close(refnum) modPatch = FALSE fin + return refnum <> 0 end // // Query routines // def query(str) byte c - + inverse clearview putsxy(20 - ^str / 2, 2, str) @@ -119,7 +111,7 @@ end def showLFO byte LFObar - LFObar = (LFO+7)/8 + LFObar = (current.LFO+7)/8 grcolor(WHITE) rect(33, 39, 6, 39, FALSE) if LFObar < 32 @@ -135,7 +127,7 @@ def showLFO // putsxy(35, 0, " ") gotoxy(35, 0) - return puti(LFO) + return puti(current.LFO) end // // Display LFO waveform @@ -146,8 +138,8 @@ def showWaveform // // Get pointer to LFO waveform by calling PWM with zero note // - envelope(0, 0, 0, 0, atkRate, dcyRate, relRate) - hilopwm(0, LFO, LFOmap) + envelope(0, 0, 0, 0, current:rateAtk, current:rateDcy, current:rateRel) + hilopwm(0, current.LFO, current.idxLFO) mapPtr = *0 // Pointer at address 0 grcolor(WHITE) rect(0, 33, 6, 39, FALSE) @@ -163,7 +155,7 @@ def showWaveform // // Restore envelope // - return envelope(atkLen, dcyLen, susLen, relLen, atkRate, dcyRate, relRate) + return envelope(current.durAtk, current.durDcy, current.durSus, current.durRel, current:rateAtk, current:rateDcy, current:rateRel) end // // Display duration @@ -190,8 +182,8 @@ def showDuration // // Show actual value // - putsxy(5, 3, " ") - gotoxy(5, 3) + putsxy(4, 3, " ") + gotoxy(4, 3) return puti(duration) end // @@ -201,7 +193,7 @@ def showOctave inverse putsxy(0, 1, "----------------------------------------") normal - putsxy(octave*10, 1, "----------") + putsxy(current.octave*10, 1, "----------") return inverse end def showMainPanel @@ -216,7 +208,7 @@ def showMainPanel gotoxy(34, 0); putc('<') gotoxy(38, 0); putc('>') gotoxy(3, 3); putc('-') - gotoxy(8, 3); putc('+') + gotoxy(6, 3); putc('+') inverse showOctave normal @@ -232,22 +224,47 @@ def showMainPanel gotoxy(24, 2); putc('I') return inverse end +def showHelp + normal + home + putsxy(15, 0, "HELP") + putsxy(0, 1, "=======================================") + putsxy(2, 3, "KEY COMMAND") + putsxy(2, 4, "-------------- --------------------") + putsxy(2, 5, "ESC HELP/CANCEL RECORD") + putsxy(2, 6, "CTRL-Q QUIT") + putsxy(2, 7, "1..8 LFO WAVEFORM") + putsxy(2, 8, "< , INCREASE LFO") + putsxy(2, 9, "> . DECREASE LFO") + putsxy(2, 10, "LEFT-ARROW PREV OCTAVE") + putsxy(2, 11, "RIGHT-ARROW NEXT OCTAVE") + putsxy(2, 12, "+ UP-ARROW INCREASE DURATION") + putsxy(2, 13, "- DOWN-ARROW DECREASE DURATION") + putsxy(2, 14, "CTRL-Z..M RECORD MACRO") + putsxy(2, 15, "/ SAVE ABS MACRO") + putsxy(2, 16, "? SAVE REL MACRO") + putsxy(2, 17, "P PERSISTANT STATE") + putsxy(8, 23, "PRESS A KEY TO RETURN") + return getc +end // // Recalc envelope parameters // def recalcEnv - atkLen = duration/8 - relLen = duration/2 - susLen = duration - atkLen - relLen - atkRate = $0FFF/atkLen - relRate = $0FFF/relLen + current.durAtk = duration/8 + current.durDcy = 0 + current.durRel = duration/2 + current.durSus = duration - current.durAtk - current.durRel + current:rateAtk = $0FFF/current.durAtk + current:rateDcy = 0 + current:rateRel = $0FFF/current.durRel end // // Rest // def restnote byte d - + for d = duration downto 1 call($FCA8, $6A, 0, 0, 0) next @@ -255,33 +272,30 @@ end // // playback a sequence // -def playback(seq) +def playback(idx) word macro - byte seq, key, i, showUpdate - - macro = macros + t_macro * seq + byte seq, key, i + byte save[t_state] + + // + // Check for recursive playback + // + if playing & (1 << idx) + return + fin + playing = playing | (1 << idx) + macro = macros + t_macro * idx + // + // Save current state + // + memcpy(@save, @current, t_state) // // Start off with initial conditions // - showUpdate = 0 if macro->absStart - if macro->idxOctave <> octave - octave = macro->idxOctave - showUpdate = showUpdate | 1 - fin - if macro->idxLFO <> LFOmap - LFOmap = macro->idxLFO - showUpdate = showUpdate | 2 - fin - if macro->perLFO <> LFO - LFO = macro->perLFO - showUpdate = showUpdate | 4 - fin - if macro->durAtk + macro->durDcy + macro->durSus + macro->durRel <> duration - envelope(macro->durAtk, macro->durDcy, macro->durSus, macro->durRel, macro=>rateAtk, macro=>rateDcy, macro=>rateRel) - duration = macro->durAtk + macro->durDcy + macro->durSus + macro->durRel - showUpdate = showUpdate | 8 - fin + memcpy(@current, macro + stateStart, t_state) + duration = current.durAtk + current.durDcy + current.durSus + current.durRel + envelope(current.durAtk, current.durDcy, current.durSus, current.durRel, current:rateAtk, current:rateDcy, current:rateRel) fin // // Run throught the sequence @@ -294,9 +308,9 @@ def playback(seq) for i = 0 to 13 if keytone[i] == key if LFO == 0 - hilopwm(scale[i]>>octave, LFO, 0) + hilopwm(scale[i] >> current.octave, current.LFO, 0) else - hilopwm(scale[i]>>octave, LFO, LFOmap) + hilopwm(scale[i] >> current.octave, current.LFO, current.idxLFO) fin break fin @@ -317,12 +331,14 @@ def playback(seq) restnote break is $15 // -> - octave++ - showUpdate = showUpdate | 1 + if current.octave < 3 + current.octave++ + fin break is $08 // <- - showUpdate = showUpdate | 1 - octave-- + if current.octave > 1 + current.octave-- + fin break is '1' is '2' @@ -332,44 +348,47 @@ def playback(seq) is '6' is '7' is '8' - LFOmap = key - '1' - showUpdate = showUpdate | 2 + current.idxLFO = key - '1' break is '<' is ',' - LFO-- - showUpdate = showUpdate | 4 + if current.LFO > 0 + current.LFO-- + fin break is '>' is '.' - LFO++ - showUpdate = showUpdate | 4 + if current.LFO < 255 + current.LFO++ + fin break is '+' is $0B // UP - duration++ + if duration < 40 + duration++ + fin recalcEnv - envelope(atkLen, dcyLen, susLen, relLen, atkRate, dcyRate, relRate) - showUpdate = showUpdate | 8 + envelope(current.durAtk, current.durDcy, current.durSus, current.durRel, current:rateAtk, current:rateDcy, current:rateRel) break is '-' is $0A // DOWN - duration-- + if duration > 1 + duration-- + fin recalcEnv - envelope(atkLen, dcyLen, susLen, relLen, atkRate, dcyRate, relRate) - showUpdate = showUpdate | 8 + envelope(current.durAtk, current.durDcy, current.durSus, current.durRel, current:rateAtk, current:rateDcy, current:rateRel) break wend fin fin next // - // Udate display + // Restore state // - if showUpdate & 1; showOctave; fin - if showUpdate & 2; showWaveform; fin - if showUpdate & 4; showLFO; fin - if showUpdate & 8; showDuration; fin + memcpy(@current, @save, t_state) + duration = current.durAtk + current.durDcy + current.durSus + current.durRel + envelope(current.durAtk, current.durDcy, current.durSus, current.durRel, current:rateAtk, current:rateDcy, current:rateRel) + playing = playing & ~(1 << idx) end // // Main loop @@ -377,7 +396,6 @@ end def main byte quit, key, i - envelope(atkLen, dcyLen, susLen, relLen, atkRate, dcyRate, relRate) quit = FALSE repeat if keypressed @@ -387,10 +405,10 @@ def main // for i = 0 to 13 if keytone[i] == key - if LFO == 0 - hilopwm(scale[i]>>octave, LFO, 0) + if current.LFO == 0 + hilopwm(scale[i] >> current.octave, current.LFO, 0) else - hilopwm(scale[i]>>octave, LFO, LFOmap) + hilopwm(scale[i] >> current.octave, current.LFO, current.idxLFO) fin break fin @@ -413,17 +431,8 @@ def main // // Save current state // + memcpy(@record.stateStart, @current, t_state) record.absStart = TRUE - record.durAtk = atkLen - record.durDcy = dcyLen - record.durSus = susLen - record.durRel = relLen - record.rateAtk = atkRate - record.rateDcy = dcyRate - record.rateRel = relRate - record.idxOctave = octave - record.perLFO = LFO - record.idxLFO = LFOmap record.sequence = 0 flash putsxy(29, 3, "RECORDING") @@ -440,10 +449,16 @@ def main recording = FALSE putsxy(29, 3, " ") else - quit = query("QUIT (Y/N)?") - if not quit - showMainPanel - fin + textmode + showHelp + grmode + showMainPanel + fin + break + is $11 // CTRL-Q + quit = query("QUIT (Y/N)?") + if not quit + showMainPanel fin break is '?' @@ -457,16 +472,16 @@ def main fin break is $15 // -> - if octave < 3 - octave++ + if current.octave < 3 + current.octave++ showOctave else key = 0 fin break is $08 // <- - if octave > 0 - octave-- + if current.octave > 0 + current.octave-- showOctave else key = 0 @@ -480,17 +495,21 @@ def main is '6' is '7' is '8' - LFOmap = key - '1' + current.idxLFO = key - '1' showWaveform break is '<' is ',' - LFO-- + if current.LFO > 0 + current.LFO-- + fin showLFO break is '>' is '.' - LFO++ + if current.LFO < 255 + current.LFO++ + fin showLFO break is '+' @@ -498,7 +517,7 @@ def main if duration < 40 duration++ recalcEnv - envelope(atkLen, dcyLen, susLen, relLen, atkRate, dcyRate, relRate) + envelope(current.durAtk, current.durDcy, current.durSus, current.durRel, current:rateAtk, current:rateDcy, current:rateRel) showDuration else key = 0 @@ -509,7 +528,7 @@ def main if duration > 1 duration-- recalcEnv - envelope(atkLen, dcyLen, susLen, relLen, atkRate, dcyRate, relRate) + envelope(current.durAtk, current.durDcy, current.durSus, current.durRel, current:rateAtk, current:rateDcy, current:rateRel) showDuration else key = 0 @@ -528,6 +547,8 @@ def main if record.sequence < 255 record.sequence++ record.sequence[record.sequence] = key + else + beep fin fin fin @@ -538,8 +559,12 @@ end // macros = *freemem heap = macros + t_macro * NMACROS -loadPatch memset(macros, 0, t_macro * NMACROS) +if not loadPatch + showHelp +fin +recalcEnv +envelope(current.durAtk, current.durDcy, current.durSus, current.durRel, current:rateAtk, current:rateDcy, current:rateRel) call($FDED, $8D, 0, 0, 0) call($FDED, $91, 0, 0, 0)// CTRL-Q = turn off 80 column call($FDED, $8D, 0, 0, 0) diff --git a/src/samplesrc/a2pwm/lfo.po b/src/samplesrc/a2pwm/lfo.po index e5bbdca81d6d899f0c70fb829b044dd3fd9f1815..c7c852db7b6231c120799d58ca8323fa547772c0 100755 GIT binary patch delta 9244 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 Za|$gP_@`T;CG)@4lDY4(BaaD({{`&jwnYE{ delta 12753 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 diff --git a/src/samplesrc/a2pwm/util.pla b/src/samplesrc/a2pwm/util.pla index e4db7f2..7c08fd4 100644 --- a/src/samplesrc/a2pwm/util.pla +++ b/src/samplesrc/a2pwm/util.pla @@ -491,9 +491,9 @@ def envelope(attack, decay, sustain, release, ainc, dinc, rinc) *$12 = dinc *$14 = rinc end -def hilopwm(HFO, LFO, LFOusr) - ^$08 = HFO - ^$09 = LFO - *$0A = LFOusr +def hilopwm(hfo, lfo, usr) + ^$08 = hfo + ^$09 = lfo + *$0A = usr return _hilopwm end