/
SDL_audiotypecvt.c
392 lines (318 loc) · 11.1 KB
1
2
/*
Simple DirectMedia Layer
3
Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../SDL_internal.h"
#include "SDL_audio.h"
#include "SDL_audio_c.h"
25
#include "SDL_assert.h"
26
27
28
29
30
#define DIVBY127 0.0078740157480315f
#define DIVBY32767 3.05185094759972e-05f
#define DIVBY2147483647 4.6566128752458e-10f
31
32
void SDLCALL
SDL_Convert_S8_to_F32(SDL_AudioCVT *cvt, SDL_AudioFormat format)
33
{
34
35
const Uint8 *src = ((const Uint8 *) (cvt->buf + cvt->len_cvt)) - 1;
float *dst = ((float *) (cvt->buf + cvt->len_cvt * 4)) - 1;
36
37
int i;
38
LOG_DEBUG_CONVERT("AUDIO_S8", "AUDIO_F32");
39
40
for (i = cvt->len_cvt / sizeof (Uint8); i; --i, --src, --dst) {
41
*dst = (((float) ((Sint8) *src)) * DIVBY127);
42
43
44
45
}
cvt->len_cvt *= 4;
if (cvt->filters[++cvt->filter_index]) {
46
cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS);
47
48
49
}
}
50
51
void SDLCALL
SDL_Convert_U8_to_F32(SDL_AudioCVT *cvt, SDL_AudioFormat format)
52
{
53
54
const Uint8 *src = ((const Uint8 *) (cvt->buf + cvt->len_cvt)) - 1;
float *dst = ((float *) (cvt->buf + cvt->len_cvt * 4)) - 1;
55
56
int i;
57
LOG_DEBUG_CONVERT("AUDIO_U8", "AUDIO_F32");
58
59
for (i = cvt->len_cvt / sizeof (Uint8); i; --i, --src, --dst) {
60
*dst = ((((float) *src) * DIVBY127) - 1.0f);
61
62
63
64
}
cvt->len_cvt *= 4;
if (cvt->filters[++cvt->filter_index]) {
65
cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS);
66
67
68
}
}
69
70
void SDLCALL
SDL_Convert_S16_to_F32(SDL_AudioCVT *cvt, SDL_AudioFormat format)
71
{
72
73
const Sint16 *src = ((const Sint16 *) (cvt->buf + cvt->len_cvt)) - 1;
float *dst = ((float *) (cvt->buf + cvt->len_cvt * 2)) - 1;
74
75
int i;
76
LOG_DEBUG_CONVERT("AUDIO_S16", "AUDIO_F32");
77
78
79
for (i = cvt->len_cvt / sizeof (Sint16); i; --i, --src, --dst) {
*dst = (((float) *src) * DIVBY32767);
80
81
82
83
}
cvt->len_cvt *= 2;
if (cvt->filters[++cvt->filter_index]) {
84
cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS);
85
86
87
}
}
88
89
void SDLCALL
SDL_Convert_U16_to_F32(SDL_AudioCVT *cvt, SDL_AudioFormat format)
90
{
91
92
const Uint16 *src = ((const Uint16 *) (cvt->buf + cvt->len_cvt)) - 1;
float *dst = ((float *) (cvt->buf + cvt->len_cvt * 2)) - 1;
93
94
int i;
95
LOG_DEBUG_CONVERT("AUDIO_U16", "AUDIO_F32");
96
97
98
for (i = cvt->len_cvt / sizeof (Uint16); i; --i, --src, --dst) {
*dst = ((((float) *src) * DIVBY32767) - 1.0f);
99
100
101
102
}
cvt->len_cvt *= 2;
if (cvt->filters[++cvt->filter_index]) {
103
cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS);
104
105
106
}
}
107
108
void SDLCALL
SDL_Convert_S32_to_F32(SDL_AudioCVT *cvt, SDL_AudioFormat format)
109
{
110
111
const Uint32 *src = (const Uint32 *) cvt->buf;
float *dst = (float *) cvt->buf;
112
113
int i;
114
LOG_DEBUG_CONVERT("AUDIO_S32", "AUDIO_F32");
115
116
117
for (i = cvt->len_cvt / sizeof (Sint32); i; --i, ++src, ++dst) {
*dst = (((float) *src) * DIVBY2147483647);
118
119
120
}
if (cvt->filters[++cvt->filter_index]) {
121
cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS);
122
123
124
}
}
125
126
void SDLCALL
SDL_Convert_F32_to_S8(SDL_AudioCVT *cvt, SDL_AudioFormat format)
127
{
128
129
const float *src = (const float *) cvt->buf;
Sint8 *dst = (Sint8 *) cvt->buf;
130
131
int i;
132
LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_S8");
133
134
135
for (i = cvt->len_cvt / sizeof (float); i; --i, ++src, ++dst) {
*dst = (Sint8) (*src * 127.0f);
136
137
}
138
cvt->len_cvt /= 4;
139
if (cvt->filters[++cvt->filter_index]) {
140
cvt->filters[cvt->filter_index](cvt, AUDIO_S8);
141
142
143
}
}
144
145
void SDLCALL
SDL_Convert_F32_to_U8(SDL_AudioCVT *cvt, SDL_AudioFormat format)
146
{
147
148
const float *src = (const float *) cvt->buf;
Uint8 *dst = (Uint8 *) cvt->buf;
149
150
int i;
151
LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_U8");
152
153
154
for (i = cvt->len_cvt / sizeof (float); i; --i, ++src, ++dst) {
*dst = (Uint8) ((*src + 1.0f) * 127.0f);
155
156
}
157
cvt->len_cvt /= 4;
158
if (cvt->filters[++cvt->filter_index]) {
159
cvt->filters[cvt->filter_index](cvt, AUDIO_U8);
160
161
162
}
}
163
164
void SDLCALL
SDL_Convert_F32_to_S16(SDL_AudioCVT *cvt, SDL_AudioFormat format)
165
{
166
167
const float *src = (const float *) cvt->buf;
Sint16 *dst = (Sint16 *) cvt->buf;
168
169
int i;
170
LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_S16");
171
172
173
for (i = cvt->len_cvt / sizeof (float); i; --i, ++src, ++dst) {
*dst = (Sint16) (*src * 32767.0f);
174
175
}
176
cvt->len_cvt /= 2;
177
if (cvt->filters[++cvt->filter_index]) {
178
cvt->filters[cvt->filter_index](cvt, AUDIO_S16SYS);
179
180
181
}
}
182
183
void SDLCALL
SDL_Convert_F32_to_U16(SDL_AudioCVT *cvt, SDL_AudioFormat format)
184
{
185
186
const float *src = (const float *) cvt->buf;
Uint16 *dst = (Uint16 *) cvt->buf;
187
188
int i;
189
LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_U16");
190
191
192
for (i = cvt->len_cvt / sizeof (float); i; --i, ++src, ++dst) {
*dst = (Uint16) ((*src + 1.0f) * 32767.0f);
193
194
}
195
cvt->len_cvt /= 2;
196
if (cvt->filters[++cvt->filter_index]) {
197
cvt->filters[cvt->filter_index](cvt, AUDIO_U16SYS);
198
199
200
}
}
201
202
void SDLCALL
SDL_Convert_F32_to_S32(SDL_AudioCVT *cvt, SDL_AudioFormat format)
203
{
204
205
const float *src = (const float *) cvt->buf;
Sint32 *dst = (Sint32 *) cvt->buf;
206
207
int i;
208
LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_S32");
209
210
211
for (i = cvt->len_cvt / sizeof (float); i; --i, ++src, ++dst) {
*dst = (Sint32) (*src * 2147483647.0);
212
213
214
}
if (cvt->filters[++cvt->filter_index]) {
215
cvt->filters[cvt->filter_index](cvt, AUDIO_S32SYS);
216
217
218
}
}
219
220
void
SDL_Upsample_Arbitrary(SDL_AudioCVT *cvt, const int channels)
221
{
222
const int srcsize = cvt->len_cvt - (64 * channels);
223
const int dstsize = (int) ((((double)(cvt->len_cvt/(channels*4))) * cvt->rate_incr)) * (channels*4);
224
register int eps = 0;
225
226
float *dst = ((float *) (cvt->buf + dstsize)) - channels;
const float *src = ((float *) (cvt->buf + cvt->len_cvt)) - channels;
227
228
229
const float *target = ((const float *) cvt->buf);
const size_t cpy = sizeof (float) * channels;
float sample[8];
230
float last_sample[8];
231
232
233
int i;
#if DEBUG_CONVERT
234
fprintf(stderr, "Upsample arbitrary (x%f), %d channels.\n", cvt->rate_incr, channels);
235
236
#endif
237
SDL_assert(channels <= 8);
238
239
240
241
for (i = 0; i < channels; i++) {
sample[i] = (float) ((((double) src[i]) + ((double) src[i - channels])) * 0.5);
}
242
SDL_memcpy(last_sample, src, cpy);
243
244
while (dst > target) {
245
SDL_memcpy(dst, sample, cpy);
246
dst -= channels;
247
248
eps += srcsize;
if ((eps << 1) >= dstsize) {
249
250
251
252
253
254
255
if (src > target) {
src -= channels;
for (i = 0; i < channels; i++) {
sample[i] = (float) ((((double) src[i]) + ((double) last_sample[i])) * 0.5);
}
} else {
256
}
257
SDL_memcpy(last_sample, src, cpy);
258
259
eps -= dstsize;
}
260
261
}
262
cvt->len_cvt = dstsize;
263
if (cvt->filters[++cvt->filter_index]) {
264
cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS);
265
266
267
}
}
268
269
void
SDL_Downsample_Arbitrary(SDL_AudioCVT *cvt, const int channels)
270
{
271
272
273
274
275
276
277
278
279
const int srcsize = cvt->len_cvt - (64 * channels);
const int dstsize = (int) (((double)(cvt->len_cvt/(channels*4))) * cvt->rate_incr) * (channels*4);
register int eps = 0;
float *dst = (float *) cvt->buf;
const float *src = (float *) cvt->buf;
const float *target = (const float *) (cvt->buf + dstsize);
const size_t cpy = sizeof (float) * channels;
float last_sample[8];
float sample[8];
280
281
282
int i;
#if DEBUG_CONVERT
283
fprintf(stderr, "Downsample arbitrary (x%f), %d channels.\n", cvt->rate_incr, channels);
284
285
#endif
286
SDL_assert(channels <= 8);
287
288
289
SDL_memcpy(sample, src, cpy);
SDL_memcpy(last_sample, src, cpy);
290
291
while (dst < target) {
292
src += channels;
293
294
295
eps += dstsize;
if ((eps << 1) >= srcsize) {
SDL_memcpy(dst, sample, cpy);
296
dst += channels;
297
298
299
for (i = 0; i < channels; i++) {
sample[i] = (float) ((((double) src[i]) + ((double) last_sample[i])) * 0.5);
}
300
SDL_memcpy(last_sample, src, cpy);
301
302
eps -= srcsize;
}
303
304
}
305
cvt->len_cvt = dstsize;
306
if (cvt->filters[++cvt->filter_index]) {
307
cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS);
308
309
310
}
}
311
void
312
SDL_Upsample_Multiple(SDL_AudioCVT *cvt, const int channels)
313
{
314
315
316
317
const int multiple = (int) cvt->rate_incr;
const int dstsize = cvt->len_cvt * multiple;
float *buf = (float *) cvt->buf;
float *dst = ((float *) (cvt->buf + dstsize)) - channels;
318
const float *src = ((float *) (cvt->buf + cvt->len_cvt)) - channels;
319
const float *target = buf + channels;
320
321
const size_t cpy = sizeof (float) * channels;
float last_sample[8];
322
323
324
int i;
#if DEBUG_CONVERT
325
fprintf(stderr, "Upsample (x%d), %d channels.\n", multiple, channels);
326
327
#endif
328
SDL_assert(channels <= 8);
329
330
331
SDL_memcpy(last_sample, src, cpy);
332
while (dst > target) {
333
334
SDL_assert(src >= buf);
335
336
337
338
for (i = 0; i < channels; i++) {
dst[i] = (float) ((((double)src[i]) + ((double)last_sample[i])) * 0.5);
}
dst -= channels;
339
340
341
342
for (i = 1; i < multiple; i++) {
SDL_memcpy(dst, dst + channels, cpy);
dst -= channels;
343
}
344
345
src -= channels;
346
347
348
if (src > buf) {
SDL_memcpy(last_sample, src - channels, cpy);
}
349
350
}
351
cvt->len_cvt = dstsize;
352
if (cvt->filters[++cvt->filter_index]) {
353
cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS);
354
355
356
}
}
357
void
358
SDL_Downsample_Multiple(SDL_AudioCVT *cvt, const int channels)
359
{
360
const int multiple = (int) (1.0 / cvt->rate_incr);
361
362
363
364
365
366
const int dstsize = cvt->len_cvt / multiple;
float *dst = (float *) cvt->buf;
const float *src = (float *) cvt->buf;
const float *target = (const float *) (cvt->buf + dstsize);
const size_t cpy = sizeof (float) * channels;
float last_sample[8];
367
368
369
int i;
#if DEBUG_CONVERT
370
fprintf(stderr, "Downsample (x%d), %d channels.\n", multiple, channels);
371
372
#endif
373
374
SDL_assert(channels <= 8);
SDL_memcpy(last_sample, src, cpy);
375
376
377
378
379
380
while (dst < target) {
for (i = 0; i < channels; i++) {
dst[i] = (float) ((((double)src[i]) + ((double)last_sample[i])) * 0.5);
}
dst += channels;
381
382
383
SDL_memcpy(last_sample, src, cpy);
src += (channels * multiple);
384
385
}
386
cvt->len_cvt = dstsize;
387
if (cvt->filters[++cvt->filter_index]) {
388
cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS);
389
390
391
392
}
}
/* vi: set ts=4 sw=4 expandtab: */