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 @ 0:02467299402e

History | View | Annotate | Download (2.83 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
    // set selection size in samples
34
    void setSelectionSize( size_t size )
35
    {
36
        mSelectionSize.set( size );
37
    }
38
39
    void setSelectionStart( size_t start )
40
    {
41
        mSelectionStart.set( start );
42
    }
43
44
    void setGrainsDurationCoeff( double coeff )
45
    {
46
        mGrainDurationCoeff.set( coeff );
47
    }
48
49
    // used for trigger callback in PGRanular
50
    void operator()( char msgType, int ID );
51
52
    ci::audio::dsp::RingBufferT<NoteMsg>& getNoteRingBuffer() { return mNoteMsgRingBufferPack.getBuffer(); }
53
54
protected:
55
56
    void initialize()                                                        override;
57
58
    void process( ci::audio::Buffer *buffer )        override;
59
60
private:
61
62
    template< typename T>
63
    class LazyAtomic
64
    {
65
    public:
66
        LazyAtomic( T val ) :
67
            mAtomic( val ),
68
            mPreviousVal( val )
69
        {}
70
71
        void set( T val )
72
        {
73
            mAtomic = val;
74
        }
75
76
        boost::optional<T> get()
77
        {
78
            const T val = mAtomic;
79
            if ( val != mPreviousVal ){
80
                mPreviousVal = val;
81
                return val;
82
            }
83
            else{
84
                return boost::none;
85
            }
86
        }
87
88
    private:
89
        std::atomic<T> mAtomic;
90
        T mPreviousVal;
91
    };
92
93
    void handleNoteMsg( const NoteMsg &msg );
94
95
    // pointer to PGranular object
96
    std::unique_ptr < collidoscope::PGranular<float, RandomGenerator, PGranularNode > > mPGranularLoop;
97
    std::array<std::unique_ptr < collidoscope::PGranular<float, RandomGenerator, PGranularNode > >, kMaxVoices> mPGranularNotes;
98
    std::array<int, kMaxVoices> mMidiNotes;
99
100
    // pointer to the random generator struct passed over to PGranular
101
    std::unique_ptr< RandomGenerator > mRandomOffset;
102
103
    /* buffer containing the recorder audio, to pass to PGranular in initialize() */
104
    ci::audio::Buffer *mGrainBuffer;
105
106
    ci::audio::BufferRef mTempBuffer;
107
108
    CursorTriggerMsgRingBuffer &mTriggerRingBuffer;
109
    RingBufferPack<NoteMsg> mNoteMsgRingBufferPack;
110
111
    LazyAtomic<size_t> mSelectionSize;
112
113
    LazyAtomic<size_t> mSelectionStart;
114
115
    LazyAtomic<double> mGrainDurationCoeff;
116
117
118
};