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 / Wave.h

History | View | Annotate | Download (7.01 KB)

1
/*
2

3
 Copyright (C) 2015  Fiore Martin
4
 Copyright (C) 2016  Queen Mary University of London 
5
 Author: Fiore Martin
6

7
 This file is part of Collidoscope.
8
 
9
 Collidoscope is free software: you can redistribute it and/or modify
10
 it under the terms of the GNU General Public License as published by
11
 the Free Software Foundation, either version 3 of the License, or
12
 (at your option) any later version.
13

14
 This program is distributed in the hope that it will be useful,
15
 but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
 GNU General Public License for more details.
18

19
 You should have received a copy of the GNU General Public License
20
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
21

22
*/
23
#pragma once
24

    
25

    
26
#include "cinder/app/App.h"
27
#include "cinder/gl/gl.h"
28
#include "cinder/gl/Batch.h"
29

    
30

    
31
#include "Chunk.h"
32
#include "DrawInfo.h"
33

    
34
#ifdef USE_PARTICLES
35
#include "ParticleController.h"
36
#endif 
37

    
38
#include "cinder/Color.h"
39
#include "cinder/PolyLine.h"
40
#include "cinder/Rand.h"
41

    
42
#include <vector>
43
#include <map>
44

    
45

    
46
class DrawInfo;
47
typedef int SynthID;
48

    
49

    
50
using ci::ivec2;
51
using ci::vec2;
52
using ci::Color;
53
using ci::ColorA;
54

    
55
/**
56
 * A Cursor is the white thingy that loops through the selection when Collidoscope is played.
57
 */ 
58
struct Cursor {
59
    static const int kNoPosition = -100;
60
    int pos;
61
    double lastUpdate;
62
};
63

    
64
/**
65
 * Collidoscope's graphical wave 
66
 *
67
 */ 
