void SampleEditor::on_PlayPushButton_clicked() { if (PlayPushButton->text() == "Stop" ){ testpTimer(); return; } const float pan_L = 0.5f; const float pan_R = 0.5f; const int nLength = -1; const float fPitch = 0.0f; const int selectedLayer = InstrumentEditorPanel::get_instance()->getSelectedLayer(); Song *pSong = Hydrogen::get_instance()->getSong(); Instrument *pInstr = pSong->get_instrument_list()->get( Hydrogen::get_instance()->getSelectedInstrumentNumber() ); Note *pNote = new Note( pInstr, 0, pInstr->get_layer( selectedLayer )->get_end_velocity() - 0.01, pan_L, pan_R, nLength, fPitch); AudioEngine::get_instance()->get_sampler()->note_on(pNote); setSamplelengthFrames(); createPositionsRulerPath(); m_pPlayButton = true; m_pMainSampleWaveDisplay->paintLocatorEvent( StartFrameSpinBox->value() / m_divider + 24 , true); m_pSampleAdjustView->setDetailSamplePosition( __loops.start_frame, m_pZoomfactor , 0); if( __rubberband.use == false ){ m_pTimer->start(40); // update ruler at 25 fps } m_pRealtimeFrameEnd = Hydrogen::get_instance()->getRealtimeFrames() + m_pslframes; //calculate the new rubberband sample length if( __rubberband.use ){ m_prealtimeframeendfortarget = Hydrogen::get_instance()->getRealtimeFrames() + (m_pslframes * m_pRatio + 0.1); }else { m_prealtimeframeendfortarget = m_pRealtimeFrameEnd; } m_pTargetDisplayTimer->start(40); // update ruler at 25 fps PlayPushButton->setText( QString( "Stop") ); }
void InstrumentTrackWindow::dropEvent( QDropEvent* event ) { QString type = StringPairDrag::decodeKey( event ); QString value = StringPairDrag::decodeValue( event ); if( type == "instrument" ) { m_track->loadInstrument( value ); Engine::getSong()->setModified(); event->accept(); setFocus(); } else if( type == "presetfile" ) { DataFile dataFile( value ); InstrumentTrack::removeMidiPortNode( dataFile ); m_track->setSimpleSerializing(); m_track->loadSettings( dataFile.content().toElement() ); Engine::getSong()->setModified(); event->accept(); setFocus(); } else if( type == "pluginpresetfile" ) { const QString ext = FileItem::extension( value ); Instrument * i = m_track->instrument(); if( !i->descriptor()->supportsFileType( ext ) ) { i = m_track->loadInstrument( pluginFactory->pluginSupportingExtension(ext).name() ); } i->loadFile( value ); event->accept(); setFocus(); } }
bool setCutoff( int instrumentNumber, int value ) { //helper function to set cutOff levels Hydrogen *engine = Hydrogen::get_instance(); Song *song = engine->getSong(); InstrumentList *instrList = song->get_instrument_list(); Instrument *instr = instrList->get( instrumentNumber ); if ( instr == NULL) return false; if( value != 0 ){ instr->set_filter_cutoff( (float) (value / 127.0 ) ); } else { instr->set_filter_cutoff( 0 ); } Hydrogen::get_instance()->setSelectedInstrumentNumber( instrList->index(instr) ); return true; }
SelectInstrument::SelectInstrument(const Instrument& instrument, QWidget* parent) : QDialog(parent) { setupUi(this); setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint); currentInstrument->setText(instrument.trackName()); buildTemplateList(); buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); connect(showMore, SIGNAL(clicked()), SLOT(buildTemplateList())); connect(instrumentList, SIGNAL(clicked(const QModelIndex &)), SLOT(expandOrCollapse(const QModelIndex &))); }
// Make the channel ready to play on. Send the program, etc. // @author Tom Breton (Tehom) void TrackInfo::makeChannelReady(Studio &studio) { #ifdef DEBUG_CONTROL_BLOCK RG_DEBUG << "TrackInfo::makeChannelReady()" << endl; #endif Instrument *instrument = studio.getInstrumentById(m_instrumentId); // If we have deleted a device, we may get a NULL instrument. In // that case, we can't do much. if (!instrument) { return; } // We can get non-Midi instruments here. There's nothing to do // for them. For fixed, sendChannelSetup is slightly wrong, but // could be adapted and parameterized by trackId. if ((instrument->getType() == Instrument::Midi) && !m_useFixedChannel) { // Re-acquire channel. It may change if instrument's program // became percussion or became non-percussion. Device* device = instrument->getDevice(); Q_CHECK_PTR(device); AllocateChannels *allocator = device->getAllocator(); if (allocator) { m_thruChannel = allocator->reallocateThruChannel(*instrument, m_thruChannel); // If somehow we got here without having a channel, we // have one now. m_hasThruChannel = true; #ifdef DEBUG_CONTROL_BLOCK RG_DEBUG << "TrackInfo::makeChannelReady() now has channel" << m_hasThruChannel << endl; #endif } // This is how Midi instrument readies a fixed channel. StudioControl::sendChannelSetup(instrument, m_thruChannel); } m_isThruChannelReady = true; }
void Seq::playEvent(const SeqEvent& event) { int type = event.type(); if (type == ME_NOTEON) { bool mute; const Note* note = event.note(); if (note) { Instrument* instr = note->staff()->part()->instr(); const Channel& a = instr->channel(note->subchannel()); mute = a.mute || a.soloMute; } else mute = false; if (!mute) synti->play(event); } else if (type == ME_CONTROLLER) synti->play(event); }
/** * Create the beam profile. Currently only supports Rectangular. The dimensions * are either specified by those provided by `SetBeam` algorithm or default * to the width and height of the samples bounding box * @param instrument A reference to the instrument object * @param sample A reference to the sample object * @return A new IBeamProfile object */ std::unique_ptr<IBeamProfile> MonteCarloAbsorption::createBeamProfile(const Instrument &instrument, const Sample &sample) const { const auto frame = instrument.getReferenceFrame(); const auto source = instrument.getSource(); auto beamWidthParam = source->getNumberParameter("beam-width"); auto beamHeightParam = source->getNumberParameter("beam-height"); double beamWidth(-1.0), beamHeight(-1.0); if (beamWidthParam.size() == 1 && beamHeightParam.size() == 1) { beamWidth = beamWidthParam[0]; beamHeight = beamHeightParam[0]; } else { const auto bbox = sample.getShape().getBoundingBox().width(); beamWidth = bbox[frame->pointingHorizontal()]; beamHeight = bbox[frame->pointingUp()]; } return Mantid::Kernel::make_unique<RectangularBeamProfile>( *frame, instrument.getSource()->getPos(), beamWidth, beamHeight); }
void display_tick(const char* tt, const Tick& t) { std::cout << tt << " @" << t.timestamp() << ":" << t.micros() << " " << t.instrument_id().id() << " price="; if (inst) std::cout << inst->format_price(t); else std::cout << t.price(); std::cout << " size=" << t.size() << " flags=" << t.flags() << std::endl; }
double note_exists(const Arg args[], const int nargs) { if (nargs != 1) return die("note_exists", "Usage: val = note_exists(Instrument_Handle)"); Instrument *Iptr = (Instrument *)args[0]; if (Iptr == NULL) { warn("note_exists", "Instrument/note not initialized"); return -1; } Iptr->ref(); // increase ref count on instrument double retval; if (Iptr->isDone() == true) retval = 0.0; else retval = 1.0; Iptr->unref(); // decrease ref count on instrument return retval; }
void JackMidiDriver::handleQueueAllNoteOff() { InstrumentList *instList = Hydrogen::get_instance()->getSong()->get_instrument_list(); Instrument *curInst; unsigned int numInstruments = instList->size(); unsigned int i; int channel; int key; for (i = 0; i < numInstruments; i++) { curInst = instList->get(i); channel = curInst->get_midi_out_channel(); if (channel < 0 || channel > 15) continue; key = curInst->get_midi_out_note(); if (key < 0 || key > 127) continue; handleQueueNoteOff(channel, key, 0); } }
bool setInstrumentPitch( int instrumentNumber, int value ) { //helper function to set cutOff levels Hydrogen *engine = Hydrogen::get_instance(); Song *song = engine->getSong(); InstrumentList *instrList = song->get_instrument_list(); Instrument *instr = instrList->get( instrumentNumber ); if ( instr == NULL) return false; if( value < 63 ){ instr->set_instrument_pitch( (float) ((value-62) / 62.0 * MAX_INSTRUMENT_PITCH ) ); } else if ( value > 64 ) { instr->set_instrument_pitch( (float) ((value-65) / 62.0 * MAX_INSTRUMENT_PITCH ) ); } else { instr->set_instrument_pitch( 0 ); } Hydrogen::get_instance()->setSelectedInstrumentNumber( instrList->index(instr) ); return true; }
bool setAbsoluteFXLevel( int nLine, int fx_channel , int fx_param) { //helper function to set fx levels Hydrogen::get_instance()->setSelectedInstrumentNumber( nLine ); Hydrogen *engine = Hydrogen::get_instance(); Song *song = engine->getSong(); InstrumentList *instrList = song->get_instrument_list(); Instrument *instr = instrList->get( nLine ); if ( instr == NULL) return false; if( fx_param != 0 ){ instr->set_fx_level( ( (float) (fx_param / 127.0 ) ), fx_channel ); } else { instr->set_fx_level( 0 , fx_channel ); } Hydrogen::get_instance()->setSelectedInstrumentNumber(nLine); return true; }
Document &DocumentManager::addDefaultDocument( const SettingsManager &settings_manager) { Document &doc = addDocument(); Score &score = doc.getScore(); auto settings = settings_manager.getReadHandle(); // Add an initial player and instrument. Player player; player.setDescription("Player 1"); player.setTuning(settings->get(Settings::DefaultTuning)); score.insertPlayer(player); Instrument instrument; instrument.setDescription(settings->get(Settings::DefaultInstrumentName) + " 1"); instrument.setMidiPreset(settings->get(Settings::DefaultInstrumentPreset)); score.insertInstrument(instrument); ScoreUtils::addStandardFilters(score); // Add an initial staff, player change, and tempo marker. System system; system.insertStaff(Staff(player.getTuning().getStringCount())); PlayerChange initialPlayers; initialPlayers.insertActivePlayer(0, ActivePlayer(0, 0)); system.insertPlayerChange(initialPlayers); TempoMarker tempo; tempo.setDescription("Moderately"); system.insertTempoMarker(tempo); score.insertSystem(system); return doc; }
void SongEditorPanel::updatePlaybackFaderPeaks() { Sampler* pSampler = AudioEngine::get_instance()->get_sampler(); Preferences * pPref = Preferences::get_instance(); Instrument* pInstrument = pSampler->__playback_instrument; bool bShowPeaks = pPref->showInstrumentPeaks(); float fallOff = pPref->getMixerFalloffSpeed(); // fader float fOldPeak_L = m_pPlaybackTrackFader->getPeak_L(); float fOldPeak_R = m_pPlaybackTrackFader->getPeak_R(); float fNewPeak_L = pInstrument->get_peak_l(); pInstrument->set_peak_l( 0.0f ); // reset instrument peak float fNewPeak_R = pInstrument->get_peak_r(); pInstrument->set_peak_r( 0.0f ); // reset instrument peak if (!bShowPeaks) { fNewPeak_L = 0.0f; fNewPeak_R = 0.0f; } if ( fNewPeak_L >= fOldPeak_L) { // LEFT peak m_pPlaybackTrackFader->setPeak_L( fNewPeak_L ); } else { m_pPlaybackTrackFader->setPeak_L( fOldPeak_L / fallOff ); } if ( fNewPeak_R >= fOldPeak_R) { // Right peak m_pPlaybackTrackFader->setPeak_R( fNewPeak_R ); } else { m_pPlaybackTrackFader->setPeak_R( fOldPeak_R / fallOff ); } }
void PowerTabOldImporter::convert(const PowerTabDocument::Guitar &guitar, Score &score) { Player player; player.setDescription(guitar.GetDescription()); player.setPan(guitar.GetPan()); Tuning tuning; convert(guitar.GetTuning(), tuning); tuning.setCapo(guitar.GetCapo()); player.setTuning(tuning); score.insertPlayer(player); Instrument instrument; instrument.setMidiPreset(guitar.GetPreset()); // Use the MIDI preset name as the description. const std::vector<std::string> presetNames = Midi::getPresetNames(); instrument.setDescription(presetNames.at(guitar.GetPreset())); score.insertInstrument(instrument); }
/** * @brief Computes the PnL for the current position * * Computes the PnL for the current position and the specified price. Undefined * behaviour if a position doesn't exist. * * A position starts with the first transaction which sets a quantity different than 0. * * Uses the gross PnL for all transactions part of this trade. * * @param[in] instrument the instrument * @param[in] price the price to compute the PnL * @param[out] realized the realized PnL * @param[out] unrealized the unrealized PnL */ void Portfolio::TransactionCollection::getPositionPnl(const Instrument & instrument, numeric price, numeric & realized, numeric & unrealized) const { auto it = container_.rbegin(); // Must not be called without a position poco_assert(it->positionQuantity != 0); unrealized = instrument.bpv()*it->positionQuantity*(price - it->positionAverageCost); // Add all realized pnl realized = 0.0; while (it->positionQuantity != 0) { realized += it->grossPnl; ++it; } }
void GateTrigger::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages) { float threshold = library->getThreshold(); int64 releaseTicks = library->getReleaseTicks(); float velocityScale = library->getVelocityScale(); int windowSize = buffer.getNumSamples(); for (int i = 0; i < buffer.getNumSamples(); i += windowSize) { float rms = 0; for (int chan = 0; chan < buffer.getNumChannels(); chan++) { rms += buffer.getMagnitude (chan, i, jmin(windowSize, buffer.getNumSamples() - i)); } rms = rms / buffer.getNumChannels() * 100; if (rms - lastRms > threshold) { if (Time::getHighResolutionTicks() - lastTriggerTick > releaseTicks) { Pattern* pattern = sequencer->getPattern(); Instrument* instrument = pattern->getActiveInstrument(); // play note float velocity = (rms - lastRms) / velocityScale; DBG("RMS: " + String(rms) + " lastRMS: " + String(lastRms) + " velocity: " + String(velocity)); int noteNumber = instrument->getNoteNumber(); MidiMessage m = MidiMessage::noteOn (1, noteNumber, velocity); midiMessages.addEvent (m, i); // insert into sequencer pattern int step = round(sequencer->getPreciseStep()); step = step % pattern->getNumSteps(); Cell* cell = pattern->getCellAt (0, step); delayedInserterThread->insertNote (cell, velocity, instrument); // Retrigger the reset timer resetTimer->retrigger(); lastTriggerTick = Time::getHighResolutionTicks(); } } lastRms = rms; } }
void MixerDetails::drumkitToggled(bool val) { if (_mti == 0) return; Part* part = _mti->part(); Channel* channel = _mti->focusedChan(); Instrument *instr; if (_mti->trackType() == MixerTrackItem::TrackType::CHANNEL) instr = _mti->instrument(); else instr = part->instrument(0); if (instr->useDrumset() == val) return; const MidiPatch* newPatch = 0; const QList<MidiPatch*> pl = synti->getPatchInfo(); for (const MidiPatch* p : pl) { if (p->drum == val) { newPatch = p; break; } } Score* score = part->score(); if (newPatch) { score->startCmd(); part->undoChangeProperty(Pid::USE_DRUMSET, val); score->undo(new ChangePatch(score, channel, newPatch)); score->setLayoutAll(); score->endCmd(); } channel->updateInitList(); }
void Sampler::note_on( Note *note ) { //infoLog( "[noteOn]" ); assert( note ); note->get_adsr()->attack(); Instrument *pInstr = note->get_instrument(); // mute group int mute_grp = pInstr->get_mute_group(); if ( mute_grp != -1 ) { // remove all notes using the same mute group for ( unsigned j = 0; j < __playing_notes_queue.size(); j++ ) { // delete older note Note *pNote = __playing_notes_queue[ j ]; if ( ( pNote->get_instrument() != pInstr ) && ( pNote->get_instrument()->get_mute_group() == mute_grp ) ) { pNote->get_adsr()->release(); } } } //note off notes if( note->get_note_off() ){ for ( unsigned j = 0; j < __playing_notes_queue.size(); j++ ) { Note *pNote = __playing_notes_queue[ j ]; if ( ( pNote->get_instrument() == pInstr ) ) { //ERRORLOG("note_off"); pNote->get_adsr()->release(); } } } pInstr->enqueue(); if( !note->get_note_off() ){ __playing_notes_queue.push_back( note ); } }
void ControlRulerWidget::setSegments(RosegardenDocument *document, std::vector<Segment *> segments) { m_document = document; // m_segments = segments; // connect(m_document, SIGNAL(pointerPositionChanged(timeT)), // this, SLOT(slotPointerPositionChanged(timeT))); Composition &comp = document->getComposition(); Track *track = comp.getTrackById(segments[0]->getTrack()); Instrument *instr = document->getStudio(). getInstrumentById(track->getInstrument()); if (instr) { Device *device = instr->getDevice(); // Cast to a Controllable if possible, otherwise leave c NULL. Controllable *c = dynamic_cast<MidiDevice *>(device); if (!c) { c = dynamic_cast<SoftSynthDevice *>(device); } if (c) { m_controlList = &(c->getControlParameters()); } } SegmentSelection selection; selection.insert(segments.begin(), segments.end()); // This is single segment code setSegment(segments[0]); }
void StateWriter::getState (MemoryBlock& destData) { DBG("StateWriter::getState(): Saving state.") ValueTree settingsTree ("settings"); ValueTree libTree ("library"); libTree.setProperty ("threshold", library->getThreshold(), nullptr); libTree.setProperty ("release", library->getReleaseTicks(), nullptr); libTree.setProperty ("velocity", library->getVelocityScale(), nullptr); settingsTree.addChild (libTree, -1, nullptr); ValueTree patternsTree ("patterns"); for (int i = 0; i < library->getNumPatterns(); i++) { Pattern* pattern = library->getPattern (i); ValueTree patternTree ("pattern"); ValueTree instrumentsTree ("instruments"); for (int j = 0; j < pattern->getNumInstruments(); j++) { Instrument* instrument = pattern->getInstrumentAt (j); ValueTree instrumentTree ("instrument"); instrumentTree.setProperty ("index", instrument->getIndex(), nullptr); instrumentTree.setProperty ("name", instrument->getName(), nullptr); instrumentTree.setProperty ("noteNumber", instrument->getNoteNumber(), nullptr); instrumentsTree.addChild (instrumentTree, -1, nullptr); } patternTree.addChild (instrumentsTree, -1, nullptr); patternsTree.addChild (patternTree, -1, nullptr); } settingsTree.addChild (patternsTree, -1, nullptr); ValueTree seqTree ("sequencer"); seqTree.setProperty ("sequencerNum", sequencer->getSequencerNum(), nullptr); settingsTree.addChild (seqTree, -1, nullptr); MemoryOutputStream stream (destData, false); settingsTree.writeToStream (stream); }
void MidiMixerWindow::slotFaderLevelChanged(float value) { const QObject *s = sender(); for (FaderVector::const_iterator it = m_faders.begin(); it != m_faders.end(); ++it) { if ((*it)->m_volumeFader == s) { Instrument *instr = m_studio-> getInstrumentById((*it)->m_id); if (instr) { instr->setControllerValue(MIDI_CONTROLLER_VOLUME, MidiByte(value)); if (instr->hasFixedChannel()) { // send out to external controllers as well if the // affected instrument is on a fixed channel. //!!! really want some notification of whether we have any! int tabIndex = m_tabWidget->currentIndex(); if (tabIndex < 0) tabIndex = 0; int i = 0; for (DeviceList::const_iterator dit = m_studio->begin(); dit != m_studio->end(); ++dit) { RG_DEBUG << "slotFaderLevelChanged: i = " << i << ", tabIndex " << tabIndex << endl; if (!dynamic_cast<MidiDevice*>(*dit)) continue; if (i != tabIndex) { ++i; continue; } RG_DEBUG << "slotFaderLevelChanged: device id = " << instr->getDevice()->getId() << ", visible device id " << (*dit)->getId() << endl; if (instr->getDevice()->getId() == (*dit)->getId()) { RG_DEBUG << "slotFaderLevelChanged: sending control device mapped event for channel " << instr->getNaturalChannel() << endl; MappedEvent mE((*it)->m_id, MappedEvent::MidiController, MIDI_CONTROLLER_VOLUME, MidiByte(value)); mE.setRecordedChannel(instr->getNaturalChannel()); mE.setRecordedDevice(Device::CONTROL_DEVICE); StudioControl::sendMappedEvent(mE); } break; } } } emit instrumentParametersChanged((*it)->m_id); return ; } } }
void MainForm::functionDeleteInstrument(int instrument) { Hydrogen * H = Hydrogen::get_instance(); Instrument *pSelectedInstrument = H->getSong()->get_instrument_list()->get( instrument ); std::list< Note* > noteList; Song* song = H->getSong(); PatternList *patList = song->get_pattern_list(); QString instrumentName = pSelectedInstrument->get_name(); QString drumkitName = H->getCurrentDrumkitname(); for ( int i = 0; i < patList->size(); i++ ) { H2Core::Pattern *pPattern = song->get_pattern_list()->get(i); const Pattern::notes_t* notes = pPattern->get_notes(); FOREACH_NOTE_CST_IT_BEGIN_END(notes,it) { Note *pNote = it->second; assert( pNote ); if ( pNote->get_instrument() == pSelectedInstrument ) { pNote->set_pattern_idx( i ); noteList.push_back( pNote ); } } }
void SceneSetting::update() { if(instrument) { Instrument * i = instrument; this->level = i->getLevel(); this->pan = i->getPan(); this->pitch = i->getPitch(); this->mute = i->isMuted(); this->solo = i->isSoloed(); } }
void SceneSetting::apply() { if(instrument) { Instrument * inst = instrument; inst->setLevel(this->level); inst->setPan(this->pan); inst->setPitch(this->pitch); inst->setMuted(this->mute); inst->setSoloed(this->solo); } }
int main(int argc, char *argv[]){ InstrumentFactory * trumpetFactory = FactoryCreator::createTrumpetFactory(); InstrumentFactory * drumFactory = FactoryCreator::createDrumFactory(); InstrumentFactory * guitarFactory = FactoryCreator::createGuitarFactory(); Instrument * trumpet = trumpetFactory->createInstrument(); Instrument * drum = drumFactory->createInstrument(); Instrument * guitar = guitarFactory->createInstrument(); trumpet->play(); drum->play(); guitar->play(); }
Volatility ImpliedVolatilityHelper::calculate( const Instrument& instrument, const PricingEngine& engine, SimpleQuote& volQuote, Real targetValue, Real accuracy, Natural maxEvaluations, Volatility minVol, Volatility maxVol) { instrument.setupArguments(engine.getArguments()); engine.getArguments()->validate(); PriceError f(engine, volQuote, targetValue); Brent solver; solver.setMaxEvaluations(maxEvaluations); Volatility guess = (minVol+maxVol)/2.0; Volatility result = solver.solve(f, accuracy, guess, minVol, maxVol); return result; }
// Convert an InstrumentInfo to an Instrument. Instrument *InstrumentInfo::toInstrument(int maxSamples, IFileLoadProgressListener * listener) { LogPtr log = LogFactory::getLog(__FILE__); Instrument *inst = new Instrument(name.c_str()); unsigned instLevel = (unsigned)atoi(level.c_str()); if(instLevel <= 0) instLevel = 100; short instPan = 0; if(pan.length() > 0) instPan = (short)atoi(pan.c_str()); inst->setLevel(instLevel); inst->setPan(instPan); inst->setSubmixName(submix); int instPitch = atoi(pitch.c_str()); inst->setPitch(instPitch); for(InstrumentInfo::LayerInfoList::iterator e = layers.begin(); e != layers.end(); ++e) { LayerInfo *layerInfo = *e; string wave = layerInfo->wave; unsigned lo = (unsigned)atoi(layerInfo->lo.c_str()); unsigned hi = (unsigned)atoi(layerInfo->hi.c_str()); if(listener) { if(!listener->progressEvent(wave)) break; } LOG_TRACE(log, "assign " << wave << " to velocity range " << lo << "-" << hi); Sample *sample = Sample::load(wave, maxSamples); if(sample) { InstrumentLayer *layer = new InstrumentLayer(sample, lo, hi); inst->add(layer); //sampleMap[sample->getFilename()] = sample; } } return inst; }
int CHAIN::run() { for (std::vector<Instrument *>::iterator it = mInstVector.begin(); it != mInstVector.end(); ++it) { Instrument *inst = *it; if (!inst->isDone()) { inst->setchunk(framesToRun()); // For outer instrument, this is done in inTraverse() inst->run(true); } else { inst->clearOutput(framesToRun()); // This should be optimized to happen only once } inst->addout(BUS_NONE_OUT, 0); // Special bus type makes this a no-op } // Copy from inputChainedBuf, which points to the outbuf of the last instrument in the chain. unsigned copySize = framesToRun() * outputChannels() * sizeof(BUFTYPE); memcpy(outbuf, inputChainBuf, copySize); return framesToRun(); }
int CHAIN::configure() { int status = -1; Instrument *previous = NULL; for (std::vector<Instrument *>::iterator it = mInstVector.begin(); it != mInstVector.end(); ++it) { Instrument *inst = *it; status = inst->configure(RTBUFSAMPS); if (status != 0) return status; if (previous != NULL) { status = inst->setChainedInputBuffer(previous->outbuf, previous->outputChannels()); if (status != 0) return status; } previous = inst; } // For CHAIN itself, we override our (what should be zero) input channel count here. This allows setChainedInputBuffer() to succeed // even though the counts don't seem to match. _input.inputchans = previous->outputChannels(); status = setChainedInputBuffer(previous->outbuf, previous->outputChannels()); return status; }