|
- /*
- ==============================================================================
-
- This file is part of the JUCETICE project - Copyright 2008 by Lucio Asnaghi.
-
- JUCETICE is based around the JUCE library - "Jules' Utility Class Extensions"
- Copyright 2008 by Julian Storer.
-
- ------------------------------------------------------------------------------
-
- JUCE and JUCETICE can be redistributed and/or modified under the terms of
- the GNU Lesser General Public License, as published by the Free Software
- Foundation; either version 2 of the License, or (at your option) any later
- version.
-
- JUCE and JUCETICE are distributed in the hope that they will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with JUCE and JUCETICE; if not, visit www.gnu.org/licenses or write to
- Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- Boston, MA 02111-1307 USA
-
- ==============================================================================
-
- @author rockhardbuns
- @tweaker Lucio Asnaghi
- @tweaker falkTX
-
- ==============================================================================
- */
-
- #ifndef DISTRHO_VEX_SYNTH_MODULE_HEADER_INCLUDED
- #define DISTRHO_VEX_SYNTH_MODULE_HEADER_INCLUDED
-
- #ifndef CARLA_EXPORT
- #define CARLA_EXPORT
- #endif
-
- #ifdef CARLA_EXPORT
- #include "juce_audio_basics.h"
- #else
- #include "../StandardHeader.h"
- #endif
-
- #include "VexVoice.h"
-
- class VexSyntModule
- {
- public:
- VexSyntModule(const float* const p)
- : parameters(p),
- sampleRate(44100),
- benchwarmer(0),
- playCount(1),
- part1(false),
- part2(false),
- part3(false)
- {
- for (int i = 0; i < kNumVoices; ++i)
- {
- vo1[i] = new VexVoice(p, 0, wr1);
- vo2[i] = new VexVoice(p, 24, wr2);
- vo3[i] = new VexVoice(p, 48, wr3);
- }
- }
-
- ~VexSyntModule()
- {
- for (int i = 0; i < kNumVoices; ++i)
- {
- delete vo1[i];
- delete vo2[i];
- delete vo3[i];
- }
- }
-
- void doProcess(AudioSampleBuffer& obf, AudioSampleBuffer& ebf1, AudioSampleBuffer& ebf2, AudioSampleBuffer& ebf3)
- {
- const int numSamples = obf.getNumSamples();
-
- tmpBuf.clear();
- float* const outPtrL = tmpBuf.getWritePointer(0);
- float* const outPtrR = tmpBuf.getWritePointer(1);
-
- if (part1)
- {
- float right = parameters[86] * parameters[83];
- float left = parameters[86] * (1.0f - parameters[83]);
-
- for (int i = 0; i < kNumVoices; ++i)
- {
- if (vo1[i]->getIsOn())
- {
- vo1[i]->doProcess(outPtrL, outPtrR, numSamples);
- obf.addFrom(0, 0, tmpBuf, 0, 0, numSamples, left);
- obf.addFrom(1, 0, tmpBuf, 1, 0, numSamples, right);
- ebf1.addFrom(0, 0, tmpBuf, 0, 0, numSamples, parameters[22] * left);
- ebf1.addFrom(1, 0, tmpBuf, 1, 0, numSamples, parameters[22] * right);
- ebf2.addFrom(0, 0, tmpBuf, 0, 0, numSamples, parameters[23] * left);
- ebf2.addFrom(1, 0, tmpBuf, 1, 0, numSamples, parameters[23] * right);
- ebf3.addFrom(0, 0, tmpBuf, 0, 0, numSamples, parameters[24] * left);
- ebf3.addFrom(1, 0, tmpBuf, 1, 0, numSamples, parameters[24] * right);
- }
- }
- }
-
- if (part2)
- {
- float right = parameters[87] * parameters[84];
- float left = parameters[87] * (1.0f - parameters[84]);
-
- for (int i = 0; i < kNumVoices; ++i)
- {
- if (vo2[i]->getIsOn())
- {
- vo2[i]->doProcess(outPtrL, outPtrR, numSamples);
- obf.addFrom(0, 0, tmpBuf, 0, 0, numSamples, left);
- obf.addFrom(1, 0, tmpBuf, 1, 0, numSamples, right);
- ebf1.addFrom(0, 0, tmpBuf, 0, 0, numSamples, parameters[22 + 24] * left);
- ebf1.addFrom(1, 0, tmpBuf, 1, 0, numSamples, parameters[22 + 24] * right);
- ebf2.addFrom(0, 0, tmpBuf, 0, 0, numSamples, parameters[23 + 24] * left);
- ebf2.addFrom(1, 0, tmpBuf, 1, 0, numSamples, parameters[23 + 24] * right);
- ebf3.addFrom(0, 0, tmpBuf, 0, 0, numSamples, parameters[24 + 24] * left);
- ebf3.addFrom(1, 0, tmpBuf, 1, 0, numSamples, parameters[24 + 24] * right);
- }
- }
- }
-
- if (part3)
- {
- float right = parameters[88] * parameters[85];
- float left = parameters[88] * (1.0f - parameters[85]);
-
- for (int i = 0; i < kNumVoices; ++i)
- {
- if (vo3[i]->getIsOn())
- {
- vo3[i]->doProcess(outPtrL, outPtrR, numSamples);
- obf.addFrom(0, 0, tmpBuf, 0, 0, numSamples, left);
- obf.addFrom(1, 0, tmpBuf, 1, 0, numSamples, right);
- ebf1.addFrom(0, 0, tmpBuf, 0, 0, numSamples, parameters[22 + 48] * left);
- ebf1.addFrom(1, 0, tmpBuf, 1, 0, numSamples, parameters[22 + 48] * right);
- ebf2.addFrom(0, 0, tmpBuf, 0, 0, numSamples, parameters[23 + 48] * left);
- ebf2.addFrom(1, 0, tmpBuf, 1, 0, numSamples, parameters[23 + 48] * right);
- ebf3.addFrom(0, 0, tmpBuf, 0, 0, numSamples, parameters[24 + 48] * left);
- ebf3.addFrom(1, 0, tmpBuf, 1, 0, numSamples, parameters[24 + 48] * right);
- }
- }
- }
- }
-
- void setBufferSize(const int size)
- {
- tmpBuf.setSize(2, size);
- }
-
- void setSampleRate(const double s)
- {
- if (sampleRate == s)
- return;
-
- sampleRate = s;
-
- for (int i = 0; i < kNumVoices; ++i)
- {
- delete vo1[i];
- delete vo2[i];
- delete vo3[i];
-
- vo1[i] = new VexVoice(parameters, 0, wr1);
- vo2[i] = new VexVoice(parameters, 24, wr2);
- vo3[i] = new VexVoice(parameters, 48, wr3);
- }
- }
-
- void updateParameterPtr(const float* const p)
- {
- parameters = p;
-
- for (int i = 0; i < kNumVoices; ++i)
- {
- vo1[i]->updateParameterPtr(parameters);
- vo2[i]->updateParameterPtr(parameters);
- vo3[i]->updateParameterPtr(parameters);
- }
- }
-
- void playNote(const int n, const int vel, const int preroll, const int part)
- {
- VexVoice** v = nullptr;
- const int note = n + 12;
-
- switch (part)
- {
- case 1:
- if (!part1) return;
- v = vo1;
- break;
- case 2:
- if (!part2) return;
- v = vo2;
- break;
- case 3:
- if (!part3) return;
- v = vo3;
- break;
- }
-
- if (v == nullptr)
- return;
-
- int OldestOn = kNumVoices-1;
- int OldestOff = kNumVoices-1;
- int OldestReleased = kNumVoices-1;
-
- int tmpOn = 100000000;
- //int tmpOff = 100000000;
- int tmpReleased = 100000000;
-
- for (int i = 0; i < kNumVoices; ++i)
- {
- if (i == benchwarmer)
- continue;
-
- if (! v[i]->getIsOn())
- {
- OldestOff = i;
- break;
- }
-
- if (v[i]->getIsReleased())
- {
- OldestReleased = (v[i]->getOrdinal() < tmpReleased) ? i : OldestReleased;
- tmpReleased = v[OldestReleased]->getOrdinal();
- continue;
- }
-
- OldestOn = (v[i]->getOrdinal() < tmpOn) ? i : OldestOn;
- tmpOn = v[OldestOn]->getOrdinal();
- }
-
- float noteInHertz = (float)MidiMessage::getMidiNoteInHertz(note);
- playCount++;
-
- if (OldestOff < kNumVoices)
- {
- v[OldestOff]->start(noteInHertz, float(vel)/127.0f, note, preroll, sampleRate, playCount);
- return;
- }
-
- if (OldestReleased < kNumVoices)
- {
- v[benchwarmer]->start(noteInHertz, float(vel)/127.0f, note, preroll, sampleRate, playCount);
- benchwarmer = OldestReleased;
- v[OldestReleased]->quickRelease();
- return;
- }
-
- if (OldestOn < kNumVoices)
- {
- v[benchwarmer]->start(noteInHertz, float(vel)/127.0f, note, preroll, sampleRate, playCount);
- benchwarmer = OldestOn;
- v[OldestReleased]->quickRelease();
- return;
- }
- }
-
- void releaseNote(const int n, const int preroll, const int part)
- {
- VexVoice** v = nullptr;
- const int note = n + 12;
-
- switch (part)
- {
- case 1:
- if (!part1) return;
- v = vo1;
- break;
- case 2:
- if (!part2) return;
- v = vo2;
- break;
- case 3:
- if (!part3) return;
- v = vo3;
- break;
- }
-
- if (v == nullptr)
- return;
-
- for (int i = 0; i < kNumVoices; ++i)
- {
- if (v[i]->getNote() == note)
- v[i]->release(preroll);
- }
- }
-
- void releaseAll(const int p)
- {
- for (int i = 0; i < kNumVoices; ++i)
- {
- vo1[i]->release(p);
- vo2[i]->release(p);
- vo3[i]->release(p);
- }
- }
-
- void kill(const int what = 0)
- {
- switch (what)
- {
- case 0:
- for (int i = 0; i < kNumVoices; ++i)
- {
- vo1[i]->kill();
- vo2[i]->kill();
- vo3[i]->kill();
- }
- break;
-
- case 1:
- for (int i = 0; i < kNumVoices; ++i)
- vo1[i]->kill();
- break;
-
- case 2:
- for (int i = 0; i < kNumVoices; ++i)
- vo2[i]->kill();
- break;
-
- case 3:
- for (int i = 0; i < kNumVoices; ++i)
- vo3[i]->kill();
- break;
- }
- }
-
- String getWaveName(const int part) const
- {
- switch (part)
- {
- case 1:
- return wr1.getCurrentWaveName();
- case 2:
- return wr2.getCurrentWaveName();
- case 3:
- return wr3.getCurrentWaveName();
- default:
- return "";
- }
- }
-
- void setWaveLater(const int part, const String& waveName)
- {
- switch (part)
- {
- case 1:
- wr1.setWaveLater(waveName);
- kill(1);
- break;
- case 2:
- wr2.setWaveLater(waveName);
- kill(2);
- break;
- case 3:
- wr3.setWaveLater(waveName);
- kill(3);
- break;
- }
- }
-
- void update(const int index)
- {
- if (index == 89)
- {
- part1 = (parameters[89] > 0.5f);
- return;
- }
- if (index == 90)
- {
- part2 = (parameters[90] > 0.5f);
- return;
- }
- if (index == 91)
- {
- part3 = (parameters[91] > 0.5f);
- return;
- }
-
- for (int i = 0; i < kNumVoices; ++i)
- {
- vo1[i]->update(index);
- vo2[i]->update(index);
- vo3[i]->update(index);
- }
- }
-
- private:
- static const int kNumVoices = 8;
-
- const float* parameters;
-
- double sampleRate;
- int benchwarmer;
-
- AudioSampleBuffer tmpBuf;
-
- VexVoice* vo1[kNumVoices];
- VexVoice* vo2[kNumVoices];
- VexVoice* vo3[kNumVoices];
-
- long playCount;
- bool part1, part2, part3;
-
- WaveRenderer wr1;
- WaveRenderer wr2;
- WaveRenderer wr3;
- };
-
- #endif // DISTRHO_VEX_SYNTH_MODULE_HEADER_INCLUDED
|