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 / src / Wave.cpp @ 4:ab6db404403a

History | View | Annotate | Download (5.69 KB)

1 0:02467299402e f
#include "Wave.h"
2
#include "DrawInfo.h"
3
4
5
using namespace ci;
6
7
Wave::Wave( size_t numChunks, Color selectionColor ):
8
    mNumChunks( numChunks ),
9
        mSelection( this, selectionColor ),
10
        mColor(Color(0.5f, 0.5f, 0.5f)),
11
    mFilterCoeff( 1.0f )
12
{
13
        mChunks.reserve( numChunks );
14
15
        for ( size_t i = 0; i < numChunks; i++ ){
16
                mChunks.emplace_back( i );
17
        }
18
19 4:ab6db404403a f
    // init cinder batch drawing
20 0:02467299402e f
    auto lambert = gl::ShaderDef().color();
21
    gl::GlslProgRef shader = gl::getStockShader( lambert );
22
    mChunkBatch = gl::Batch::create( geom::Rect( ci::Rectf( 0, 0, Chunk::kWidth, 1 ) ), shader );
23
}
24
25
void Wave::reset( bool onlyChunks )
26
{
27
        for (size_t i = 0; i < getSize(); i++){
28
                mChunks[i].reset();
29
        }
30
31
        if (onlyChunks)
32
                return;
33
34
        mSelection.setToNull();
35
}
36
37
38
void Wave::setChunk(size_t index, float bottom, float top)
39
{
40
        Chunk &c = mChunks[index];
41
        c.setTop(top);
42
        c.setBottom(bottom);
43
}
44
45
inline const Chunk & Wave::getChunk(size_t index)
46
{
47
        return mChunks[index];
48
}
49
50
void Wave::update( double secondsPerChunk, const DrawInfo& di ) {
51
    typedef std::map<int, Cursor>::iterator MapItr;
52
53
54
    // update the cursor positions
55
    double now = ci::app::getElapsedSeconds();
56
    for (MapItr itr = mCursors.begin(); itr != mCursors.end(); ++itr){
57
        if (mSelection.isNull()){
58
            itr->second.pos = Cursor::kNoPosition;
59
        }
60
61
        if ( itr->second.pos == Cursor::kNoPosition )
62
            continue;
63
64
65
        double elapsed = now - itr->second.lastUpdate;
66
67 4:ab6db404403a f
        // A chunk of audio corresponds to a certain time according to sample rate.
68
        // Use elapsed time to advance through chunks so that the cursor is animated
69
        // and goes from start to end of the seleciton in the time span of the grain
70 0:02467299402e f
        itr->second.pos = mSelection.getStart() + int( elapsed / secondsPerChunk );
71
72 4:ab6db404403a f
        // check we don't go too far off
73 0:02467299402e f
        if (itr->second.pos > mSelection.getEnd()){
74
            itr->second.pos = Cursor::kNoPosition;
75
        }
76
    }
77
78
    // update chunks for animation
79
    for ( auto &chunk : mChunks ){
80
        chunk.update( di );
81
    }
82
83
#ifdef USE_PARTICLES
84
    mParticleController.updateParticles();
85
#endif
86
87
}
88
89
void Wave::draw( const DrawInfo& di ){
90
91
92
        /* ########### draw the particles ########## */
93
#ifdef USE_PARTICLES
94
        mParticleController.draw();
95
#endif
96
97
        /* ########### draw the wave ########## */
98
        /* scale the wave to fit the window */
99
        gl::pushModelView();
100
101
102
        const float wavePixelLen =  ( mNumChunks * ( 2 + Chunk::kWidth ) );
103 3:7fb593d53361 f
        /* scale the x-axis for the wave to fit the window precisely */
104 0:02467299402e f
        gl::scale( ((float)di.getWindowWidth() ) / wavePixelLen , 1.0f);
105
        /* draw the chunks */
106
        if (mSelection.isNull()){
107
                /* no selection: all chunks the same color */
108
                gl::color(mColor);
109
                for (size_t i = 0; i < getSize(); i++){
110
                        mChunks[i].draw( di, mChunkBatch );
111
                }
112
        }
113
    else{
114
        // Selection not null
115
                gl::color(this->mColor);
116
117
        // update the array with cursor positions
118
        mCursorsPos.clear();
119
        for ( auto cursor : mCursors ){
120
            mCursorsPos.push_back( cursor.second.pos );
121
        }
122
123
                gl::enableAlphaBlending();
124
125
                const float selectionAlpha = 0.5f + mFilterCoeff * 0.5f;
126
127
128
                for (size_t i = 0; i < getSize(); i++){
129
                        /* when in selection use selection color */
130
131
                        if (i == mSelection.getStart()){
132
                                /* draw the selection bar with a transparent selection color */
133
                                gl::color(mSelection.getColor().r, mSelection.getColor().g, mSelection.getColor().b, 0.5f);
134
                mChunks[i].drawBar( di, mChunkBatch );
135
136
                                /* set the color to the selection */
137
                                gl::color(mSelection.getColor().r, mSelection.getColor().g, mSelection.getColor().b, selectionAlpha);
138
                        }
139
140
            // check if one of the cursors is positioned in this chunk
141
                        if (std::find(mCursorsPos.begin(), mCursorsPos.end(),i) != mCursorsPos.end() ){
142
                                gl::color(CURSOR_CLR);
143
                                mChunks[i].draw( di, mChunkBatch );
144
                                gl::color(mSelection.getColor().r, mSelection.getColor().g, mSelection.getColor().b, selectionAlpha);
145
                        }
146
                        else{
147
                                /* just draw with current color */
148
                                mChunks[i].draw( di, mChunkBatch );
149
                        }
150
151
                        /* exit selection: go back to wave color */
152
                        if (i == mSelection.getEnd()){
153
                                /* draw the selection bar with a transparent selection color */
154
                                gl::color(mSelection.getColor().r, mSelection.getColor().g, mSelection.getColor().b, 0.5f);
155
                mChunks[i].drawBar( di, mChunkBatch );
156
                                /* set the colo to the wave */
157
                                gl::color(this->mColor);
158
                        }
159
                }
160
                gl::disableAlphaBlending();
161
        }
162
163
164
        gl::popModelView();
165
166
}
167
168
169
170
//**************** Selection ***************//
171
172
Wave::Selection::Selection(Wave * w, Color color) :
173
    mWave( w ),
