Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed USBDevice PinDetect
AudioEngine.cpp
00001 /* 00002 * The interface for all audio input and output. 00003 * This class acts as a container for individual voices. 00004 * It takes in MIDI events and handles processing and output. 00005 * 00006 * @author Austin Suszek 00007 */ 00008 00009 #include "AudioEngine.h" 00010 00011 #if USE_PWM 00012 PwmOut audioOut(p21); 00013 #else 00014 AnalogOut audioOut(p18); 00015 #endif 00016 00017 AudioEngine::AudioEngine() { 00018 // Initialize the synthesizers. 00019 for (int i = 0; i < C::MAX_POLYPHONY; i++) { 00020 synthesizers[i] = Synthesizer(); 00021 } 00022 00023 outputSample = 0.0; 00024 00025 #if USE_PWM 00026 audioOut.period(1.0/200000.0); 00027 #endif 00028 00029 // Set up the sampler. 00030 samplePeriod.attach(this, &AudioEngine::outputAudio, 1.0 / float(C::SAMPLE_RATE)); 00031 } 00032 00033 void AudioEngine::midiNoteOn(const int key, const int velocity) { 00034 // Find the firt disabled voice or the one that has been playing longest. 00035 int64_t min = synthesizers[0].getVoiceIndex(); 00036 int minIndex = 0; 00037 for (int i = 1; i < C::MAX_POLYPHONY; i++) { 00038 int64_t voiceIndex = synthesizers[i].getVoiceIndex(); 00039 if (voiceIndex < min) { 00040 min = voiceIndex; 00041 minIndex = i; 00042 } 00043 } 00044 00045 // Send the note to the minimum voice. 00046 synthesizers[minIndex].midiNoteOn(key, velocity); 00047 } 00048 00049 void AudioEngine::midiNoteOff(const int key) { 00050 for (int i = 0; i < C::MAX_POLYPHONY; i++) { 00051 if (synthesizers[i].isPlaying() && synthesizers[i].getCurrentKey() == key) { 00052 synthesizers[i].midiNoteOff(); 00053 break; 00054 } 00055 } 00056 } 00057 00058 int AudioEngine::nextSynth(int direction) { 00059 int nextIndex; 00060 // Hand the command down to the synthesizers. 00061 for (int i = 0; i < C::MAX_POLYPHONY; i++) { 00062 nextIndex = synthesizers[i].nextSynth(direction); 00063 } 00064 return nextIndex; 00065 } 00066 00067 void AudioEngine::outputAudio() { 00068 // The first thing we do is output the last calculated sample. 00069 // Map [-1, 1] range to [0, 1] range. 00070 audioOut = (outputSample + 1.0) / 2.0; 00071 00072 // Now reset output and calculate the next sample. 00073 outputSample = 0.0; 00074 00075 // Poll all of the synthesizers. 00076 for (int i = 0; i < C::MAX_POLYPHONY; i++) { 00077 if (synthesizers[i].isPlaying()) { 00078 // Get the next sample. 00079 outputSample += synthesizers[i].getSample(); 00080 } 00081 } 00082 00083 // Scale the output by the number of voices. 00084 outputSample /= float(C::MAX_POLYPHONY); 00085 // Check that we do not clip. 00086 if (outputSample > 1.0) { 00087 outputSample = 1.0; 00088 } 00089 if (outputSample < -1.0) { 00090 outputSample = -1.0; 00091 } 00092 }
Generated on Thu Aug 11 2022 16:09:57 by
1.7.2