Cinder  0.8.6
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Converter.h
Go to the documentation of this file.
1 /*
2  Copyright (c) 2014, The Cinder Project
3 
4  This code is intended to be used with the Cinder C++ library, http://libcinder.org
5 
6  Redistribution and use in source and binary forms, with or without modification, are permitted provided that
7  the following conditions are met:
8 
9  * Redistributions of source code must retain the above copyright notice, this list of conditions and
10  the following disclaimer.
11  * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
12  the following disclaimer in the documentation and/or other materials provided with the distribution.
13 
14  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
15  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
16  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
17  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
18  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
19  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
20  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
21  POSSIBILITY OF SUCH DAMAGE.
22  */
23 
24 #pragma once
25 
26 #include "cinder/audio/Buffer.h"
27 
28 #include <memory>
29 
30 namespace cinder { namespace audio { namespace dsp {
31 
33 class Converter {
34  public:
36  static std::unique_ptr<Converter> create( size_t sourceSampleRate, size_t destSampleRate, size_t sourceNumChannels, size_t destNumChannels, size_t sourceMaxFramesPerBlock );
37 
38  virtual ~Converter() {}
39 
42  virtual std::pair<size_t, size_t> convert( const Buffer *sourceBuffer, Buffer *destBuffer ) = 0;
43 
45  virtual void clear() {}
46 
47  size_t getSourceSampleRate() const { return mSourceSampleRate; }
48  size_t getDestSampleRate() const { return mDestSampleRate; }
49  size_t getSourceNumChannels() const { return mSourceNumChannels; }
50  size_t getDestNumChannels() const { return mDestNumChannels; }
53 
54  protected:
55  Converter( size_t sourceSampleRate, size_t destSampleRate, size_t sourceNumChannels, size_t destNumChannels, size_t sourceMaxFramesPerBlock );
56 
58 };
59 
61 void mixBuffers( const Buffer *sourceBuffer, Buffer *destBuffer, size_t numFrames );
63 inline void mixBuffers( const Buffer *sourceBuffer, Buffer *destBuffer ) { mixBuffers( sourceBuffer, destBuffer, std::min( sourceBuffer->getNumFrames(), destBuffer->getNumFrames() ) ); }
64 
66 void sumBuffers( const Buffer *sourceBuffer, Buffer *destBuffer, size_t numFrames );
68 inline void sumBuffers( const Buffer *sourceBuffer, Buffer *destBuffer ) { sumBuffers( sourceBuffer, destBuffer, std::min( sourceBuffer->getNumFrames(), destBuffer->getNumFrames() ) ); }
69 
71 template <typename SourceT, typename DestT>
72 void convert( const SourceT *sourceArray, DestT *destArray, size_t length )
73 {
74  for( size_t i = 0; i < length; i++ )
75  destArray[i] = static_cast<DestT>( sourceArray[i] );
76 }
77 
79 template <typename SourceT, typename DestT>
80 void convertBuffer( const BufferT<SourceT> *sourceBuffer, BufferT<DestT> *destBuffer )
81 {
82  size_t numFrames = std::min( sourceBuffer->getNumFrames(), destBuffer->getNumFrames() );
83  size_t numChannels = std::min( sourceBuffer->getNumChannels(), destBuffer->getNumChannels() );
84 
85  for( size_t ch = 0; ch < numChannels; ch++ )
86  convert( sourceBuffer->getChannel( ch ), destBuffer->getChannel( ch ), numFrames );
87 }
88 
90 template<typename FloatT>
91 void convertInt24ToFloat( const char *sourceArray, FloatT *destArray, size_t length )
92 {
93  const FloatT floatNormalizer = (FloatT)1 / (FloatT)8388607;
94 
95  for( size_t i = 0; i < length; i++ ) {
96  int32_t sample = (int32_t)( ( (int32_t)sourceArray[2] ) << 16 ) | ( ( (int32_t)(uint8_t)sourceArray[1] ) << 8 ) | ( (int32_t)(uint8_t)sourceArray[0] );
97  destArray[i] = sample * floatNormalizer;
98  sourceArray += 3;
99  }
100 }
101 
103 template<typename FloatT>
104 void convertFloatToInt24( const FloatT *sourceArray, char *destArray, size_t length )
105 {
106  const FloatT intNormalizer = 8388607;
107 
108  for( size_t i = 0; i < length; i++ ) {
109  int32_t sample = int32_t( sourceArray[i] * intNormalizer );
110  *(destArray++) = (char)( sample & 255 );
111  *(destArray++) = (char)( ( sample >> 8 ) & 255 );
112  *(destArray++) = (char)( ( sample >> 16 ) & 255 );
113  }
114 }
115 
117 template<typename T>
118 void interleave( const T *nonInterleavedSourceArray, T *interleavedDestArray, size_t numFramesPerChannel, size_t numChannels, size_t numCopyFrames )
119 {
120  for( size_t ch = 0; ch < numChannels; ch++ ) {
121  size_t x = ch;
122  const T *sourceChannel = &nonInterleavedSourceArray[ch * numFramesPerChannel];
123  for( size_t i = 0; i < numCopyFrames; i++ ) {
124  interleavedDestArray[x] = sourceChannel[i];
125  x += numChannels;
126  }
127  }
128 }
129 
131 template<typename FloatT>
132 void interleave( const FloatT *nonInterleavedFloatSourceArray, int16_t *interleavedInt16DestArray, size_t numFramesPerChannel, size_t numChannels, size_t numCopyFrames )
133 {
134  const FloatT intNormalizer = 32768;
135 
136  for( size_t ch = 0; ch < numChannels; ch++ ) {
137  size_t x = ch;
138  const FloatT *sourceChannel = &nonInterleavedFloatSourceArray[ch * numFramesPerChannel];
139  for( size_t i = 0; i < numCopyFrames; i++ ) {
140  interleavedInt16DestArray[x] = int16_t( sourceChannel[i] * intNormalizer );
141  x += numChannels;
142  }
143  }
144 }
145 
147 template<typename T>
148 void deinterleave( const T *interleavedSourceArray, T *nonInterleavedDestArray, size_t numFramesPerChannel, size_t numChannels, size_t numCopyFrames )
149 {
150  for( size_t ch = 0; ch < numChannels; ch++ ) {
151  size_t x = ch;
152  T *destChannel = &nonInterleavedDestArray[ch * numFramesPerChannel];
153  for( size_t i = 0; i < numCopyFrames; i++ ) {
154  destChannel[i] = interleavedSourceArray[x];
155  x += numChannels;
156  }
157  }
158 }
159 
161 template<typename FloatT>
162 void deinterleave( const int16_t *interleavedInt16SourceArray, FloatT *nonInterleavedFloatDestArray, size_t numFramesPerChannel, size_t numChannels, size_t numCopyFrames )
163 {
164  const FloatT floatNormalizer = (FloatT)3.0517578125e-05; // 1.0 / 32768.0
165 
166  for( size_t ch = 0; ch < numChannels; ch++ ) {
167  size_t x = ch;
168  FloatT *destChannel = &nonInterleavedFloatDestArray[ch * numFramesPerChannel];
169  for( size_t i = 0; i < numCopyFrames; i++ ) {
170  destChannel[i] = (FloatT)interleavedInt16SourceArray[x] * floatNormalizer;
171  x += numChannels;
172  }
173  }
174 }
175 
177 template<typename T>
178 void interleaveBuffer( const BufferT<T> *nonInterleavedSource, BufferInterleavedT<T> *interleavedDest )
179 {
180  CI_ASSERT( interleavedDest->getNumChannels() == nonInterleavedSource->getNumChannels() );
181  CI_ASSERT( interleavedDest->getSize() <= nonInterleavedSource->getSize() );
182 
183  interleave( nonInterleavedSource->getData(), interleavedDest->getData(), interleavedDest->getNumFrames(), interleavedDest->getNumChannels(), interleavedDest->getNumFrames() );
184 }
185 
187 template<typename T>
188 void deinterleaveBuffer( const BufferInterleavedT<T> *interleavedSource, BufferT<T> *nonInterleavedDest )
189 {
190  CI_ASSERT( interleavedSource->getNumChannels() == nonInterleavedDest->getNumChannels() );
191  CI_ASSERT( nonInterleavedDest->getSize() <= interleavedSource->getSize() );
192 
193  deinterleave( interleavedSource->getData(), nonInterleavedDest->getData(), nonInterleavedDest->getNumFrames(), nonInterleavedDest->getNumChannels(), nonInterleavedDest->getNumFrames() );
194 }
195 
197 template<typename T>
198 void interleaveStereoBuffer( const BufferT<T> *nonInterleavedSource, BufferInterleavedT<T> *interleavedDest )
199 {
200  CI_ASSERT( interleavedDest->getNumChannels() == 2 && nonInterleavedSource->getNumChannels() == 2 );
201  CI_ASSERT( interleavedDest->getSize() <= nonInterleavedSource->getSize() );
202 
203  size_t numFrames = interleavedDest->getNumFrames();
204  const T *left = nonInterleavedSource->getChannel( 0 );
205  const T *right = nonInterleavedSource->getChannel( 1 );
206 
207  T *mixed = interleavedDest->getData();
208 
209  size_t i, j;
210  for( i = 0, j = 0; i < numFrames; i++, j += 2 ) {
211  mixed[j] = left[i];
212  mixed[j + 1] = right[i];
213  }
214 }
215 
217 template<typename T>
218 void deinterleaveStereoBuffer( const BufferInterleavedT<T> *interleavedSource, BufferT<T> *nonInterleavedDest )
219 {
220  CI_ASSERT( interleavedSource->getNumChannels() == 2 && nonInterleavedDest->getNumChannels() == 2 );
221  CI_ASSERT( nonInterleavedDest->getSize() <= interleavedSource->getSize() );
222 
223  size_t numFrames = nonInterleavedDest->getNumFrames();
224  T *left = nonInterleavedDest->getChannel( 0 );
225  T *right = nonInterleavedDest->getChannel( 1 );
226  const T *mixed = interleavedSource->getData();
227 
228  size_t i, j;
229  for( i = 0, j = 0; i < numFrames; i++, j += 2 ) {
230  left[i] = mixed[j];
231  right[i] = mixed[j + 1];
232  }
233 }
234 
235 } } } // namespace cinder::audio::dsp
T * getChannel(size_t ch)
Returns a pointer offset to the first sample of channel ch.
Definition: Buffer.h:97
void sumBuffers(const Buffer *sourceBuffer, Buffer *destBuffer, size_t numFrames)
Sums numFrames frames of sourceBuffer into destBuffer. Channel up or down mixing is applied if necess...
Definition: Converter.cpp:101
size_t mDestNumChannels
Definition: Converter.h:57
size_t getDestNumChannels() const
Definition: Converter.h:50
void deinterleave(const T *interleavedSourceArray, T *nonInterleavedDestArray, size_t numFramesPerChannel, size_t numChannels, size_t numCopyFrames)
De-interleaves numCopyFrames of interleavedSourceArray, placing the result in nonInterleavedDestArray...
Definition: Converter.h:148
A platform-specific converter that supports samplerate and channel conversion.
Definition: Converter.h:33
void interleaveStereoBuffer(const BufferT< T > *nonInterleavedSource, BufferInterleavedT< T > *interleavedDest)
Interleaves nonInterleavedSource, placing the result in interleavedDest. This method is only slightly...
Definition: Converter.h:198
void deinterleaveStereoBuffer(const BufferInterleavedT< T > *interleavedSource, BufferT< T > *nonInterleavedDest)
De-interleaves interleavedSource, placing the result in nonInterleavedDest. This method is only sligh...
Definition: Converter.h:218
size_t getSourceMaxFramesPerBlock() const
Definition: Converter.h:51
size_t getSourceSampleRate() const
Definition: Converter.h:47
virtual std::pair< size_t, size_t > convert(const Buffer *sourceBuffer, Buffer *destBuffer)=0
void mixBuffers(const Buffer *sourceBuffer, Buffer *destBuffer, size_t numFrames)
Mixes numFrames frames of sourceBuffer to destBuffer's layout, replacing its content. Channel up or down mixing is applied if necessary.
Definition: Converter.cpp:62
size_t mSourceMaxFramesPerBlock
Definition: Converter.h:57
#define min(a, b)
Definition: AppImplMsw.cpp:36
Converter(size_t sourceSampleRate, size_t destSampleRate, size_t sourceNumChannels, size_t destNumChannels, size_t sourceMaxFramesPerBlock)
Definition: Converter.cpp:49
virtual void clear()
Clears the state of the converter, discarding / flushing accumulated samples. Optional for implementa...
Definition: Converter.h:45
size_t mSourceSampleRate
Definition: Converter.h:57
size_t getNumChannels() const
Returns the number of channels in the buffer.
Definition: Buffer.h:50
size_t getDestMaxFramesPerBlock() const
Definition: Converter.h:52
size_t getNumFrames() const
Returns the number of frames in the buffer.
Definition: Buffer.h:48
void convertBuffer(const BufferT< SourceT > *sourceBuffer, BufferT< DestT > *destBuffer)
Converts between two BufferT's of different precision (ex. float to double). The number of frames con...
Definition: Converter.h:80
void convertFloatToInt24(const FloatT *sourceArray, char *destArray, size_t length)
Converts the floating point sourceArray to 24-bit int precision, placing the result in destArray...
Definition: Converter.h:104
size_t getSize() const
Returns the total size of the buffer (frames * channels).
Definition: Buffer.h:52
virtual ~Converter()
Definition: Converter.h:38
GLenum GLint x
Definition: GLee.h:987
GLdouble left
Definition: GLee.h:13559
Audio buffer that stores its channels of type T contiguously (ie. the first sample of channel 1 is di...
Definition: Buffer.h:89
GLuint GLsizei GLsizei * length
Definition: GLee.h:2313
void deinterleaveBuffer(const BufferInterleavedT< T > *interleavedSource, BufferT< T > *nonInterleavedDest)
De-interleaves interleavedSource, placing the result in nonInterleavedDest.
Definition: Converter.h:188
GLdouble GLdouble right
Definition: GLee.h:13559
void interleave(const T *nonInterleavedSourceArray, T *interleavedDestArray, size_t numFramesPerChannel, size_t numChannels, size_t numCopyFrames)
Interleaves numCopyFrames of nonInterleavedSourceArray, placing the result in interleavedDestArray. numFramesPerChannel and numChannels describe the layout of the non-interleaved array.
Definition: Converter.h:118
size_t getSourceNumChannels() const
Definition: Converter.h:49
T * getData()
Returns a pointer to the first sample in the data buffer.
Definition: Buffer.h:56
void convertInt24ToFloat(const char *sourceArray, FloatT *destArray, size_t length)
Converts the 24-bit int sourceArray to floating point precision, placing the result in destArray...
Definition: Converter.h:91
size_t mDestSampleRate
Definition: Converter.h:57
size_t getDestSampleRate() const
Definition: Converter.h:48
static std::unique_ptr< Converter > create(size_t sourceSampleRate, size_t destSampleRate, size_t sourceNumChannels, size_t destNumChannels, size_t sourceMaxFramesPerBlock)
If destSampleRate is 0, it is set to match sourceSampleRate. If destNumChannels is 0...
Definition: Converter.cpp:40
size_t mDestMaxFramesPerBlock
Definition: Converter.h:57
size_t mSourceNumChannels
Definition: Converter.h:57
Audio buffer that stores its channels of type T in one interleaved array (ie. the first sample of cha...
Definition: Buffer.h:171
void interleaveBuffer(const BufferT< T > *nonInterleavedSource, BufferInterleavedT< T > *interleavedDest)
Interleaves nonInterleavedSource, placing the result in interleavedDest.
Definition: Converter.h:178
#define CI_ASSERT(expr)
Definition: CinderAssert.h:75
void convert(const SourceT *sourceArray, DestT *destArray, size_t length)
Converts between two arrays of different precision (ex. float to double). length samples are converte...
Definition: Converter.h:72