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

Dependencies:   mbed USBDevice PinDetect

Committer:
asuszek
Date:
Wed Apr 13 19:46:28 2016 +0000
Revision:
9:1e012f67470c
Parent:
Synthesizer.h@6:688698f814c0
Child:
13:bb0ec927e458
Moved Audio into it's own folder

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 6:688698f814c0 18
asuszek 6:688698f814c0 19 /**
asuszek 6:688698f814c0 20 * An enum representing the possible states of the synthesizer.
asuszek 6:688698f814c0 21 */
asuszek 6:688698f814c0 22 enum SynthState {
asuszek 6:688698f814c0 23 OFF,
asuszek 6:688698f814c0 24 FILL,
asuszek 6:688698f814c0 25 SUSTAIN,
asuszek 6:688698f814c0 26 RELEASE
asuszek 6:688698f814c0 27 };
asuszek 6:688698f814c0 28
asuszek 6:688698f814c0 29 class Synthesizer {
asuszek 6:688698f814c0 30 public:
asuszek 6:688698f814c0 31
asuszek 6:688698f814c0 32 /**
asuszek 6:688698f814c0 33 * Constructor
asuszek 6:688698f814c0 34 */
asuszek 6:688698f814c0 35 Synthesizer();
asuszek 6:688698f814c0 36
asuszek 6:688698f814c0 37 /**
asuszek 6:688698f814c0 38 * Signal the beginning of a note being pressed.
asuszek 6:688698f814c0 39 *
asuszek 6:688698f814c0 40 * @param key The integer representation of the note
asuszek 6:688698f814c0 41 * @param velocity (optional) The note velocity in the range of 0-127
asuszek 6:688698f814c0 42 */
asuszek 6:688698f814c0 43 void midiNoteOn(int key, int velocity);
asuszek 6:688698f814c0 44
asuszek 6:688698f814c0 45 /**
asuszek 6:688698f814c0 46 * Signal the end of a note being pressed.
asuszek 6:688698f814c0 47 */
asuszek 6:688698f814c0 48 void midiNoteOff();
asuszek 6:688698f814c0 49
asuszek 6:688698f814c0 50 /**
asuszek 6:688698f814c0 51 * Get the next sample to output.
asuszek 6:688698f814c0 52 */
asuszek 6:688698f814c0 53 float getSample();
asuszek 6:688698f814c0 54
asuszek 6:688698f814c0 55 /**
asuszek 6:688698f814c0 56 * Process the current buffer.
asuszek 6:688698f814c0 57 */
asuszek 6:688698f814c0 58 void processBuffer();
asuszek 6:688698f814c0 59
asuszek 6:688698f814c0 60 /**
asuszek 6:688698f814c0 61 * Returns false for SynthState OFF and true for all other states.
asuszek 6:688698f814c0 62 */
asuszek 6:688698f814c0 63 bool isPlaying();
asuszek 6:688698f814c0 64
asuszek 6:688698f814c0 65 /**
asuszek 6:688698f814c0 66 * Getter for the voiceIndex variable.
asuszek 6:688698f814c0 67 */
asuszek 6:688698f814c0 68 int64_t getVoiceIndex();
asuszek 6:688698f814c0 69
asuszek 6:688698f814c0 70 /**
asuszek 6:688698f814c0 71 * Switch to a new synth instrument.
asuszek 6:688698f814c0 72 *
asuszek 6:688698f814c0 73 * @param direction 1 for next, -1 for previous.
asuszek 6:688698f814c0 74 */
asuszek 6:688698f814c0 75 void nextSynth(int direction);
asuszek 6:688698f814c0 76
asuszek 6:688698f814c0 77 /**
asuszek 6:688698f814c0 78 * A getter for the current key.
asuszek 6:688698f814c0 79 * It is always overwritten to the most recent key.
asuszek 6:688698f814c0 80 */
asuszek 6:688698f814c0 81 int getCurrentKey();
asuszek 6:688698f814c0 82
asuszek 6:688698f814c0 83 /**
asuszek 6:688698f814c0 84 * Processor functions. These are responsible for all procesing of the buffer based on their instrument.
asuszek 6:688698f814c0 85 */
asuszek 6:688698f814c0 86 void processSine();
asuszek 6:688698f814c0 87 void processTriangle();
asuszek 6:688698f814c0 88 void processSquare();
asuszek 6:688698f814c0 89 void processSaw();
asuszek 6:688698f814c0 90
asuszek 6:688698f814c0 91 private:
asuszek 6:688698f814c0 92
asuszek 6:688698f814c0 93 float buffer[(C::SAMPLE_RATE / C::MIN_FREQUENCY) + 1];
asuszek 6:688698f814c0 94 int bufferIndex;
asuszek 6:688698f814c0 95
asuszek 6:688698f814c0 96 SynthState currentState;
asuszek 6:688698f814c0 97
asuszek 6:688698f814c0 98 int currentKey;
asuszek 6:688698f814c0 99 int bufferSize;
asuszek 6:688698f814c0 100 float velocity;
asuszek 6:688698f814c0 101
asuszek 6:688698f814c0 102 int nextBufferSize;
asuszek 6:688698f814c0 103 float nextVelocity;
asuszek 6:688698f814c0 104
asuszek 6:688698f814c0 105 int64_t voiceIndex;
asuszek 6:688698f814c0 106 static int64_t nextVoiceIndex;
asuszek 6:688698f814c0 107 bool fromDisabled;
asuszek 6:688698f814c0 108
asuszek 6:688698f814c0 109 // A process that just outputs input.
asuszek 6:688698f814c0 110 void identityProcess();
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