void SamplePlayerNodeTestApp::setupFilePlayerNode() { mGain->disconnectAllInputs(); auto ctx = audio::master(); // mSourceFile->setMaxFramesPerRead( 8192 ); bool asyncRead = mAsyncButton.mEnabled; CI_LOG_V( "async read: " << asyncRead ); mSamplePlayerNode = ctx->makeNode( new audio::FilePlayerNode( mSourceFile, asyncRead ) ); // TODO: it is pretty surprising when you recreate mMonitor here without checking if there has already been one added. // - user will no longer see the old mMonitor, but the context still owns a reference to it, so another gets added each time we call this method. if( ! mMonitor ) mMonitor = ctx->makeNode( new audio::MonitorNode( audio::MonitorNode::Format().windowSize( 1024 ) ) ); // when these connections are called, some (GainNode and Pan) will already be connected, but this is okay, they should silently no-op. // or connect in series (it is added to the Context's 'auto pulled list') mSamplePlayerNode >> mGain >> mPan >> ctx->getOutput(); mPan >> mMonitor; mSamplePlayerNode->setLoopEnabled( mLoopButton.mEnabled ); mSamplePlayerNode->setLoopBeginTime( mLoopBeginSlider.mValueScaled ); mSamplePlayerNode->setLoopEndTime( mLoopEndSlider.mValueScaled != 0 ? mLoopEndSlider.mValueScaled : mSamplePlayerNode->getNumSeconds() ); PRINT_GRAPH( audio::master() ); }
void SamplePlayerNodeTestApp::processDrag( Vec2i pos ) { if( mGainSlider.hitTest( pos ) ) mGain->setValue( mGainSlider.mValueScaled ); else if( mPanSlider.hitTest( pos ) ) mPan->setPos( mPanSlider.mValueScaled ); else if( mLoopBeginSlider.hitTest( pos ) ) mSamplePlayerNode->setLoopBeginTime( mLoopBeginSlider.mValueScaled ); else if( mLoopEndSlider.hitTest( pos ) ) mSamplePlayerNode->setLoopEndTime( mLoopEndSlider.mValueScaled ); else if( pos.y > getWindowCenter().y ) seek( pos.x ); }
void SamplePlayerNodeTestApp::processDrag( ivec2 pos ) { if( mGainSlider.hitTest( pos ) ) mGain->setValue( mGainSlider.mValueScaled ); else if( mPanSlider.hitTest( pos ) ) { #if TEST_STEREO_INPUT_PANNING mPan->getParamPos()->applyRamp( mPanSlider.mValueScaled, 0.6f ); #else mPan->setPos( mPanSlider.mValueScaled ); #endif } else if( mLoopBeginSlider.hitTest( pos ) ) mSamplePlayerNode->setLoopBeginTime( mLoopBeginSlider.mValueScaled ); else if( mLoopEndSlider.hitTest( pos ) ) mSamplePlayerNode->setLoopEndTime( mLoopEndSlider.mValueScaled ); else if( mTriggerDelaySlider.hitTest( pos ) ) { } else if( pos.y > getWindowCenter().y ) seek( pos.x ); }
void SamplePlayerNodeTestApp::setupBufferPlayerNode() { auto bufferPlayer = audio::master()->makeNode( new audio::BufferPlayerNode() ); auto loadFn = [bufferPlayer, this] { bufferPlayer->loadBuffer( mSourceFile ); mWaveformPlot.load( bufferPlayer->getBuffer(), getWindowBounds() ); CI_LOG_V( "loaded source buffer, frames: " << bufferPlayer->getBuffer()->getNumFrames() ); }; auto connectFn = [bufferPlayer, this] { mGain->disconnectAllInputs(); mSamplePlayerNode = bufferPlayer; mSamplePlayerNode >> mGain >> mPan >> audio::master()->getOutput(); PRINT_GRAPH( audio::master() ); mSamplePlayerNode->setLoopEnabled( mLoopButton.mEnabled ); mSamplePlayerNode->setLoopBeginTime( mLoopBeginSlider.mValueScaled ); mSamplePlayerNode->setLoopEndTime( mLoopEndSlider.mValueScaled != 0 ? mLoopEndSlider.mValueScaled : mSamplePlayerNode->getNumSeconds() ); }; bool asyncLoad = mAsyncButton.mEnabled; CI_LOG_V( "async load: " << boolalpha << asyncLoad << dec ); if( asyncLoad ) { mWaveformPlot.clear(); mAsyncLoadFuture = std::async( [=] { loadFn(); dispatchAsync( [=] { connectFn(); } ); } ); } else { loadFn(); connectFn(); }; }