1 /* Copyright (C) 2010-2020 The RetroArch team
3 * ---------------------------------------------------------------------------------------
4 * The following license statement only applies to this file (audio_mix.c).
5 * ---------------------------------------------------------------------------------------
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:
13 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
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.
27 #include <retro_environment.h>
30 #include <emmintrin.h>
31 #elif defined(__ALTIVEC__)
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>
41 void audio_mix_volume_C(float *out, const float *in, float vol, size_t samples)
44 for (i = 0; i < samples; i++)
45 out[i] += in[i] * vol;
49 void audio_mix_volume_SSE2(float *out, const float *in, float vol, size_t samples)
51 size_t i, remaining_samples;
52 __m128 volume = _mm_set1_ps(vol);
54 for (i = 0; i + 16 <= samples; i += 16, out += 16, in += 16)
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);
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));
70 for (j = 0; j < 4; j++)
71 _mm_storeu_ps(out + 4 * j, _mm_add_ps(input[j], additive[j]));
74 remaining_samples = samples - i;
76 for (i = 0; i < remaining_samples; i++)
77 out[i] += in[i] * vol;
81 void audio_mix_free_chunk(audio_chunk_t *chunk)
87 if (chunk->rwav && chunk->rwav->samples)
89 /* rwav_free only frees the samples */
90 rwav_free(chunk->rwav);
98 if (chunk->upsample_buf)
99 memalign_free(chunk->upsample_buf);
101 if (chunk->float_buf)
102 memalign_free(chunk->float_buf);
104 if (chunk->float_resample_buf)
105 memalign_free(chunk->float_resample_buf);
107 if (chunk->resample_buf)
108 memalign_free(chunk->resample_buf);
110 if (chunk->resampler && chunk->resampler_data)
111 chunk->resampler->free(chunk->resampler_data);
116 audio_chunk_t* audio_mix_load_wav_file(const char *path, int sample_rate,
117 const char *resampler_ident, enum resampler_quality quality)
123 audio_chunk_t *chunk = (audio_chunk_t*)malloc(sizeof(*chunk));
129 chunk->upsample_buf = NULL;
130 chunk->float_buf = NULL;
131 chunk->float_resample_buf = NULL;
132 chunk->resample_buf = NULL;
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));
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;
152 if (!filestream_read_file(path, &buf, &len))
158 if (rwav_load(chunk->rwav, chunk->buf, chunk->len) == RWAV_ITERATE_ERROR)
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));
166 sample_size = chunk->rwav->bitspersample / 8;
168 if (sample_size == 1)
172 if (chunk->rwav->numchannels == 1)
174 for (i = 0; i < chunk->rwav->numsamples; i++)
177 (uint8_t*)chunk->rwav->samples) + i;
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);
185 else if (chunk->rwav->numchannels == 2)
187 for (i = 0; i < chunk->rwav->numsamples; i++)
190 (uint8_t*)chunk->rwav->samples) +
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);
200 else if (sample_size == 2)
202 if (chunk->rwav->numchannels == 1)
206 for (i = 0; i < chunk->rwav->numsamples; i++)
208 int16_t sample = ((int16_t*)
209 chunk->rwav->samples)[i];
211 chunk->upsample_buf[i * 2] = sample;
212 chunk->upsample_buf[(i * 2) + 1] = sample;
215 else if (chunk->rwav->numchannels == 2)
216 memcpy(chunk->upsample_buf, chunk->rwav->samples,
217 chunk->rwav->subchunk2size);
219 else if (sample_size != 2)
221 /* we don't support any other sample size besides 8 and 16-bit yet */
225 if (sample_rate != (int)chunk->rwav->samplerate)
227 chunk->resample = true;
228 chunk->ratio = (double)sample_rate / chunk->rwav->samplerate;
230 retro_resampler_realloc(&chunk->resampler_data,
236 if (chunk->resampler && chunk->resampler_data)
238 struct resampler_data info;
240 chunk->float_buf = (float*)memalign_alloc(128,
241 chunk->rwav->numsamples * 2 *
242 chunk->ratio * sizeof(float));
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));
250 convert_s16_to_float(chunk->float_buf,
251 chunk->upsample_buf, chunk->rwav->numsamples * 2, 1.0);
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;
261 chunk->resampler->process(chunk->resampler_data, &info);
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);
276 audio_mix_free_chunk(chunk);
281 size_t audio_mix_get_chunk_num_samples(audio_chunk_t *chunk)
290 return chunk->resample_len;
291 return chunk->rwav->numsamples;
295 /* no other filetypes supported yet */
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
305 * Get a sample from an audio chunk.
307 * Returns: A signed 16-bit audio sample.
309 int16_t audio_mix_get_chunk_sample(audio_chunk_t *chunk,
310 unsigned channel, size_t index)
318 int sample_size = chunk->rwav->bitspersample / 8;
319 int16_t sample_out = 0;
321 /* 0 is the first/left channel */
322 uint8_t *sample = NULL;
325 sample = (uint8_t*)chunk->resample_buf +
326 (sample_size * index * chunk->rwav->numchannels)
327 + (channel * sample_size);
329 sample = (uint8_t*)chunk->upsample_buf +
330 (sample_size * index * chunk->rwav->numchannels)
331 + (channel * sample_size);
333 sample_out = (int16_t)*sample;
339 /* no other filetypes supported yet */
343 int16_t* audio_mix_get_chunk_samples(audio_chunk_t *chunk)
354 sample = chunk->resample_buf;
356 sample = chunk->upsample_buf;
365 int audio_mix_get_chunk_num_channels(audio_chunk_t *chunk)
372 return chunk->rwav->numchannels;
375 /* don't support other formats yet */