annotate CollidoscopeApp/include/PGranularNode.h @ 18:f1ff1a81be20 tip

Changed licenses names. Fixed one comment and usage text in CollidoscopeApp.cpp.
author Fiore Martin <f.martin@qmul.ac.uk>
date Thu, 25 Aug 2016 12:07:50 +0200
parents 4dad0b810f18
children
rev   line source
f@5 1 /*
f@5 2
f@5 3 Copyright (C) 2016 Queen Mary University of London
f@5 4 Author: Fiore Martin
f@5 5
f@5 6 This file is part of Collidoscope.
f@5 7
f@5 8 Collidoscope is free software: you can redistribute it and/or modify
f@5 9 it under the terms of the GNU General Public License as published by
f@5 10 the Free Software Foundation, either version 3 of the License, or
f@5 11 (at your option) any later version.
f@5 12
f@5 13 This program is distributed in the hope that it will be useful,
f@5 14 but WITHOUT ANY WARRANTY; without even the implied warranty of
f@5 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
f@5 16 GNU General Public License for more details.
f@5 17
f@5 18 You should have received a copy of the GNU General Public License
f@5 19 along with this program. If not, see <http://www.gnu.org/licenses/>.
f@5 20 */
f@5 21
f@0 22 #pragma once
f@0 23
f@0 24 #include "cinder/Cinder.h"
f@0 25 #include "cinder/audio/Node.h"
f@0 26 #include "cinder/audio/dsp/RingBuffer.h"
f@0 27 #include "boost/optional.hpp"
f@0 28 #include "Messages.h"
f@0 29 #include "RingBufferPack.h"
f@0 30
f@0 31 #include <memory>
f@0 32
f@0 33 #include "PGranular.h"
f@0 34 #include "EnvASR.h"
f@0 35
f@0 36 typedef std::shared_ptr<class PGranularNode> PGranularNodeRef;
f@0 37 typedef ci::audio::dsp::RingBufferT<CursorTriggerMsg> CursorTriggerMsgRingBuffer;
f@0 38
f@0 39
f@0 40 struct RandomGenerator;
f@0 41
f@0 42 /*
f@16 43 A node in the Cinder audio graph that holds PGranulars for loop and keyboard playing
f@0 44 */
f@0 45 class PGranularNode : public ci::audio::Node
f@0 46 {
f@0 47 public:
f@0 48 static const size_t kMaxVoices = 6;
f@0 49 static const int kNoMidiNote = -50;
f@0 50
f@0 51 explicit PGranularNode( ci::audio::Buffer *grainBuffer, CursorTriggerMsgRingBuffer &triggerRingBuffer );
f@0 52 ~PGranularNode();
f@0 53
f@3 54 /** Set selection size in samples */
f@0 55 void setSelectionSize( size_t size )
f@0 56 {
f@0 57 mSelectionSize.set( size );
f@0 58 }
f@0 59
f@3 60 /** Set selection start in samples */
f@0 61 void setSelectionStart( size_t start )
f@0 62 {
f@0 63 mSelectionStart.set( start );
f@0 64 }
f@0 65
f@0 66 void setGrainsDurationCoeff( double coeff )
f@0 67 {
f@0 68 mGrainDurationCoeff.set( coeff );
f@0 69 }
f@0 70
f@3 71 /* PGranularNode passes itself as trigger callback in PGranular */
f@0 72 void operator()( char msgType, int ID );
f@0 73
f@0 74 ci::audio::dsp::RingBufferT<NoteMsg>& getNoteRingBuffer() { return mNoteMsgRingBufferPack.getBuffer(); }
f@0 75
f@0 76 protected:
f@0 77
f@5 78 void initialize() override;
f@0 79
f@5 80 void process( ci::audio::Buffer *buffer ) override;
f@0 81
f@0 82 private:
f@0 83
f@3 84 // Wraps a std::atomic but get() returns a boost::optional that is set to a real value only when the atomic has changed.
f@16 85 // It is used to avoid calling PGranular setter methods with the same value at each audio callback.
f@0 86 template< typename T>
f@0 87 class LazyAtomic
f@0 88 {
f@0 89 public:
f@0 90 LazyAtomic( T val ) :
f@0 91 mAtomic( val ),
f@0 92 mPreviousVal( val )
f@0 93 {}
f@0 94
f@0 95 void set( T val )
f@0 96 {
f@0 97 mAtomic = val;
f@0 98 }
f@0 99
f@0 100 boost::optional<T> get()
f@0 101 {
f@0 102 const T val = mAtomic;
f@0 103 if ( val != mPreviousVal ){
f@0 104 mPreviousVal = val;
f@0 105 return val;
f@0 106 }
f@0 107 else{
f@0 108 return boost::none;
f@0 109 }
f@0 110 }
f@0 111
f@0 112 private:
f@0 113 std::atomic<T> mAtomic;
f@0 114 T mPreviousVal;
f@0 115 };
f@0 116
f@3 117 // creates or re-start a PGranular and sets the pitch according to the MIDI note passed as argument
f@0 118 void handleNoteMsg( const NoteMsg &msg );
f@0 119
f@3 120 // pointers to PGranular objects
f@0 121 std::unique_ptr < collidoscope::PGranular<float, RandomGenerator, PGranularNode > > mPGranularLoop;
f@0 122 std::array<std::unique_ptr < collidoscope::PGranular<float, RandomGenerator, PGranularNode > >, kMaxVoices> mPGranularNotes;
f@16 123 // maps midi notes to pgranulars. When a noteOff is received makes sure the right PGranular is turned off
f@0 124 std::array<int, kMaxVoices> mMidiNotes;
f@0 125
f@0 126 // pointer to the random generator struct passed over to PGranular
f@0 127 std::unique_ptr< RandomGenerator > mRandomOffset;
f@0 128
f@16 129 // buffer containing the recorded audio, to pass to PGranular in initialize()
f@0 130 ci::audio::Buffer *mGrainBuffer;
f@0 131
f@0 132 ci::audio::BufferRef mTempBuffer;
f@0 133
f@0 134 CursorTriggerMsgRingBuffer &mTriggerRingBuffer;
f@0 135 RingBufferPack<NoteMsg> mNoteMsgRingBufferPack;
f@0 136
f@0 137 LazyAtomic<size_t> mSelectionSize;
f@0 138
f@0 139 LazyAtomic<size_t> mSelectionStart;
f@0 140
f@0 141 LazyAtomic<double> mGrainDurationCoeff;
f@0 142
f@0 143
f@0 144 };
f@0 145