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_ */