//============================================================================== bool AudioProcessor::setPreferredBusArrangement (bool isInput, int busIndex, const AudioChannelSet& preferredSet) { const int oldNumInputs = getTotalNumInputChannels(); const int oldNumOutputs = getTotalNumOutputChannels(); Array<AudioProcessorBus>& buses = isInput ? busArrangement.inputBuses : busArrangement.outputBuses; const int numBuses = buses.size(); if (! isPositiveAndBelow (busIndex, numBuses)) return false; AudioProcessorBus& bus = buses.getReference (busIndex); #ifdef JucePlugin_PreferredChannelConfigurations // the user is using the deprecated way to specify channel configurations if (numBuses > 0 && busIndex == 0) { const short channelConfigs[][2] = { JucePlugin_PreferredChannelConfigurations }; const int numChannelConfigs = sizeof (channelConfigs) / sizeof (*channelConfigs); // we need the main bus in the opposite direction Array<AudioProcessorBus>& oppositeBuses = isInput ? busArrangement.outputBuses : busArrangement.inputBuses; AudioProcessorBus* oppositeBus = (busIndex < oppositeBuses.size()) ? &oppositeBuses.getReference (0) : nullptr; // get the target number of channels const int mainBusNumChannels = preferredSet.size(); const int mainBusOppositeChannels = (oppositeBus != nullptr) ? oppositeBus->channels.size() : 0; const int dir = isInput ? 0 : 1; // find a compatible channel configuration on the opposite bus which is the closest match // to the current number of channels on that bus int distance = std::numeric_limits<int>::max(); int bestConfiguration = -1; for (int i = 0; i < numChannelConfigs; ++i) { // is the configuration compatible with the preferred set if (channelConfigs[i][dir] == mainBusNumChannels) { const int configChannels = channelConfigs[i][dir^1]; const int channelDifference = std::abs (configChannels - mainBusOppositeChannels); if (channelDifference < distance) { distance = channelDifference; bestConfiguration = configChannels; // we can exit if we found a perfect match if (distance == 0) break; } } } // unable to find a good configuration if (bestConfiguration == -1) return false; // did the number of channels change on the opposite bus? if (mainBusOppositeChannels != bestConfiguration && oppositeBus != nullptr) { // if the channels on the opposite bus are the same as the preferred set // then also copy over the layout information. If not, then assume // a cononical channel layout if (bestConfiguration == mainBusNumChannels) oppositeBus->channels = preferredSet; else oppositeBus->channels = AudioChannelSet::canonicalChannelSet (bestConfiguration); } } #endif bus.channels = preferredSet; if (oldNumInputs != getTotalNumInputChannels() || oldNumOutputs != getTotalNumOutputChannels()) { updateSpeakerFormatStrings(); numChannelsChanged(); } return true; }
void SynthAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages) { const int totalNumInputChannels = getTotalNumInputChannels(); const int totalNumOutputChannels = getTotalNumOutputChannels(); // In case we have more outputs than inputs, this code clears any output // channels that didn't contain input data, (because these aren't // guaranteed to be empty - they may contain garbage). // This is here to avoid people getting screaming feedback // when they first compile a plugin, but obviously you don't need to keep // this code if your algorithm always overwrites all the output channels. MidiBuffer Midi; int time; MidiMessage m; for(MidiBuffer::Iterator i(midiMessages); i.getNextEvent(m, time);){ //handle monophonic on/off of notes if(m.isNoteOn()){ noteOn++; } if(m.isNoteOff()){ noteOn--; } if(noteOn > 0){ monoNoteOn = 1.0f; env.reset(); //handle the pitch of the note noteVal = m.getNoteNumber(); osc.setF(m.getMidiNoteInHertz(noteVal)); }else{ monoNoteOn = 0.0f; } } for (int i = totalNumInputChannels; i < totalNumOutputChannels; ++i) buffer.clear (i, 0, buffer.getNumSamples()); for (int channel = 0; channel < totalNumOutputChannels; ++channel){ //just do the synth stuff on one channel. if(channel == 0){ for(int sample = 0; sample < buffer.getNumSamples(); ++sample){ //do this stuff here. it's terribly inefficient.. freqValScaled = 20000.0f * pow(freqP->get(), 3.0f); envValScaled = 10000.0f * pow(envP->get(), 3.0f); speedValScaled = pow((1.0f - speedP->get()), 2.0f); oscValScaled = (oscP->get() - 0.5f) * 70.0f; detValScaled = (detP->get() - 0.5f) * 24.0f; filter.setFc(freqSmoothing.process(freqValScaled + (envValScaled * pow(env.process(),3.0f))) / UPSAMPLING); env.setSpeed(speedValScaled); filter.setQ(qP->get()); float frequency = noteVal + 24.0f + oscValScaled + modOsc.process(0) + (driftSmoothing.process(random.nextFloat() - 0.5f) * 20.0f); float frequency2 = exp((frequency + detValScaled + (driftSmoothing2.process(random.nextFloat() - 0.5f) * 10.0f)) / 17.31f) / UPSAMPLING; frequency = exp(frequency / 17.31f) / UPSAMPLING; osc.setF(frequency); osc2.setF(frequency2); float monoNoteOn2 = ampSmoothing.process(monoNoteOn); float data; for(int i = 0; i < UPSAMPLING; i++){ data = 20.0f * filter.process(0.1f * osc.process() + ampP->get() * 0.1f * osc2.process()); } data *= monoNoteOn2; buffer.setSample(0, sample, data); buffer.setSample(1, sample, data); } } } }
void AudioProcessor::processBypassed (AudioBuffer<floatType>& buffer, MidiBuffer&) { for (int ch = getMainBusNumInputChannels(); ch < getTotalNumOutputChannels(); ++ch) buffer.clear (ch, 0, buffer.getNumSamples()); }