0x4f, 0x51, 0x54, 0x57, 0x5a, 0x5d, 0x60, 0x63, 0x67, 0x6a, 0x6d, 0x70, 0x73, 0x76, 0x79, 0x7c\r
};\r
\r
-struct\r
-{\r
- uint8_t Pitch;\r
- uint8_t Velocity;\r
- \r
- uint8_t CurrentPos;\r
- uint8_t ElapsedTicks;\r
-} ChannelStates[10];\r
+uint8_t Pitch;\r
+uint8_t Velocity; \r
+uint8_t CurrentPos;\r
\r
/** Main program entry point. This routine contains the overall program flow, including initial\r
* setup of all components and the main program loop.\r
MIDI_EventPacket_t ReceivedMIDIEvent;\r
if (MIDI_Device_ReceiveEventPacket(&Keyboard_MIDI_Interface, &ReceivedMIDIEvent))\r
{\r
- if (ReceivedMIDIEvent.Command == (MIDI_COMMAND_NOTE_ON >> 4))\r
+ if ((ReceivedMIDIEvent.Command == (MIDI_COMMAND_NOTE_ON >> 4)) && ((ReceivedMIDIEvent.Data1 & 0x0F) == 0))\r
{\r
- ChannelStates[ReceivedMIDIEvent.Data1 & 0x0F].Pitch = ReceivedMIDIEvent.Data2;\r
- ChannelStates[ReceivedMIDIEvent.Data1 & 0x0F].Velocity = ReceivedMIDIEvent.Data3;\r
+ Pitch = ReceivedMIDIEvent.Data2;\r
+ Velocity = ReceivedMIDIEvent.Data3;\r
\r
LEDs_SetAllLEDs(LEDS_LED1);\r
}\r
- else if (ReceivedMIDIEvent.Command == (MIDI_COMMAND_NOTE_OFF >> 4))\r
+ else if ((ReceivedMIDIEvent.Command == (MIDI_COMMAND_NOTE_OFF >> 4)) && ((ReceivedMIDIEvent.Data1 & 0x0F) == 0))\r
{\r
- ChannelStates[ReceivedMIDIEvent.Data1 & 0x0F].Velocity = 0;\r
+ Velocity = 0;\r
\r
LEDs_SetAllLEDs(LEDS_NO_LEDS);\r
}\r
/* Clear the sample reload timer */\r
TIFR0 |= (1 << OCF0A);\r
\r
- uint8_t OutputSample = 0;\r
- \r
- /* Loop through the channels (excluding percussion channel 10) and generate next sample */\r
- for (uint8_t Channel = 0; Channel < 9; Channel++)\r
- {\r
- /* Channel only contributes if it is not muted */\r
- if (ChannelStates[Channel].Velocity)\r
- {\r
- /* Fetch the current sample from the sine lookup table */\r
- uint8_t TableValue = pgm_read_byte(&SineTable[ChannelStates[Channel].CurrentPos]);\r
+ /* Fetch the current sample from the sine lookup table */\r
+ OCR3A = Velocity ? pgm_read_byte(&SineTable[CurrentPos]) : 0;\r
\r
- /* Scale sample value by the velocity of the channel */\r
- TableValue = ((uint16_t)TableValue << 6) / ChannelStates[Channel].Velocity;\r
- \r
- /* Add the sample to the output waveform */\r
- OutputSample += TableValue;\r
- }\r
- \r
- /* Calculate next sample table position for this channel */\r
- ChannelStates[Channel].CurrentPos += ChannelStates[Channel].Pitch;\r
- }\r
- \r
- /* Output the sample to the PWM timer */\r
- OCR3A = OutputSample;\r
+ /* Calculate next sample table position for this channel */\r
+ CurrentPos += (Pitch >> 1);\r
}\r
\r
MIDI_Device_USBTask(&Keyboard_MIDI_Interface);\r