Skip to content

Commit

Permalink
Implement aaudio_set_input_processing_params
Browse files Browse the repository at this point in the history
  • Loading branch information
Pehrsons committed Jun 17, 2024
1 parent d2179a0 commit 13d39fb
Showing 1 changed file with 59 additions and 8 deletions.
67 changes: 59 additions & 8 deletions src/cubeb_aaudio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <limits>
#include <memory>
#include <mutex>
#include <optional>
#include <thread>
#include <vector>

Expand Down Expand Up @@ -172,6 +173,7 @@ struct cubeb_stream {
unsigned out_frame_size{};
bool voice_input{};
bool voice_output{};
std::optional<aaudio_input_preset_t> input_preset{};
uint64_t previous_clock{};
};

Expand Down Expand Up @@ -1010,6 +1012,7 @@ aaudio_stream_destroy(cubeb_stream * stm)
{
lock_guard lock(stm->mutex);
stm->in_use.store(false);
stm->input_preset = std::nullopt;
aaudio_stream_destroy_locked(stm, lock);
}

Expand Down Expand Up @@ -1191,13 +1194,11 @@ aaudio_stream_init_impl(cubeb_stream * stm, lock_guard<mutex> & lock)
// input
cubeb_stream_params in_params;
if (stm->input_stream_params) {
// Match what the OpenSL backend does for now, we could use UNPROCESSED and
// VOICE_COMMUNICATION here, but we'd need to make it clear that
// application-level AEC and other voice processing should be disabled
// there.
int input_preset = stm->voice_input ? AAUDIO_INPUT_PRESET_VOICE_RECOGNITION
: AAUDIO_INPUT_PRESET_CAMCORDER;
WRAP(AAudioStreamBuilder_setInputPreset)(sb, input_preset);
if (!stm->input_preset) {
stm->input_preset = stm->voice_input ? AAUDIO_INPUT_PRESET_UNPROCESSED
: AAUDIO_INPUT_PRESET_CAMCORDER;
}
WRAP(AAudioStreamBuilder_setInputPreset)(sb, *stm->input_preset);
WRAP(AAudioStreamBuilder_setDirection)(sb, AAUDIO_DIRECTION_INPUT);
WRAP(AAudioStreamBuilder_setDataCallback)(sb, in_data_callback, stm);
assert(stm->latency_frames < std::numeric_limits<int32_t>::max());
Expand Down Expand Up @@ -1669,6 +1670,56 @@ aaudio_stream_set_volume(cubeb_stream * stm, float volume)
return CUBEB_OK;
}

static int
aaudio_set_input_processing_params(cubeb_stream * stm,
cubeb_input_processing_params params)
{
assert(stm);

if (!stm->istream) {
LOG("%s: no input stream", __func__);
return CUBEB_ERROR_INVALID_PARAMETER;
}

if (!stm->voice_input) {
LOG("%s: input stream is not a voice stream", __func__);
return CUBEB_ERROR_INVALID_PARAMETER;
}

// Make sure we support all the params we are trying to enable by mapping
// them to a preset.
const auto preset = ([params]() -> std::optional<aaudio_input_preset_t> {
switch (static_cast<int>(params)) {
case CUBEB_INPUT_PROCESSING_PARAM_NONE:
return AAUDIO_INPUT_PRESET_UNPROCESSED;
case CUBEB_INPUT_PROCESSING_PARAM_AUTOMATIC_GAIN_CONTROL:
return AAUDIO_INPUT_PRESET_VOICE_RECOGNITION;
case (CUBEB_INPUT_PROCESSING_PARAM_ECHO_CANCELLATION |
CUBEB_INPUT_PROCESSING_PARAM_AUTOMATIC_GAIN_CONTROL |
CUBEB_INPUT_PROCESSING_PARAM_NOISE_SUPPRESSION):
return AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION;
default:
return std::nullopt;
}
})();

if (!preset) {
LOG("%s: attempted to set unsupported params. params=%d", __func__, params);
return CUBEB_ERROR_INVALID_PARAMETER;
}

{
lock_guard lock(stm->mutex);
if (*preset != stm->input_preset) {
stm->input_preset = *preset;
reinitialize_stream_locked(stm, lock);
}
}

LOG("%s: successfully set params %d", __func__, params);
return CUBEB_OK;
}

aaudio_data_callback_result_t
dummy_callback(AAudioStream * stream, void * userData, void * audioData,
int32_t numFrames)
Expand Down Expand Up @@ -1785,7 +1836,7 @@ const static struct cubeb_ops aaudio_ops = {
/*.stream_set_name =*/nullptr,
/*.stream_get_current_device =*/nullptr,
/*.stream_set_input_mute =*/nullptr,
/*.stream_set_input_processing_params =*/nullptr,
/*.stream_set_input_processing_params =*/aaudio_set_input_processing_params,
/*.stream_device_destroy =*/nullptr,
/*.stream_register_device_changed_callback =*/nullptr,
/*.register_device_collection_changed =*/nullptr};
Expand Down

0 comments on commit 13d39fb

Please sign in to comment.