annotate CollidoscopeApp/include/Wave.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) 2015 Fiore Martin
f@5 4 Copyright (C) 2016 Queen Mary University of London
f@5 5 Author: Fiore Martin
f@5 6
f@5 7 This file is part of Collidoscope.
f@5 8
f@5 9 Collidoscope is free software: you can redistribute it and/or modify
f@5 10 it under the terms of the GNU General Public License as published by
f@5 11 the Free Software Foundation, either version 3 of the License, or
f@5 12 (at your option) any later version.
f@5 13
f@5 14 This program is distributed in the hope that it will be useful,
f@5 15 but WITHOUT ANY WARRANTY; without even the implied warranty of
f@5 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
f@5 17 GNU General Public License for more details.
f@5 18
f@5 19 You should have received a copy of the GNU General Public License
f@5 20 along with this program. If not, see <http://www.gnu.org/licenses/>.
f@5 21
f@5 22 */
f@0 23 #pragma once
f@0 24
f@0 25
f@0 26 #include "cinder/app/App.h"
f@0 27 #include "cinder/gl/gl.h"
f@0 28 #include "cinder/gl/Batch.h"
f@0 29
f@0 30
f@0 31 #include "Chunk.h"
f@0 32 #include "DrawInfo.h"
f@0 33
f@0 34 #ifdef USE_PARTICLES
f@0 35 #include "ParticleController.h"
f@0 36 #endif
f@0 37
f@0 38 #include "cinder/Color.h"
f@0 39 #include "cinder/PolyLine.h"
f@0 40 #include "cinder/Rand.h"
f@0 41
f@0 42 #include <vector>
f@0 43 #include <map>
f@0 44
f@0 45
f@0 46 class DrawInfo;
f@0 47 typedef int SynthID;
f@0 48
f@0 49
f@0 50 using ci::ivec2;
f@0 51 using ci::vec2;
f@0 52 using ci::Color;
f@0 53 using ci::ColorA;
f@0 54
f@3 55 /**
f@3 56 * A Cursor is the white thingy that loops through the selection when Collidoscope is played.
f@3 57 */
f@0 58 struct Cursor {
f@0 59 static const int kNoPosition = -100;
f@0 60 int pos;
f@0 61 double lastUpdate;
f@0 62 };
f@0 63
f@3 64 /**
f@3 65 * Collidoscope's graphical wave
f@3 66 *
f@3 67 */
f@0 68 class Wave
f@0 69 {
f@5 70 friend class ParticleController;
f@0 71
f@0 72 public:
f@0 73
f@3 74 /**
f@3 75 * The selection of the wave that is controlled by the big horizontal knob
f@3 76 *
f@3 77 */
f@5 78 class Selection {
f@5 79
f@5 80 public:
f@0 81
f@0 82 Selection( Wave * w, Color color );
f@0 83
f@3 84 /** Sets the start of selection. start is the index of the first chunk of the selection */
f@0 85 void setStart( size_t start );
f@0 86
f@3 87 /** Sets the size of selection. size is the number of chunks the selection is made of */
f@5 88 void setSize( size_t size );
f@5 89
f@7 90 /** The particle spread parameter affects the size of the cloud of particles
f@16 91 * The cloud is the visual counterpart of the grain duration coefficient in sound.
f@7 92 * Indeed spread accepts values from 1 to 8, exactly as the duration coefficient
f@7 93 */
f@0 94 void inline setParticleSpread( float spread ){
f@0 95 mParticleSpread = spread;
f@5 96 }
f@0 97
f@5 98 size_t getStart(void) const { return mSelectionStart; }
f@5 99
f@0 100 size_t getEnd(void) const { return mSelectionEnd; }
f@0 101
f@5 102 size_t inline getSize(void) const {
f@5 103 if (mNull)
f@5 104 return 0;
f@5 105 else
f@5 106 return 1 + mSelectionEnd - mSelectionStart;
f@5 107 }
f@0 108
f@5 109 float inline getParticleSpread() const { return mParticleSpread; }
f@0 110
f@3 111 /** When selection is null no selection is showed on the wave */
f@5 112 inline void setToNull(){
f@0 113 mParticleSpread = 1.0f;
f@5 114 mNull = true;
f@5 115 }
f@0 116
f@5 117 inline bool isNull() const{
f@5 118 return mNull;
f@5 119 }
f@0 120
f@5 121 inline const Color & getColor() const{
f@5 122 return mColor;
f@5 123 }
f@0 124
f@0 125 private:
f@0 126
f@0 127 size_t mSelectionStart;
f@0 128
f@0 129 size_t mSelectionEnd;
f@0 130
f@0 131 float mParticleSpread;
f@0 132
f@0 133 bool mNull = true;
f@0 134
f@0 135 Color mColor;
f@0 136
f@0 137 Wave * mWave;
f@0 138
f@5 139 }; // class Selection
f@0 140
f@5 141
f@0 142
f@0 143 #ifdef USE_PARTICLES
f@5 144 ParticleController mParticleController;
f@0 145 #endif
f@0 146
f@5 147
f@0 148
f@5 149 /* Maps id of the synth to cursor. There is one cursor for each Synth being played */
f@5 150 std::map < SynthID, Cursor > mCursors;
f@16 151 /** Holds the positions of the cursor, namely on which chunk the cursor is currently on */
f@5 152 std::vector<int> mCursorsPos;
f@0 153
f@0 154 public:
f@5 155
f@3 156 // value used to identify the loop for cursor position
f@0 157 static const int kLoopNote = -1;
f@5 158 static const cinder::Color CURSOR_CLR;
f@5 159 static const int MAX_DURATION = 8;
f@0 160 #ifdef USE_PARTICLES
f@5 161 static const int PARTICLESIZE_COEFF = 40;
f@0 162 #endif
f@0 163
f@16 164 /** Resetting a wave makes it shrink until it disappears. Each time a new sample is recorded, the wave is reset.
f@3 165 * \param onlyChunks if false the selection is also set to null, if true only the chunks are reset
f@3 166 */
f@5 167 void reset(bool onlyChunks);
f@0 168
f@3 169 /** sets top and bottom values for the chunk.
f@3 170 * \a bottom and \a top are in audio coordinates [-1.0, 1.0]
f@3 171 */
f@5 172 void setChunk(size_t index, float bottom, float top);
f@0 173
f@5 174 const Chunk & getChunk(size_t index);
f@0 175
f@16 176 /** Places the cursor on the wave. Every cursor is associated to a synth voice of the audio engine.
f@3 177 * The synth id identifies uniquely the cursor in the internal map of the wave.
f@3 178 * If the cursor doesn't exist it is created */
f@0 179 inline void setCursorPos( SynthID id, int pos, const DrawInfo& di ){
f@0 180
f@5 181 Cursor & cursor = mCursors[id];
f@5 182 cursor.pos = pos;
f@5 183 cursor.lastUpdate = ci::app::getElapsedSeconds();
f@0 184
f@0 185 #ifdef USE_PARTICLES
f@16 186 // The idea is that, if the duration is greater than 1.0, the cursor continues in form of particles.
f@16 187 // The smaller the selection the more particles; the bigger the duration the more particles.
f@5 188 if (mSelection.getParticleSpread() > 1.0f){
f@5 189 /* amountCoeff ranges from 1/8 to 1 */
f@0 190 const float amountCoeff = (mSelection.getParticleSpread() / MAX_DURATION);
f@0 191
f@0 192 /* get radom point within seleciton as center of the particle */
f@16 193 vec2 centrePoint;
f@0 194 const int randomChunkIndex = ci::Rand::randInt(mSelection.getStart(), mSelection.getEnd() );
f@0 195
f@0 196 centrePoint.x = di.flipX( 1 + (randomChunkIndex * (2 + Chunk::kWidth)) + Chunk::kWidth / 2 );
f@0 197 centrePoint.y = di.flipY( di.audioToHeigt(0.0) );
f@0 198
f@0 199 const float wavePixelLen = mNumChunks * ( 2 + Chunk::kWidth);
f@5 200 centrePoint.x *= float(di.getWindowWidth()) / wavePixelLen;
f@0 201
f@5 202 mParticleController.addParticles(
f@0 203 std::max( 1, (int)(amountCoeff * ParticleController::kMaxParticleAdd * mFilterCoeff) ), // amount of particles to add
f@5 204 centrePoint,
f@0 205 mSelection.getParticleSpread() * PARTICLESIZE_COEFF // size of the cloud
f@5 206 );
f@5 207 }
f@0 208 #endif
f@0 209
f@5 210
f@5 211 }
f@0 212
f@0 213 void update( double secondsPerChunk, const DrawInfo& di );
f@0 214
f@0 215 void removeCursor( SynthID id ) { mCursors.erase( id ); }
f@0 216
f@3 217 /** Sets the transparency of this wave. \a alpha ranges from 0 to 1 */
f@5 218 inline void setselectionAlpha(float alpha){ mFilterCoeff = alpha;}
f@0 219
f@0 220 void draw( const DrawInfo& di );
f@0 221
f@5 222 Selection& getSelection() { return mSelection; };
f@0 223
f@5 224 size_t getSize() const{ return mChunks.size(); }
f@0 225
f@5 226 void setScopePoint(int index, float audioVal);
f@0 227
f@0 228 Wave( size_t numChunks, Color selectionColor );
f@0 229
f@3 230 /** no copies */
f@0 231 Wave( const Wave &copy ) = delete;
f@0 232 Wave & operator=(const Wave &copy) = delete;
f@0 233
f@0 234
f@0 235 private:
f@0 236
f@0 237 const size_t mNumChunks;
f@0 238
f@0 239 std::vector<Chunk> mChunks;
f@0 240
f@0 241 Selection mSelection;
f@0 242
f@0 243 cinder::Color mColor;
f@0 244
f@16 245 // How much filter is applied in audio. It affects the alpha value of the selection color.
f@0 246 float mFilterCoeff;
f@0 247
f@3 248 // cinder gl batch for batch drawing
f@0 249 ci::gl::BatchRef mChunkBatch;
f@0 250
f@0 251 };
f@0 252