aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorMatthew Gregan <[email protected]>2021-05-24 11:53:51 +1200
committerMatthew Gregan <[email protected]>2021-05-25 08:15:25 +1200
commit5ebe69cb3a1c7b022af85c04187456948b209d4b (patch)
tree58116e9789ae5d743768a602148d4024bb2ba76f /src
parent701b73c5c8d0b25b06e547ca2c969e1b00678772 (diff)
downloadcubeb-5ebe69cb3a1c7b022af85c04187456948b209d4b.tar.gz
cubeb-5ebe69cb3a1c7b022af85c04187456948b209d4b.zip
wasapi: Adjust output stream volume internally rather than using IAudioStreamVolume.
Diffstat (limited to 'src')
-rw-r--r--src/cubeb_wasapi.cpp49
1 files changed, 47 insertions, 2 deletions
diff --git a/src/cubeb_wasapi.cpp b/src/cubeb_wasapi.cpp
index 535a7ae..272793e 100644
--- a/src/cubeb_wasapi.cpp
+++ b/src/cubeb_wasapi.cpp
@@ -277,8 +277,10 @@ struct cubeb_stream {
com_ptr<IAudioClient> output_client;
/* Interface pointer to use the event-driven interface. */
com_ptr<IAudioRenderClient> render_client;
+#ifdef CUBEB_WASAPI_USE_IAUDIOSTREAMVOLUME
/* Interface pointer to use the volume facilities. */
com_ptr<IAudioStreamVolume> audio_stream_volume;
+#endif
/* Interface pointer to use the stream audio clock. */
com_ptr<IAudioClock> audio_clock;
/* Frames written to the stream since it was opened. Reset on device
@@ -821,9 +823,11 @@ refill(cubeb_stream * stm, void * input_buffer, long input_frames_count,
/* TODO: Report out_frames < 0 as an error via the API. */
XASSERT(out_frames >= 0);
+ float volume = 1.0;
{
auto_lock lock(stm->stream_reset_lock);
stm->frames_written += out_frames;
+ volume = stm->volume;
}
/* Go in draining mode if we got fewer frames than requested. If the stream
@@ -839,6 +843,36 @@ refill(cubeb_stream * stm, void * input_buffer, long input_frames_count,
It is alright to have produced less frames if we are draining, though. */
XASSERT(out_frames == output_frames_needed || stm->draining || !has_output(stm) || stm->has_dummy_output);
+#ifndef CUBEB_WASAPI_USE_IAUDIOSTREAMVOLUME
+ if (has_output(stm) && !stm->has_dummy_output && volume != 1.0) {
+ // Adjust the output volume.
+ // Note: This could be integrated with the remixing below.
+ long out_samples = out_frames * stm->output_stream_params.channels;
+ if (volume == 0.0) {
+ memset(dest, 0, out_samples * stm->bytes_per_sample);
+ } else {
+ switch (stm->output_stream_params.format) {
+ case CUBEB_SAMPLE_FLOAT32NE: {
+ float * buf = static_cast<float *>(dest);
+ for (long i = 0; i < out_samples; ++i) {
+ buf[i] *= volume;
+ }
+ break;
+ }
+ case CUBEB_SAMPLE_S16NE: {
+ short * buf = static_cast<short *>(dest);
+ for (long i = 0; i < out_samples; ++i) {
+ buf[i] = static_cast<short>(static_cast<float>(buf[i]) * volume);
+ }
+ break;
+ }
+ default:
+ XASSERT(false);
+ }
+ }
+ }
+#endif
+
// We don't bother mixing dummy output as it will be silenced, otherwise mix output if needed
if (!stm->has_dummy_output && has_output(stm) && stm->output_mixer) {
XASSERT(dest == stm->mix_buffer.data());
@@ -1488,6 +1522,7 @@ current_stream_delay(cubeb_stream * stm)
return delay;
}
+#ifdef CUBEB_WASAPI_USE_IAUDIOSTREAMVOLUME
int
stream_set_volume(cubeb_stream * stm, float volume)
{
@@ -1522,6 +1557,7 @@ stream_set_volume(cubeb_stream * stm, float volume)
return CUBEB_OK;
}
+#endif
} // namespace anonymous
extern "C" {
@@ -2322,12 +2358,15 @@ int setup_wasapi_stream(cubeb_stream * stm)
return rv;
}
- HRESULT hr = stm->output_client->GetService(__uuidof(IAudioStreamVolume),
- stm->audio_stream_volume.receive_vpp());
+ HRESULT hr = 0;
+#ifdef CUBEB_WASAPI_USE_IAUDIOSTREAMVOLUME
+ hr = stm->output_client->GetService(__uuidof(IAudioStreamVolume),
+ stm->audio_stream_volume.receive_vpp());
if (FAILED(hr)) {
LOG("Could not get the IAudioStreamVolume: %lx", hr);
return CUBEB_ERROR;
}
+#endif
XASSERT(stm->frames_written == 0);
hr = stm->output_client->GetService(__uuidof(IAudioClock),
@@ -2337,11 +2376,13 @@ int setup_wasapi_stream(cubeb_stream * stm)
return CUBEB_ERROR;
}
+#ifdef CUBEB_WASAPI_USE_IAUDIOSTREAMVOLUME
/* Restore the stream volume over a device change. */
if (stream_set_volume(stm, stm->volume) != CUBEB_OK) {
LOG("Could not set the volume.");
return CUBEB_ERROR;
}
+#endif
}
/* If we have both input and output, we resample to
@@ -2569,7 +2610,9 @@ void close_wasapi_stream(cubeb_stream * stm)
stm->output_device = nullptr;
stm->input_device = nullptr;
+#ifdef CUBEB_WASAPI_USE_IAUDIOSTREAMVOLUME
stm->audio_stream_volume = nullptr;
+#endif
stm->audio_clock = nullptr;
stm->total_frames_written += static_cast<UINT64>(round(stm->frames_written * stream_to_mix_samplerate_ratio(stm->output_stream_params, stm->output_mix_params)));
@@ -2850,9 +2893,11 @@ int wasapi_stream_set_volume(cubeb_stream * stm, float volume)
return CUBEB_ERROR;
}
+#ifdef CUBEB_WASAPI_USE_IAUDIOSTREAMVOLUME
if (stream_set_volume(stm, volume) != CUBEB_OK) {
return CUBEB_ERROR;
}
+#endif
stm->volume = volume;