1 /* 2 * Author: Harry van Haaren 2013 3 * harryhaaren@gmail.com 4 * 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, either version 3 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 #ifndef LUPPP_LOOPER_CLIP_H 20 #define LUPPP_LOOPER_CLIP_H 21 22 #include <stdio.h> 23 #include "state/stately.hxx" 24 #include "config.hxx" 25 #include "gridlogic.hxx" 26 27 class AudioBuffer; 28 29 /** LooperClip 30 * Represents each clip that a looper can playback. The core of the audio 31 * samples is stored in AudioBuffer objects which are dynamically resized. The 32 * base size of a AudioBuffer is 1 second's worth, after which larger buffers 33 * will be requested. 34 * The transition between AudioBuffer instances is seamless: when the clip is 35 * running out, the new one is requested. Upon its arrival the current data is 36 * copied, and the old buffer is returned for deallocation. 37 * 38 * This system allows for arbitrary length recordings, without huge 39 * pre-allocated buffers while it is still quite simple. 40 * 41 * Each clip has its properties like length and bars/beats, so the Looper knows 42 * to dynamically stretch / process the audio appropriately. Controllers and the 43 * UI are updated from this data. 44 * 45 * This class inherits from SaveAble to save its state. 46 **/ 47 class LooperClip : public Stately 48 { 49 public: 50 LooperClip(int track, int scene); 51 52 void init(); 53 54 /// loads a sample: eg from disk, unloading current sample if necessary 55 void load( AudioBuffer* ab ); 56 57 /// audio functionality 58 void getSample(long double playSpeed, float* L, float* R); 59 void record(int count, float* L, float* R); 60 61 /// TimeObserver override 62 void bar(); 63 64 /// SaveAble overrides 65 void save(); 66 void reset(); 67 68 /// analyses current _playing _recording vars, returns the current State 69 GridLogic::State getState(); 70 bool playing(); 71 bool getLoaded(); 72 bool getQueueStop(); 73 bool getQueuePlay(); 74 bool recording(); 75 76 /// get buffer details 77 int getBeats(); 78 float getProgress(); 79 float getPlayhead(); 80 //Return the length of the complete buffer 81 long getBufferLenght(); 82 //Return the nr of samples holding actual audio. This is less then getBufferLength(); 83 long getActualAudioLength(); 84 size_t audioBufferSize(); 85 getAudioBuffer()86 AudioBuffer* getAudioBuffer() 87 { 88 return _buffer; 89 } 90 91 /// set clip state 92 void queuePlay(bool=true); 93 void queueStop(); 94 void queueRecord(); 95 96 void neutralize(); // removes all play || record states if on 97 bool somethingQueued(); // returns true if any state is queued 98 99 /// set buffer state 100 void setBeats(int beats); 101 102 /// Luppp internal buffer resizing 103 void newBufferInTransit(bool n); 104 bool newBufferInTransit(); 105 unsigned long recordSpaceAvailable(); 106 107 /** used to update the size of the buffer for this looperclip. The current 108 * data is copied into the new buffer, then the smaller buffer is sent 109 * for de-allocation. 110 **/ 111 void setRequestedBuffer( AudioBuffer* ab ); 112 113 /// used for saving the contents of this buffer to disk 114 void recieveSaveBuffer( AudioBuffer* ab ); 115 116 ///reset the play head to zero. Does nothing when recording 117 void setPlayHead(float ph); 118 119 #ifdef BUILD_TESTS 120 // used only in test cases 121 void setState( bool load, bool play, bool rec, bool qPlay, bool qStop, bool qRec ); 122 #endif 123 124 private: 125 int track, scene; 126 127 /** Luppp needs more than the current state of the clip to accuratly handle 128 * it. The current state of the grid is kept up-to-date by GridLogic 129 * abstracting detail away, sending GridLogic::State to Controllers. 130 **/ 131 bool _loaded; 132 bool _playing; 133 bool _recording; 134 135 bool _queuePlay; 136 bool _queueStop; 137 bool _queueRecord; 138 139 bool _newBufferInTransit; 140 141 long double _playhead; 142 float _recordhead; 143 144 unsigned int _barsPlayed; 145 AudioBuffer* _buffer; 146 }; 147 148 #endif // LUPPP_LOOPER_CLIP_H 149 150