68
class Wave
69
{
70
    friend class ParticleController;
71

    
72
public:
73

    
74
    /**
75
     * The selection of the wave that is controlled by the big horizontal knob
76
     *
77
     */ 
78
    class Selection {
79
        
80
    public:
81

    
82
        Selection( Wave * w, Color color );
83
        
84
        /** Sets the start of selection. start is the index of the first chunk of the selection  */
85
        void setStart( size_t start );
86

    
87
        /** Sets the size of selection. size is the number of chunks the selection is made of */
88
        void setSize( size_t size );
89
        
90
        /** The particle spread parameter affects the size of the cloud of particles
91
         *  The cloud is the visual counterpart of the grain duration coefficient in sound.
92
         *  Indeed spread accepts values from 1 to 8, exactly as the duration coefficient
93
         */
94
        void inline setParticleSpread( float spread ){
95
            mParticleSpread = spread;
96
        }
97

    
98
        size_t getStart(void) const { return mSelectionStart; }
99
        
100
        size_t getEnd(void) const { return mSelectionEnd; }
101

    
102
        size_t inline getSize(void) const { 
103
            if (mNull)
104
                return 0;
105
            else
106
                return 1 + mSelectionEnd - mSelectionStart; 
107
        }
108

    
109
        float inline  getParticleSpread() const { return mParticleSpread; }
110

    
111
        /** When selection is null no selection is showed on the wave */
112
        inline void setToNull(){
113
            mParticleSpread = 1.0f;
114
            mNull = true;
115
        }
116

    
117
        inline bool isNull() const{
118
            return mNull;
119
        }
120

    
121
        inline const Color & getColor() const{
122
            return mColor;
123
        }
124

    
125
    private:
126

    
127
        size_t mSelectionStart;
128
        
129
        size_t mSelectionEnd;
130
        
131
        float mParticleSpread;
132

    
133
        bool mNull = true;
134

    
135
        Color mColor;
136

    
137
        Wave * mWave;
138

    
139
    }; // class Selection
140

    
141
    
142

    
143
#ifdef USE_PARTICLES
144
    ParticleController mParticleController;
145
#endif 
146

    
147
    
148

    
149
    /* Maps id of the synth to cursor. There is one cursor for each Synth being played */
150
    std::map < SynthID, Cursor > mCursors;
151
    /** Holds the positions of the cursor, namely on which chunk the cursor is currently on */
152
    std::vector<int> mCursorsPos;
153

    
154
public:
155
    
156
    // value used to identify the loop for cursor position 
157
    static const int kLoopNote = -1;
158
    static const cinder::Color CURSOR_CLR;
159
    static const int MAX_DURATION = 8;
160
#ifdef USE_PARTICLES
161
    static const int PARTICLESIZE_COEFF = 40;
162
#endif
163

    
164
    /** Resetting a wave makes it shrink until it disappears. Each time a new sample is recorded, the wave is reset.
165
     *  \param onlyChunks if false the selection is also set to null, if true only the chunks are reset
166
     */
167
    void reset(bool onlyChunks);
168

    
169
    /** sets top and bottom values for the chunk. 
170
     * \a bottom and \a top are in audio coordinates [-1.0, 1.0]
171
     */
172
    void setChunk(size_t index, float bottom, float top);
173

    
174
    const Chunk & getChunk(size_t index);
175

    
176
    /** Places the cursor on the wave. Every cursor is associated to a synth voice of the audio engine. 
177
     *  The synth id identifies uniquely the cursor in the internal map of the wave.
178
     *  If the cursor doesn't exist it is created */
179
    inline void setCursorPos( SynthID id, int pos, const DrawInfo& di ){
180

    
181
        Cursor & cursor = mCursors[id];
182
        cursor.pos = pos;
183
        cursor.lastUpdate = ci::app::getElapsedSeconds();
184

    
185
#ifdef USE_PARTICLES
186
        // The idea is that, if the duration is greater than 1.0, the cursor continues in form of particles.
187
        // The smaller the selection the more particles; the bigger the duration the more particles. 
188
        if (mSelection.getParticleSpread() > 1.0f){
189
            /* amountCoeff ranges from 1/8 to 1 */
190
            const float amountCoeff = (mSelection.getParticleSpread() / MAX_DURATION);
191
                
192
            /* get radom point within seleciton as center of the particle */
193
            vec2 centrePoint;
194
            const int randomChunkIndex = ci::Rand::randInt(mSelection.getStart(), mSelection.getEnd() );
195

    
196
            centrePoint.x = di.flipX( 1 + (randomChunkIndex * (2 + Chunk::kWidth)) + Chunk::kWidth / 2 );
197
            centrePoint.y = di.flipY( di.audioToHeigt(0.0) );
198

    
199
            const float wavePixelLen = mNumChunks * ( 2 + Chunk::kWidth);
200
            centrePoint.x *= float(di.getWindowWidth()) / wavePixelLen;
201

    
202
            mParticleController.addParticles(
203
                std::max( 1, (int)(amountCoeff * ParticleController::kMaxParticleAdd * mFilterCoeff) ), // amount of particles to add 
204
                centrePoint,
205
                mSelection.getParticleSpread() * PARTICLESIZE_COEFF   // size of the cloud 
206
                );
207
        }
208
#endif
209

    
210
        
211
    }
212

    
213
    void update( double secondsPerChunk, const DrawInfo& di );
214

    
215
    void removeCursor( SynthID id ) { mCursors.erase( id ); }
216

    
217
    /** Sets the transparency of this wave. \a alpha ranges from 0 to 1 */
218
    inline void setselectionAlpha(float alpha){ mFilterCoeff = alpha;}
219

    
220
    void draw( const DrawInfo& di );
221

    
222
    Selection& getSelection() { return mSelection; };
223

    
224
    size_t getSize() const{ return mChunks.size();  }
225

    
226
    void setScopePoint(int index, float audioVal);
227

    
228
    Wave( size_t numChunks, Color selectionColor );
229

    
230
    /** no copies */
231
    Wave( const Wave &copy ) = delete;
232
    Wave & operator=(const Wave &copy) = delete;
233

    
234

    
235
private:
236
    
237
    const size_t mNumChunks;
238

    
239
    std::vector<Chunk> mChunks;
240
    
241
    Selection mSelection;
242

    
243
    cinder::Color mColor;
244

    
245
    // How much filter is applied in audio. It affects the alpha value of the selection color.
246
    float mFilterCoeff;
247

    
248
    // cinder gl batch for batch drawing 
249
    ci::gl::BatchRef mChunkBatch;
250

    
251
};
252