Mercurial > hg > opencollidoscope
diff CollidoscopeApp/include/PGranularNode.h @ 0:02467299402e
First import
CollidoscopeApp for Raspberry Pi
JackDevice
Teensy code for Collidoscope
author | Fiore Martin <f.martin@qmul.ac.uk> |
---|---|
date | Thu, 30 Jun 2016 14:50:06 +0200 |
parents | |
children | 7fb593d53361 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CollidoscopeApp/include/PGranularNode.h Thu Jun 30 14:50:06 2016 +0200 @@ -0,0 +1,119 @@ +#pragma once + +#include "cinder/Cinder.h" +#include "cinder/audio/Node.h" +#include "cinder/audio/dsp/RingBuffer.h" +#include "boost/optional.hpp" +#include "Messages.h" +#include "RingBufferPack.h" + +#include <memory> + +#include "PGranular.h" +#include "EnvASR.h" + +typedef std::shared_ptr<class PGranularNode> PGranularNodeRef; +typedef ci::audio::dsp::RingBufferT<CursorTriggerMsg> CursorTriggerMsgRingBuffer; + + +struct RandomGenerator; + +/* +A node in the Cinder audio graph that holds a PGranular +*/ +class PGranularNode : public ci::audio::Node +{ +public: + static const size_t kMaxVoices = 6; + static const int kNoMidiNote = -50; + + explicit PGranularNode( ci::audio::Buffer *grainBuffer, CursorTriggerMsgRingBuffer &triggerRingBuffer ); + ~PGranularNode(); + + // set selection size in samples + void setSelectionSize( size_t size ) + { + mSelectionSize.set( size ); + } + + void setSelectionStart( size_t start ) + { + mSelectionStart.set( start ); + } + + void setGrainsDurationCoeff( double coeff ) + { + mGrainDurationCoeff.set( coeff ); + } + + // used for trigger callback in PGRanular + void operator()( char msgType, int ID ); + + ci::audio::dsp::RingBufferT<NoteMsg>& getNoteRingBuffer() { return mNoteMsgRingBufferPack.getBuffer(); } + +protected: + + void initialize() override; + + void process( ci::audio::Buffer *buffer ) override; + +private: + + template< typename T> + class LazyAtomic + { + public: + LazyAtomic( T val ) : + mAtomic( val ), + mPreviousVal( val ) + {} + + void set( T val ) + { + mAtomic = val; + } + + boost::optional<T> get() + { + const T val = mAtomic; + if ( val != mPreviousVal ){ + mPreviousVal = val; + return val; + } + else{ + return boost::none; + } + } + + private: + std::atomic<T> mAtomic; + T mPreviousVal; + }; + + void handleNoteMsg( const NoteMsg &msg ); + + // pointer to PGranular object + std::unique_ptr < collidoscope::PGranular<float, RandomGenerator, PGranularNode > > mPGranularLoop; + std::array<std::unique_ptr < collidoscope::PGranular<float, RandomGenerator, PGranularNode > >, kMaxVoices> mPGranularNotes; + std::array<int, kMaxVoices> mMidiNotes; + + // pointer to the random generator struct passed over to PGranular + std::unique_ptr< RandomGenerator > mRandomOffset; + + /* buffer containing the recorder audio, to pass to PGranular in initialize() */ + ci::audio::Buffer *mGrainBuffer; + + ci::audio::BufferRef mTempBuffer; + + CursorTriggerMsgRingBuffer &mTriggerRingBuffer; + RingBufferPack<NoteMsg> mNoteMsgRingBufferPack; + + LazyAtomic<size_t> mSelectionSize; + + LazyAtomic<size_t> mSelectionStart; + + LazyAtomic<double> mGrainDurationCoeff; + + +}; +