174
    mSelectionStart( 0 ),
175
    mSelectionEnd( 0 ),
176
    mColor( color ),
177
    mParticleSpread( 1 )
178
{}
179
180
181
void Wave::Selection::setStart(size_t start)  {
182
183
        /* deselect the previous */
184
    mWave->mChunks[mSelectionStart].setAsSelectionStart( false );
185
        /* select the next */
186
    mWave->mChunks[start].setAsSelectionStart( true );
187
188
        mNull = false;
189
190
    size_t size = getSize();
191
192
        mSelectionStart = start;
193
    mSelectionEnd = start + size - 1;
194
    if ( mSelectionEnd > mWave->getSize() - 1 )
195
        mSelectionEnd = mWave->getSize() - 1;
196
197
}
198
199
void Wave::Selection::setSize(size_t size)  {
200
201
    if ( size <= 0 ){
202
        mNull = true;
203
        return;
204
    }
205
206
    size -= 1;
207
208
    // check boundaries: size cannot bring the selection end beyond the end of the wave
209
    if ( mSelectionStart+size >= mWave->mNumChunks ){
210
        size = mWave->mNumChunks - mSelectionStart - 1;
211
    }
212
213
        /* deselect the previous */
214
    mWave->mChunks[mSelectionEnd].setAsSelectionEnd( false );
215
216
    mSelectionEnd = mSelectionStart + size;
217
        /* select the next */
218
    mWave->mChunks[mSelectionEnd].setAsSelectionEnd( true );
219
220
        mNull = false;
221
}
222
223
224
const cinder::Color Wave::CURSOR_CLR = Color(1.f, 1.f, 1.f);
225