A MIDI piano synthesizer that implements the Karplus Strong physical modeling algorithm.

Dependencies:   mbed USBDevice PinDetect

Committer:
asuszek
Date:
Thu Apr 21 01:41:13 2016 +0000
Revision:
18:26d93c5b9bb6
Parent:
13:bb0ec927e458
Added a counter to show what instrument you are on.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
asuszek 6:688698f814c0 1 /**
asuszek 6:688698f814c0 2 * The class representing a single monophonic voice.
asuszek 6:688698f814c0 3 * This class holds and processes its own buffer and play state.
asuszek 6:688698f814c0 4 *
asuszek 6:688698f814c0 5 * Note: This class also holds implementations for each of the different instruments.
asuszek 6:688698f814c0 6 * In a perfect OOP world this would be extracted out into an interface with a
asuszek 6:688698f814c0 7 * concrete class for each instrument, but in order to keep overhead low, I
asuszek 6:688698f814c0 8 * went for an array of member function pointers instead.
asuszek 6:688698f814c0 9 *
asuszek 6:688698f814c0 10 * @author Austin Suszek
asuszek 6:688698f814c0 11 */
asuszek 6:688698f814c0 12
asuszek 6:688698f814c0 13 #ifndef AS_SYNTHESIZER_H
asuszek 6:688698f814c0 14 #define AS_SYNTHESIZER_H
asuszek 6:688698f814c0 15
asuszek 9:1e012f67470c 16 #include "../Constants.h"
asuszek 9:1e012f67470c 17 #include "../mbed.h"
asuszek 13:bb0ec927e458 18 #include "KarplusStrong.h"
asuszek 6:688698f814c0 19
asuszek 6:688698f814c0 20 /**
asuszek 6:688698f814c0 21 * An enum representing the possible states of the synthesizer.
asuszek 6:688698f814c0 22 */
asuszek 6:688698f814c0 23 enum SynthState {
asuszek 6:688698f814c0 24 OFF,
asuszek 6:688698f814c0 25 FILL,
asuszek 6:688698f814c0 26 SUSTAIN,
asuszek 6:688698f814c0 27 RELEASE
asuszek 6:688698f814c0 28 };
asuszek 6:688698f814c0 29
asuszek 6:688698f814c0 30 class Synthesizer {
asuszek 6:688698f814c0 31 public:
asuszek 6:688698f814c0 32
asuszek 6:688698f814c0 33 /**
asuszek 6:688698f814c0 34 * Constructor
asuszek 6:688698f814c0 35 */
asuszek 6:688698f814c0 36 Synthesizer();
asuszek 6:688698f814c0 37
asuszek 6:688698f814c0 38 /**
asuszek 6:688698f814c0 39 * Signal the beginning of a note being pressed.
asuszek 6:688698f814c0 40 *
asuszek 6:688698f814c0 41 * @param key The integer representation of the note
asuszek 6:688698f814c0 42 * @param velocity (optional) The note velocity in the range of 0-127
asuszek 6:688698f814c0 43 */
asuszek 6:688698f814c0 44 void midiNoteOn(int key, int velocity);
asuszek 6:688698f814c0 45
asuszek 6:688698f814c0 46 /**
asuszek 6:688698f814c0 47 * Signal the end of a note being pressed.
asuszek 6:688698f814c0 48 */
asuszek 6:688698f814c0 49 void midiNoteOff();
asuszek 6:688698f814c0 50
asuszek 6:688698f814c0 51 /**
asuszek 13:bb0ec927e458 52 * Get the next sample to output, and process the buffer for the next period.
asuszek 6:688698f814c0 53 */
asuszek 6:688698f814c0 54 float getSample();
asuszek 6:688698f814c0 55
asuszek 6:688698f814c0 56 /**
asuszek 6:688698f814c0 57 * Returns false for SynthState OFF and true for all other states.
asuszek 6:688698f814c0 58 */
asuszek 6:688698f814c0 59 bool isPlaying();
asuszek 6:688698f814c0 60
asuszek 6:688698f814c0 61 /**
asuszek 6:688698f814c0 62 * Getter for the voiceIndex variable.
asuszek 6:688698f814c0 63 */
asuszek 6:688698f814c0 64 int64_t getVoiceIndex();
asuszek 6:688698f814c0 65
asuszek 6:688698f814c0 66 /**
asuszek 6:688698f814c0 67 * Switch to a new synth instrument.
asuszek 6:688698f814c0 68 *
asuszek 6:688698f814c0 69 * @param direction 1 for next, -1 for previous.
asuszek 18:26d93c5b9bb6 70 * @return The new index being played.
asuszek 6:688698f814c0 71 */
asuszek 18:26d93c5b9bb6 72 int nextSynth(int direction);
asuszek 6:688698f814c0 73
asuszek 6:688698f814c0 74 /**
asuszek 6:688698f814c0 75 * A getter for the current key.
asuszek 6:688698f814c0 76 * It is always overwritten to the most recent key.
asuszek 6:688698f814c0 77 */
asuszek 6:688698f814c0 78 int getCurrentKey();
asuszek 6:688698f814c0 79
asuszek 6:688698f814c0 80 /**
asuszek 6:688698f814c0 81 * Processor functions. These are responsible for all procesing of the buffer based on their instrument.
asuszek 6:688698f814c0 82 */
asuszek 13:bb0ec927e458 83 void processKarplusStrong();
asuszek 6:688698f814c0 84 void processSine();
asuszek 6:688698f814c0 85 void processTriangle();
asuszek 6:688698f814c0 86 void processSquare();
asuszek 6:688698f814c0 87 void processSaw();
asuszek 6:688698f814c0 88
asuszek 6:688698f814c0 89 private:
asuszek 6:688698f814c0 90
asuszek 6:688698f814c0 91 float buffer[(C::SAMPLE_RATE / C::MIN_FREQUENCY) + 1];
asuszek 6:688698f814c0 92 int bufferIndex;
asuszek 6:688698f814c0 93
asuszek 6:688698f814c0 94 SynthState currentState;
asuszek 13:bb0ec927e458 95 KarplusStrong karplusStrong;
asuszek 6:688698f814c0 96
asuszek 6:688698f814c0 97 int currentKey;
asuszek 6:688698f814c0 98 int bufferSize;
asuszek 6:688698f814c0 99 float velocity;
asuszek 6:688698f814c0 100
asuszek 6:688698f814c0 101 int nextBufferSize;
asuszek 6:688698f814c0 102 float nextVelocity;
asuszek 6:688698f814c0 103
asuszek 6:688698f814c0 104 int64_t voiceIndex;
asuszek 6:688698f814c0 105 static int64_t nextVoiceIndex;
asuszek 6:688698f814c0 106 bool fromDisabled;
asuszek 6:688698f814c0 107
asuszek 6:688698f814c0 108 // A process that just outputs input.
asuszek 6:688698f814c0 109 void identityProcess();
asuszek 13:bb0ec927e458 110 void checkFillBounds();
asuszek 6:688698f814c0 111
asuszek 6:688698f814c0 112 volatile int processorIndex;
asuszek 6:688698f814c0 113
asuszek 6:688698f814c0 114 };
asuszek 6:688698f814c0 115
asuszek 6:688698f814c0 116 #endif