1 #include "core/advdumper.hpp"
2 #include "core/audioapi.hpp"
3 #include "core/dispatch.hpp"
4 #include "core/framerate.hpp"
5 #include "core/instance.hpp"
6 #include "library/minmax.hpp"
7 #include "library/threads.hpp"
15 #define MUSIC_BUFFERS 8
16 #define MAX_VOICE_ADJUST 200
18 bool audioapi_instance::vu_disabled
= false;
20 audioapi_instance::dummy_cb_proc::dummy_cb_proc(audioapi_instance
& _parent
)
25 int audioapi_instance::dummy_cb_proc::operator()()
28 uint64_t last_ts
= framerate_regulator::get_utime();
29 while(!parent
.dummy_cb_quit
) {
30 uint64_t cur_ts
= framerate_regulator::get_utime();
31 uint64_t dt
= cur_ts
- last_ts
;
33 unsigned samples
= dt
/ 25;
35 samples
= 16384; //Don't get crazy.
36 if(parent
.dummy_cb_active_play
)
37 parent
.get_mixed(buf
, samples
, false);
38 if(parent
.dummy_cb_active_record
)
39 parent
.put_voice(NULL
, samples
);
47 // | -1 1 -1 1 | 1 0 0 0 |
48 // | 0 0 0 1 | 0 1 0 0 |
49 // | 1 1 1 1 | 0 0 1 0 |
50 // | 8 4 2 1 | 0 0 0 1 |
53 // | 6 0 0 0 |-1 4 -3 1 | |-1 3 -3 1|
54 // | 0 6 0 0 | 3 -6 3 0 | 1/6 | 3 -6 3 0|
55 // | 0 0 6 0 |-2 -4 6 -1 | |-2 -3 6 -1|
56 // | 0 0 0 6 | 0 6 0 0 | | 0 6 0 0|
60 void cubicitr_solve(double v1
, double v2
, double v3
, double v4
, double& A
, double& B
, double& C
, double& D
)
62 A
= (-v1
+ 3 * v2
- 3 * v3
+ v4
) / 6;
63 B
= (v1
- 2 * v2
+ v3
) / 2;
64 C
= (-2 * v1
- 3 * v2
+ 6 * v3
- v4
) / 6;
69 audioapi_instance::resampler::resampler()
72 vAl
= vBl
= vCl
= vDl
= 0;
73 vAr
= vBr
= vCr
= vDr
= 0;
76 void audioapi_instance::resampler::resample(float*& in
, size_t& insize
, float*& out
, size_t& outsize
, double ratio
,
79 double iratio
= 1 / ratio
;
81 double newpos
= position
+ iratio
;
83 //Gotta load a new sample.
86 vAl
= vBl
; vBl
= vCl
; vCl
= vDl
; vDl
= in
[0];
87 vAr
= vBr
; vBr
= vCr
; vCr
= vDr
; vDr
= in
[stereo
? 1 : 0];
89 in
+= (stereo
? 2 : 1);
94 cubicitr_solve(vAl
, vBl
, vCl
, vDl
, A
, B
, C
, D
);
95 *(out
++) = ((A
* position
+ B
) * position
+ C
) * position
+ D
;
97 cubicitr_solve(vAr
, vBr
, vCr
, vDr
, A
, B
, C
, D
);
98 *(out
++) = ((A
* position
+ B
) * position
+ C
) * position
+ D
;
106 audioapi_instance::audioapi_instance()
110 last_complete_music_seen
= MUSIC_BUFFERS
+ 1;
111 last_complete_music
= MUSIC_BUFFERS
;
112 for(unsigned i
= 0; i
< MUSIC_BUFFERS
; i
++) {
114 music_rate
[i
] = 48000;
115 music_stereo
[i
] = false;
121 voice_rate_play
= 40000;
122 orig_voice_rate_play
= 40000;
123 voice_rate_rec
= 40000;
124 dummy_cb_active_record
= false;
125 dummy_cb_active_play
= false;
126 dummy_cb_quit
= false;
128 _voicep_volume
= 32767.0;
129 _voicer_volume
= 1.0/32768;
133 audioapi_instance::~audioapi_instance()
138 std::pair
<unsigned, unsigned> audioapi_instance::voice_rate()
140 return std::make_pair(voice_rate_rec
, voice_rate_play
);
143 unsigned audioapi_instance::orig_voice_rate()
145 return orig_voice_rate_play
;
148 void audioapi_instance::voice_rate(unsigned rate_rec
, unsigned rate_play
)
151 voice_rate_rec
= rate_rec
;
153 voice_rate_rec
= 40000;
154 dummy_cb_active_record
= !rate_rec
;
156 orig_voice_rate_play
= voice_rate_play
= rate_play
;
158 orig_voice_rate_play
= voice_rate_play
= 40000;
159 dummy_cb_active_play
= !rate_play
;
162 unsigned audioapi_instance::voice_p_status()
164 unsigned p
= voicep_put
;
165 unsigned g
= voicep_get
;
169 return voicep_bufsize
- (p
- g
) - 1;
172 unsigned audioapi_instance::voice_p_status2()
174 unsigned p
= voicep_put
;
175 unsigned g
= voicep_get
;
177 return voicep_bufsize
- (g
- p
);
182 unsigned audioapi_instance::voice_r_status()
184 unsigned p
= voicer_put
;
185 unsigned g
= voicer_get
;
187 return voicer_bufsize
- (g
- p
);
192 void audioapi_instance::play_voice(float* samples
, size_t count
)
194 unsigned ptr
= voicep_put
;
195 for(size_t i
= 0; i
< count
; i
++) {
196 voicep_buffer
[ptr
++] = samples
[i
];
197 if(ptr
== voicep_bufsize
)
203 void audioapi_instance::record_voice(float* samples
, size_t count
)
205 unsigned ptr
= voicer_get
;
206 for(size_t i
= 0; i
< count
; i
++) {
207 samples
[i
] = voicer_buffer
[ptr
++];
208 if(ptr
== voicer_bufsize
)
214 void audioapi_instance::submit_buffer(int16_t* samples
, size_t count
, bool stereo
, double rate
)
217 for(unsigned i
= 0; i
< count
; i
++)
218 CORE().mdumper
->on_sample(samples
[2 * i
+ 0], samples
[2 * i
+ 1]);
220 for(unsigned i
= 0; i
< count
; i
++)
221 CORE().mdumper
->on_sample(samples
[i
], samples
[i
]);
222 //Limit buffers to avoid overrunning.
223 if(count
> music_bufsize
/ (stereo
? 2 : 1))
224 count
= music_bufsize
/ (stereo
? 2 : 1);
225 unsigned bidx
= last_complete_music
;
226 bidx
= (bidx
> (MUSIC_BUFFERS
- 2)) ? 0 : bidx
+ 1;
227 memcpy(music_buffer
+ bidx
* music_bufsize
, samples
, count
* (stereo
? 2 : 1) * sizeof(int16_t));
228 music_stereo
[bidx
] = stereo
;
229 music_rate
[bidx
] = rate
;
230 music_size
[bidx
] = count
;
231 last_complete_music
= bidx
;
234 struct audioapi_instance::buffer
audioapi_instance::get_music(size_t played
)
236 unsigned midx
= last_complete_music_seen
;
237 unsigned midx2
= last_complete_music
;
238 if(midx2
>= MUSIC_BUFFERS
) {
239 //Special case: No buffer.
243 //The rest are arbitrary.
249 //Handle ACK. If the current buffer is too old, we want to ignore the ACK.
250 if(midx
>= MUSIC_BUFFERS
) {
251 //Load initial buffer.
252 midx
= last_complete_music_seen
= 0;
256 //Otherwise, check if current buffer is not next on the line to be overwritten.
257 if((midx2
+ 1) % MUSIC_BUFFERS
== midx
) {
258 //It is, bump buffer by one.
259 if(!last_adjust
&& voice_rate_play
> orig_voice_rate_play
- MAX_VOICE_ADJUST
)
262 midx
= last_complete_music_seen
= (midx
+ 1) % MUSIC_BUFFERS
;
264 } else if(music_ptr
>= music_size
[midx
] && midx
!= midx2
) {
265 //It isn't, but current buffer is finished.
266 midx
= last_complete_music_seen
= (midx
+ 1) % MUSIC_BUFFERS
;
269 } else if(music_ptr
>= music_size
[midx
] && midx
== midx2
) {
270 if(!last_adjust
&& voice_rate_play
< orig_voice_rate_play
+ MAX_VOICE_ADJUST
)
273 //Current buffer is finished, but there is no new buffer.
280 //Fill the structure.
282 if(music_ptr
< music_size
[midx
]) {
283 out
.samples
= music_buffer
+ midx
* music_bufsize
;
284 out
.pointer
= music_ptr
;
285 out
.total
= music_size
[midx
];
286 out
.stereo
= music_stereo
[midx
];
287 out
.rate
= music_rate
[midx
];
289 //Run out of buffers to play.
292 out
.total
= 64; //Arbitrary.
293 out
.stereo
= music_stereo
[midx
];
294 out
.rate
= music_rate
[midx
];
296 out
.rate
= 48000; //Apparently there are buffers with zero rate.
301 void audioapi_instance::get_voice(float* samples
, size_t count
)
303 unsigned g
= voicep_get
;
304 unsigned p
= voicep_put
;
306 for(size_t i
= 0; i
< count
; i
++) {
308 samples
[i
] = _voicep_volume
* voicep_buffer
[g
++];
311 if(g
== voicep_bufsize
)
315 for(size_t i
= 0; i
< count
; i
++) {
318 if(g
== voicep_bufsize
)
325 void audioapi_instance::put_voice(float* samples
, size_t count
)
327 unsigned ptr
= voicer_put
;
328 vu_vin(samples
, count
, false, voice_rate_rec
, _voicer_volume
);
329 for(size_t i
= 0; i
< count
; i
++) {
330 voicer_buffer
[ptr
++] = samples
? _voicer_volume
* samples
[i
] : 0.0;
331 if(ptr
== voicer_bufsize
)
337 void audioapi_instance::init()
343 last_complete_music
= 3;
344 last_complete_music_seen
= 4;
345 dummy_cb_active_play
= true;
346 dummy_cb_active_record
= true;
347 dummy_cb_quit
= false;
348 dummythread
= new threads::thread(dummyproc
);
351 void audioapi_instance::quit()
353 dummy_cb_quit
= true;
360 void audioapi_instance::music_volume(float volume
)
362 _music_volume
= volume
;
365 float audioapi_instance::music_volume()
367 return _music_volume
;
370 void audioapi_instance::voicep_volume(float volume
)
372 _voicep_volume
= volume
* 32767;
375 float audioapi_instance::voicep_volume()
377 return _voicep_volume
/ 32767;
380 void audioapi_instance::voicer_volume(float volume
)
382 _voicer_volume
= volume
/ 32768;
385 float audioapi_instance::voicer_volume()
387 return _voicer_volume
* 32768;
390 void audioapi_instance::get_mixed(int16_t* samples
, size_t count
, bool stereo
)
392 const size_t intbuf_size
= 256;
393 float intbuf
[intbuf_size
];
394 float intbuf2
[intbuf_size
];
396 buffer b
= get_music(0);
398 float* out
= intbuf2
;
401 size_t indata
= min(b
.total
- b
.pointer
, intbuf_size
/ 2);
402 size_t outdata
= min(intbuf_size
/ 2, count
);
403 size_t indata_used
= indata
;
404 outdata_used
= outdata
;
406 for(size_t i
= 0; i
< 2 * indata
; i
++)
407 intbuf
[i
] = _music_volume
* b
.samples
[i
+ 2 * b
.pointer
];
409 for(size_t i
= 0; i
< 2 * indata
; i
++)
411 music_resampler
.resample(in
, indata
, out
, outdata
, (double)voice_rate_play
/ b
.rate
, true);
412 indata_used
-= indata
;
413 outdata_used
-= outdata
;
414 get_music(indata_used
);
415 get_voice(intbuf
, outdata_used
);
417 vu_mleft(intbuf2
, outdata_used
, true, voice_rate_play
, 1 / 32768.0);
418 vu_mright(intbuf2
+ 1, outdata_used
, true, voice_rate_play
, 1 / 32768.0);
419 vu_vout(intbuf
, outdata_used
, false, voice_rate_play
, 1 / 32768.0);
421 for(size_t i
= 0; i
< outdata_used
* (stereo
? 2 : 1); i
++)
422 intbuf2
[i
] = max(min(intbuf2
[i
] + intbuf
[i
/ 2], 32766.0f
), -32767.0f
);
424 for(size_t i
= 0; i
< outdata_used
* 2; i
++)
425 samples
[i
] = intbuf2
[i
];
427 for(size_t i
= 0; i
< outdata_used
; i
++)
428 samples
[i
] = (intbuf2
[2 * i
+ 0] + intbuf2
[2 * i
+ 1]) / 2;
430 size_t indata
= min(b
.total
- b
.pointer
, intbuf_size
);
431 size_t outdata
= min(intbuf_size
, count
);
432 size_t indata_used
= indata
;
433 outdata_used
= outdata
;
435 for(size_t i
= 0; i
< indata
; i
++)
436 intbuf
[i
] = _music_volume
* b
.samples
[i
+ b
.pointer
];
438 for(size_t i
= 0; i
< indata
; i
++)
440 music_resampler
.resample(in
, indata
, out
, outdata
, (double)voice_rate_play
/ b
.rate
, false);
441 indata_used
-= indata
;
442 outdata_used
-= outdata
;
443 get_music(indata_used
);
444 get_voice(intbuf
, outdata_used
);
446 vu_mleft(intbuf2
, outdata_used
, false, voice_rate_play
, 1 / 32768.0);
447 vu_mright(intbuf2
, outdata_used
, false, voice_rate_play
, 1 / 32768.0);
448 vu_vout(intbuf
, outdata_used
, false, voice_rate_play
, 1 / 32768.0);
450 for(size_t i
= 0; i
< outdata_used
; i
++)
451 intbuf2
[i
] = max(min(intbuf2
[i
] + intbuf
[i
], 32766.0f
), -32767.0f
);
453 for(size_t i
= 0; i
< outdata_used
; i
++) {
454 samples
[2 * i
+ 0] = intbuf2
[i
];
455 samples
[2 * i
+ 1] = intbuf2
[i
];
458 for(size_t i
= 0; i
< outdata_used
; i
++)
459 samples
[i
] = intbuf2
[i
];
461 samples
+= (stereo
? 2 : 1) * outdata_used
;
462 count
-= outdata_used
;
466 audioapi_instance::vumeter::vumeter()
473 void audioapi_instance::vumeter::operator()(float* asamples
, size_t count
, bool stereo
, double rate
, double scale
)
475 size_t limit
= rate
/ 25;
476 //If we already at or exceed limit, cut immediately.
480 double sscale
= scale
* scale
;
483 for(size_t i
= 0; i
< count
; i
++) {
484 accumulator
+= sscale
* asamples
[j
] * asamples
[j
];
491 for(size_t i
= 0; i
< count
; i
++) {
492 accumulator
+= sscale
* asamples
[i
] * asamples
[i
];
498 for(size_t i
= 0; i
< count
; i
++) {
505 void audioapi_instance::vumeter::update_vu()
513 double a
= accumulator
;
515 a
= 1e-120; //Don't take log of zero.
516 vu
= 10 / log(10) * (log(a
) - log(samples
));
522 CORE().dispatch
->vu_change();
525 void audioapi_instance::disable_vu_updates()