2013-09-04 13:37:36 +00:00
|
|
|
#include "PluginProcessor.h"
|
|
|
|
#include "PluginEditor.h"
|
2013-09-09 16:14:43 +00:00
|
|
|
#include "EnumFloatParameter.h"
|
2013-09-04 13:37:36 +00:00
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
JuceOplvstiAudioProcessor::JuceOplvstiAudioProcessor()
|
|
|
|
{
|
2013-09-04 14:19:22 +00:00
|
|
|
Opl = new Hiopl(44100); // 1 second at 44100
|
2013-09-09 16:14:43 +00:00
|
|
|
const String waveforms[] = {"Sine", "Half Sine", "Abs Sine", "Quarter Sine"};
|
|
|
|
params.push_back(new EnumFloatParameter("Carrier Wave",
|
|
|
|
StringArray(waveforms, sizeof(waveforms)/sizeof(String)))
|
|
|
|
);
|
|
|
|
params.push_back(new EnumFloatParameter("Modulator Wave",
|
|
|
|
StringArray(waveforms, sizeof(waveforms)/sizeof(String)))
|
|
|
|
);
|
2013-09-10 17:30:05 +00:00
|
|
|
const String levels[] = {"-0.75 dB", "-1.5 dB", "-3 dB", "-6 dB", "-12 dB", "-24 dB"};
|
|
|
|
params.push_back(new EnumFloatParameter("Carrier Attenuation",
|
|
|
|
StringArray(levels, sizeof(levels)/sizeof(String)))
|
|
|
|
);
|
|
|
|
params.push_back(new EnumFloatParameter("Modulator Attenuation",
|
|
|
|
StringArray(levels, sizeof(levels)/sizeof(String)))
|
|
|
|
);
|
|
|
|
const String frq_multipliers[] = {
|
|
|
|
"x0.5", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x10", "x12", "x12", "x15", "x15"
|
|
|
|
};
|
|
|
|
params.push_back(new EnumFloatParameter("Carrier Frequency Multiplier",
|
|
|
|
StringArray(frq_multipliers, sizeof(frq_multipliers)/sizeof(String)))
|
|
|
|
);
|
|
|
|
params.push_back(new EnumFloatParameter("Modulator Frequency Multiplier",
|
|
|
|
StringArray(frq_multipliers, sizeof(frq_multipliers)/sizeof(String)))
|
|
|
|
);
|
2013-09-04 13:37:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
JuceOplvstiAudioProcessor::~JuceOplvstiAudioProcessor()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
const String JuceOplvstiAudioProcessor::getName() const
|
|
|
|
{
|
|
|
|
return JucePlugin_Name;
|
|
|
|
}
|
|
|
|
|
|
|
|
int JuceOplvstiAudioProcessor::getNumParameters()
|
|
|
|
{
|
2013-09-09 16:14:43 +00:00
|
|
|
return params.size();
|
2013-09-04 13:37:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
float JuceOplvstiAudioProcessor::getParameter (int index)
|
|
|
|
{
|
2013-09-09 16:14:43 +00:00
|
|
|
return params[index]->getParameter();
|
2013-09-04 13:37:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void JuceOplvstiAudioProcessor::setParameter (int index, float newValue)
|
|
|
|
{
|
2013-09-10 17:30:05 +00:00
|
|
|
FloatParameter* p = params[index];
|
|
|
|
p->setParameter(newValue);
|
|
|
|
String name = p->getName();
|
|
|
|
if (name == "Carrier Wave") {
|
|
|
|
Opl->SetWaveform(1, 1, (Waveform)((EnumFloatParameter*)p)->getParameterIndex());
|
|
|
|
} else if (name == "Modulator Wave") {
|
|
|
|
Opl->SetWaveform(1, 2, (Waveform)((EnumFloatParameter*)p)->getParameterIndex());
|
|
|
|
} else if (name == "Modulator Attenuation") {
|
|
|
|
Opl->SetAttenuation(1, 1, 0x1<<((EnumFloatParameter*)p)->getParameterIndex());
|
|
|
|
} else if (name == "Carrier Attenuation") {
|
|
|
|
Opl->SetAttenuation(1, 2, 0x1<<((EnumFloatParameter*)p)->getParameterIndex());
|
|
|
|
} else if (name == "Carrier Frequency Multiplier") {
|
|
|
|
Opl->SetFrequencyMultiple(1, 1, (FreqMultiple)((EnumFloatParameter*)p)->getParameterIndex());
|
|
|
|
} else if (name == "Modulator Frequency Multiplier") {
|
|
|
|
Opl->SetFrequencyMultiple(1, 2, (FreqMultiple)((EnumFloatParameter*)p)->getParameterIndex());
|
|
|
|
}
|
2013-09-04 13:37:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const String JuceOplvstiAudioProcessor::getParameterName (int index)
|
|
|
|
{
|
2013-09-09 16:14:43 +00:00
|
|
|
return params[index]->getName();
|
2013-09-04 13:37:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const String JuceOplvstiAudioProcessor::getParameterText (int index)
|
|
|
|
{
|
2013-09-09 16:14:43 +00:00
|
|
|
return params[index]->getParameterText();
|
2013-09-04 13:37:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const String JuceOplvstiAudioProcessor::getInputChannelName (int channelIndex) const
|
|
|
|
{
|
|
|
|
return String (channelIndex + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
const String JuceOplvstiAudioProcessor::getOutputChannelName (int channelIndex) const
|
|
|
|
{
|
|
|
|
return String (channelIndex + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool JuceOplvstiAudioProcessor::isInputChannelStereoPair (int index) const
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool JuceOplvstiAudioProcessor::isOutputChannelStereoPair (int index) const
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool JuceOplvstiAudioProcessor::acceptsMidi() const
|
|
|
|
{
|
|
|
|
#if JucePlugin_WantsMidiInput
|
|
|
|
return true;
|
|
|
|
#else
|
|
|
|
return false;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
bool JuceOplvstiAudioProcessor::producesMidi() const
|
|
|
|
{
|
|
|
|
#if JucePlugin_ProducesMidiOutput
|
|
|
|
return true;
|
|
|
|
#else
|
|
|
|
return false;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
bool JuceOplvstiAudioProcessor::silenceInProducesSilenceOut() const
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
double JuceOplvstiAudioProcessor::getTailLengthSeconds() const
|
|
|
|
{
|
|
|
|
return 0.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int JuceOplvstiAudioProcessor::getNumPrograms()
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int JuceOplvstiAudioProcessor::getCurrentProgram()
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void JuceOplvstiAudioProcessor::setCurrentProgram (int index)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
const String JuceOplvstiAudioProcessor::getProgramName (int index)
|
|
|
|
{
|
|
|
|
return String::empty;
|
|
|
|
}
|
|
|
|
|
|
|
|
void JuceOplvstiAudioProcessor::changeProgramName (int index, const String& newName)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
void JuceOplvstiAudioProcessor::prepareToPlay (double sampleRate, int samplesPerBlock)
|
|
|
|
{
|
2013-09-04 15:36:55 +00:00
|
|
|
Opl->SetSampleRate((int)sampleRate);
|
2013-09-04 13:37:36 +00:00
|
|
|
// Use this method as the place to do any pre-playback
|
|
|
|
// initialisation that you need..
|
|
|
|
}
|
|
|
|
|
|
|
|
void JuceOplvstiAudioProcessor::releaseResources()
|
|
|
|
{
|
|
|
|
// When playback stops, you can use this as an opportunity to free up any
|
|
|
|
// spare memory, etc.
|
|
|
|
}
|
|
|
|
|
|
|
|
void JuceOplvstiAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages)
|
|
|
|
{
|
2013-09-04 14:19:22 +00:00
|
|
|
buffer.clear(0, 0, buffer.getNumSamples());
|
2013-09-04 15:36:55 +00:00
|
|
|
MidiBuffer::Iterator midi_buffer_iterator(midiMessages);
|
|
|
|
|
|
|
|
MidiMessage midi_message(0);
|
|
|
|
int sample_number;
|
|
|
|
while (midi_buffer_iterator.getNextEvent(midi_message,sample_number)) {
|
|
|
|
if (midi_message.isNoteOn()) {
|
|
|
|
//note on at sample_number samples after
|
2013-09-09 16:14:43 +00:00
|
|
|
//the beginning of the current buffer
|
|
|
|
float noteHz = (float)MidiMessage::getMidiNoteInHertz(midi_message.getNoteNumber());
|
2013-09-04 15:36:55 +00:00
|
|
|
Opl->KeyOn(0, noteHz);
|
|
|
|
}
|
|
|
|
else if (midi_message.isNoteOff()) {
|
|
|
|
Opl->KeyOff(0);
|
|
|
|
}
|
|
|
|
}
|
2013-09-04 14:19:22 +00:00
|
|
|
Opl->Generate(buffer.getNumSamples(), buffer.getSampleData(0));
|
2013-09-04 13:37:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
bool JuceOplvstiAudioProcessor::hasEditor() const
|
|
|
|
{
|
2013-09-09 16:14:43 +00:00
|
|
|
return false; // (change this to false if you choose to not supply an editor)
|
2013-09-04 13:37:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
AudioProcessorEditor* JuceOplvstiAudioProcessor::createEditor()
|
|
|
|
{
|
|
|
|
return new JuceOplvstiAudioProcessorEditor (this);
|
|
|
|
}
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
void JuceOplvstiAudioProcessor::getStateInformation (MemoryBlock& destData)
|
|
|
|
{
|
|
|
|
// You should use this method to store your parameters in the memory block.
|
|
|
|
// You could do that either as raw data, or use the XML or ValueTree classes
|
|
|
|
// as intermediaries to make it easy to save and load complex data.
|
|
|
|
}
|
|
|
|
|
|
|
|
void JuceOplvstiAudioProcessor::setStateInformation (const void* data, int sizeInBytes)
|
|
|
|
{
|
|
|
|
// You should use this method to restore your parameters from this memory block,
|
|
|
|
// whose contents will have been created by the getStateInformation() call.
|
|
|
|
}
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
// This creates new instances of the plugin..
|
|
|
|
AudioProcessor* JUCE_CALLTYPE createPluginFilter()
|
|
|
|
{
|
|
|
|
return new JuceOplvstiAudioProcessor();
|
|
|
|
}
|