/* * Author: Harry van Haaren 2013 * harryhaaren@gmail.com * * This program 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 . */ #ifndef LOOPP_LOOPER_CLIP_H #define LOOPP_LOOPER_CLIP_H #include #include "state/stately.hxx" #include "config.hxx" #include "gridlogic.hxx" class AudioBuffer; /** LooperClip * Represents each clip that a looper can playback. The core of the audio * samples is stored in AudioBuffer objects which are dynamically resized. The * base size of a AudioBuffer is 1 second's worth, after which larger buffers * will be requested. * The transition between AudioBuffer instances is seamless: when the clip is * running out, the new one is requested. Upon its arrival the current data is * copied, and the old buffer is returned for deallocation. * * This system allows for arbitrary length recordings, without huge * pre-allocated buffers while it is still quite simple. * * Each clip has its properties like length and bars/beats, so the Looper knows * to dynamically stretch / process the audio appropriately. Controllers and the * UI are updated from this data. * * This class inherits from Stately to save its state. **/ class LooperClip : public Stately, public TimeObserver { public: LooperClip(int track, int scene); /// Set everything up void init(); /// loads a sample: eg from disk, unloading current sample if necessary void load( AudioBuffer* ab ); /// Return one Sample according to current playSpeed void getSample(long double playSpeed, float* L, float* R); /// Record $count Samples into internal Buffer void record(int count, float* L, float* R); /// TimeObserver override void bar(); void beat(); /// Start process of saving the clip void save(); /// Reset the clip to initial state void reset(); /// analyses current _playing _recording vars, returns the current State GridLogic::State getState(); bool playing(); bool getLoaded(); bool getQueueStop(); bool getQueuePlay(); bool recording(); /// Get number of Beats in the Buffer int getBeats(); /// Get playback progress float getProgress(); /// Get position of the playhead float getPlayhead(); /// Return the length of the complete buffer long getBufferLenght(); /// Return the nr of samples holding actual audio. This is less then getBufferLength(); long getActualAudioLength(); /// Return Size of the Buffer size_t audioBufferSize(); int getRecFpb() { return _recFpb; }; /// Queue Play void queuePlay(); /// Queue Stop void queueStop(); /// Queue Record void queueRecord(); // removes all queued States void resetQueues(); // returns true if any state is queued bool somethingQueued(); /// set buffer state void setBeats(int beats); /** used to update the size of the buffer for this looperclip. The current * data is copied into the new buffer, then the smaller buffer is sent * for de-allocation. **/ void setRequestedBuffer( AudioBuffer* ab ); /// used for saving the contents of this buffer to disk void recieveSaveBuffer( AudioBuffer* ab ); /// reset the play head to zero. Does nothing when recording void resetPlayHead(); /// Change State to Recording void setRecording(); /// Change State to Playing void setPlaying(); void processFreeRec(); #ifdef BUILD_TESTS // used only in test cases void setState( bool load, bool play, bool rec, bool qPlay, bool qStop, bool qRec ); #endif private: int track, scene; /** Loopp needs more than the current state of the clip to accuratly handle * it. The current state of the grid is kept up-to-date by GridLogic * abstracting detail away, sending GridLogic::State to Controllers. **/ bool _loaded; bool _playing; bool _recording; bool _queuePlay; bool _queueStop; bool _queueRecord; bool _newBufferInTransit; long double _playhead; float _recordhead; int _recFpb; long double _playbackSpeed; long double _nextPlaybackSpeed; bool _playbackSpeedChange; unsigned int _beatsPlayed; unsigned int _barsPlayed; unsigned int _barsRecorded; AudioBuffer *_buffer; /// Request new internal Buffer void requestNewBuffer(); /// Get if a new internal Buffer is on the way bool newBufferInTransit(); /// Get available Space to record unsigned long recordSpaceAvailable(); /// Change State to Stopped void setStopped(); }; #endif // LOOPP_LOOPER_CLIP_H