Add C wrapper to access APM functions
BUG=chromium:710465
TEST=Apply whole patch series. emerge-eve webrtc-apm and
check libwebrtc_apm.so is built.
Change-Id: If26bd17ca509f83fd978890305594fdce94bfaeb
Reviewed-on: https://chromium-review.googlesource.com/970198
Commit-Ready: Hsinyu Chao <hychao@chromium.org>
Tested-by: Hsinyu Chao <hychao@chromium.org>
Reviewed-by: Cheng-Yi Chiang <cychiang@chromium.org>
diff --git a/webrtc_apm.cc b/webrtc_apm.cc
new file mode 100644
index 0000000..b92a008
--- /dev/null
+++ b/webrtc_apm.cc
@@ -0,0 +1,164 @@
+/* Copyright (c) 2018 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "api/audio/echo_canceller3_factory.h"
+#include "modules/audio_processing/aec_dump/aec_dump_factory.h"
+#include "modules/audio_processing/include/aec_dump.h"
+#include "modules/audio_processing/include/audio_processing.h"
+#include "modules/include/module_common_types.h"
+#include "rtc_base/task_queue.h"
+
+extern "C" {
+#include "webrtc_apm.h"
+
+webrtc_apm webrtc_apm_create(unsigned int num_channels,
+ unsigned int frame_rate,
+ unsigned int enable_echo_cancellation)
+{
+ int err;
+ webrtc::AudioProcessing *apm;
+ webrtc::AudioProcessing::ChannelLayout channel_layout;
+ webrtc::AudioProcessingBuilder apm_builder;
+ std::unique_ptr<webrtc::EchoControlFactory> ec3_factory(new webrtc::EchoCanceller3Factory());
+
+ switch (num_channels) {
+ case 1:
+ channel_layout = webrtc::AudioProcessing::kMono;
+ break;
+ case 2:
+ channel_layout = webrtc::AudioProcessing::kStereo;
+ break;
+ default:
+ return NULL;
+ }
+
+ apm_builder.SetEchoControlFactory(std::move(ec3_factory));
+ apm = apm_builder.Create();
+
+ err = apm->Initialize(frame_rate, frame_rate, frame_rate,
+ channel_layout, channel_layout, channel_layout);
+ if (err) {
+ delete apm;
+ return NULL;
+ }
+
+ return reinterpret_cast<webrtc_apm>(apm);
+}
+
+int webrtc_apm_process_reverse_stream_f(
+ webrtc_apm ptr,
+ int num_channels, int rate,
+ float *const *data)
+{
+ webrtc::AudioProcessing *apm;
+ webrtc::StreamConfig config =
+ webrtc::StreamConfig(rate, num_channels);
+
+ apm = reinterpret_cast<webrtc::AudioProcessing *>(ptr);
+
+ return apm->ProcessReverseStream(data, config, config, data);
+}
+
+int webrtc_apm_process_reverse_stream(webrtc_apm ptr,
+ int num_channels, int rate,
+ int16_t *data, int nframes)
+{
+ webrtc::AudioFrame af;
+ webrtc::AudioProcessing *apm;
+
+ apm = reinterpret_cast<webrtc::AudioProcessing *>(ptr);
+
+ af.UpdateFrame(0xFFFFFFFF, data, nframes, rate,
+ webrtc::AudioFrame::kNormalSpeech,
+ webrtc::AudioFrame::kVadUnknown,
+ num_channels);
+ return apm->ProcessReverseStream(&af);
+}
+
+int webrtc_apm_process_stream_f(webrtc_apm ptr,
+ int num_channels,
+ int rate,
+ float *const *data)
+{
+ webrtc::AudioProcessing *apm;
+
+ webrtc::StreamConfig config =
+ webrtc::StreamConfig(rate, num_channels);
+ apm = reinterpret_cast<webrtc::AudioProcessing *>(ptr);
+ return apm->ProcessStream(data, config, config, data);
+}
+
+
+int webrtc_apm_process_stream(webrtc_apm ptr, int num_channels,
+ int rate, int16_t *data, int nframes)
+{
+ int ret;
+ webrtc::AudioFrame af;
+ webrtc::AudioProcessing *apm;
+
+ apm = reinterpret_cast<webrtc::AudioProcessing *>(ptr);
+ //set stream delay
+ af.UpdateFrame(0xFFFFFFFF, data, nframes, rate,
+ webrtc::AudioFrame::kNormalSpeech,
+ webrtc::AudioFrame::kVadUnknown,
+ num_channels);
+ ret = apm->ProcessStream(&af);
+ if (ret)
+ return ret;
+
+ memcpy(data, af.data(), nframes * num_channels * 2);
+ return ret;
+}
+
+void webrtc_apm_destroy(webrtc_apm ptr)
+{
+ webrtc::AudioProcessing *apm;
+ apm = reinterpret_cast<webrtc::AudioProcessing *>(ptr);
+ delete apm;
+}
+
+int webrtc_apm_set_stream_delay(webrtc_apm ptr, int delay_ms)
+{
+ webrtc::AudioProcessing *apm;
+
+ apm = reinterpret_cast<webrtc::AudioProcessing *>(ptr);
+ return apm->set_stream_delay_ms(delay_ms);
+}
+
+int webrtc_apm_aec_dump(webrtc_apm ptr, void** wq_ptr, int start, FILE *handle)
+{
+ webrtc::AudioProcessing *apm;
+ rtc::TaskQueue *work_queue;
+
+ apm = reinterpret_cast<webrtc::AudioProcessing *>(ptr);
+
+ if (start) {
+ work_queue = new rtc::TaskQueue("aecdump-worker-queue",
+ rtc::TaskQueue::Priority::LOW);
+ auto aec_dump = webrtc::AecDumpFactory::Create(handle, -1, work_queue);
+ if (!aec_dump)
+ return -ENOMEM;
+ apm->AttachAecDump(std::move(aec_dump));
+ *wq_ptr = reinterpret_cast<void *>(work_queue);
+ } else {
+ apm->DetachAecDump();
+ work_queue = reinterpret_cast<rtc::TaskQueue *>(*wq_ptr);
+ if (work_queue) {
+ delete work_queue;
+ work_queue = NULL;
+ }
+ }
+ return 0;
+}
+
+int webrtc_apm_has_echo(webrtc_apm ptr)
+{
+ webrtc::AudioProcessing *apm;
+
+ apm = reinterpret_cast<webrtc::AudioProcessing *>(ptr);
+ return apm->echo_cancellation()->stream_has_echo();
+}
+
+} // extern "C"
diff --git a/webrtc_apm.h b/webrtc_apm.h
new file mode 100644
index 0000000..a68e96f
--- /dev/null
+++ b/webrtc_apm.h
@@ -0,0 +1,98 @@
+/* Copyright (c) 2018 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef WEBRTC_APM_H_
+#define WEBRTC_APM_H_
+
+#include <stdint.h>
+#include <stdio.h>
+
+#define WEBRTC_APM_API __attribute__((visibility("default")))
+
+/* Pointer to a webrtc::AudioProcessing instance. */
+typedef void* webrtc_apm;
+
+/* Creates a webrtc_apm for forward stream properties. In CRAS use case it
+ * is usually created for input stream.
+ * Args:
+ * num_channels - Number of channels of the forward stream.
+ * frame_rate - Frame rate used by forward stream.
+ * enable_echo_cancellation - Set to true to enable echo cancellation in
+ * created webrtc_apm instance.
+ */
+WEBRTC_APM_API webrtc_apm webrtc_apm_create(
+ unsigned int num_channels,
+ unsigned int frame_rate,
+ unsigned int enable_echo_cancellation);
+
+/* Destroys a webrtc_apm instance. */
+WEBRTC_APM_API void webrtc_apm_destroy(webrtc_apm apm);
+
+/* Processes data in reverse stream. In CRAS use case this is called for
+ * output stream data.
+ * Args:
+ * ptr - The webrtc_apm to process reverse stream data.
+ * num_channels - Number of channels of the reverse stream.
+ * rate - Frame rate used by reverse stream.
+ * data - Pointer to the data in reverse stream to be processed.
+ * nframes - Number of frames of reverse stream's data.
+ */
+WEBRTC_APM_API int webrtc_apm_process_reverse_stream(
+ webrtc_apm ptr,
+ int num_channels, int rate,
+ int16_t *data, int nframes);
+
+/* Processes deinterleaved float data in reverse stream. Expecting data
+ * size be 10 ms equivalent of frames. */
+WEBRTC_APM_API int webrtc_apm_process_reverse_stream_f(
+ webrtc_apm ptr,
+ int num_channels, int rate,
+ float *const *data);
+
+/* Processes data in forward stream. In CRAS use case this is called for
+ * input stream data.
+ * Args:
+ * ptr - The webrtc_apm to process forward stream data.
+ * num_channels - Number of channels of the forward stream.
+ * rate - Frame rate used by forward stream.
+ * data - Pointer to the data in forward stream to be processed.
+ * nframes - Number of frames of forward stream's data.
+ */
+WEBRTC_APM_API int webrtc_apm_process_stream(
+ webrtc_apm ptr, int num_channels,
+ int rate, int16_t *data, int nframes);
+
+/* Processes deinterleaved float data in forward stream. Expecting data
+ * size be 10 ms equivalent of frames. */
+WEBRTC_APM_API int webrtc_apm_process_stream_f(webrtc_apm ptr,
+ int num_channels,
+ int rate,
+ float *const *data);
+
+/* Sets the delay in ms between apm analyzes a frame in reverse stream
+ * (playback) and this frame received as echo in forward stream (record)
+ * This is required for echo cancellation enabled apm.
+ * Args:
+ * ptr - Pointer to the webrtc_apm instance.
+ * delay_ms - The delay in ms.
+ */
+WEBRTC_APM_API int webrtc_apm_set_stream_delay(webrtc_apm ptr, int delay_ms);
+
+/* Checks if apm detects echo in forward stream. */
+WEBRTC_APM_API int webrtc_apm_has_echo(webrtc_apm ptr);
+
+/* Dump aec debug info to a file.
+ * Args:
+ * ptr - Pointer to the webrtc_apm instance.
+ * work_queue - Pointer holding or to hold the allocated task queue for
+ * aec dump. Will be deleted when aec dump stops.
+ * start - True to start dumping, false to stop.
+ * handle - Pointer of the file storing aec dump.
+ */
+WEBRTC_APM_API int webrtc_apm_aec_dump(
+ webrtc_apm ptr, void** work_queue,
+ int start, FILE *handle);
+
+#endif /* WEBRTC_APM_H_ */