update libchdr
[pcsx_rearmed.git] / deps / libretro-common / audio / audio_mix.c
1 /* Copyright  (C) 2010-2020 The RetroArch team
2  *
3  * ---------------------------------------------------------------------------------------
4  * The following license statement only applies to this file (audio_mix.c).
5  * ---------------------------------------------------------------------------------------
6  *
7  * Permission is hereby granted, free of charge,
8  * to any person obtaining a copy of this software and associated documentation files (the "Software"),
9  * to deal in the Software without restriction, including without limitation the rights to
10  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
11  * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
16  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  */
22
23 #include <stdlib.h>
24 #include <string.h>
25 #include <memalign.h>
26
27 #include <retro_environment.h>
28
29 #if defined(__SSE2__)
30 #include <emmintrin.h>
31 #elif defined(__ALTIVEC__)
32 #include <altivec.h>
33 #endif
34
35 #include <retro_miscellaneous.h>
36 #include <audio/audio_mix.h>
37 #include <streams/file_stream.h>
38 #include <audio/conversion/float_to_s16.h>
39 #include <audio/conversion/s16_to_float.h>
40
41 void audio_mix_volume_C(float *out, const float *in, float vol, size_t samples)
42 {
43    size_t i;
44    for (i = 0; i < samples; i++)
45       out[i] += in[i] * vol;
46 }
47
48 #ifdef __SSE2__
49 void audio_mix_volume_SSE2(float *out, const float *in, float vol, size_t samples)
50 {
51    size_t i, remaining_samples;
52    __m128 volume = _mm_set1_ps(vol);
53
54    for (i = 0; i + 16 <= samples; i += 16, out += 16, in += 16)
55    {
56       unsigned j;
57       __m128 input[4];
58       __m128 additive[4];
59
60       input[0]    = _mm_loadu_ps(out +  0);
61       input[1]    = _mm_loadu_ps(out +  4);
62       input[2]    = _mm_loadu_ps(out +  8);
63       input[3]    = _mm_loadu_ps(out + 12);
64
65       additive[0] = _mm_mul_ps(volume, _mm_loadu_ps(in +  0));
66       additive[1] = _mm_mul_ps(volume, _mm_loadu_ps(in +  4));
67       additive[2] = _mm_mul_ps(volume, _mm_loadu_ps(in +  8));
68       additive[3] = _mm_mul_ps(volume, _mm_loadu_ps(in + 12));
69
70       for (j = 0; j < 4; j++)
71          _mm_storeu_ps(out + 4 * j, _mm_add_ps(input[j], additive[j]));
72    }
73
74    remaining_samples = samples - i;
75
76    for (i = 0; i < remaining_samples; i++)
77       out[i] += in[i] * vol;
78 }
79 #endif
80
81 void audio_mix_free_chunk(audio_chunk_t *chunk)
82 {
83    if (!chunk)
84       return;
85
86 #ifdef HAVE_RWAV
87    if (chunk->rwav && chunk->rwav->samples)
88    {
89       /* rwav_free only frees the samples */
90       rwav_free(chunk->rwav);
91       free(chunk->rwav);
92    }
93 #endif
94
95    if (chunk->buf)
96       free(chunk->buf);
97
98    if (chunk->upsample_buf)
99       memalign_free(chunk->upsample_buf);
100
101    if (chunk->float_buf)
102       memalign_free(chunk->float_buf);
103
104    if (chunk->float_resample_buf)
105       memalign_free(chunk->float_resample_buf);
106
107    if (chunk->resample_buf)
108       memalign_free(chunk->resample_buf);
109
110    if (chunk->resampler && chunk->resampler_data)
111       chunk->resampler->free(chunk->resampler_data);
112
113    free(chunk);
114 }
115
116 audio_chunk_t* audio_mix_load_wav_file(const char *path, int sample_rate,
117       const char *resampler_ident, enum resampler_quality quality)
118 {
119 #ifdef HAVE_RWAV
120    int sample_size;
121    int64_t len                = 0;
122    void *buf                  = NULL;
123    audio_chunk_t *chunk       = (audio_chunk_t*)malloc(sizeof(*chunk));
124
125    if (!chunk)
126       return NULL;
127
128    chunk->buf                 = NULL;
129    chunk->upsample_buf        = NULL;
130    chunk->float_buf           = NULL;
131    chunk->float_resample_buf  = NULL;
132    chunk->resample_buf        = NULL;
133    chunk->len                 = 0;
134    chunk->resample_len        = 0;
135    chunk->sample_rate         = sample_rate;
136    chunk->resample            = false;
137    chunk->resampler           = NULL;
138    chunk->resampler_data      = NULL;
139    chunk->ratio               = 0.00f;
140    chunk->rwav                = (rwav_t*)malloc(sizeof(rwav_t));
141
142    if (!chunk->rwav)
143       goto error;
144
145    chunk->rwav->bitspersample = 0;
146    chunk->rwav->numchannels   = 0;
147    chunk->rwav->samplerate    = 0;
148    chunk->rwav->numsamples    = 0;
149    chunk->rwav->subchunk2size = 0;
150    chunk->rwav->samples       = NULL;
151
152    if (!filestream_read_file(path, &buf, &len))
153       goto error;
154
155    chunk->buf                 = buf;
156    chunk->len                 = len;
157
158    if (rwav_load(chunk->rwav, chunk->buf, chunk->len) == RWAV_ITERATE_ERROR)
159       goto error;
160
161    /* numsamples does not know or care about
162     * multiple channels, but we need space for 2 */
163    chunk->upsample_buf        = (int16_t*)memalign_alloc(128,
164          chunk->rwav->numsamples * 2 * sizeof(int16_t));
165
166    sample_size                = chunk->rwav->bitspersample / 8;
167
168    if (sample_size == 1)
169    {
170       unsigned i;
171
172       if (chunk->rwav->numchannels == 1)
173       {
174          for (i = 0; i < chunk->rwav->numsamples; i++)
175          {
176             uint8_t *sample                  = (
177                   (uint8_t*)chunk->rwav->samples) + i;
178
179             chunk->upsample_buf[i * 2]       = 
180                (int16_t)((sample[0] - 128) << 8);
181             chunk->upsample_buf[(i * 2) + 1] = 
182                (int16_t)((sample[0] - 128) << 8);
183          }
184       }
185       else if (chunk->rwav->numchannels == 2)
186       {
187          for (i = 0; i < chunk->rwav->numsamples; i++)
188          {
189             uint8_t *sample                  = (
190                   (uint8_t*)chunk->rwav->samples) +
191                (i * 2);
192
193             chunk->upsample_buf[i * 2]       = 
194                (int16_t)((sample[0] - 128) << 8);
195             chunk->upsample_buf[(i * 2) + 1] = 
196                (int16_t)((sample[1] - 128) << 8);
197          }
198       }
199    }
200    else if (sample_size == 2)
201    {
202       if (chunk->rwav->numchannels == 1)
203       {
204          unsigned i;
205
206          for (i = 0; i < chunk->rwav->numsamples; i++)
207          {
208             int16_t sample                   = ((int16_t*)
209                   chunk->rwav->samples)[i];
210
211             chunk->upsample_buf[i * 2]       = sample;
212             chunk->upsample_buf[(i * 2) + 1] = sample;
213          }
214       }
215       else if (chunk->rwav->numchannels == 2)
216          memcpy(chunk->upsample_buf, chunk->rwav->samples,
217                chunk->rwav->subchunk2size);
218    }
219    else if (sample_size != 2)
220    {
221       /* we don't support any other sample size besides 8 and 16-bit yet */
222       goto error;
223    }
224
225    if (sample_rate != (int)chunk->rwav->samplerate)
226    {
227       chunk->resample = true;
228       chunk->ratio    = (double)sample_rate / chunk->rwav->samplerate;
229
230       retro_resampler_realloc(&chunk->resampler_data,
231             &chunk->resampler,
232             resampler_ident,
233             quality,
234             chunk->ratio);
235
236       if (chunk->resampler && chunk->resampler_data)
237       {
238          struct resampler_data info;
239
240          chunk->float_buf          = (float*)memalign_alloc(128,
241                chunk->rwav->numsamples * 2 * 
242                chunk->ratio * sizeof(float));
243
244          /* why is *3 needed instead of just *2? Does the 
245           * sinc driver require more space than we know about? */
246          chunk->float_resample_buf = (float*)memalign_alloc(128,
247                chunk->rwav->numsamples * 3 * 
248                chunk->ratio * sizeof(float));
249
250          convert_s16_to_float(chunk->float_buf,
251                chunk->upsample_buf, chunk->rwav->numsamples * 2, 1.0);
252
253          info.data_in       = (const float*)chunk->float_buf;
254          info.data_out      = chunk->float_resample_buf;
255          /* a 'frame' consists of two channels, so we set this
256           * to the number of samples irrespective of channel count */
257          info.input_frames  = chunk->rwav->numsamples;
258          info.output_frames = 0;
259          info.ratio         = chunk->ratio;
260
261          chunk->resampler->process(chunk->resampler_data, &info);
262
263          /* number of output_frames does not increase with 
264           * multiple channels, but assume we need space for 2 */
265          chunk->resample_buf = (int16_t*)memalign_alloc(128,
266                info.output_frames * 2 * sizeof(int16_t));
267          chunk->resample_len = info.output_frames;
268          convert_float_to_s16(chunk->resample_buf,
269                chunk->float_resample_buf, info.output_frames * 2);
270       }
271    }
272
273    return chunk;
274
275 error:
276    audio_mix_free_chunk(chunk);
277 #endif
278    return NULL;
279 }
280
281 size_t audio_mix_get_chunk_num_samples(audio_chunk_t *chunk)
282 {
283    if (!chunk)
284       return 0;
285
286 #ifdef HAVE_RWAV
287    if (chunk->rwav)
288    {
289       if (chunk->resample)
290          return chunk->resample_len;
291       return chunk->rwav->numsamples;
292    }
293 #endif
294
295    /* no other filetypes supported yet */
296    return 0;
297 }
298
299 /**
300  * audio_mix_get_chunk_sample:
301  * @chunk              : audio chunk instance
302  * @channel            : channel of the sample (0=left, 1=right)
303  * @index              : index of the sample
304  *
305  * Get a sample from an audio chunk.
306  *
307  * Returns: A signed 16-bit audio sample.
308  **/
309 int16_t audio_mix_get_chunk_sample(audio_chunk_t *chunk,
310       unsigned channel, size_t index)
311 {
312    if (!chunk)
313       return 0;
314
315 #ifdef HAVE_RWAV
316    if (chunk->rwav)
317    {
318       int sample_size    = chunk->rwav->bitspersample / 8;
319       int16_t sample_out = 0;
320
321       /* 0 is the first/left channel */
322       uint8_t *sample    = NULL;
323
324       if (chunk->resample)
325          sample = (uint8_t*)chunk->resample_buf +
326             (sample_size * index * chunk->rwav->numchannels) 
327             + (channel * sample_size);
328       else
329          sample = (uint8_t*)chunk->upsample_buf +
330             (sample_size * index * chunk->rwav->numchannels) 
331             + (channel * sample_size);
332
333       sample_out = (int16_t)*sample;
334
335       return sample_out;
336    }
337 #endif
338
339    /* no other filetypes supported yet */
340    return 0;
341 }
342
343 int16_t* audio_mix_get_chunk_samples(audio_chunk_t *chunk)
344 {
345    if (!chunk)
346       return 0;
347
348 #ifdef HAVE_RWAV
349    if (chunk->rwav)
350    {
351       int16_t *sample;
352
353       if (chunk->resample)
354          sample = chunk->resample_buf;
355       else
356          sample = chunk->upsample_buf;
357
358       return sample;
359    }
360 #endif
361
362    return NULL;
363 }
364
365 int audio_mix_get_chunk_num_channels(audio_chunk_t *chunk)
366 {
367    if (!chunk)
368       return 0;
369
370 #ifdef HAVE_RWAV
371    if (chunk->rwav)
372       return chunk->rwav->numchannels;
373 #endif
374
375    /* don't support other formats yet */
376    return 0;
377 }