Mercurial > hg > opencollidoscope
view CollidoscopeApp/include/Wave.h @ 16:4dad0b810f18
Comment tidy up + attributions
author | Fiore Martin <f.martin@qmul.ac.uk> |
---|---|
date | Tue, 16 Aug 2016 14:27:53 +0100 |
parents | a4a336624f5a |
children |
line wrap: on
line source
/* Copyright (C) 2015 Fiore Martin Copyright (C) 2016 Queen Mary University of London Author: Fiore Martin This file is part of Collidoscope. Collidoscope is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ #pragma once #include "cinder/app/App.h" #include "cinder/gl/gl.h" #include "cinder/gl/Batch.h" #include "Chunk.h" #include "DrawInfo.h" #ifdef USE_PARTICLES #include "ParticleController.h" #endif #include "cinder/Color.h" #include "cinder/PolyLine.h" #include "cinder/Rand.h" #include <vector> #include <map> class DrawInfo; typedef int SynthID; using ci::ivec2; using ci::vec2; using ci::Color; using ci::ColorA; /** * A Cursor is the white thingy that loops through the selection when Collidoscope is played. */ struct Cursor { static const int kNoPosition = -100; int pos; double lastUpdate; }; /** * Collidoscope's graphical wave * */ class Wave { friend class ParticleController; public: /** * The selection of the wave that is controlled by the big horizontal knob * */ class Selection { public: Selection( Wave * w, Color color ); /** Sets the start of selection. start is the index of the first chunk of the selection */ void setStart( size_t start ); /** Sets the size of selection. size is the number of chunks the selection is made of */ void setSize( size_t size ); /** The particle spread parameter affects the size of the cloud of particles * The cloud is the visual counterpart of the grain duration coefficient in sound. * Indeed spread accepts values from 1 to 8, exactly as the duration coefficient */ void inline setParticleSpread( float spread ){ mParticleSpread = spread; } size_t getStart(void) const { return mSelectionStart; } size_t getEnd(void) const { return mSelectionEnd; } size_t inline getSize(void) const { if (mNull) return 0; else return 1 + mSelectionEnd - mSelectionStart; } float inline getParticleSpread() const { return mParticleSpread; } /** When selection is null no selection is showed on the wave */ inline void setToNull(){ mParticleSpread = 1.0f; mNull = true; } inline bool isNull() const{ return mNull; } inline const Color & getColor() const{ return mColor; } private: size_t mSelectionStart; size_t mSelectionEnd; float mParticleSpread; bool mNull = true; Color mColor; Wave * mWave; }; // class Selection #ifdef USE_PARTICLES ParticleController mParticleController; #endif /* Maps id of the synth to cursor. There is one cursor for each Synth being played */ std::map < SynthID, Cursor > mCursors; /** Holds the positions of the cursor, namely on which chunk the cursor is currently on */ std::vector<int> mCursorsPos; public: // value used to identify the loop for cursor position static const int kLoopNote = -1; static const cinder::Color CURSOR_CLR; static const int MAX_DURATION = 8; #ifdef USE_PARTICLES static const int PARTICLESIZE_COEFF = 40; #endif /** Resetting a wave makes it shrink until it disappears. Each time a new sample is recorded, the wave is reset. * \param onlyChunks if false the selection is also set to null, if true only the chunks are reset */ void reset(bool onlyChunks); /** sets top and bottom values for the chunk. * \a bottom and \a top are in audio coordinates [-1.0, 1.0] */ void setChunk(size_t index, float bottom, float top); const Chunk & getChunk(size_t index); /** Places the cursor on the wave. Every cursor is associated to a synth voice of the audio engine. * The synth id identifies uniquely the cursor in the internal map of the wave. * If the cursor doesn't exist it is created */ inline void setCursorPos( SynthID id, int pos, const DrawInfo& di ){ Cursor & cursor = mCursors[id]; cursor.pos = pos; cursor.lastUpdate = ci::app::getElapsedSeconds(); #ifdef USE_PARTICLES // The idea is that, if the duration is greater than 1.0, the cursor continues in form of particles. // The smaller the selection the more particles; the bigger the duration the more particles. if (mSelection.getParticleSpread() > 1.0f){ /* amountCoeff ranges from 1/8 to 1 */ const float amountCoeff = (mSelection.getParticleSpread() / MAX_DURATION); /* get radom point within seleciton as center of the particle */ vec2 centrePoint; const int randomChunkIndex = ci::Rand::randInt(mSelection.getStart(), mSelection.getEnd() ); centrePoint.x = di.flipX( 1 + (randomChunkIndex * (2 + Chunk::kWidth)) + Chunk::kWidth / 2 ); centrePoint.y = di.flipY( di.audioToHeigt(0.0) ); const float wavePixelLen = mNumChunks * ( 2 + Chunk::kWidth); centrePoint.x *= float(di.getWindowWidth()) / wavePixelLen; mParticleController.addParticles( std::max( 1, (int)(amountCoeff * ParticleController::kMaxParticleAdd * mFilterCoeff) ), // amount of particles to add centrePoint, mSelection.getParticleSpread() * PARTICLESIZE_COEFF // size of the cloud ); } #endif } void update( double secondsPerChunk, const DrawInfo& di ); void removeCursor( SynthID id ) { mCursors.erase( id ); } /** Sets the transparency of this wave. \a alpha ranges from 0 to 1 */ inline void setselectionAlpha(float alpha){ mFilterCoeff = alpha;} void draw( const DrawInfo& di ); Selection& getSelection() { return mSelection; }; size_t getSize() const{ return mChunks.size(); } void setScopePoint(int index, float audioVal); Wave( size_t numChunks, Color selectionColor ); /** no copies */ Wave( const Wave © ) = delete; Wave & operator=(const Wave ©) = delete; private: const size_t mNumChunks; std::vector<Chunk> mChunks; Selection mSelection; cinder::Color mColor; // How much filter is applied in audio. It affects the alpha value of the selection color. float mFilterCoeff; // cinder gl batch for batch drawing ci::gl::BatchRef mChunkBatch; };