Merge pull request #112 from alexey-lysiuk/embed_hrtf_pr
[openal-soft.git] / Alc / converter.c
blobf1a3a96b21a42cc382b25e4f32263ee21abd4234
2 #include "config.h"
4 #include "converter.h"
6 #include "mixer_defs.h"
9 SampleConverter *CreateSampleConverter(enum DevFmtType srcType, enum DevFmtType dstType, ALsizei numchans, ALsizei srcRate, ALsizei dstRate)
11 SampleConverter *converter;
13 if(numchans <= 0 || srcRate <= 0 || dstRate <= 0)
14 return NULL;
16 converter = al_calloc(16, FAM_SIZE(SampleConverter, Chan, numchans));
17 converter->mSrcType = srcType;
18 converter->mDstType = dstType;
19 converter->mNumChannels = numchans;
20 converter->mSrcTypeSize = BytesFromDevFmt(srcType);
21 converter->mDstTypeSize = BytesFromDevFmt(dstType);
23 converter->mSrcPrepCount = 0;
25 converter->mFracOffset = 0;
26 converter->mIncrement = (ALsizei)clampu64((ALuint64)srcRate*FRACTIONONE/dstRate,
27 1, MAX_PITCH*FRACTIONONE);
28 if(converter->mIncrement == FRACTIONONE)
29 converter->mResample = Resample_copy32_C;
30 else
32 /* TODO: Allow other resamplers. */
33 converter->mResample = SelectResampler(LinearResampler);
36 return converter;
39 void DestroySampleConverter(SampleConverter **converter)
41 if(converter)
43 al_free(*converter);
44 *converter = NULL;
49 static inline ALfloat Sample_ALbyte(ALbyte val)
50 { return val * (1.0f/128.0f); }
51 static inline ALfloat Sample_ALubyte(ALubyte val)
52 { return Sample_ALbyte((ALint)val - 128); }
54 static inline ALfloat Sample_ALshort(ALshort val)
55 { return val * (1.0f/32768.0f); }
56 static inline ALfloat Sample_ALushort(ALushort val)
57 { return Sample_ALshort((ALint)val - 32768); }
59 static inline ALfloat Sample_ALint(ALint val)
60 { return (val>>7) * (1.0f/16777216.0f); }
61 static inline ALfloat Sample_ALuint(ALuint val)
62 { return ((ALint)(val>>7) - 16777216) * (1.0f/16777216.0f); }
64 static inline ALfloat Sample_ALfloat(ALfloat val)
65 { return val; }
67 #define DECL_TEMPLATE(T) \
68 static inline void Load_##T(ALfloat *restrict dst, const T *restrict src, \
69 ALint srcstep, ALsizei samples) \
70 { \
71 ALsizei i; \
72 for(i = 0;i < samples;i++) \
73 dst[i] = Sample_##T(src[i*srcstep]); \
76 DECL_TEMPLATE(ALbyte)
77 DECL_TEMPLATE(ALubyte)
78 DECL_TEMPLATE(ALshort)
79 DECL_TEMPLATE(ALushort)
80 DECL_TEMPLATE(ALint)
81 DECL_TEMPLATE(ALuint)
82 DECL_TEMPLATE(ALfloat)
84 #undef DECL_TEMPLATE
86 static void LoadSamples(ALfloat *dst, const ALvoid *src, ALint srcstep, enum DevFmtType srctype, ALsizei samples)
88 switch(srctype)
90 case DevFmtByte:
91 Load_ALbyte(dst, src, srcstep, samples);
92 break;
93 case DevFmtUByte:
94 Load_ALubyte(dst, src, srcstep, samples);
95 break;
96 case DevFmtShort:
97 Load_ALshort(dst, src, srcstep, samples);
98 break;
99 case DevFmtUShort:
100 Load_ALushort(dst, src, srcstep, samples);
101 break;
102 case DevFmtInt:
103 Load_ALint(dst, src, srcstep, samples);
104 break;
105 case DevFmtUInt:
106 Load_ALuint(dst, src, srcstep, samples);
107 break;
108 case DevFmtFloat:
109 Load_ALfloat(dst, src, srcstep, samples);
110 break;
115 static inline ALbyte ALbyte_Sample(ALfloat val)
116 { return (ALbyte)clampf(val*128.0f, -128.0f, 127.0f); }
117 static inline ALubyte ALubyte_Sample(ALfloat val)
118 { return ALbyte_Sample(val)+128; }
120 static inline ALshort ALshort_Sample(ALfloat val)
121 { return (ALshort)clampf(val*32768.0f, -32768.0f, 32767.0f); }
122 static inline ALushort ALushort_Sample(ALfloat val)
123 { return ALshort_Sample(val)+32768; }
125 static inline ALint ALint_Sample(ALfloat val)
126 { return (ALint)clampf(val*16777216.0f, -16777216.0f, 16777215.0f) << 7; }
127 static inline ALuint ALuint_Sample(ALfloat val)
128 { return ALint_Sample(val)+INT_MAX+1; }
130 static inline ALfloat ALfloat_Sample(ALfloat val)
131 { return val; }
133 #define DECL_TEMPLATE(T) \
134 static inline void Store_##T(T *restrict dst, const ALfloat *restrict src, \
135 ALint dststep, ALsizei samples) \
137 ALsizei i; \
138 for(i = 0;i < samples;i++) \
139 dst[i*dststep] = T##_Sample(src[i]); \
142 DECL_TEMPLATE(ALbyte)
143 DECL_TEMPLATE(ALubyte)
144 DECL_TEMPLATE(ALshort)
145 DECL_TEMPLATE(ALushort)
146 DECL_TEMPLATE(ALint)
147 DECL_TEMPLATE(ALuint)
148 DECL_TEMPLATE(ALfloat)
150 #undef DECL_TEMPLATE
152 static void StoreSamples(ALvoid *dst, const ALfloat *src, ALint dststep, enum DevFmtType dsttype, ALsizei samples)
154 switch(dsttype)
156 case DevFmtByte:
157 Store_ALbyte(dst, src, dststep, samples);
158 break;
159 case DevFmtUByte:
160 Store_ALubyte(dst, src, dststep, samples);
161 break;
162 case DevFmtShort:
163 Store_ALshort(dst, src, dststep, samples);
164 break;
165 case DevFmtUShort:
166 Store_ALushort(dst, src, dststep, samples);
167 break;
168 case DevFmtInt:
169 Store_ALint(dst, src, dststep, samples);
170 break;
171 case DevFmtUInt:
172 Store_ALuint(dst, src, dststep, samples);
173 break;
174 case DevFmtFloat:
175 Store_ALfloat(dst, src, dststep, samples);
176 break;
181 ALsizei SampleConverterAvailableOut(SampleConverter *converter, ALsizei srcframes)
183 ALint prepcount = converter->mSrcPrepCount;
184 ALsizei increment = converter->mIncrement;
185 ALsizei DataPosFrac = converter->mFracOffset;
186 ALuint64 DataSize64;
188 if(prepcount < 0)
190 /* Negative prepcount means we need to skip that many input samples. */
191 if(-prepcount >= srcframes)
192 return 0;
193 srcframes += prepcount;
194 prepcount = 0;
197 if(prepcount < MAX_POST_SAMPLES+MAX_PRE_SAMPLES &&
198 MAX_POST_SAMPLES+MAX_PRE_SAMPLES-prepcount >= srcframes)
200 /* Not enough input samples to generate an output sample. */
201 return 0;
204 DataSize64 = prepcount;
205 DataSize64 += srcframes;
206 DataSize64 -= MAX_POST_SAMPLES+MAX_PRE_SAMPLES;
207 DataSize64 <<= FRACTIONBITS;
208 DataSize64 -= DataPosFrac;
210 /* If we have a full prep, we can generate at least one sample. */
211 return (ALsizei)clampu64(DataSize64/increment, 1, INT_MAX);
215 ALsizei SampleConverterInput(SampleConverter *converter, const ALvoid **src, ALsizei *srcframes, ALvoid *dst, ALsizei dstframes)
217 const ALsizei SrcFrameSize = converter->mNumChannels * converter->mSrcTypeSize;
218 const ALsizei DstFrameSize = converter->mNumChannels * converter->mDstTypeSize;
219 const ALsizei increment = converter->mIncrement;
220 ALsizei pos = 0;
222 while(pos < dstframes)
224 ALfloat *restrict SrcData = ASSUME_ALIGNED(converter->mSrcSamples, 16);
225 ALfloat *restrict DstData = ASSUME_ALIGNED(converter->mDstSamples, 16);
226 ALint prepcount = converter->mSrcPrepCount;
227 ALsizei DataPosFrac = converter->mFracOffset;
228 ALuint64 DataSize64;
229 ALsizei DstSize;
230 ALint toread;
231 ALsizei chan;
233 if(prepcount < 0)
235 /* Negative prepcount means we need to skip that many input samples. */
236 if(-prepcount >= *srcframes)
238 converter->mSrcPrepCount = prepcount + *srcframes;
239 *srcframes = 0;
240 break;
242 *src = (const ALbyte*)*src + SrcFrameSize*-prepcount;
243 *srcframes += prepcount;
244 prepcount = 0;
246 toread = mini(*srcframes, BUFFERSIZE-(MAX_POST_SAMPLES+MAX_PRE_SAMPLES));
248 if(prepcount < MAX_POST_SAMPLES+MAX_PRE_SAMPLES &&
249 MAX_POST_SAMPLES+MAX_PRE_SAMPLES-prepcount >= toread)
251 /* Not enough input samples to generate an output sample. Store
252 * what we're given for later.
254 for(chan = 0;chan < converter->mNumChannels;chan++)
255 LoadSamples(&converter->Chan[chan].mPrevSamples[prepcount],
256 (const ALbyte*)src + converter->mSrcTypeSize*chan,
257 converter->mNumChannels, converter->mSrcType, toread
260 converter->mSrcPrepCount = prepcount + toread;
261 *srcframes = 0;
262 break;
265 DataSize64 = prepcount;
266 DataSize64 += toread;
267 DataSize64 -= MAX_POST_SAMPLES+MAX_PRE_SAMPLES;
268 DataSize64 <<= FRACTIONBITS;
269 DataSize64 -= DataPosFrac;
271 /* If we have a full prep, we can generate at least one sample. */
272 DstSize = (ALsizei)clampu64(DataSize64/increment, 1, BUFFERSIZE);
273 DstSize = mini(DstSize, dstframes-pos);
275 for(chan = 0;chan < converter->mNumChannels;chan++)
277 const ALbyte *SrcSamples = (const ALbyte*)*src + converter->mSrcTypeSize*chan;
278 ALbyte *DstSamples = (ALbyte*)dst + converter->mSrcTypeSize*chan;
279 const ALfloat *ResampledData;
280 ALsizei SrcDataEnd;
282 /* Load the previous samples into the source data first, then the
283 * new samples from the input buffer.
285 memcpy(SrcData, converter->Chan[chan].mPrevSamples,
286 prepcount*sizeof(ALfloat));
287 LoadSamples(SrcData + prepcount, SrcSamples,
288 converter->mNumChannels, converter->mSrcType, toread
291 /* Store as many prep samples for next time as possible, given the
292 * number of output samples being generated.
294 SrcDataEnd = (DataPosFrac + increment*DstSize)>>FRACTIONBITS;
295 if(SrcDataEnd >= prepcount+toread)
296 memset(converter->Chan[chan].mPrevSamples, 0,
297 sizeof(converter->Chan[chan].mPrevSamples));
298 else
300 size_t len = mini(MAX_PRE_SAMPLES+MAX_POST_SAMPLES, prepcount+toread-SrcDataEnd);
301 memcpy(converter->Chan[chan].mPrevSamples, &SrcData[SrcDataEnd],
302 len*sizeof(ALfloat));
303 memset(converter->Chan[chan].mPrevSamples+len, 0,
304 sizeof(converter->Chan[chan].mPrevSamples) - len*sizeof(ALfloat));
307 /* Now resample, and store the result in the output buffer. */
308 ResampledData = converter->mResample(NULL,
309 SrcData+MAX_PRE_SAMPLES, DataPosFrac, increment,
310 DstData, DstSize
313 StoreSamples(DstSamples, ResampledData, converter->mNumChannels,
314 converter->mDstType, DstSize);
317 /* Update the number of prep samples still available, as well as the
318 * fractional offset.
320 DataPosFrac += increment*DstSize;
321 converter->mSrcPrepCount = mini(MAX_PRE_SAMPLES+MAX_POST_SAMPLES,
322 prepcount+toread-(DataPosFrac>>FRACTIONBITS));
323 converter->mFracOffset = DataPosFrac & FRACTIONMASK;
325 /* Update the src and dst pointers in case there's still more to do. */
326 *src = (const ALbyte*)*src + SrcFrameSize*(DataPosFrac>>FRACTIONBITS);
327 *srcframes -= mini(*srcframes, (DataPosFrac>>FRACTIONBITS));
329 dst = (ALbyte*)dst + DstFrameSize*DstSize;
330 pos += DstSize;
333 return pos;
337 ChannelConverter *CreateChannelConverter(enum DevFmtType srcType, enum DevFmtChannels srcChans, enum DevFmtChannels dstChans)
339 ChannelConverter *converter;
341 if(srcChans != dstChans && !((srcChans == DevFmtMono && dstChans == DevFmtStereo) ||
342 (srcChans == DevFmtStereo && dstChans == DevFmtMono)))
343 return NULL;
345 converter = al_calloc(DEF_ALIGN, sizeof(*converter));
346 converter->mSrcType = srcType;
347 converter->mSrcChans = srcChans;
348 converter->mDstChans = dstChans;
350 return converter;
353 void DestroyChannelConverter(ChannelConverter **converter)
355 if(converter)
357 al_free(*converter);
358 *converter = NULL;
363 #define DECL_TEMPLATE(T) \
364 static void Mono2Stereo##T(ALfloat *restrict dst, const T *src, ALsizei frames)\
366 ALsizei i; \
367 for(i = 0;i < frames;i++) \
368 dst[i*2 + 1] = dst[i*2 + 0] = Sample_##T(src[i]) * 0.707106781187f; \
371 static void Stereo2Mono##T(ALfloat *restrict dst, const T *src, ALsizei frames)\
373 ALsizei i; \
374 for(i = 0;i < frames;i++) \
375 dst[i] = (Sample_##T(src[i*2 + 0])+Sample_##T(src[i*2 + 1])) * \
376 0.707106781187f; \
379 DECL_TEMPLATE(ALbyte)
380 DECL_TEMPLATE(ALubyte)
381 DECL_TEMPLATE(ALshort)
382 DECL_TEMPLATE(ALushort)
383 DECL_TEMPLATE(ALint)
384 DECL_TEMPLATE(ALuint)
385 DECL_TEMPLATE(ALfloat)
387 #undef DECL_TEMPLATE
389 void ChannelConverterInput(ChannelConverter *converter, const ALvoid *src, ALfloat *dst, ALsizei frames)
391 if(converter->mSrcChans == converter->mDstChans)
393 LoadSamples(dst, src, 1, converter->mSrcType,
394 frames*ChannelsFromDevFmt(converter->mSrcChans, 0));
395 return;
398 if(converter->mSrcChans == DevFmtStereo && converter->mDstChans == DevFmtMono)
400 switch(converter->mSrcType)
402 case DevFmtByte:
403 Stereo2MonoALbyte(dst, src, frames);
404 break;
405 case DevFmtUByte:
406 Stereo2MonoALubyte(dst, src, frames);
407 break;
408 case DevFmtShort:
409 Stereo2MonoALshort(dst, src, frames);
410 break;
411 case DevFmtUShort:
412 Stereo2MonoALushort(dst, src, frames);
413 break;
414 case DevFmtInt:
415 Stereo2MonoALint(dst, src, frames);
416 break;
417 case DevFmtUInt:
418 Stereo2MonoALuint(dst, src, frames);
419 break;
420 case DevFmtFloat:
421 Stereo2MonoALfloat(dst, src, frames);
422 break;
425 else /*if(converter->mSrcChans == DevFmtMono && converter->mDstChans == DevFmtStereo)*/
427 switch(converter->mSrcType)
429 case DevFmtByte:
430 Mono2StereoALbyte(dst, src, frames);
431 break;
432 case DevFmtUByte:
433 Mono2StereoALubyte(dst, src, frames);
434 break;
435 case DevFmtShort:
436 Mono2StereoALshort(dst, src, frames);
437 break;
438 case DevFmtUShort:
439 Mono2StereoALushort(dst, src, frames);
440 break;
441 case DevFmtInt:
442 Mono2StereoALint(dst, src, frames);
443 break;
444 case DevFmtUInt:
445 Mono2StereoALuint(dst, src, frames);
446 break;
447 case DevFmtFloat:
448 Mono2StereoALfloat(dst, src, frames);
449 break;