JSON-based controller descriptions
[lsnes.git] / src / core / audioapi.cpp
bloba45a8f650ed46327292062cddc1aba8cf623156d
1 #include "core/audioapi.hpp"
2 #include "core/dispatch.hpp"
3 #include "core/framerate.hpp"
4 #include "library/minmax.hpp"
5 #include "library/threadtypes.hpp"
6 #include <cstring>
7 #include <cmath>
8 #include <iostream>
9 #include <unistd.h>
10 #include <sys/time.h>
12 //3 music buffers is not enough due to huge blocksizes used by SDL.
13 #define MUSIC_BUFFERS 8
14 #define MAX_VOICE_ADJUST 200
16 namespace
18 const unsigned voicep_bufsize = 65536;
19 const unsigned voicer_bufsize = 65536;
20 const unsigned music_bufsize = 8192;
21 float voicep_buffer[voicep_bufsize];
22 float voicer_buffer[voicer_bufsize];
23 int16_t music_buffer[MUSIC_BUFFERS * music_bufsize];
24 volatile bool music_stereo[MUSIC_BUFFERS];
25 volatile double music_rate[MUSIC_BUFFERS];
26 volatile size_t music_size[MUSIC_BUFFERS];
27 unsigned music_ptr;
28 unsigned last_complete_music_seen = MUSIC_BUFFERS + 1;
29 volatile unsigned last_complete_music = MUSIC_BUFFERS;
30 volatile unsigned voicep_get = 0;
31 volatile unsigned voicep_put = 0;
32 volatile unsigned voicer_get = 0;
33 volatile unsigned voicer_put = 0;
34 volatile unsigned voice_rate_play = 40000;
35 volatile unsigned orig_voice_rate_play = 40000;
36 volatile unsigned voice_rate_rec = 40000;
37 volatile bool dummy_cb_active_record = false;
38 volatile bool dummy_cb_active_play = false;
39 volatile bool dummy_cb_quit = false;
40 volatile float music_volume = 1;
41 volatile float voicep_volume = 32767.0;
42 volatile float voicer_volume = 1.0/32768;
44 struct dummy_cb_proc
46 int operator()()
48 int16_t buf[16384];
49 uint64_t last_ts = get_utime();
50 while(!dummy_cb_quit) {
51 uint64_t cur_ts = get_utime();
52 uint64_t dt = cur_ts - last_ts;
53 last_ts = cur_ts;
54 unsigned samples = dt / 25;
55 if(samples > 16384)
56 samples = 16384; //Don't get crazy.
57 if(dummy_cb_active_play)
58 audioapi_get_mixed(buf, samples, false);
59 if(dummy_cb_active_record)
60 audioapi_put_voice(NULL, samples);
61 usleep(10000);
63 return 0;
67 dummy_cb_proc* dummy_cb_proc_obj;
68 thread_class* dummy_cb_thread;
71 // | -1 1 -1 1 | 1 0 0 0 |
72 // | 0 0 0 1 | 0 1 0 0 |
73 // | 1 1 1 1 | 0 0 1 0 |
74 // | 8 4 2 1 | 0 0 0 1 |
77 // | 6 0 0 0 |-1 4 -3 1 | |-1 3 -3 1|
78 // | 0 6 0 0 | 3 -6 3 0 | 1/6 | 3 -6 3 0|
79 // | 0 0 6 0 |-2 -4 6 -1 | |-2 -3 6 -1|
80 // | 0 0 0 6 | 0 6 0 0 | | 0 6 0 0|
84 void cubicitr_solve(double v1, double v2, double v3, double v4, double& A, double& B, double& C, double& D)
86 A = (-v1 + 3 * v2 - 3 * v3 + v4) / 6;
87 B = (v1 - 2 * v2 + v3) / 2;
88 C = (-2 * v1 - 3 * v2 + 6 * v3 - v4) / 6;
89 D = v2;
92 void linintr_solve(double v1, double v2, double& A, double& B)
94 A = (v2 - v1);
95 B = v1;
99 audioapi_resampler::audioapi_resampler()
101 position = 0;
102 vAl = vBl = vCl = vDl = 0;
103 vAr = vBr = vCr = vDr = 0;
106 void audioapi_resampler::resample(float*& in, size_t& insize, float*& out, size_t& outsize, double ratio, bool stereo)
108 double iratio = 1 / ratio;
109 while(outsize) {
110 double newpos = position + iratio;
111 while(newpos >= 1) {
112 //Gotta load a new sample.
113 if(!insize)
114 goto exit;
115 vAl = vBl; vBl = vCl; vCl = vDl; vDl = in[0];
116 vAr = vBr; vBr = vCr; vCr = vDr; vDr = in[stereo ? 1 : 0];
117 --insize;
118 in += (stereo ? 2 : 1);
119 newpos = newpos - 1;
121 position = newpos;
122 double A, B, C, D;
123 cubicitr_solve(vAl, vBl, vCl, vDl, A, B, C, D);
124 *(out++) = ((A * position + B) * position + C) * position + D;
125 if(stereo) {
126 cubicitr_solve(vAr, vBr, vCr, vDr, A, B, C, D);
127 *(out++) = ((A * position + B) * position + C) * position + D;
129 --outsize;
131 exit:
136 std::pair<unsigned, unsigned> audioapi_voice_rate()
138 return std::make_pair(voice_rate_rec, voice_rate_play);
141 unsigned audioapi_orig_voice_rate()
143 return orig_voice_rate_play;
146 void audioapi_voice_rate(unsigned rate_rec, unsigned rate_play)
148 if(rate_rec)
149 voice_rate_rec = rate_rec;
150 else
151 voice_rate_rec = 40000;
152 dummy_cb_active_record = !rate_rec;
153 if(rate_play)
154 orig_voice_rate_play = voice_rate_play = rate_play;
155 else
156 orig_voice_rate_play = voice_rate_play = 40000;
157 dummy_cb_active_play = !rate_play;
160 unsigned audioapi_voice_p_status()
162 unsigned p = voicep_put;
163 unsigned g = voicep_get;
164 if(g > p)
165 return g - p - 1;
166 else
167 return voicep_bufsize - (p - g) - 1;
170 unsigned audioapi_voice_p_status2()
172 unsigned p = voicep_put;
173 unsigned g = voicep_get;
174 if(g > p)
175 return voicep_bufsize - (g - p);
176 else
177 return (p - g);
180 unsigned audioapi_voice_r_status()
182 unsigned p = voicer_put;
183 unsigned g = voicer_get;
184 if(g > p)
185 return voicer_bufsize - (g - p);
186 else
187 return (p - g);
190 void audioapi_play_voice(float* samples, size_t count)
192 unsigned ptr = voicep_put;
193 for(size_t i = 0; i < count; i++) {
194 voicep_buffer[ptr++] = samples[i];
195 if(ptr == voicep_bufsize)
196 ptr = 0;
198 voicep_put = ptr;
201 void audioapi_record_voice(float* samples, size_t count)
203 unsigned ptr = voicer_get;
204 for(size_t i = 0; i < count; i++) {
205 samples[i] = voicer_buffer[ptr++];
206 if(ptr == voicer_bufsize)
207 ptr = 0;
209 voicer_get = ptr;
212 void audioapi_submit_buffer(int16_t* samples, size_t count, bool stereo, double rate)
214 if(stereo)
215 for(unsigned i = 0; i < count; i++)
216 information_dispatch::do_sample(samples[2 * i + 0], samples[2 * i + 1]);
217 else
218 for(unsigned i = 0; i < count; i++)
219 information_dispatch::do_sample(samples[i], samples[i]);
220 //Limit buffers to avoid overrunning.
221 if(count > music_bufsize / (stereo ? 2 : 1))
222 count = music_bufsize / (stereo ? 2 : 1);
223 unsigned bidx = last_complete_music;
224 bidx = (bidx > (MUSIC_BUFFERS - 2)) ? 0 : bidx + 1;
225 memcpy(music_buffer + bidx * music_bufsize, samples, count * (stereo ? 2 : 1) * sizeof(int16_t));
226 music_stereo[bidx] = stereo;
227 music_rate[bidx] = rate;
228 music_size[bidx] = count;
229 last_complete_music = bidx;
232 struct audioapi_buffer audioapi_get_music(size_t played)
234 static bool last_adjust = false; //Adjusting consequtively is too hard.
235 unsigned midx = last_complete_music_seen;
236 unsigned midx2 = last_complete_music;
237 if(midx2 >= MUSIC_BUFFERS) {
238 //Special case: No buffer.
239 struct audioapi_buffer out;
240 out.samples = NULL;
241 out.pointer = 0;
242 //The rest are arbitrary.
243 out.total = 64;
244 out.stereo = false;
245 out.rate = 48000;
246 return out;
248 //Handle ACK. If the current buffer is too old, we want to ignore the ACK.
249 if(midx >= MUSIC_BUFFERS) {
250 //Load initial buffer.
251 midx = last_complete_music_seen = 0;
252 music_ptr = 0;
253 } else {
254 music_ptr += played;
255 //Otherwise, check if current buffer is not next on the line to be overwritten.
256 if((midx2 + 1) % MUSIC_BUFFERS == midx) {
257 //It is, bump buffer by one.
258 if(!last_adjust && voice_rate_play > orig_voice_rate_play - MAX_VOICE_ADJUST)
259 voice_rate_play--;
260 last_adjust = true;
261 midx = last_complete_music_seen = (midx + 1) % MUSIC_BUFFERS;
262 music_ptr = 0;
263 } else if(music_ptr >= music_size[midx] && midx != midx2) {
264 //It isn't, but current buffer is finished.
265 midx = last_complete_music_seen = (midx + 1) % MUSIC_BUFFERS;
266 music_ptr = 0;
267 last_adjust = false;
268 } else if(music_ptr >= music_size[midx] && midx == midx2) {
269 if(!last_adjust && voice_rate_play < orig_voice_rate_play + MAX_VOICE_ADJUST)
270 voice_rate_play++;
271 last_adjust = true;
272 //Current buffer is finished, but there is no new buffer.
273 //Send silence.
274 } else {
275 last_adjust = false;
276 //Can continue.
279 //Fill the structure.
280 struct audioapi_buffer out;
281 if(music_ptr < music_size[midx]) {
282 out.samples = music_buffer + midx * music_bufsize;
283 out.pointer = music_ptr;
284 out.total = music_size[midx];
285 out.stereo = music_stereo[midx];
286 out.rate = music_rate[midx];
287 } else {
288 //Run out of buffers to play.
289 out.samples = NULL;
290 out.pointer = 0;
291 out.total = 64; //Arbitrary.
292 out.stereo = music_stereo[midx];
293 out.rate = music_rate[midx];
294 if(out.rate < 100)
295 out.rate = 48000; //Apparently there are buffers with zero rate.
297 return out;
300 void audioapi_get_voice(float* samples, size_t count)
302 unsigned g = voicep_get;
303 unsigned p = voicep_put;
304 if(samples) {
305 for(size_t i = 0; i < count; i++) {
306 if(g != p)
307 samples[i] = voicep_volume * voicep_buffer[g++];
308 else
309 samples[i] = 0.0;
310 if(g == voicep_bufsize)
311 g = 0;
313 } else {
314 for(size_t i = 0; i < count; i++) {
315 if(g != p)
316 g++;
317 if(g == voicep_bufsize)
318 g = 0;
321 voicep_get = g;
324 void audioapi_put_voice(float* samples, size_t count)
326 unsigned ptr = voicer_put;
327 audioapi_vu_vin(samples, count, false, voice_rate_rec, voicer_volume);
328 for(size_t i = 0; i < count; i++) {
329 voicer_buffer[ptr++] = samples ? voicer_volume * samples[i] : 0.0;
330 if(ptr == voicer_bufsize)
331 ptr = 0;
333 voicer_put = ptr;
336 void audioapi_init()
338 voicep_get = 0;
339 voicep_put = 0;
340 voicer_get = 0;
341 voicer_put = 0;
342 last_complete_music = 3;
343 last_complete_music_seen = 4;
344 dummy_cb_active_play = true;
345 dummy_cb_active_record = true;
346 dummy_cb_quit = false;
347 dummy_cb_proc_obj = new dummy_cb_proc;
348 dummy_cb_thread = new thread_class(*dummy_cb_proc_obj);
351 void audioapi_quit()
353 dummy_cb_quit = true;
354 dummy_cb_thread->join();
355 delete dummy_cb_proc_obj;
358 void audioapi_music_volume(float volume)
360 music_volume = volume;
363 float audioapi_music_volume()
365 return music_volume;
368 void audioapi_voicep_volume(float volume)
370 voicep_volume = volume * 32767;
373 float audioapi_voicep_volume()
375 return voicep_volume / 32767;
378 void audioapi_voicer_volume(float volume)
380 voicer_volume = volume / 32768;
383 float audioapi_voicer_volume()
385 return voicer_volume * 32768;
388 void audioapi_get_mixed(int16_t* samples, size_t count, bool stereo)
390 static audioapi_resampler music_resampler;
391 const size_t intbuf_size = 256;
392 float intbuf[intbuf_size];
393 float intbuf2[intbuf_size];
394 while(count > 0) {
395 audioapi_buffer b = audioapi_get_music(0);
396 float* in = intbuf;
397 float* out = intbuf2;
398 size_t outdata_used;
399 if(b.stereo) {
400 size_t indata = min(b.total - b.pointer, intbuf_size / 2);
401 size_t outdata = min(intbuf_size / 2, count);
402 size_t indata_used = indata;
403 outdata_used = outdata;
404 if(b.samples)
405 for(size_t i = 0; i < 2 * indata; i++)
406 intbuf[i] = music_volume * b.samples[i + 2 * b.pointer];
407 else
408 for(size_t i = 0; i < 2 * indata; i++)
409 intbuf[i] = 0;
410 music_resampler.resample(in, indata, out, outdata, (double)voice_rate_play / b.rate, true);
411 indata_used -= indata;
412 outdata_used -= outdata;
413 audioapi_get_music(indata_used);
414 audioapi_get_voice(intbuf, outdata_used);
416 audioapi_vu_mleft(intbuf2, outdata_used, true, voice_rate_play, 1 / 32768.0);
417 audioapi_vu_mright(intbuf2 + 1, outdata_used, true, voice_rate_play, 1 / 32768.0);
418 audioapi_vu_vout(intbuf, outdata_used, false, voice_rate_play, 1 / 32768.0);
420 for(size_t i = 0; i < outdata_used * (stereo ? 2 : 1); i++)
421 intbuf2[i] = max(min(intbuf2[i] + intbuf[i / 2], 32766.0f), -32767.0f);
422 if(stereo)
423 for(size_t i = 0; i < outdata_used * 2; i++)
424 samples[i] = intbuf2[i];
425 else
426 for(size_t i = 0; i < outdata_used; i++)
427 samples[i] = (intbuf2[2 * i + 0] + intbuf2[2 * i + 1]) / 2;
428 } else {
429 size_t indata = min(b.total - b.pointer, intbuf_size);
430 size_t outdata = min(intbuf_size, count);
431 size_t indata_used = indata;
432 outdata_used = outdata;
433 if(b.samples)
434 for(size_t i = 0; i < indata; i++)
435 intbuf[i] = music_volume * b.samples[i + b.pointer];
436 else
437 for(size_t i = 0; i < indata; i++)
438 intbuf[i] = 0;
439 music_resampler.resample(in, indata, out, outdata, (double)voice_rate_play / b.rate, false);
440 indata_used -= indata;
441 outdata_used -= outdata;
442 audioapi_get_music(indata_used);
443 audioapi_get_voice(intbuf, outdata_used);
445 audioapi_vu_mleft(intbuf2, outdata_used, false, voice_rate_play, 1 / 32768.0);
446 audioapi_vu_mright(intbuf2, outdata_used, false, voice_rate_play, 1 / 32768.0);
447 audioapi_vu_vout(intbuf, outdata_used, false, voice_rate_play, 1 / 32768.0);
449 for(size_t i = 0; i < outdata_used; i++)
450 intbuf2[i] = max(min(intbuf2[i] + intbuf[i], 32766.0f), -32767.0f);
451 if(stereo)
452 for(size_t i = 0; i < outdata_used; i++) {
453 samples[2 * i + 0] = intbuf2[i];
454 samples[2 * i + 1] = intbuf2[i];
456 else
457 for(size_t i = 0; i < outdata_used; i++)
458 samples[i] = intbuf2[i];
460 samples += (stereo ? 2 : 1) * outdata_used;
461 count -= outdata_used;
465 audioapi_vumeter::audioapi_vumeter()
467 accumulator = 0;
468 samples = 0;
469 vu = -999.0;
472 void audioapi_vumeter::operator()(float* asamples, size_t count, bool stereo, double rate, double scale)
474 size_t limit = rate / 25;
475 //If we already at or exceed limit, cut immediately.
476 if(samples >= limit)
477 update_vu();
478 if(asamples) {
479 double sscale = scale * scale;
480 size_t j = 0;
481 if(stereo)
482 for(size_t i = 0; i < count; i++) {
483 accumulator += sscale * asamples[j] * asamples[j];
484 j += 2;
485 samples++;
486 if(samples >= limit)
487 update_vu();
489 else
490 for(size_t i = 0; i < count; i++) {
491 accumulator += sscale * asamples[i] * asamples[i];
492 samples++;
493 if(samples >= limit)
494 update_vu();
496 } else
497 for(size_t i = 0; i < count; i++) {
498 samples++;
499 if(samples >= limit)
500 update_vu();
504 void audioapi_vumeter::update_vu()
506 if(!samples) {
507 vu = -999.0;
508 accumulator = 0;
509 } else {
510 double a = accumulator;
511 if(a < 1e-120)
512 a = 1e-120; //Don't take log of zero.
513 vu = 10 / log(10) * (log(a) - log(samples));
514 if(vu < -999.0)
515 vu = -999.0;
516 accumulator = 0;
517 samples = 0;
519 notify_vu_change();
522 //VU values.
523 audioapi_vumeter audioapi_vu_mleft;
524 audioapi_vumeter audioapi_vu_mright;
525 audioapi_vumeter audioapi_vu_vout;
526 audioapi_vumeter audioapi_vu_vin;