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.
This commit is contained in:
Saracen 2018-07-27 03:47:22 +01:00
parent 7142e1d3f7
commit aca6e291d6
3 changed files with 34 additions and 14 deletions

View File

@ -65,6 +65,8 @@ const IID IID_IAudioCaptureClient = __uuidof(IAudioCaptureClient);
#define REFTIMES_PER_SEC 10000000 #define REFTIMES_PER_SEC 10000000
#define REFTIMES_PER_MILLISEC 10000 #define REFTIMES_PER_MILLISEC 10000
#define CAPTURE_BUFFER_CHANNELS 2
static StringName capture_device_id; static StringName capture_device_id;
static bool default_render_device_changed = false; static bool default_render_device_changed = false;
static bool default_capture_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); 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); ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);
if (p_capture) { if (p_capture) {
@ -338,11 +340,12 @@ Error AudioDriverWASAPI::init_capture_device(bool reinit) {
ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN); ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);
// Set the buffer size // 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++) { for (int i = 0; i < audio_input_buffer.size(); i++) {
audio_input_buffer.write[i] = 0; audio_input_buffer.write[i] = 0;
} }
audio_input_position = 0; audio_input_position = 0;
audio_input_size = 0;
return OK; return OK;
} }
@ -676,7 +679,7 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
// fixme: Only works for floating point atm // fixme: Only works for floating point atm
for (int j = 0; j < num_frames_available; j++) { 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) { if (flags & AUDCLNT_BUFFERFLAGS_SILENT) {
sample_channel[0] = sample_channel[1] = 0; 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]; ad->audio_input_buffer.write[ad->audio_input_position++] = sample_channel[k];
if (ad->audio_input_position >= ad->audio_input_buffer.size()) { if (ad->audio_input_position >= ad->audio_input_buffer.size()) {
ad->audio_input_position = 0; ad->audio_input_position = 0;
} }
if (ad->audio_input_size < ad->audio_input_buffer.size()) {
ad->audio_input_size++;
}
} }
} }

View File

@ -135,19 +135,31 @@ void AudioStreamPlaybackMicrophone::_mix_internal(AudioFrame *p_buffer, int p_fr
AudioDriver::get_singleton()->lock(); AudioDriver::get_singleton()->lock();
Vector<int32_t> buf = AudioDriver::get_singleton()->get_audio_input_buffer(); 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++) { // p_frames is multipled by two since an AudioFrame is stereo
if ((p_frames * 2) > audio_input_size) {
float l = (buf[input_ofs++] >> 16) / 32768.f; for (int i = 0; i < p_frames; i++) {
if (input_ofs >= buf.size()) { p_buffer[i] = AudioFrame(0.0f, 0.0f);
input_ofs = 0;
}
float r = (buf[input_ofs++] >> 16) / 32768.f;
if (input_ofs >= buf.size()) {
input_ofs = 0;
} }
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(); AudioDriver::get_singleton()->unlock();

View File

@ -55,6 +55,7 @@ class AudioDriver {
protected: protected:
Vector<int32_t> audio_input_buffer; Vector<int32_t> audio_input_buffer;
unsigned int audio_input_position; 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 audio_server_process(int p_frames, int32_t *p_buffer, bool p_update_mix_time = true);
void update_mix_time(int p_frames); void update_mix_time(int p_frames);
@ -109,6 +110,7 @@ public:
Vector<int32_t> get_audio_input_buffer() { return audio_input_buffer; } 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_position() { return audio_input_position; }
unsigned int get_audio_input_size() { return audio_input_size; }
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
uint64_t get_profiling_time() const { return prof_time; } uint64_t get_profiling_time() const { return prof_time; }