michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: /// michael@0: /// A buffer class for temporarily storaging sound samples, operates as a michael@0: /// first-in-first-out pipe. michael@0: /// michael@0: /// Samples are added to the end of the sample buffer with the 'putSamples' michael@0: /// function, and are received from the beginning of the buffer by calling michael@0: /// the 'receiveSamples' function. The class automatically removes the michael@0: /// output samples from the buffer as well as grows the storage size michael@0: /// whenever necessary. michael@0: /// michael@0: /// Author : Copyright (c) Olli Parviainen michael@0: /// Author e-mail : oparviai 'at' iki.fi michael@0: /// SoundTouch WWW: http://www.surina.net/soundtouch michael@0: /// michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: // michael@0: // Last changed : $Date: 2014-01-05 15:40:22 -0600 (Sun, 05 Jan 2014) $ michael@0: // File revision : $Revision: 4 $ michael@0: // michael@0: // $Id: FIFOSampleBuffer.h 177 2014-01-05 21:40:22Z oparviai $ michael@0: // michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: // michael@0: // License : michael@0: // michael@0: // SoundTouch audio processing library michael@0: // Copyright (c) Olli Parviainen michael@0: // michael@0: // This library is free software; you can redistribute it and/or michael@0: // modify it under the terms of the GNU Lesser General Public michael@0: // License as published by the Free Software Foundation; either michael@0: // version 2.1 of the License, or (at your option) any later version. michael@0: // michael@0: // This library is distributed in the hope that it will be useful, michael@0: // but WITHOUT ANY WARRANTY; without even the implied warranty of michael@0: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU michael@0: // Lesser General Public License for more details. michael@0: // michael@0: // You should have received a copy of the GNU Lesser General Public michael@0: // License along with this library; if not, write to the Free Software michael@0: // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA michael@0: // michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: #ifndef FIFOSampleBuffer_H michael@0: #define FIFOSampleBuffer_H michael@0: michael@0: #include "FIFOSamplePipe.h" michael@0: michael@0: namespace soundtouch michael@0: { michael@0: michael@0: /// Sample buffer working in FIFO (first-in-first-out) principle. The class takes michael@0: /// care of storage size adjustment and data moving during input/output operations. michael@0: /// michael@0: /// Notice that in case of stereo audio, one sample is considered to consist of michael@0: /// both channel data. michael@0: class FIFOSampleBuffer : public FIFOSamplePipe michael@0: { michael@0: private: michael@0: /// Sample buffer. michael@0: SAMPLETYPE *buffer; michael@0: michael@0: // Raw unaligned buffer memory. 'buffer' is made aligned by pointing it to first michael@0: // 16-byte aligned location of this buffer michael@0: SAMPLETYPE *bufferUnaligned; michael@0: michael@0: /// Sample buffer size in bytes michael@0: uint sizeInBytes; michael@0: michael@0: /// How many samples are currently in buffer. michael@0: uint samplesInBuffer; michael@0: michael@0: /// Channels, 1=mono, 2=stereo. michael@0: uint channels; michael@0: michael@0: /// Current position pointer to the buffer. This pointer is increased when samples are michael@0: /// removed from the pipe so that it's necessary to actually rewind buffer (move data) michael@0: /// only new data when is put to the pipe. michael@0: uint bufferPos; michael@0: michael@0: /// Rewind the buffer by moving data from position pointed by 'bufferPos' to real michael@0: /// beginning of the buffer. michael@0: void rewind(); michael@0: michael@0: /// Ensures that the buffer has capacity for at least this many samples. michael@0: void ensureCapacity(uint capacityRequirement); michael@0: michael@0: /// Returns current capacity. michael@0: uint getCapacity() const; michael@0: michael@0: public: michael@0: michael@0: /// Constructor michael@0: FIFOSampleBuffer(int numChannels = 2 ///< Number of channels, 1=mono, 2=stereo. michael@0: ///< Default is stereo. michael@0: ); michael@0: michael@0: /// destructor michael@0: ~FIFOSampleBuffer(); michael@0: michael@0: /// Returns a pointer to the beginning of the output samples. michael@0: /// This function is provided for accessing the output samples directly. michael@0: /// Please be careful for not to corrupt the book-keeping! michael@0: /// michael@0: /// When using this function to output samples, also remember to 'remove' the michael@0: /// output samples from the buffer by calling the michael@0: /// 'receiveSamples(numSamples)' function michael@0: virtual SAMPLETYPE *ptrBegin(); michael@0: michael@0: /// Returns a pointer to the end of the used part of the sample buffer (i.e. michael@0: /// where the new samples are to be inserted). This function may be used for michael@0: /// inserting new samples into the sample buffer directly. Please be careful michael@0: /// not corrupt the book-keeping! michael@0: /// michael@0: /// When using this function as means for inserting new samples, also remember michael@0: /// to increase the sample count afterwards, by calling the michael@0: /// 'putSamples(numSamples)' function. michael@0: SAMPLETYPE *ptrEnd( michael@0: uint slackCapacity ///< How much free capacity (in samples) there _at least_ michael@0: ///< should be so that the caller can succesfully insert the michael@0: ///< desired samples to the buffer. If necessary, the function michael@0: ///< grows the buffer size to comply with this requirement. michael@0: ); michael@0: michael@0: /// Adds 'numSamples' pcs of samples from the 'samples' memory position to michael@0: /// the sample buffer. michael@0: virtual void putSamples(const SAMPLETYPE *samples, ///< Pointer to samples. michael@0: uint numSamples ///< Number of samples to insert. michael@0: ); michael@0: michael@0: /// Adjusts the book-keeping to increase number of samples in the buffer without michael@0: /// copying any actual samples. michael@0: /// michael@0: /// This function is used to update the number of samples in the sample buffer michael@0: /// when accessing the buffer directly with 'ptrEnd' function. Please be michael@0: /// careful though! michael@0: virtual void putSamples(uint numSamples ///< Number of samples been inserted. michael@0: ); michael@0: michael@0: /// Output samples from beginning of the sample buffer. Copies requested samples to michael@0: /// output buffer and removes them from the sample buffer. If there are less than michael@0: /// 'numsample' samples in the buffer, returns all that available. michael@0: /// michael@0: /// \return Number of samples returned. michael@0: virtual uint receiveSamples(SAMPLETYPE *output, ///< Buffer where to copy output samples. michael@0: uint maxSamples ///< How many samples to receive at max. michael@0: ); michael@0: michael@0: /// Adjusts book-keeping so that given number of samples are removed from beginning of the michael@0: /// sample buffer without copying them anywhere. michael@0: /// michael@0: /// Used to reduce the number of samples in the buffer when accessing the sample buffer directly michael@0: /// with 'ptrBegin' function. michael@0: virtual uint receiveSamples(uint maxSamples ///< Remove this many samples from the beginning of pipe. michael@0: ); michael@0: michael@0: /// Returns number of samples currently available. michael@0: virtual uint numSamples() const; michael@0: michael@0: /// Sets number of channels, 1 = mono, 2 = stereo. michael@0: void setChannels(int numChannels); michael@0: michael@0: /// Get number of channels michael@0: int getChannels() michael@0: { michael@0: return channels; michael@0: } michael@0: michael@0: /// Returns nonzero if there aren't any samples available for outputting. michael@0: virtual int isEmpty() const; michael@0: michael@0: /// Clears all the samples. michael@0: virtual void clear(); michael@0: michael@0: /// allow trimming (downwards) amount of samples in pipeline. michael@0: /// Returns adjusted amount of samples michael@0: uint adjustAmountOfSamples(uint numSamples); michael@0: }; michael@0: michael@0: } michael@0: michael@0: #endif