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 @ 2:dd889fff8423

History | View | Annotate | Download (2.83 KB)

1
#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
};
119