To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

Statistics Download as Zip
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (3.34 KB)

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