12-polyphonic "chiptune" MIDI synthesizer for LPC1768 (Standalone version)
Dependencies: ClockControl PowerControl mbed
Instrument.cpp@0:727737138ac5, 2014-11-09 (annotated)
- Committer:
- kayekss
- Date:
- Sun Nov 09 08:00:33 2014 +0000
- Revision:
- 0:727737138ac5
- Child:
- 4:b2423ad4b248
12-polyphonic "chiptune" MIDI synthesizer for mbed LPC1768 (Standalone version)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kayekss | 0:727737138ac5 | 1 | #include <climits> |
kayekss | 0:727737138ac5 | 2 | #include "defs.h" |
kayekss | 0:727737138ac5 | 3 | #include "Instrument.h" |
kayekss | 0:727737138ac5 | 4 | |
kayekss | 0:727737138ac5 | 5 | /** Constructor of class Instrument */ |
kayekss | 0:727737138ac5 | 6 | Instrument::Instrument() { |
kayekss | 0:727737138ac5 | 7 | this->enableFlag = false; |
kayekss | 0:727737138ac5 | 8 | this->soundingPosition = -1; |
kayekss | 0:727737138ac5 | 9 | this->duration = 0; |
kayekss | 0:727737138ac5 | 10 | this->frequency = 0; |
kayekss | 0:727737138ac5 | 11 | this->volume = 100; |
kayekss | 0:727737138ac5 | 12 | this->expression = 127; |
kayekss | 0:727737138ac5 | 13 | this->velocity = 0; |
kayekss | 0:727737138ac5 | 14 | this->calculatePhaseDelta(); |
kayekss | 0:727737138ac5 | 15 | this->calculateMasterVolume(); |
kayekss | 0:727737138ac5 | 16 | } |
kayekss | 0:727737138ac5 | 17 | |
kayekss | 0:727737138ac5 | 18 | /** Destructor of class Instrument */ |
kayekss | 0:727737138ac5 | 19 | Instrument::~Instrument() { |
kayekss | 0:727737138ac5 | 20 | } |
kayekss | 0:727737138ac5 | 21 | |
kayekss | 0:727737138ac5 | 22 | /** Enable instrument */ |
kayekss | 0:727737138ac5 | 23 | void Instrument::enable() { |
kayekss | 0:727737138ac5 | 24 | this->enableFlag = true; |
kayekss | 0:727737138ac5 | 25 | } |
kayekss | 0:727737138ac5 | 26 | |
kayekss | 0:727737138ac5 | 27 | /** Disable instrument */ |
kayekss | 0:727737138ac5 | 28 | void Instrument::disable() { |
kayekss | 0:727737138ac5 | 29 | this->enableFlag = false; |
kayekss | 0:727737138ac5 | 30 | } |
kayekss | 0:727737138ac5 | 31 | |
kayekss | 0:727737138ac5 | 32 | /** Set sampling rate */ |
kayekss | 0:727737138ac5 | 33 | void Instrument::setSamplingRate(uint16_t fsamp) { |
kayekss | 0:727737138ac5 | 34 | this->samplingRate = fsamp; |
kayekss | 0:727737138ac5 | 35 | } |
kayekss | 0:727737138ac5 | 36 | |
kayekss | 0:727737138ac5 | 37 | /** Advance wave phase by one sample */ |
kayekss | 0:727737138ac5 | 38 | void Instrument::advancePhase() { |
kayekss | 0:727737138ac5 | 39 | this->phase += this->phaseDelta; |
kayekss | 0:727737138ac5 | 40 | } |
kayekss | 0:727737138ac5 | 41 | |
kayekss | 0:727737138ac5 | 42 | /** Reset wave phase to zero */ |
kayekss | 0:727737138ac5 | 43 | void Instrument::resetPhase() { |
kayekss | 0:727737138ac5 | 44 | this->phase = 0; |
kayekss | 0:727737138ac5 | 45 | } |
kayekss | 0:727737138ac5 | 46 | |
kayekss | 0:727737138ac5 | 47 | /** Set wave parameters */ |
kayekss | 0:727737138ac5 | 48 | void Instrument::setWave(Wavetable::wave_t w) { |
kayekss | 0:727737138ac5 | 49 | this->wave = w; |
kayekss | 0:727737138ac5 | 50 | this->phase = 0; |
kayekss | 0:727737138ac5 | 51 | } |
kayekss | 0:727737138ac5 | 52 | |
kayekss | 0:727737138ac5 | 53 | /** Set wave frequency */ |
kayekss | 0:727737138ac5 | 54 | void Instrument::setFrequency(uint16_t f) { |
kayekss | 0:727737138ac5 | 55 | this->frequency = f; |
kayekss | 0:727737138ac5 | 56 | this->duration = 0; // Reset duration |
kayekss | 0:727737138ac5 | 57 | calculatePhaseDelta(); // Recalculate phase delta |
kayekss | 0:727737138ac5 | 58 | } |
kayekss | 0:727737138ac5 | 59 | |
kayekss | 0:727737138ac5 | 60 | /** Set volume */ |
kayekss | 0:727737138ac5 | 61 | void Instrument::setVolume(uint8_t vo) { |
kayekss | 0:727737138ac5 | 62 | this->volume = vo; |
kayekss | 0:727737138ac5 | 63 | calculateMasterVolume(); |
kayekss | 0:727737138ac5 | 64 | } |
kayekss | 0:727737138ac5 | 65 | |
kayekss | 0:727737138ac5 | 66 | /** Set expression */ |
kayekss | 0:727737138ac5 | 67 | void Instrument::setExpression(uint8_t ex) { |
kayekss | 0:727737138ac5 | 68 | this->expression = ex; |
kayekss | 0:727737138ac5 | 69 | calculateMasterVolume(); |
kayekss | 0:727737138ac5 | 70 | } |
kayekss | 0:727737138ac5 | 71 | |
kayekss | 0:727737138ac5 | 72 | /** Set note velocity */ |
kayekss | 0:727737138ac5 | 73 | void Instrument::setVelocity(uint8_t ve) { |
kayekss | 0:727737138ac5 | 74 | this->velocity = ve; |
kayekss | 0:727737138ac5 | 75 | calculateMasterVolume(); |
kayekss | 0:727737138ac5 | 76 | } |
kayekss | 0:727737138ac5 | 77 | |
kayekss | 0:727737138ac5 | 78 | /** Get sampling rate */ |
kayekss | 0:727737138ac5 | 79 | uint16_t Instrument::getSamplingRate() { |
kayekss | 0:727737138ac5 | 80 | return this->samplingRate; |
kayekss | 0:727737138ac5 | 81 | } |
kayekss | 0:727737138ac5 | 82 | |
kayekss | 0:727737138ac5 | 83 | /** Get channel ID */ |
kayekss | 0:727737138ac5 | 84 | uint8_t Instrument::getChannelId() { |
kayekss | 0:727737138ac5 | 85 | return this->channelId; |
kayekss | 0:727737138ac5 | 86 | } |
kayekss | 0:727737138ac5 | 87 | |
kayekss | 0:727737138ac5 | 88 | /** Get enable flag */ |
kayekss | 0:727737138ac5 | 89 | bool Instrument::isEnable() { |
kayekss | 0:727737138ac5 | 90 | return this->enableFlag; |
kayekss | 0:727737138ac5 | 91 | } |
kayekss | 0:727737138ac5 | 92 | |
kayekss | 0:727737138ac5 | 93 | /** Get sounding note position */ |
kayekss | 0:727737138ac5 | 94 | int16_t Instrument::getSoundingPosition() { |
kayekss | 0:727737138ac5 | 95 | return this->soundingPosition; |
kayekss | 0:727737138ac5 | 96 | } |
kayekss | 0:727737138ac5 | 97 | |
kayekss | 0:727737138ac5 | 98 | /** Get sounding duration */ |
kayekss | 0:727737138ac5 | 99 | uint32_t Instrument::getDuration() { |
kayekss | 0:727737138ac5 | 100 | if (this->duration < UINT_MAX) { |
kayekss | 0:727737138ac5 | 101 | this->duration++; |
kayekss | 0:727737138ac5 | 102 | } |
kayekss | 0:727737138ac5 | 103 | return this->duration; |
kayekss | 0:727737138ac5 | 104 | } |
kayekss | 0:727737138ac5 | 105 | |
kayekss | 0:727737138ac5 | 106 | /** Get wave parameters */ |
kayekss | 0:727737138ac5 | 107 | Wavetable::wave_t Instrument::getWave() { |
kayekss | 0:727737138ac5 | 108 | return this->wave; |
kayekss | 0:727737138ac5 | 109 | } |
kayekss | 0:727737138ac5 | 110 | |
kayekss | 0:727737138ac5 | 111 | /** Get wave frequency */ |
kayekss | 0:727737138ac5 | 112 | uint16_t Instrument::getFrequency() { |
kayekss | 0:727737138ac5 | 113 | return this->frequency; |
kayekss | 0:727737138ac5 | 114 | } |
kayekss | 0:727737138ac5 | 115 | |
kayekss | 0:727737138ac5 | 116 | /** Get master volume */ |
kayekss | 0:727737138ac5 | 117 | uint8_t Instrument::getMasterVolume() { |
kayekss | 0:727737138ac5 | 118 | return this->masterVolume; |
kayekss | 0:727737138ac5 | 119 | } |
kayekss | 0:727737138ac5 | 120 | |
kayekss | 0:727737138ac5 | 121 | /** Get volume */ |
kayekss | 0:727737138ac5 | 122 | uint8_t Instrument::getVolume() { |
kayekss | 0:727737138ac5 | 123 | return this->volume; |
kayekss | 0:727737138ac5 | 124 | } |
kayekss | 0:727737138ac5 | 125 | |
kayekss | 0:727737138ac5 | 126 | /** Get expression */ |
kayekss | 0:727737138ac5 | 127 | uint8_t Instrument::getExpression() { |
kayekss | 0:727737138ac5 | 128 | return this->expression; |
kayekss | 0:727737138ac5 | 129 | } |
kayekss | 0:727737138ac5 | 130 | |
kayekss | 0:727737138ac5 | 131 | /** Get note velocity */ |
kayekss | 0:727737138ac5 | 132 | uint8_t Instrument::getVelocity() { |
kayekss | 0:727737138ac5 | 133 | return this->velocity; |
kayekss | 0:727737138ac5 | 134 | } |
kayekss | 0:727737138ac5 | 135 | |
kayekss | 0:727737138ac5 | 136 | /** Get current phase */ |
kayekss | 0:727737138ac5 | 137 | uint16_t Instrument::getPhase() { |
kayekss | 0:727737138ac5 | 138 | return this->phase; |
kayekss | 0:727737138ac5 | 139 | } |
kayekss | 0:727737138ac5 | 140 | |
kayekss | 0:727737138ac5 | 141 | /** Get phase delta per sample */ |
kayekss | 0:727737138ac5 | 142 | uint16_t Instrument::getPhaseDelta() { |
kayekss | 0:727737138ac5 | 143 | return this->phaseDelta; |
kayekss | 0:727737138ac5 | 144 | } |
kayekss | 0:727737138ac5 | 145 | |
kayekss | 0:727737138ac5 | 146 | /** (Re)calculate phase delta per sample */ |
kayekss | 0:727737138ac5 | 147 | void Instrument::calculatePhaseDelta() { |
kayekss | 0:727737138ac5 | 148 | phase = 0x0000; |
kayekss | 0:727737138ac5 | 149 | phaseDelta = (uint16_t) ((uint32_t) frequency * WAVETABLE_LENGTH * 256 |
kayekss | 0:727737138ac5 | 150 | / samplingRate); |
kayekss | 0:727737138ac5 | 151 | } |
kayekss | 0:727737138ac5 | 152 | |
kayekss | 0:727737138ac5 | 153 | /** Calculate master volume from product of its volume, expression, and velocity */ |
kayekss | 0:727737138ac5 | 154 | void Instrument::calculateMasterVolume() { |
kayekss | 0:727737138ac5 | 155 | this->masterVolume |
kayekss | 0:727737138ac5 | 156 | = ((uint32_t) this->volume * this->expression * this->velocity) >> 16; |
kayekss | 0:727737138ac5 | 157 | } |