PSEUDOCODE ========== '---------------------------- ' Synchronia--Duet 0.0.7 ' (C)2018 Thomas R. Mahanna '---------------------------- 'CONFIGURE HARDWARE I/O (ATMEGA2560 in the Case of the Prototype) 'Configure Communication Open Serial1 For Binary As #0 'Serial Connection to PC Open Serial2 For Binary As #1 'MIDI Out / QUNexus In Open Serial3 For Binary As #2 'UNZTRUMENT I/O 'DIMESION VARIABLES 'Serial Input Variables Dim SerialInbyte As Byte Dim SerialFlag As Bit Dim QuNexusInbyte As Byte Dim QuNexusFlag As Bit Dim UntzInbyte As Byte Dim UntzFlag As Bit 'MIDI Variables Dim MIDICh as byte Dim Timbre as Byte Dim Status As Byte Dim Data1 As Byte Dim Data2 As Byte Dim StrumDelay As Byte Dim ChordArray(4) as Byte Dim ScaleArray(5) as Byte Dim Vel as Byte Dim Pedal as bit Dim Notes(5) as Byte 'Main Variables Dim I As Byte Dim ChordType As Byte Dim OldChord As Byte Dim Root As Byte Dim OldRoot As Byte Dim OldChordButton As Byte Dim OldRootButton As Byte Dim ButtonHold As Bit Dim Offset as Byte Dim Temp as byte 'DEFINE IRQ HANDLERS On Serial1 PCSerial_isr On Serial2 Qunexus_isr On Serial3 Untz_isr 'ENABLE INTERRUPTS Enable IRQ0 Enable IRQ1 Enable IRQ2 Enable Global Interrupts 'DEFINE / DECLARE SUBROUTINES Declare Sub Midiout(byval Ch As Byte , Byval Note As Byte , Byval Vel As Byte) Declare Sub Midipatch(byval Ch As Byte , Byval Patch As Byte) Declare Sub Mastervolume(byval Vol As Byte) Declare Sub Allnotesoff Declare Sub ProcessUntzButton 'MAIN ' Entering Main Loop For I = 0 To 15 SerialOut #2 , I 'All Chord Buttons Off Waitms 1 Next For I = 76 To 79 SerialOut #2 , I Waitms 1 Next For I = 92 To 95 SerialOut #2 , I Waitms 1 Next For I = 108 To 111 SerialOut #2 , I 'All Trellis Root Buttons Off Waitms 1 Next Chordtype = 0 SerialOut #2 , 140 OldChordButton = 12 Root = 0 SerialOut #2 , 204 OldRootButton = 76 Offset = 48 'Octave 4 * 12 Call ProcessUntzButton MIDICh = 1 'Set MIDI Output Channel Timbre = 0 'GM Piano [0] Vel = 96 'Velocity StrumDelay = 40 'Spread Between Notes (mS) Pedal = 1 'Pedal off SerialOut #1 , &HB0 SerialOut #1 , &H7B SerialOut #1 , &H00 'All Notes Off SerialOut #1 , 176 SerialOut #1 , 7 SerialOut #1 , 64 'Set Volume to 96 Call Mastervolume(64) 'Set Volume to 96 Call Midipatch(midich , Timbre) 'Change MIDI Intrument Timbre Do '// PROCESS UNTZTRUMENT If UntzFlag = 1 Then Select Case UntzInbyte '// Button Release Case 12 ButtonHold = 0 Case 13 ButtonHold = 0 Case 14 ButtonHold = 0 Case 15 ButtonHold = 0 Case 16 to 127 If Pedal = 0 then Call MIDIOut(MIDICh , ChordArray(1) , 0) Call MIDIOut(MIDICh , ChordArray(2) , 0) Call MIDIOut(MIDICh , ChordArray(3) , 0) Call MIDIOut(MIDICh , ChordArray(4) , 0) End If '// Chord Selection Case 140 Chordtype = 0 'Major SerialOut #2 , OldChordButton 'Turn old chordtype button off SerialOut #2 , UntzInbyte 'Turn new chordtype button on If UntzInbyte > 127 Then OldChordButton = UntzInbyte - 128 Else OldChordButton = UntzInbyte End If Buttonhold = 1 Call ProcessUntzButton Case 141 Chordtype = 1 'Minor SerialOut #2 , OldChordButton 'Turn old chordtype button off SerialOut #2 , UntzInbyte 'Turn new chordtype button on If UntzInbyte > 127 Then OldChordButton = UntzInbyte - 128 Else OldChordButton = UntzInbyte End If Buttonhold = 1 Case 142 Chordtype = 2 'Sus4 SerialOut #2 , OldChordButton 'Turn old chordtype button off SerialOut #2 , UntzInbyte 'Turn new chordtype button on If UntzInbyte > 127 Then OldChordButton = UntzInbyte - 128 Else OldChordButton = UntzInbyte End If Buttonhold = 1 Case 143 Chordtype = 3 'Dom7 SerialOut #2 , OldChordButton 'Turn old chordtype button off SerialOut #2 , UntzInbyte 'Turn new chordtype button on If UntzInbyte > 127 Then OldChordButton = UntzInbyte - 128 Else OldChordButton = UntzInbyte End If Buttonhold = 1 '// Root Selection Case 204 SerialOut #2 , OldRootButton 'Turn old root button off SerialOut #2 , UntzInbyte 'Turn new root button on Root = 0 'Root C Call ProcessUntzButton If ButtonHold = 1 Then Call MIDIOut(MIDICh , ChordArray(1) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(2) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(3) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(4) , Vel) waitms StrumDelay End If If UntzInbyte > 127 Then OldRootButton = UntzInbyte - 128 Else OldRootButton = UntzInbyte End If Case 205 SerialOut #2 , OldRootButton 'Turn old root button off SerialOut #2 , UntzInbyte 'Turn new root button on Root = 1 'Root C# Call ProcessUntzButton If ButtonHold = 1 Then Call MIDIOut(MIDICh , ChordArray(1) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(2) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(3) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(4) , Vel) waitms StrumDelay End If If UntzInbyte > 127 Then OldRootButton = UntzInbyte - 128 Else OldRootButton = UntzInbyte End If Case 206 SerialOut #2 , OldRootButton 'Turn old root button off SerialOut #2 , UntzInbyte 'Turn new root button on Root = 2 'Root D Call ProcessUntzButton If ButtonHold = 1 Then Call MIDIOut(MIDICh , ChordArray(1) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(2) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(3) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(4) , Vel) waitms StrumDelay End If If UntzInbyte > 127 Then OldRootButton = UntzInbyte - 128 Else OldRootButton = UntzInbyte End If Case 207 SerialOut #2 , OldRootButton 'Turn old root button off SerialOut #2 , UntzInbyte 'Turn new root button on Root = 3 'Root D# Call ProcessUntzButton If ButtonHold = 1 Then Call MIDIOut(MIDICh , ChordArray(1) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(2) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(3) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(4) , Vel) waitms StrumDelay End If If UntzInbyte > 127 Then OldRootButton = UntzInbyte - 128 Else OldRootButton = UntzInbyte End If Case 220 SerialOut #2 , OldRootButton 'Turn old root button off SerialOut #2 , UntzInbyte 'Turn new root button on Root = 4 'Root E Call ProcessUntzButton If ButtonHold = 1 Then Call MIDIOut(MIDICh , ChordArray(1) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(2) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(3) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(4) , Vel) waitms StrumDelay End If If UntzInbyte > 127 Then OldRootButton = UntzInbyte - 128 Else OldRootButton = UntzInbyte End If Case 221 SerialOut #2 , OldRootButton 'Turn old root button off SerialOut #2 , UntzInbyte 'Turn new root button on Root = 5 'Root F Call ProcessUntzButton If ButtonHold = 1 Then Call MIDIOut(MIDICh , ChordArray(1) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(2) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(3) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(4) , Vel) waitms StrumDelay End If If UntzInbyte > 127 Then OldRootButton = UntzInbyte - 128 Else OldRootButton = UntzInbyte End If Case 222 SerialOut #2 , OldRootButton 'Turn old root button off SerialOut #2 , UntzInbyte 'Turn new root button on Root = 6 'Root F# Call ProcessUntzButton If ButtonHold = 1 Then Call MIDIOut(MIDICh , ChordArray(1) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(2) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(3) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(4) , Vel) waitms StrumDelay End If If UntzInbyte > 127 Then OldRootButton = UntzInbyte - 128 Else OldRootButton = UntzInbyte End If Case 223 SerialOut #2 , OldRootButton 'Turn old root button off SerialOut #2 , UntzInbyte 'Turn new root button on Root = 7 'Root G Call ProcessUntzButton If ButtonHold = 1 Then Call MIDIOut(MIDICh , ChordArray(1) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(2) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(3) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(4) , Vel) waitms StrumDelay End If If UntzInbyte > 127 Then OldRootButton = UntzInbyte - 128 Else OldRootButton = UntzInbyte End If 'Print "Root = G" Case 236 SerialOut #2 , OldRootButton 'Turn old root button off SerialOut #2 , UntzInbyte 'Turn new root button on Root = 8 'Root G# Call ProcessUntzButton If ButtonHold = 1 Then Call MIDIOut(MIDICh , ChordArray(1) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(2) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(3) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(4) , Vel) waitms StrumDelay End If If UntzInbyte > 127 Then OldRootButton = UntzInbyte - 128 Else OldRootButton = UntzInbyte End If Case 237 SerialOut #2 , OldRootButton 'Turn old root button off SerialOut #2 , UntzInbyte 'Turn new root button on Root = 9 'Root A Call ProcessUntzButton If ButtonHold = 1 Then Call MIDIOut(MIDICh , ChordArray(1) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(2) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(3) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(4) , Vel) waitms StrumDelay End If If UntzInbyte > 127 Then OldRootButton = UntzInbyte - 128 Else OldRootButton = UntzInbyte End If Case 238 SerialOut #2 , OldRootButton 'Turn old root button off SerialOut #2 , UntzInbyte 'Turn new root button on Root = 10 'Root A# Call ProcessUntzButton If ButtonHold = 1 Then Call MIDIOut(MIDICh , ChordArray(1) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(2) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(3) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(4) , Vel) waitms StrumDelay End If If UntzInbyte > 127 Then OldRootButton = UntzInbyte - 128 Else OldRootButton = UntzInbyte End If Case 239 SerialOut #2 , OldRootButton 'Turn old root button off SerialOut #2 , UntzInbyte 'Turn new root button on Root = 11 'Root B Call ProcessUntzButton If ButtonHold = 1 Then Call MIDIOut(MIDICh , ChordArray(1) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(2) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(3) , Vel) waitms StrumDelay Call MIDIOut(MIDICh , ChordArray(4) , Vel) waitms StrumDelay End If If UntzInbyte > 127 Then OldRootButton = UntzInbyte - 128 Else OldRootButton = UntzInbyte End If End Select UntzFlag = 0 End If '// PROCESS QUNEXUS If QuNexusFlag = 1 Then If Data2 > 0 then Select Case Data1 '// Process White Keys Case 48 Temp = ChordArray(1) - 12 Case 50 Temp = ChordArray(2) - 12 Case 52 Temp = ChordArray(3) - 12 Case 53 Temp = ChordArray(4) - 12 Case 55 Temp = ChordArray(1) Case 57 Temp = ChordArray(2) Case 59 Temp = ChordArray(3) Case 60 Temp = ChordArray(4) Case 62 Temp = ChordArray(1) + 12 Case 64 Temp = ChordArray(2) + 12 Case 65 Temp = ChordArray(3) + 12 Case 67 Temp = ChordArray(4) + 12 Case 69 Temp = ChordArray(1) + 24 Case 71 Temp = ChordArray(2) + 24 Case 72 Temp = ChordArray(3) + 24 '// Process Blue Keys Case 49 Temp = ScaleArray(1) Case 51 Temp = ScaleArray(2) Case 54 Temp = ScaleArray(3) Case 56 Temp = ScaleArray(4) Case 58 Temp = ScaleArray(5) Case 61 Temp = ScaleArray(1) + 12 Case 63 Temp = ScaleArray(2) + 12 Case 66 Temp = ScaleArray(3) + 12 Case 68 Temp = ScaleArray(4) + 12 Case 70 Temp = ScaleArray(5) + 12 End Select Call MidiOut(MIDICh , Temp , Vel) Else If Pedal = 0 Then Select Case Data1 '// Process White Keys Case 48 Temp = ChordArray(1) - 12 Case 50 Temp = ChordArray(2) - 12 Case 52 Temp = ChordArray(3) - 12 Case 53 Temp = ChordArray(4) - 12 Case 55 Temp = ChordArray(1) Case 57 Temp = ChordArray(2) Case 59 Temp = ChordArray(3) Case 60 Temp = ChordArray(4) Case 62 Temp = ChordArray(1) + 12 Case 64 Temp = ChordArray(2) + 12 Case 65 Temp = ChordArray(3) + 12 Case 67 Temp = ChordArray(4) + 12 Case 69 Temp = ChordArray(1) + 24 Case 71 Temp = ChordArray(2) + 24 Case 72 Temp = ChordArray(3) + 24 '// Process Blue Keys Case 49 Temp = ScaleArray(1) Case 51 Temp = ScaleArray(2) Case 54 Temp = ScaleArray(3) Case 56 Temp = ScaleArray(4) Case 58 Temp = ScaleArray(5) Case 61 Temp = ScaleArray(1) + 12 Case 63 Temp = ScaleArray(2) + 12 Case 66 Temp = ScaleArray(3) + 12 Case 68 Temp = ScaleArray(4) + 12 Case 70 Temp = ScaleArray(5) + 12 End Select Call MidiOut(MIDICh , Temp , 0) End If End If QuNexusFlag = 0 End If Loop Sub MIDIOut(Byval Ch As Byte , Byval Note As Byte , Byval Vel As Byte) Ch = &H8F + Ch SerialOut #1 , Ch SerialOut #1 , Note SerialOut #1 , Vel End Sub Sub MIDIPatch(byval Ch As Byte , Byval Patch As Byte) Ch = &HBF + Ch SerialOut #1 , Ch SerialOut #1 , Patch End Sub Sub MasterVolume(byval Vol As Byte) SerialOut #1 , 176 SerialOut #1 , 7 SerialOut #1 , Vol End Sub Sub AllNotesOff SerialOut #1 , &HB0 SerialOut #1 , &H7B SerialOut #1 , &H00 'All Notes Off End Sub Sub ProcessUntzButton ChordArray(1) = Root + Offset ScaleArray(1) = Root + Offset Select Case ChordType Case 0 ' Major ChordArray(2) = ChordArray(1) + 7 ChordArray(3) = ChordArray(1) + 16 ChordArray(4) = ChordArray(1) + 24 ScaleArray(2) = ScaleArray(1) + 2 ScaleArray(3) = ScaleArray(1) + 4 ScaleArray(4) = ScaleArray(1) + 7 ScaleArray(5) = ScaleArray(1) + 9 Case 1 ' Minor ChordArray(2) = ChordArray(1) + 7 ChordArray(3) = ChordArray(1) + 15 ChordArray(4) = ChordArray(1) + 24 ScaleArray(2) = ScaleArray(1) + 3 ScaleArray(3) = ScaleArray(1) + 5 ScaleArray(4) = ScaleArray(1) + 7 ScaleArray(5) = ScaleArray(1) + 10 Case 2 ' Sus4 ChordArray(2) = ChordArray(1) + 7 ChordArray(3) = ChordArray(1) + 17 ChordArray(4) = ChordArray(1) + 24 ScaleArray(2) = ScaleArray(1) + 2 ScaleArray(3) = ScaleArray(1) + 5 ScaleArray(4) = ScaleArray(1) + 7 ScaleArray(5) = ScaleArray(1) + 9 Case 3 ' Dom7 ChordArray(2) = ChordArray(1) + 7 ChordArray(3) = ChordArray(1) + 16 ChordArray(4) = ChordArray(1) + 22 ScaleArray(2) = ScaleArray(1) + 2 ScaleArray(3) = ScaleArray(1) + 4 ScaleArray(4) = ScaleArray(1) + 7 ScaleArray(5) = ScaleArray(1) + 10 End Select End Sub PCSerial_isr: SerialInbyte = Udr SerialFlag = 1 Return QuNexus_ISR: QuNexusInbyte = UDR1 Select Case QuNexusInbyte Case &H80 to &H9F 'Note On / Off Status = QuNexusInbyte Data1 = &HFF Data2 = &HFF Case 0 To 127 'Data If Status > 0 Then If Data1 = &HFF Then Data1 = QuNexusInbyte Else Data2 = QuNexusInbyte QuNexusFlag = 1 End If End If End Select Return Untz_isr: UntzInbyte = Udr2 UntzFlag = 1 Return