Skip to content

Commit

Permalink
Fix possible audio input buffer issues
Browse files Browse the repository at this point in the history
  • Loading branch information
marcelofg55 committed Oct 20, 2018
1 parent cf7a661 commit fa26a55
Show file tree
Hide file tree
Showing 8 changed files with 33 additions and 23 deletions.
5 changes: 2 additions & 3 deletions drivers/coreaudio/audio_driver_coreaudio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,6 @@ Error AudioDriverCoreAudio::init() {
unsigned int buffer_size = buffer_frames * channels;
samples_in.resize(buffer_size);
input_buf.resize(buffer_size);
input_buffer.resize(buffer_size * 8);
input_position = 0;
input_size = 0;

print_verbose("CoreAudio: detected " + itos(channels) + " channels");
print_verbose("CoreAudio: audio buffer frames: " + itos(buffer_frames) + " calculated latency: " + itos(buffer_frames * 1000 / mix_rate) + "ms");
Expand Down Expand Up @@ -487,6 +484,8 @@ void AudioDriverCoreAudio::capture_finish() {

Error AudioDriverCoreAudio::capture_start() {

input_buffer_init(buffer_frames);

OSStatus result = AudioOutputUnitStart(input_unit);
if (result != noErr) {
ERR_PRINTS("AudioOutputUnitStart failed, code: " + itos(result));
Expand Down
18 changes: 8 additions & 10 deletions drivers/pulseaudio/audio_driver_pulseaudio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -613,20 +613,18 @@ Error AudioDriverPulseAudio::capture_init_device() {
break;
}

print_verbose("PulseAudio: detected " + itos(pa_rec_map.channels) + " input channels");

pa_sample_spec spec;

spec.format = PA_SAMPLE_S16LE;
spec.channels = pa_rec_map.channels;
spec.rate = mix_rate;

int latency = 30;
input_buffer_frames = closest_power_of_2(latency * mix_rate / 1000);
int buffer_size = input_buffer_frames * spec.channels;
int input_latency = 30;
int input_buffer_frames = closest_power_of_2(input_latency * mix_rate / 1000);
int input_buffer_size = input_buffer_frames * spec.channels;

pa_buffer_attr attr;
attr.fragsize = buffer_size * sizeof(int16_t);
attr.fragsize = input_buffer_size * sizeof(int16_t);

pa_rec_str = pa_stream_new(pa_ctx, "Record", &spec, &pa_rec_map);
if (pa_rec_str == NULL) {
Expand All @@ -642,9 +640,10 @@ Error AudioDriverPulseAudio::capture_init_device() {
ERR_FAIL_V(ERR_CANT_OPEN);
}

input_buffer.resize(input_buffer_frames * 8);
input_position = 0;
input_size = 0;
input_buffer_init(input_buffer_frames);

print_verbose("PulseAudio: detected " + itos(pa_rec_map.channels) + " input channels");
print_verbose("PulseAudio: input buffer frames: " + itos(input_buffer_frames) + " calculated latency: " + itos(input_buffer_frames * 1000 / mix_rate) + "ms");

return OK;
}
Expand Down Expand Up @@ -760,7 +759,6 @@ AudioDriverPulseAudio::AudioDriverPulseAudio() {

mix_rate = 0;
buffer_frames = 0;
input_buffer_frames = 0;
pa_buffer_size = 0;
channels = 0;
pa_ready = 0;
Expand Down
1 change: 0 additions & 1 deletion drivers/pulseaudio/audio_driver_pulseaudio.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ class AudioDriverPulseAudio : public AudioDriver {

unsigned int mix_rate;
unsigned int buffer_frames;
unsigned int input_buffer_frames;
unsigned int pa_buffer_size;
int channels;
int pa_ready;
Expand Down
5 changes: 1 addition & 4 deletions drivers/wasapi/audio_driver_wasapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -336,10 +336,7 @@ Error AudioDriverWASAPI::init_capture_device(bool reinit) {
HRESULT hr = audio_input.audio_client->GetBufferSize(&max_frames);
ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);

// Set the buffer size
input_buffer.resize(max_frames * CAPTURE_BUFFER_CHANNELS);
input_position = 0;
input_size = 0;
input_buffer_init(max_frames);

return OK;
}
Expand Down
16 changes: 13 additions & 3 deletions servers/audio/audio_stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,16 +136,20 @@ void AudioStreamPlaybackMicrophone::_mix_internal(AudioFrame *p_buffer, int p_fr

Vector<int32_t> buf = AudioDriver::get_singleton()->get_input_buffer();
unsigned int input_size = AudioDriver::get_singleton()->get_input_size();
int mix_rate = AudioDriver::get_singleton()->get_mix_rate();
int playback_delay = MIN(((50 * mix_rate) / 1000) * 2, buf.size() >> 1);
#ifdef DEBUG_ENABLED
unsigned int input_position = AudioDriver::get_singleton()->get_input_position();
#endif

// p_frames is multiplied by two since an AudioFrame is stereo
if ((p_frames + MICROPHONE_PLAYBACK_DELAY * 2) > input_size) {
if (playback_delay > input_size) {
for (int i = 0; i < p_frames; i++) {
p_buffer[i] = AudioFrame(0.0f, 0.0f);
}
input_ofs = 0;
} else {
for (int i = 0; i < p_frames; i++) {
if (input_size >= input_ofs) {
if (input_size > input_ofs) {
float l = (buf[input_ofs++] >> 16) / 32768.f;
if (input_ofs >= buf.size()) {
input_ofs = 0;
Expand All @@ -162,6 +166,12 @@ void AudioStreamPlaybackMicrophone::_mix_internal(AudioFrame *p_buffer, int p_fr
}
}

#ifdef DEBUG_ENABLED
if (input_ofs > input_position && (input_ofs - input_position) < (p_frames * 2)) {
print_verbose(String(get_class_name()) + " buffer underrun: input_position=" + itos(input_position) + " input_ofs=" + itos(input_ofs) + " input_size=" + itos(input_size));
}
#endif

AudioDriver::get_singleton()->unlock();
}

Expand Down
2 changes: 0 additions & 2 deletions servers/audio/audio_stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,6 @@ class AudioStreamPlaybackMicrophone : public AudioStreamPlaybackResampled {
GDCLASS(AudioStreamPlaybackMicrophone, AudioStreamPlayback)
friend class AudioStreamMicrophone;

static const int MICROPHONE_PLAYBACK_DELAY = 256;

bool active;
unsigned int input_ofs;

Expand Down
8 changes: 8 additions & 0 deletions servers/audio_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,14 @@ double AudioDriver::get_mix_time() const {
return total;
}

void AudioDriver::input_buffer_init(int driver_buffer_frames) {

const int input_buffer_channels = 2;
input_buffer.resize(driver_buffer_frames * input_buffer_channels * 4);
input_position = 0;
input_size = 0;
}

void AudioDriver::input_buffer_write(int32_t sample) {

input_buffer.write[input_position++] = sample;
Expand Down
1 change: 1 addition & 0 deletions servers/audio_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class AudioDriver {

void audio_server_process(int p_frames, int32_t *p_buffer, bool p_update_mix_time = true);
void update_mix_time(int p_frames);
void input_buffer_init(int driver_buffer_frames);
void input_buffer_write(int32_t sample);

#ifdef DEBUG_ENABLED
Expand Down

0 comments on commit fa26a55

Please sign in to comment.