btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / apps / cortex / addons / common / audio_buffer_tools.h
blob8eba1bfd19e8aab9ba0c7450739117491f62c7e6
1 /*
2 * Copyright (c) 1999-2000, Eric Moon.
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions, and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions, and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
27 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 // audio_buffer_tools.h
33 // eamoon@meadgroup.com
35 // Some straightforward audio buffer-handling routines
37 #ifndef __AUDIO_BUFFER_TOOLS_H__
38 #define __AUDIO_BUFFER_TOOLS_H__
40 #include <ByteOrder.h>
41 #include <Debug.h>
43 // ---------------------------------------------------------------- //
44 // sample conversion +++++
45 // 31mar99: providing conversion to and from float, and defining
46 // other conversions based on that.
47 // ---------------------------------------------------------------- //
50 template<class from_sample_t, class to_sample_t>
51 void convert_sample(from_sample_t in, to_sample_t& out) {
52 out = (to_sample_t)in; // +++++ arbitrary conversion stub
56 inline void convert_sample(float& in, float& out) {
57 out = in;
60 inline void convert_sample(uchar& in, float& out) {
61 out = (float)(in - 128) / 127.0;
64 inline void convert_sample(short& in, float& out) {
65 out = (float)in / 32767.0;
68 inline void convert_sample(int32& in, float& out) {
69 out = (float)in / (float)0x7fffffff;
72 inline void convert_sample(float& in, uchar& out) {
73 out = (uchar)(in * 127.0);
76 inline void convert_sample(float& in, short& out) {
77 out = (short)(in * 32767.0);
80 inline void convert_sample(float& in, int32& out) {
81 out = (int32)(in * 0x7fffffff);
84 inline void swap_convert_sample(float& in, float& out) {
85 out = B_SWAP_FLOAT(in);
88 inline void swap_convert_sample(uchar& in, float& out) {
89 // no swap needed for char
90 out = (float)(in - 128) / 127.0;
93 inline void swap_convert_sample(short& in, float& out) {
94 out = (float)(int16)(B_SWAP_INT16(in)) / 32767.0;
97 inline void swap_convert_sample(int32& in, float& out) {
98 out = (float)(int32)(B_SWAP_INT32(in)) / (float)0x7fffffff;
101 inline void swap_convert_sample(float& in, uchar& out) {
102 out = (uchar)((B_SWAP_FLOAT(in)) * 127.0);
105 inline void swap_convert_sample(float& in, short& out) {
106 out = (short)((B_SWAP_FLOAT(in)) * 32767.0);
109 inline void swap_convert_sample(float& in, int32& out) {
110 out = (int32)((B_SWAP_FLOAT(in)) * 0x7fffffff);
114 template<class to_sample_t>
115 inline void convert_sample(void* pIn, to_sample_t& out, int32 in_audio_format) {
116 switch(in_audio_format) {
117 case media_raw_audio_format::B_AUDIO_UCHAR:
118 convert_sample(*(uchar*)pIn, out);
119 break;
120 case media_raw_audio_format::B_AUDIO_SHORT:
121 convert_sample(*(short*)pIn, out);
122 break;
123 case media_raw_audio_format::B_AUDIO_FLOAT:
124 convert_sample(*(float*)pIn, out);
125 break;
126 case media_raw_audio_format::B_AUDIO_INT:
127 convert_sample(*(int32*)pIn, out);
128 break;
129 default:
130 ASSERT(!"convert_sample(): bad raw_audio_format value");
134 template<class from_sample_t>
135 inline void convert_sample(from_sample_t in, void* pOut, int32 out_audio_format) {
136 switch(out_audio_format) {
137 case media_raw_audio_format::B_AUDIO_UCHAR:
138 convert_sample(in, *(uchar*)pOut);
139 break;
140 case media_raw_audio_format::B_AUDIO_SHORT:
141 convert_sample(in, *(short*)pOut);
142 break;
143 case media_raw_audio_format::B_AUDIO_FLOAT:
144 convert_sample(in, *(float*)pOut);
145 break;
146 case media_raw_audio_format::B_AUDIO_INT:
147 convert_sample(in, *(int32*)pOut);
148 break;
149 default:
150 ASSERT(!"convert_sample(): bad raw_audio_format value");
154 inline void convert_sample(void* pIn, void* pOut,
155 int32 in_audio_format, int32 out_audio_format) {
157 // simplest case
158 if(in_audio_format == out_audio_format)
159 return;
161 // one-step cases
162 if(in_audio_format == media_raw_audio_format::B_AUDIO_FLOAT)
163 convert_sample(*(float*)pIn, pOut, out_audio_format);
165 else if(out_audio_format == media_raw_audio_format::B_AUDIO_FLOAT)
166 convert_sample(pOut, *(float*)pIn, in_audio_format);
168 else {
169 // two-step cases
170 float fTemp = 0;
171 convert_sample(pIn, fTemp, in_audio_format);
172 convert_sample(fTemp, pOut, out_audio_format);
176 // ---------------------------------------------------------------- //
177 // data-copying helper templates
178 // ---------------------------------------------------------------- //
180 // copy from linear buffer to circular buffer; no rescaling
181 // returns new offset into destination buffer
183 template<class from_sample_t, class to_sample_t>
184 inline size_t copy_linear_to_circular(
185 from_sample_t* pFrom,
186 to_sample_t* pTo,
187 size_t samples, size_t toOffset, size_t toLength) {
189 ASSERT(pFrom != 0);
190 ASSERT(pTo != 0);
191 ASSERT(samples > 0);
192 ASSERT(toLength > 0);
193 ASSERT(toOffset < toLength);
195 size_t n = toOffset;
196 for(; samples; samples--) {
197 pTo[n] = (to_sample_t)*pFrom++;
198 if(++n >= toLength)
199 n = 0;
202 return n;
205 // copy from a linear buffer in one sample format to a circular buffer
206 // in another, delegating rescaling duties to convert_sample().
207 // returns new offset into destination buffer
209 template<class from_sample_t, class to_sample_t>
210 inline size_t copy_linear_to_circular_convert(
211 from_sample_t* pFrom,
212 to_sample_t* pTo,
213 size_t samples, size_t toOffset, size_t toLength) {
215 ASSERT(pFrom != 0);
216 ASSERT(pTo != 0);
217 ASSERT(samples > 0);
218 ASSERT(toLength > 0);
219 ASSERT(toOffset < toLength);
221 size_t n = toOffset;
222 for(; samples; samples--) {
223 convert_sample(*pFrom++, pTo[n]);
224 if(++n >= toLength)
225 n = 0;
228 return n;
231 // copy from linear buffer to circular buffer; no rescaling
232 // returns new offset into source buffer
234 template<class from_sample_t, class to_sample_t>
235 inline size_t copy_circular_to_linear(
236 from_sample_t* pFrom,
237 to_sample_t* pTo,
238 size_t samples, size_t fromOffset, size_t fromLength) {
240 ASSERT(pFrom != 0);
241 ASSERT(pTo != 0);
242 ASSERT(samples > 0);
243 ASSERT(fromLength > 0);
244 ASSERT(fromOffset < fromLength);
246 size_t n = fromOffset;
247 for(; samples; samples--) {
248 *pTo++ = (to_sample_t)pFrom[n];
249 if(++n >= fromLength)
250 n = 0;
253 return n;
256 // copy from a circular buffer in one sample format to a linear buffer
257 // in another, delegating rescaling duties to convert_sample().
258 // returns new offset into source buffer
260 template<class from_sample_t, class to_sample_t>
261 inline size_t copy_circular_to_linear_convert(
262 from_sample_t* pFrom,
263 to_sample_t* pTo,
264 size_t samples, size_t fromOffset, size_t fromLength) {
266 ASSERT(pFrom != 0);
267 ASSERT(pTo != 0);
268 ASSERT(samples > 0);
269 ASSERT(fromLength > 0);
270 ASSERT(fromOffset < fromLength);
272 size_t n = fromOffset;
273 for(; samples; samples--) {
274 convert_sample(pFrom[n], *pTo++);
275 if(++n >= fromLength)
276 n = 0;
279 return n;
282 //// copy between circular buffers in the same format
283 //// +++++ re-templatize
285 ///*template<class samp_t>
286 //inline*/ void copy_circular_to_circular(
287 // sample_t* pFrom,
288 // sample_t* pTo,
289 // size_t samples,
290 // size_t& ioFromOffset, size_t fromLength,
291 // size_t& ioToOffset, size_t toLength);
293 // mix from a linear buffer to a circular buffer (no rescaling)
294 // input samples are multiplied by fSourceGain; destination samples
295 // are multiplied by fFeedback
296 // returns new offset within destination buffer
298 template<class from_sample_t, class to_sample_t>
299 inline size_t mix_linear_to_circular(
300 from_sample_t* pFrom,
301 to_sample_t* pTo,
302 uint32 samples,
303 uint32 toOffset,
304 uint32 toLength,
305 float fSourceGain,
306 float fFeedback) {
308 // feedback
309 size_t n, nLength;
310 if(fFeedback == 0.0) // +++++ memset?
311 for(n = toOffset, nLength = samples;
312 nLength;
313 n = (n+1 == toLength) ? 0 : n+1, nLength--) { pTo[n] = 0.0; }
314 else if(fFeedback != 1.0)
315 for(n = toOffset, nLength = samples;
316 nLength;
317 n = (n+1 == toLength) ? 0 : n+1, nLength--) { pTo[n] *= fFeedback; }
318 // else nothing to do
320 // mix source, unless muted or not provided
321 if(pFrom && fSourceGain != 0.0) {
322 if(fSourceGain == 1.0)
323 for(n = toOffset, nLength = samples;
324 nLength;
325 n = (n+1 == toLength) ? 0 : n+1, nLength--) {
326 pTo[n] += (to_sample_t)*pFrom++;
328 else
329 for(n = toOffset, nLength = samples;
330 nLength;
331 n = (n+1 == toLength) ? 0 : n+1, nLength--) {
332 pTo[n] += (to_sample_t)*pFrom++ * fSourceGain; // +++++ re-cast to dest format?
336 // increment loop position w/ rollover
337 toOffset += samples;
338 if(toOffset >= toLength)
339 toOffset -= toLength;
341 return toOffset;
344 // mix from a linear buffer in one sample format to a
345 // circular buffer in another, delegating to convert_sample() for rescaling
346 // input samples are multiplied by fSourceGain; destination samples
347 // are multiplied by fFeedback
348 // returns new offset within destination buffer
350 template<class from_sample_t, class to_sample_t>
351 inline size_t mix_linear_to_circular_convert(
352 from_sample_t* pFrom,
353 to_sample_t* pTo,
354 size_t samples,
355 size_t toOffset,
356 size_t toLength,
357 float fSourceGain,
358 float fFeedback) {
360 // feedback
361 size_t n, nLength;
362 if(fFeedback == 0.0) // +++++ memset?
363 for(n = toOffset, nLength = samples;
364 nLength;
365 n = (n+1 == toLength) ? 0 : n+1, nLength--) { pTo[n] = 0.0; }
366 else if(fFeedback != 1.0)
367 for(n = toOffset, nLength = samples;
368 nLength;
369 n = (n+1 == toLength) ? 0 : n+1, nLength--) { pTo[n] *= fFeedback; }
370 // else nothing to do
372 // mix source, unless muted or not provided
373 if(pFrom && fSourceGain != 0.0) {
374 if(fSourceGain == 1.0)
375 for(n = toOffset, nLength = samples;
376 nLength;
377 n = (n+1 == toLength) ? 0 : n+1, nLength--) {
378 to_sample_t from;
379 convert_sample(*pFrom++, from);
380 pTo[n] += from;
382 else
383 for(n = toOffset, nLength = samples;
384 nLength;
385 n = (n+1 == toLength) ? 0 : n+1, nLength--) {
386 to_sample_t from;
387 convert_sample(*pFrom++, from);
388 pTo[n] += from * fSourceGain; // +++++ re-cast to dest format?
392 // increment loop position w/ rollover
393 toOffset += samples;
394 if(toOffset >= toLength)
395 toOffset -= toLength;
397 return toOffset;
400 #endif /* __AUDIO_BUFFER_TOOLS_H__ */