diff options
author | Saracen <SaracenOne@gmail.com> | 2018-07-27 03:47:22 +0100 |
---|---|---|
committer | Saracen <SaracenOne@gmail.com> | 2018-07-27 16:50:12 +0100 |
commit | aca6e291d64fcbd253ea9c34756db6f8c6915c72 (patch) | |
tree | 33b05c875a0cf1deaf79e0731dd8c1b82c2b4f46 | |
parent | 7142e1d3f7af98850d64ec881d21ed82222396a0 (diff) |
Fixed audio clipping on WASAPI by fixing argument order on AudioClient
Initialize method ensuring a larger capture buffer and adding bounds
to the capture and stream.
-rw-r--r-- | drivers/wasapi/audio_driver_wasapi.cpp | 14 | ||||
-rw-r--r-- | servers/audio/audio_stream.cpp | 32 | ||||
-rw-r--r-- | servers/audio_server.h | 2 |
3 files changed, 34 insertions, 14 deletions
diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp index 7ae87f04a8..f4d0d3c1dc 100644 --- a/drivers/wasapi/audio_driver_wasapi.cpp +++ b/drivers/wasapi/audio_driver_wasapi.cpp @@ -65,6 +65,8 @@ const IID IID_IAudioCaptureClient = __uuidof(IAudioCaptureClient); #define REFTIMES_PER_SEC 10000000 #define REFTIMES_PER_MILLISEC 10000 +#define CAPTURE_BUFFER_CHANNELS 2 + static StringName capture_device_id; static bool default_render_device_changed = false; static bool default_capture_device_changed = false; @@ -271,7 +273,7 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_c pwfex->nAvgBytesPerSec = pwfex->nSamplesPerSec * pwfex->nChannels * (pwfex->wBitsPerSample / 8); } - hr = p_device->audio_client->Initialize(AUDCLNT_SHAREMODE_SHARED, streamflags, 0, p_capture ? REFTIMES_PER_SEC : 0, pwfex, NULL); + hr = p_device->audio_client->Initialize(AUDCLNT_SHAREMODE_SHARED, streamflags, p_capture ? REFTIMES_PER_SEC : 0, 0, pwfex, NULL); ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN); if (p_capture) { @@ -338,11 +340,12 @@ Error AudioDriverWASAPI::init_capture_device(bool reinit) { ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN); // Set the buffer size - audio_input_buffer.resize(max_frames * 8); + audio_input_buffer.resize(max_frames * CAPTURE_BUFFER_CHANNELS); for (int i = 0; i < audio_input_buffer.size(); i++) { audio_input_buffer.write[i] = 0; } audio_input_position = 0; + audio_input_size = 0; return OK; } @@ -676,7 +679,7 @@ void AudioDriverWASAPI::thread_func(void *p_udata) { // fixme: Only works for floating point atm for (int j = 0; j < num_frames_available; j++) { - int32_t sample_channel[2]; + int32_t sample_channel[CAPTURE_BUFFER_CHANNELS]; if (flags & AUDCLNT_BUFFERFLAGS_SILENT) { sample_channel[0] = sample_channel[1] = 0; @@ -692,11 +695,14 @@ void AudioDriverWASAPI::thread_func(void *p_udata) { } } - for (int k = 0; k < 2; k++) { + for (int k = 0; k < CAPTURE_BUFFER_CHANNELS; k++) { ad->audio_input_buffer.write[ad->audio_input_position++] = sample_channel[k]; if (ad->audio_input_position >= ad->audio_input_buffer.size()) { ad->audio_input_position = 0; } + if (ad->audio_input_size < ad->audio_input_buffer.size()) { + ad->audio_input_size++; + } } } diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp index 0c8a1810d2..f7622b8a4e 100644 --- a/servers/audio/audio_stream.cpp +++ b/servers/audio/audio_stream.cpp @@ -135,19 +135,31 @@ void AudioStreamPlaybackMicrophone::_mix_internal(AudioFrame *p_buffer, int p_fr AudioDriver::get_singleton()->lock(); Vector<int32_t> buf = AudioDriver::get_singleton()->get_audio_input_buffer(); + unsigned int audio_input_size = AudioDriver::get_singleton()->get_audio_input_size(); - for (int i = 0; i < p_frames; i++) { - - float l = (buf[input_ofs++] >> 16) / 32768.f; - if (input_ofs >= buf.size()) { - input_ofs = 0; - } - float r = (buf[input_ofs++] >> 16) / 32768.f; - if (input_ofs >= buf.size()) { - input_ofs = 0; + // p_frames is multipled by two since an AudioFrame is stereo + if ((p_frames * 2) > audio_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 (audio_input_size >= input_ofs) { + float l = (buf[input_ofs++] >> 16) / 32768.f; + if (input_ofs >= buf.size()) { + input_ofs = 0; + } + float r = (buf[input_ofs++] >> 16) / 32768.f; + if (input_ofs >= buf.size()) { + input_ofs = 0; + } - p_buffer[i] = AudioFrame(l, r); + p_buffer[i] = AudioFrame(l, r); + } else { + p_buffer[i] = AudioFrame(0.0f, 0.0f); + } + } } AudioDriver::get_singleton()->unlock(); diff --git a/servers/audio_server.h b/servers/audio_server.h index c199a337eb..a9ed66a2d5 100644 --- a/servers/audio_server.h +++ b/servers/audio_server.h @@ -55,6 +55,7 @@ class AudioDriver { protected: Vector<int32_t> audio_input_buffer; unsigned int audio_input_position; + unsigned int audio_input_size; void audio_server_process(int p_frames, int32_t *p_buffer, bool p_update_mix_time = true); void update_mix_time(int p_frames); @@ -109,6 +110,7 @@ public: Vector<int32_t> get_audio_input_buffer() { return audio_input_buffer; } unsigned int get_audio_input_position() { return audio_input_position; } + unsigned int get_audio_input_size() { return audio_input_size; } #ifdef DEBUG_ENABLED uint64_t get_profiling_time() const { return prof_time; } |