annotate CollidoscopeApp/include/PGranularNode.h @ 3:7fb593d53361

added comments
author Fiore Martin <f.martin@qmul.ac.uk>
date Tue, 12 Jul 2016 18:29:38 +0200
parents 02467299402e
children 75b744078d66
rev   line source
f@0 1 #pragma once
f@0 2
f@0 3 #include "cinder/Cinder.h"
f@0 4 #include "cinder/audio/Node.h"
f@0 5 #include "cinder/audio/dsp/RingBuffer.h"
f@0 6 #include "boost/optional.hpp"
f@0 7 #include "Messages.h"
f@0 8 #include "RingBufferPack.h"
f@0 9
f@0 10 #include <memory>
f@0 11
f@0 12 #include "PGranular.h"
f@0 13 #include "EnvASR.h"
f@0 14
f@0 15 typedef std::shared_ptr<class PGranularNode> PGranularNodeRef;
f@0 16 typedef ci::audio::dsp::RingBufferT<CursorTriggerMsg> CursorTriggerMsgRingBuffer;
f@0 17
f@0 18
f@0 19 struct RandomGenerator;
f@0 20
f@0 21 /*
f@0 22 A node in the Cinder audio graph that holds a PGranular
f@0 23 */
f@0 24 class PGranularNode : public ci::audio::Node
f@0 25 {
f@0 26 public:
f@0 27 static const size_t kMaxVoices = 6;
f@0 28 static const int kNoMidiNote = -50;
f@0 29
f@0 30 explicit PGranularNode( ci::audio::Buffer *grainBuffer, CursorTriggerMsgRingBuffer &triggerRingBuffer );
f@0 31 ~PGranularNode();
f@0 32
f@3 33 /** Set selection size in samples */
f@0 34 void setSelectionSize( size_t size )
f@0 35 {
f@0 36 mSelectionSize.set( size );
f@0 37 }
f@0 38
f@3 39 /** Set selection start in samples */
f@0 40 void setSelectionStart( size_t start )
f@0 41 {
f@0 42 mSelectionStart.set( start );
f@0 43 }
f@0 44
f@0 45 void setGrainsDurationCoeff( double coeff )
f@0 46 {
f@0 47 mGrainDurationCoeff.set( coeff );
f@0 48 }
f@0 49
f@3 50 /* PGranularNode passes itself as trigger callback in PGranular */
f@0 51 void operator()( char msgType, int ID );
f@0 52
f@0 53 ci::audio::dsp::RingBufferT<NoteMsg>& getNoteRingBuffer() { return mNoteMsgRingBufferPack.getBuffer(); }
f@0 54
f@0 55 protected:
f@0 56
f@0 57 void initialize() override;
f@0 58
f@0 59 void process( ci::audio::Buffer *buffer ) override;
f@0 60
f@0 61 private:
f@0 62
f@3 63 // Wraps a std::atomic but get() returns a boost::optional that is set to a real value only when the atomic has changed.
f@3 64 // It is used to avoid calling PGranulat setter methods with * the same value at each audio callback.
f@0 65 template< typename T>
f@0 66 class LazyAtomic
f@0 67 {
f@0 68 public:
f@0 69 LazyAtomic( T val ) :
f@0 70 mAtomic( val ),
f@0 71 mPreviousVal( val )
f@0 72 {}
f@0 73
f@0 74 void set( T val )
f@0 75 {
f@0 76 mAtomic = val;
f@0 77 }
f@0 78
f@0 79 boost::optional<T> get()
f@0 80 {
f@0 81 const T val = mAtomic;
f@0 82 if ( val != mPreviousVal ){
f@0 83 mPreviousVal = val;
f@0 84 return val;
f@0 85 }
f@0 86 else{
f@0 87 return boost::none;
f@0 88 }
f@0 89 }
f@0 90
f@0 91 private:
f@0 92 std::atomic<T> mAtomic;
f@0 93 T mPreviousVal;
f@0 94 };
f@0 95
f@3 96 // creates or re-start a PGranular and sets the pitch according to the MIDI note passed as argument
f@0 97 void handleNoteMsg( const NoteMsg &msg );
f@0 98
f@3 99 // pointers to PGranular objects
f@0 100 std::unique_ptr < collidoscope::PGranular<float, RandomGenerator, PGranularNode > > mPGranularLoop;
f@0 101 std::array<std::unique_ptr < collidoscope::PGranular<float, RandomGenerator, PGranularNode > >, kMaxVoices> mPGranularNotes;
f@3 102 // maps midi notes to pgranulars. When a noteOff is received maks sure the right PGranular is turned off
f@0 103 std::array<int, kMaxVoices> mMidiNotes;
f@0 104
f@0 105 // pointer to the random generator struct passed over to PGranular
f@0 106 std::unique_ptr< RandomGenerator > mRandomOffset;
f@0 107
f@3 108 // buffer containing the recorder audio, to pass to PGranular in initialize()
f@0 109 ci::audio::Buffer *mGrainBuffer;
f@0 110
f@0 111 ci::audio::BufferRef mTempBuffer;
f@0 112
f@0 113 CursorTriggerMsgRingBuffer &mTriggerRingBuffer;
f@0 114 RingBufferPack<NoteMsg> mNoteMsgRingBufferPack;
f@0 115
f@0 116 LazyAtomic<size_t> mSelectionSize;
f@0 117
f@0 118 LazyAtomic<size_t> mSelectionStart;
f@0 119
f@0 120 LazyAtomic<double> mGrainDurationCoeff;
f@0 121
f@0 122
f@0 123 };
f@0 124