12-polyphonic "chiptune" MIDI synthesizer for LPC1768 (Standalone version)

Dependencies:   ClockControl PowerControl mbed

Committer:
kayekss
Date:
Tue Dec 23 21:50:53 2014 +0000
Revision:
6:cda45a5e723e
Parent:
4:b2423ad4b248
Supports "Panic on offline" feature when using MIDI-port input

Who changed what in which revision?

UserRevisionLine numberNew 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 calculatePhaseDelta(); // Recalculate phase delta
kayekss 0:727737138ac5 57 }
kayekss 0:727737138ac5 58
kayekss 0:727737138ac5 59 /** Set volume */
kayekss 0:727737138ac5 60 void Instrument::setVolume(uint8_t vo) {
kayekss 0:727737138ac5 61 this->volume = vo;
kayekss 0:727737138ac5 62 calculateMasterVolume();
kayekss 0:727737138ac5 63 }
kayekss 0:727737138ac5 64
kayekss 0:727737138ac5 65 /** Set expression */
kayekss 0:727737138ac5 66 void Instrument::setExpression(uint8_t ex) {
kayekss 0:727737138ac5 67 this->expression = ex;
kayekss 0:727737138ac5 68 calculateMasterVolume();
kayekss 0:727737138ac5 69 }
kayekss 0:727737138ac5 70
kayekss 0:727737138ac5 71 /** Set note velocity */
kayekss 0:727737138ac5 72 void Instrument::setVelocity(uint8_t ve) {
kayekss 0:727737138ac5 73 this->velocity = ve;
kayekss 0:727737138ac5 74 calculateMasterVolume();
kayekss 0:727737138ac5 75 }
kayekss 0:727737138ac5 76
kayekss 4:b2423ad4b248 77 /** Reset sounding duration to zero */
kayekss 4:b2423ad4b248 78 void Instrument::resetDuration() {
kayekss 4:b2423ad4b248 79 this->duration = 0;
kayekss 4:b2423ad4b248 80 }
kayekss 4:b2423ad4b248 81
kayekss 0:727737138ac5 82 /** Get sampling rate */
kayekss 0:727737138ac5 83 uint16_t Instrument::getSamplingRate() {
kayekss 0:727737138ac5 84 return this->samplingRate;
kayekss 0:727737138ac5 85 }
kayekss 0:727737138ac5 86
kayekss 0:727737138ac5 87 /** Get channel ID */
kayekss 0:727737138ac5 88 uint8_t Instrument::getChannelId() {
kayekss 0:727737138ac5 89 return this->channelId;
kayekss 0:727737138ac5 90 }
kayekss 0:727737138ac5 91
kayekss 0:727737138ac5 92 /** Get enable flag */
kayekss 0:727737138ac5 93 bool Instrument::isEnable() {
kayekss 0:727737138ac5 94 return this->enableFlag;
kayekss 0:727737138ac5 95 }
kayekss 0:727737138ac5 96
kayekss 0:727737138ac5 97 /** Get sounding note position */
kayekss 0:727737138ac5 98 int16_t Instrument::getSoundingPosition() {
kayekss 0:727737138ac5 99 return this->soundingPosition;
kayekss 0:727737138ac5 100 }
kayekss 0:727737138ac5 101
kayekss 0:727737138ac5 102 /** Get sounding duration */
kayekss 0:727737138ac5 103 uint32_t Instrument::getDuration() {
kayekss 0:727737138ac5 104 if (this->duration < UINT_MAX) {
kayekss 0:727737138ac5 105 this->duration++;
kayekss 0:727737138ac5 106 }
kayekss 0:727737138ac5 107 return this->duration;
kayekss 0:727737138ac5 108 }
kayekss 0:727737138ac5 109
kayekss 0:727737138ac5 110 /** Get wave parameters */
kayekss 0:727737138ac5 111 Wavetable::wave_t Instrument::getWave() {
kayekss 0:727737138ac5 112 return this->wave;
kayekss 0:727737138ac5 113 }
kayekss 0:727737138ac5 114
kayekss 0:727737138ac5 115 /** Get wave frequency */
kayekss 0:727737138ac5 116 uint16_t Instrument::getFrequency() {
kayekss 0:727737138ac5 117 return this->frequency;
kayekss 0:727737138ac5 118 }
kayekss 0:727737138ac5 119
kayekss 0:727737138ac5 120 /** Get master volume */
kayekss 0:727737138ac5 121 uint8_t Instrument::getMasterVolume() {
kayekss 0:727737138ac5 122 return this->masterVolume;
kayekss 0:727737138ac5 123 }
kayekss 0:727737138ac5 124
kayekss 0:727737138ac5 125 /** Get volume */
kayekss 0:727737138ac5 126 uint8_t Instrument::getVolume() {
kayekss 0:727737138ac5 127 return this->volume;
kayekss 0:727737138ac5 128 }
kayekss 0:727737138ac5 129
kayekss 0:727737138ac5 130 /** Get expression */
kayekss 0:727737138ac5 131 uint8_t Instrument::getExpression() {
kayekss 0:727737138ac5 132 return this->expression;
kayekss 0:727737138ac5 133 }
kayekss 0:727737138ac5 134
kayekss 0:727737138ac5 135 /** Get note velocity */
kayekss 0:727737138ac5 136 uint8_t Instrument::getVelocity() {
kayekss 0:727737138ac5 137 return this->velocity;
kayekss 0:727737138ac5 138 }
kayekss 0:727737138ac5 139
kayekss 0:727737138ac5 140 /** Get current phase */
kayekss 0:727737138ac5 141 uint16_t Instrument::getPhase() {
kayekss 0:727737138ac5 142 return this->phase;
kayekss 0:727737138ac5 143 }
kayekss 0:727737138ac5 144
kayekss 0:727737138ac5 145 /** Get phase delta per sample */
kayekss 0:727737138ac5 146 uint16_t Instrument::getPhaseDelta() {
kayekss 0:727737138ac5 147 return this->phaseDelta;
kayekss 0:727737138ac5 148 }
kayekss 0:727737138ac5 149
kayekss 0:727737138ac5 150 /** (Re)calculate phase delta per sample */
kayekss 0:727737138ac5 151 void Instrument::calculatePhaseDelta() {
kayekss 4:b2423ad4b248 152 // phase = 0x0000;
kayekss 0:727737138ac5 153 phaseDelta = (uint16_t) ((uint32_t) frequency * WAVETABLE_LENGTH * 256
kayekss 0:727737138ac5 154 / samplingRate);
kayekss 0:727737138ac5 155 }
kayekss 0:727737138ac5 156
kayekss 0:727737138ac5 157 /** Calculate master volume from product of its volume, expression, and velocity */
kayekss 0:727737138ac5 158 void Instrument::calculateMasterVolume() {
kayekss 0:727737138ac5 159 this->masterVolume
kayekss 0:727737138ac5 160 = ((uint32_t) this->volume * this->expression * this->velocity) >> 16;
kayekss 0:727737138ac5 161 }