1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
|
/*
* AudioConversion.h
* audio-utils
*
* Created by Søren Christiansen on 2/9/11.
* Copyright 2011 Unity Technologies. All rights reserved.
*
*/
#pragma once
#include <algorithm>
#include <functional>
#include <assert.h>
#include "Runtime/Audio/correct_fmod_includer.h"
#include "Runtime/Utilities/dynamic_array.h"
using std::unary_function;
using std::transform;
typedef union {
UInt8 int8[3];
} SInt24;
template<typename InType, typename OutType >
struct Reformat : public unary_function<InType, OutType> {
float operator()(const InType x) { assert("NO REFORMAT BETWEEN THESE TYPES"); return OutType(); }
};
// --> normalized float
template<typename InType >
struct Reformat<InType, float> : public unary_function<InType, float> {
float operator()(const InType x) { return ( (float) x ) / ( 1 << ( ( sizeof(InType) * 8) - 1 ) ) ; }
};
template< >
struct Reformat<SInt16, float> : public unary_function<SInt16, float> {
float operator()(const SInt16 x) { return ( ((float)x) / ( 1 << 15)) ; }
};
template< >
struct Reformat<float, float> : public unary_function<float, float> {
float operator()(const float x) { return x; }
};
template< >
struct Reformat<SInt24, float> : public unary_function<SInt24, float> {
float operator()(const SInt24 x)
{
int val;
val = ((unsigned int)x.int8[0] << 8);
val |= ((unsigned int)x.int8[1] << 16);
val |= ((unsigned int)x.int8[2] << 24);
val >>= 8;
return (float)(val) * (1.0f / (float)(1<<23));
}
};
// --> 16 bit
template< >
struct Reformat<UInt8, SInt16> {
SInt16 operator()(const UInt8 x) { return (( ( UInt16 ) x << 8 )); }
};
template< >
struct Reformat<SInt24, SInt16> {
SInt16 operator()(const SInt24 x) {
SInt16 out = ( x.int8[2] << 8 );
out |= ( x.int8[1] );
return out;
}
};
template<typename T>
struct Reformat<float, T> {
T operator()(const float x) { return (T)(x * ( 1 << ( ( sizeof(T) * 8) - 1 ))); }
};
template<>
struct Reformat<float, SInt16> {
SInt16 operator()(const float x) { return SInt16(x * (1 << 15)); }
};
template<typename T>
struct NOP : public unary_function<T, T> {
T operator()(const T x) { return x; }
};
// --> helper functors
template <typename FO1, typename FO2>
class Composer : public unary_function<typename FO1::argument_type, typename FO2::result_type> {
private:
typedef typename FO2::result_type FO2Result;
typedef typename FO1::argument_type FO1Arg;
public:
FO1 fo1; // first/inner function object to call
FO2 fo2; // second/outer function object to call
// constructor: initialize function objects
Composer (FO1 f1, FO2 f2)
: fo1(f1), fo2(f2) {
}
// ''function call'': nested call of function objects
FO2Result operator() (const FO1Arg v) {
return fo2(fo1(v));
}
};
template <typename FO1, typename FO2>
inline
Composer<FO1,FO2> compose (FO1 f1, FO2 f2) {
return Composer<FO1,FO2> (f1, f2);
}
template<typename _InputIterator, typename _Function>
_Function
for_each_channel(_InputIterator __first, _InputIterator __last, _Function __f, int channel, int channels)
{
for ( __first = __first + channel; __first < __last - channel; __first = __first+channels)
__f(*__first);
return __f;
}
// --> helper functions interface
typedef Reformat<SInt8, float> SInt8ToFloat;
typedef Reformat<SInt16, float> SInt16ToFloat;
typedef Reformat<SInt24, float> SInt24ToFloat;
typedef Reformat<SInt32, float> SInt32ToFloat;
typedef Reformat<float, float> FloatToFloat;
typedef Reformat<float, SInt8> FloatToSInt8;
typedef Reformat<float, SInt16> FloatToSInt16;
typedef Reformat<float, SInt24> FloatToSInt24;
typedef Reformat<float, SInt32> FloatToSInt32;
template<typename _Function>
inline void ArrayToNormFloat(FMOD_SOUND_FORMAT inFormat, const void* beginIterator, const void* endIterator, dynamic_array<float>& v, _Function __f)
{
if (inFormat == FMOD_SOUND_FORMAT_PCM8)
std::transform((const SInt8*) beginIterator, (const SInt8*) endIterator, std::back_inserter(v), compose( SInt8ToFloat(), __f ));
else if (inFormat == FMOD_SOUND_FORMAT_PCM16)
std::transform((const SInt16*) beginIterator, (const SInt16*) endIterator, std::back_inserter(v), compose ( SInt16ToFloat(), __f));
else if (inFormat == FMOD_SOUND_FORMAT_PCM24)
std::transform((const SInt24*) beginIterator, (const SInt24*) endIterator, std::back_inserter(v), compose ( SInt24ToFloat(), __f));
else if (inFormat == FMOD_SOUND_FORMAT_PCM32)
std::transform((const SInt32*) beginIterator, (const SInt32*) endIterator, std::back_inserter(v), compose ( SInt32ToFloat(), __f));
else if (inFormat == FMOD_SOUND_FORMAT_PCMFLOAT)
std::transform((const float*) beginIterator, (const float*) endIterator, std::back_inserter(v), compose ( FloatToFloat(), __f));
}
inline void ArrayToNormFloat(FMOD_SOUND_FORMAT inFormat, const void* beginIterator, const void* endIterator, dynamic_array<float>& v)
{
if (inFormat == FMOD_SOUND_FORMAT_PCM8)
std::transform((const SInt8*) beginIterator, (const SInt8*) endIterator, std::back_inserter(v), SInt8ToFloat());
else if (inFormat == FMOD_SOUND_FORMAT_PCM16)
std::transform((const SInt16*) beginIterator, (const SInt16*) endIterator, std::back_inserter(v), SInt16ToFloat());
else if (inFormat == FMOD_SOUND_FORMAT_PCM24)
std::transform((const SInt24*) beginIterator, (const SInt24*) endIterator, std::back_inserter(v), SInt24ToFloat());
else if (inFormat == FMOD_SOUND_FORMAT_PCM32)
std::transform((const SInt32*) beginIterator, (const SInt32*) endIterator, std::back_inserter(v), SInt32ToFloat());
else if (inFormat == FMOD_SOUND_FORMAT_PCMFLOAT)
std::transform((const float*) beginIterator, (const float*) endIterator, std::back_inserter(v), FloatToFloat());
}
template<typename T>
inline void ArrayFromNormFloat(FMOD_SOUND_FORMAT outFormat, const float* beginIterator, const float* endIterator, dynamic_array<T>& v)
{
if (outFormat == FMOD_SOUND_FORMAT_PCM8)
std::transform(beginIterator, endIterator, std::back_inserter(v), FloatToSInt8());
else if (outFormat == FMOD_SOUND_FORMAT_PCM16)
std::transform( beginIterator, endIterator, std::back_inserter(v), FloatToSInt16());
//else if (outFormat == FMOD_SOUND_FORMAT_PCM24)
// std::transform( beginIterator, endIterator, std::back_inserter(v), FloatToSInt24());
else if (outFormat == FMOD_SOUND_FORMAT_PCM32)
std::transform( beginIterator, endIterator, std::back_inserter(v), FloatToSInt32());
else if (outFormat == FMOD_SOUND_FORMAT_PCMFLOAT)
std::transform( beginIterator, endIterator, std::back_inserter(v), FloatToFloat());
}
inline void ArrayFromNormFloat(FMOD_SOUND_FORMAT outFormat, const float* beginIterator, const float* endIterator, void* outbuffer)
{
if (outFormat == FMOD_SOUND_FORMAT_PCM8)
{
SInt8* dstPtr = (SInt8*)outbuffer;
while (beginIterator != endIterator)
{
*dstPtr = FloatToSInt8()(*beginIterator);
beginIterator++;
dstPtr++;
}
}
else
if (outFormat == FMOD_SOUND_FORMAT_PCM16)
{
SInt16* dstPtr = (SInt16*)outbuffer;
while (beginIterator != endIterator)
{
*dstPtr = FloatToSInt16()(*beginIterator);
beginIterator++;
dstPtr++;
}
}
else
if (outFormat == FMOD_SOUND_FORMAT_PCM32)
{
SInt32* dstPtr = (SInt32*)outbuffer;
while (beginIterator != endIterator)
{
*dstPtr = FloatToSInt32()(*beginIterator);
beginIterator++;
dstPtr++;
}
}
else
if (outFormat == FMOD_SOUND_FORMAT_PCMFLOAT)
{
memcpy (outbuffer, beginIterator, (endIterator - beginIterator) * sizeof(float));
}
else {
Assert("Conversion NOT supported");
}
}
inline void ArrayToNormFloat(FMOD_SOUND_FORMAT inFormat, const void* beginIterator, const void* endIterator, float* outbuffer)
{
if (inFormat == FMOD_SOUND_FORMAT_PCM8)
{
SInt8* srcPtr = (SInt8*)beginIterator;
while (srcPtr != (SInt8*)endIterator)
{
*outbuffer = SInt8ToFloat()(*srcPtr);
srcPtr++;
outbuffer++;
}
}
else
if (inFormat == FMOD_SOUND_FORMAT_PCM16)
{
SInt16* srcPtr = (SInt16*)beginIterator;
while (srcPtr != (SInt16*)endIterator)
{
*outbuffer = SInt16ToFloat()(*srcPtr);
srcPtr++;
outbuffer++;
}
}
else
if (inFormat == FMOD_SOUND_FORMAT_PCM24)
{
SInt24* srcPtr = (SInt24*)beginIterator;
while (srcPtr != (SInt24*)endIterator)
{
*outbuffer = SInt24ToFloat()(*srcPtr);
srcPtr++;
outbuffer++;
}
}
else
if (inFormat == FMOD_SOUND_FORMAT_PCM32)
{
SInt32* srcPtr = (SInt32*)beginIterator;
while (srcPtr != (SInt32*)endIterator)
{
*outbuffer = SInt32ToFloat()(*srcPtr);
srcPtr++;
outbuffer++;
}
}
else
if (inFormat == FMOD_SOUND_FORMAT_PCMFLOAT)
{
memcpy (outbuffer, beginIterator, ((float*)endIterator - (float*)beginIterator) * sizeof(float));
}
else {
ErrorString("Conversion from this format NOT supported");
}
}
template<typename InType, typename OutType>
inline void ReformatArray(const InType* inArray, const unsigned size, OutType* outArray)
{
Reformat<InType, OutType> reformater;
std::transform( inArray, inArray + size, outArray, reformater );
}
|