Skip to content

Commit 9be7483

Browse files
committed
mic: fix resampling, apple drivers
1 parent 75d7f08 commit 9be7483

File tree

3 files changed

+690
-572
lines changed

3 files changed

+690
-572
lines changed

audio/audio_driver.c

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2509,7 +2509,7 @@ static size_t microphone_driver_flush(
25092509
{ /* If the mic's native rate is practically the same as the requested one... */
25102510

25112511
/* ...then skip the resampler, since it'll produce (more or less) identical results. */
2512-
frames_to_enqueue = MIN(FIFO_WRITE_AVAIL(microphone->outgoing_samples), resampler_data.input_frames);
2512+
frames_to_enqueue = MIN(FIFO_WRITE_AVAIL(microphone->outgoing_samples) / sizeof(int16_t), resampler_data.input_frames);
25132513

25142514
/* If this mic provides floating-point samples... */
25152515
if (microphone->flags & MICROPHONE_FLAG_USE_FLOAT)
@@ -2520,7 +2520,7 @@ static size_t microphone_driver_flush(
25202520
else
25212521
fifo_write(microphone->outgoing_samples, mic_st->input_frames, frames_to_enqueue * sizeof(int16_t));
25222522

2523-
return resampler_data.input_frames;
2523+
return frames_to_enqueue;
25242524
}
25252525
/* Couldn't take the fast path, so let's resample the mic input */
25262526

@@ -2548,9 +2548,9 @@ static size_t microphone_driver_flush(
25482548
/* Finally, we convert the audio back to 16-bit ints, as the mic interface requires. */
25492549
convert_float_to_s16(mic_st->final_frames, mic_st->resampled_mono_frames, resampler_data.output_frames);
25502550

2551-
frames_to_enqueue = MIN(FIFO_WRITE_AVAIL(microphone->outgoing_samples), resampler_data.output_frames);
2551+
frames_to_enqueue = MIN(FIFO_WRITE_AVAIL(microphone->outgoing_samples) / sizeof(int16_t), resampler_data.output_frames);
25522552
fifo_write(microphone->outgoing_samples, mic_st->final_frames, frames_to_enqueue * sizeof(int16_t));
2553-
return resampler_data.output_frames;
2553+
return frames_to_enqueue;
25542554
}
25552555

25562556
int microphone_driver_read(retro_microphone_t *microphone, int16_t* frames, size_t num_frames)
@@ -2587,9 +2587,10 @@ int microphone_driver_read(retro_microphone_t *microphone, int16_t* frames, size
25872587
|| is_fastforward
25882588
|| is_slowmo
25892589
|| is_rewind
2590+
|| core_paused
25902591
)
25912592
{ /* If the microphone is pending, suspended, or disabled...
2592-
...or if the core is in fast-forward, slow-mo, or rewind...*/
2593+
...or if the core is paused, in fast-forward, slow-mo, or rewind...*/
25932594
memset(frames, 0, num_frames * sizeof(*frames));
25942595
return (int)num_frames;
25952596
/* ...then copy silence to the provided buffer. Not an error if the mic is pending,
@@ -2612,25 +2613,32 @@ int microphone_driver_read(retro_microphone_t *microphone, int16_t* frames, size
26122613
return -1;
26132614
}
26142615

2615-
/* If the core asked for more frames than we can fit... */
2616-
if (num_frames > microphone->outgoing_samples->size)
2616+
/* If the core asked for more frames than the FIFO can hold... */
2617+
if (num_frames * sizeof(int16_t) > microphone->outgoing_samples->size - 1)
26172618
return -1;
26182619

26192620
retro_assert(mic_st->input_frames != NULL);
26202621

2621-
while (FIFO_READ_AVAIL(microphone->outgoing_samples) < num_frames * sizeof(int16_t))
2622-
{ /* Until we can give the core the frames it asked for... */
2623-
size_t frames_to_read = MIN(AUDIO_CHUNK_SIZE_NONBLOCKING, frames_remaining);
2624-
size_t frames_read = 0;
2625-
2626-
/* If the game is running and the mic driver is active... */
2627-
if (!core_paused)
2628-
frames_read = microphone_driver_flush(mic_st, microphone, frames_to_read);
2629-
2630-
/* Otherwise, advance the counters. We're not gonna get new data,
2631-
* but we still need to finish this loop */
2632-
frames_remaining -= frames_read;
2633-
} /* If the queue already has enough samples to give, the loop will be skipped */
2622+
{
2623+
unsigned stall_count = 0;
2624+
while (FIFO_READ_AVAIL(microphone->outgoing_samples) < num_frames * sizeof(int16_t))
2625+
{ /* Until we can give the core the frames it asked for... */
2626+
size_t frames_to_read = MIN(AUDIO_CHUNK_SIZE_NONBLOCKING, frames_remaining);
2627+
size_t frames_read = microphone_driver_flush(
2628+
mic_st, microphone, frames_to_read);
2629+
if (frames_read == 0)
2630+
{
2631+
if (++stall_count > 512)
2632+
{ /* Driver isn't providing data; return silence */
2633+
memset(frames, 0, num_frames * sizeof(int16_t));
2634+
return (int)num_frames;
2635+
}
2636+
}
2637+
else
2638+
stall_count = 0;
2639+
frames_remaining -= frames_read;
2640+
} /* If the queue already has enough samples to give, the loop will be skipped */
2641+
}
26342642

26352643
fifo_read(microphone->outgoing_samples, frames, num_frames * sizeof(int16_t));
26362644
return (int)num_frames;

0 commit comments

Comments
 (0)