}
}
-config("capi-media-audio-io") {
- if (is_tizen) {
- ldflags = [ "-lcapi-media-audio-io" ]
- }
-}
-
tizen_pkg_config("capi-boost-tv") {
packages = []
if (tizen_product_tv && tizen_version >= 70) {
}
}
-tizen_pkg_config("libcapi-media-audio-io") {
- packages = []
- if (is_tizen) {
- packages = [ "capi-media-audio-io" ]
- }
-}
-
-config("capi-media-audio-io-public") {
- if (is_tizen) {
- cflags = [ "-capi-media-audio-io" ]
- }
-}
-
config("capi-network-bluetooth") {
if (tizen_product_tv) {
ldflags = [ "-lcapi-network-bluetooth" ]
#include "media/audio/tizen/capi_audio_input.h"
-#include <audio_io.h>
#include <sys/types.h>
#include "base/functional/bind.h"
#include "base/logging.h"
#include "media/audio/tizen/audio_manager_capi.h"
+#include "tizen_src/platform/capi-media-audio-io/capi_media_audio_io_proxy.h"
+
#if BUILDFLAG(IS_TIZEN_TV)
#include "content/public/browser/browser_thread.h"
#endif
audio_worker_("AudioInput"),
fifo_(params.channels(),
params.frames_per_buffer(),
- kNumberOfBlocksBufferInFifo) {}
+ kNumberOfBlocksBufferInFifo),
+ proxy_(platform::CapiMediaAudioIoProxy::Get()) {}
CapiAudioInputStream::~CapiAudioInputStream() {}
#include "media/base/audio_block_fifo.h"
#include "media/base/audio_parameters.h"
+namespace platform {
+class CapiMediaAudioIoProxy;
+}
+
namespace media {
class AudioManagerCapi;
std::unique_ptr<AudioDebugRecorder> debug_recorder_;
AudioManagerCapi* audio_manager_{nullptr};
double volume_;
+ std::shared_ptr<platform::CapiMediaAudioIoProxy> proxy_;
};
} // namespace media
#include "media/audio/tizen/capi_audio_output.h"
-#include <audio_io.h>
-
#include "base/functional/bind.h"
#include "base/logging.h"
#include "base/task/single_thread_task_runner.h"
#include "base/time/default_tick_clock.h"
#include "media/audio/audio_manager_base.h"
#include "media/base/audio_parameters.h"
+#include "tizen_src/platform/capi-media-audio-io/capi_media_audio_io_proxy.h"
#if BUILDFLAG(IS_TIZEN_TV)
#include "base/command_line.h"
volume_(1.0f),
buffer_(NULL),
state_(media::kIsClosed),
- source_callback_(NULL) {
+ source_callback_(NULL),
+ proxy_(platform::CapiMediaAudioIoProxy::Get()) {
LOG(INFO);
DCHECK(manager_->GetTaskRunner()->BelongsToCurrentThread());
CHECK(params_.IsValid());
LOG(INFO) << __func__ << " : state_ : " << static_cast<InternalState>(state_);
if (AUDIO_IO_ERROR_NONE !=
- audio_out_create_new(
+ proxy_->audio_out_create_new(
params_.sample_rate(), ToCapiAudioEnum(params_.channel_layout()),
ToCapiSampleType(kDefaultSampleFormat), &audio_out_)) {
LOG(ERROR) << "Fail to create audio output";
stream_info = nullptr;
return false;
}
- ret = audio_out_set_sound_stream_info(audio_out_, stream_info);
+ ret = proxy_->audio_out_set_sound_stream_info(audio_out_, stream_info);
if (AUDIO_IO_ERROR_NONE != ret) {
LOG(ERROR) << __func__ << " Fail to set stream info. ret : " << ret;
return false;
LOG(INFO) << __func__ << " : state_ : " << static_cast<InternalState>(state_);
if (AUDIO_IO_ERROR_NONE !=
- audio_out_set_stream_cb(audio_out_, &AudioStreamWriteCB, this)) {
+ proxy_->audio_out_set_stream_cb(audio_out_, &AudioStreamWriteCB, this)) {
LOG(ERROR) << "Fail to set audio output stream cb";
HandleError();
return;
}
- if (AUDIO_IO_ERROR_NONE != audio_out_prepare(audio_out_)) {
+ if (AUDIO_IO_ERROR_NONE != proxy_->audio_out_prepare(audio_out_)) {
LOG(ERROR) << "Cannot prepare audio output";
HandleError();
return;
DCHECK(state_ == media::kIsStarted);
LOG(INFO) << __func__ << " : state_ : " << static_cast<InternalState>(state_);
- if (AUDIO_IO_ERROR_NONE != audio_out_unprepare(audio_out_)) {
+ if (AUDIO_IO_ERROR_NONE != proxy_->audio_out_unprepare(audio_out_)) {
LOG(WARNING) << "Cannot unprepare audio output";
}
- if (AUDIO_IO_ERROR_NONE != audio_out_unset_stream_cb(audio_out_)) {
+ if (AUDIO_IO_ERROR_NONE != proxy_->audio_out_unset_stream_cb(audio_out_)) {
LOG(WARNING) << "Cannot unset audio output cb";
}
state_ = media::kIsClosed;
- audio_out_destroy(audio_out_); // always success
+ proxy_->audio_out_destroy(audio_out_); // always success
audio_out_ = NULL;
free(buffer_);
manager_->ReleaseOutputStream(this);
if (state_ != media::kIsStarted)
return;
- int flush_status = audio_out_flush(audio_out_);
+ int flush_status = proxy_->audio_out_flush(audio_out_);
if (flush_status != AUDIO_IO_ERROR_NONE) {
LOG(ERROR) << "Flush Error Code "
<< GetString(static_cast<audio_io_error_e>(flush_status));
audio_bus_->ToInterleaved<media::SignedInt16SampleTypeTraits>(
audio_bus_->frames(), reinterpret_cast<int16_t*>(buffer_));
- int bytes_written = audio_out_write(audio_out_, buffer_, bytes_to_fill);
+ int bytes_written = proxy_->audio_out_write(audio_out_, buffer_, bytes_to_fill);
if (bytes_written < 0) {
if (source_callback_) {
#ifndef MEDIA_AUDIO_TIZEN_CAPI_AUDIO_OUTPUT_H_
#define MEDIA_AUDIO_TIZEN_CAPI_AUDIO_OUTPUT_H_
-#include <audio_io.h>
#include <sound_manager.h>
#include "base/threading/thread.h"
media::InternalState state_;
AudioSourceCallback* source_callback_;
std::unique_ptr<AudioBus> audio_bus_;
+ std::shared_ptr<platform::CapiMediaAudioIoProxy> proxy_;
};
} // namespace media
#include "media/audio/tizen/capi_bt_audio_input_stream.h"
-#include <audio_io.h>
#include <sys/types.h>
#include "base/functional/bind.h"
#ifndef MEDIA_AUDIO_TIZEN_CAPI_BT_AUDIO_INPUT_STREAM_H_
#define MEDIA_AUDIO_TIZEN_CAPI_BT_AUDIO_INPUT_STREAM_H_
-#include <audio_io.h>
#include <string>
#include "base/memory/weak_ptr.h"
#include "media/audio/tizen/capi_usb_audio_input_stream.h"
-#include <audio_io.h>
#include <sys/types.h>
#include "base/functional/bind.h"
#include "base/logging.h"
#include "media/audio/tizen/audio_manager_capi.h"
+#include "tizen_src/platform/capi-media-audio-io/capi_media_audio_io_proxy.h"
#if BUILDFLAG(IS_TIZEN_TV)
#include "wrt/src/common/privilege.h"
AudioManagerCapi* audio_manager,
const std::string& device_name,
const AudioParameters& params)
- : CapiAudioInputStream(audio_manager, params) {
+ : CapiAudioInputStream(audio_manager, params),
+ proxy_(platform::CapiMediaAudioIoProxy::Get()) {
device_ = nullptr;
device_name_ = device_name;
#if BUILDFLAG(IS_TIZEN_TV)
}
#endif
- ret = audio_in_create(params_.sample_rate(), AUDIO_CHANNEL_STEREO,
+ ret = proxy_->audio_in_create(params_.sample_rate(), AUDIO_CHANNEL_STEREO,
AUDIO_SAMPLE_TYPE_S16_LE, &device_);
if (ret != AUDIO_IO_ERROR_NONE) {
LOG(ERROR) << "audio_in_create failed. Err:" << ret;
}
#if BUILDFLAG(IS_TIZEN_TV)
- ret = audio_in_set_sound_stream_info(device_, stream_info_);
+ ret = proxy_->audio_in_set_sound_stream_info(device_, stream_info_);
if (ret != SOUND_MANAGER_ERROR_NONE) {
LOG(ERROR) << "audio_in_set_sound_stream_info failed. Err:" << ret;
CloseMic(false);
DCHECK(device_);
LOG(INFO);
- int ret = audio_in_set_stream_cb(device_, &AudioStreamReadCB, this);
+ int ret = proxy_->audio_in_set_stream_cb(device_, &AudioStreamReadCB, this);
if (ret != AUDIO_IO_ERROR_NONE) {
LOG(ERROR) << "audio_in_set_stream_cb failed. Err:" << ret;
if (callback_)
audio_worker_.Start();
StartAgc();
- ret = audio_in_prepare(device_);
+ ret = proxy_->audio_in_prepare(device_);
if (ret != AUDIO_IO_ERROR_NONE) {
LOG(ERROR) << "Cannot prepare audio input. Err:" << ret;
if (callback_)
DCHECK(device_);
LOG(INFO);
- if (AUDIO_IO_ERROR_NONE != audio_in_unprepare(device_))
+ if (AUDIO_IO_ERROR_NONE != proxy_->audio_in_unprepare(device_))
LOG(WARNING) << "Cannot unprepare audio input";
- if (AUDIO_IO_ERROR_NONE != audio_in_unset_stream_cb(device_))
+ if (AUDIO_IO_ERROR_NONE != proxy_->audio_in_unset_stream_cb(device_))
LOG(WARNING) << "Cannot unset audio input cb";
}
#endif
if (device_) {
- int ret = audio_in_destroy(device_);
+ int ret = proxy_->audio_in_destroy(device_);
if (ret != AUDIO_IO_ERROR_NONE)
LOG(WARNING) << "audio_in_destroy failed. Err:" << ret;
unsigned int bytes_read = 0;
const void* loc_buff = nullptr;
- if (AUDIO_IO_ERROR_NONE != audio_in_peek(device_, &loc_buff, &bytes_read)) {
+ if (AUDIO_IO_ERROR_NONE != proxy_->audio_in_peek(device_, &loc_buff, &bytes_read)) {
LOG(ERROR) << "audio_in_peek() failed";
if (callback_)
callback_->OnError();
}
}
- if (AUDIO_IO_ERROR_NONE != audio_in_drop(device_)) {
+ if (AUDIO_IO_ERROR_NONE != proxy_->audio_in_drop(device_)) {
LOG(ERROR) << "audio_in_drop() failed";
if (callback_)
callback_->OnError();
#ifndef MEDIA_AUDIO_TIZEN_CAPI_USB_AUDIO_INPUT_STREAM_H_
#define MEDIA_AUDIO_TIZEN_CAPI_USB_AUDIO_INPUT_STREAM_H_
-#include <audio_io.h>
#include <string>
#include "base/memory/weak_ptr.h"
#include "media/audio/tizen/capi_util.h"
#include "media/base/audio_block_fifo.h"
#include "media/base/audio_parameters.h"
+
namespace media {
class CapiUsbAudioInputStream final : public CapiAudioInputStream {
sound_device_h sound_device_;
sound_stream_info_h stream_info_;
#endif
+ std::shared_ptr<platform::CapiMediaAudioIoProxy> proxy_;
};
} // namespace media
#include "base/logging.h"
#include "base/time/time.h"
+#include "tizen_src/platform/capi-media-audio-io/capi_media_audio_io_proxy.h"
namespace media {
bool local_audio_handle = false;
int err = AUDIO_IO_ERROR_NONE;
+ std::shared_ptr<platform::CapiMediaAudioIoProxy> proxy
+ = platform::CapiMediaAudioIoProxy::Get();
if (audio_in) {
// |audio_in| is created as well as prepared.
- err = audio_in_get_buffer_size(audio_in, &buffer_size);
+ err = proxy->audio_in_get_buffer_size(audio_in, &buffer_size);
if (AUDIO_IO_ERROR_NONE == err && buffer_size > 0) {
return buffer_size;
} else {
}
} else {
// create |audio_in| locally to get buffer size.
- err = audio_in_create(kDefaultSampleRate, AUDIO_CHANNEL_STEREO,
+ err = proxy->audio_in_create(kDefaultSampleRate, AUDIO_CHANNEL_STEREO,
AUDIO_SAMPLE_TYPE_S16_LE, &audio_in);
if (AUDIO_IO_ERROR_NONE != err) {
LOG(ERROR) << "audio_in_create() failed, Error code " << err;
}
if (AUDIO_IO_ERROR_NONE == audio_in_prepare(audio_in)) {
- audio_in_get_buffer_size(audio_in, &buffer_size);
- audio_in_unprepare(audio_in);
+ proxy->audio_in_get_buffer_size(audio_in, &buffer_size);
+ proxy->audio_in_unprepare(audio_in);
}
if (local_audio_handle) {
- audio_in_destroy(audio_in);
+ proxy->audio_in_destroy(audio_in);
}
return buffer_size;
}
bool local_audio_handle = false;
int err = AUDIO_IO_ERROR_NONE;
+ std::shared_ptr<platform::CapiMediaAudioIoProxy> proxy
+ = platform::CapiMediaAudioIoProxy::Get();
if (audio_out) {
// |audio_out| is created as well as prepared.
- err = audio_out_get_buffer_size(audio_out, &buffer_size);
+ err = proxy->audio_out_get_buffer_size(audio_out, &buffer_size);
if (AUDIO_IO_ERROR_NONE == err && buffer_size > 0) {
return buffer_size;
} else {
}
} else {
// create |audio_out| locally to get buffer size.
- err = audio_out_create_new(sample_rate, ToCapiAudioEnum(channel_layout),
+ err = proxy->audio_out_create_new(sample_rate, ToCapiAudioEnum(channel_layout),
ToCapiSampleType(sample_format), &audio_out);
if (AUDIO_IO_ERROR_NONE != err) {
LOG(ERROR) << "audio_out_create_new() failed, Error code " << err;
local_audio_handle = true;
}
- if (AUDIO_IO_ERROR_NONE == audio_out_prepare(audio_out)) {
- audio_out_get_buffer_size(audio_out, &buffer_size);
- audio_out_unprepare(audio_out);
+ if (AUDIO_IO_ERROR_NONE == proxy->audio_out_prepare(audio_out)) {
+ proxy->audio_out_get_buffer_size(audio_out, &buffer_size);
+ proxy->audio_out_unprepare(audio_out);
}
if (local_audio_handle) {
- audio_out_destroy(audio_out);
+ proxy->audio_out_destroy(audio_out);
}
return buffer_size;
}
media::ChannelLayout channel_layout,
SampleFormat sample_format) {
int err = AUDIO_IO_ERROR_NONE;
+ std::shared_ptr<platform::CapiMediaAudioIoProxy> proxy
+ = platform::CapiMediaAudioIoProxy::Get();
// If NULL try to create audio handle with passed sample rate.
if (audio_out == NULL) {
- err = audio_out_create_new(sample_rate, ToCapiAudioEnum(channel_layout),
+ err = proxy->audio_out_create_new(sample_rate, ToCapiAudioEnum(channel_layout),
ToCapiSampleType(sample_format), &audio_out);
if (AUDIO_IO_ERROR_NONE == err) {
- audio_out_destroy(audio_out);
+ proxy->audio_out_destroy(audio_out);
return sample_rate;
}
return 0;
// If not NULL get samplerate of passed audio_out handle.
if (AUDIO_IO_ERROR_NONE !=
- audio_out_get_sample_rate(audio_out, &sample_rate)) {
+ proxy->audio_out_get_sample_rate(audio_out, &sample_rate)) {
return 0;
}
// FIXME: Find a way to get audio input device latency.
static int latency_milli = 0;
static int sample_rate = 0;
+ std::shared_ptr<platform::CapiMediaAudioIoProxy> proxy
+ = platform::CapiMediaAudioIoProxy::Get();
if (sample_rate == 0 &&
- AUDIO_IO_ERROR_NONE != audio_in_get_sample_rate(audio_in, &sample_rate))
+ AUDIO_IO_ERROR_NONE != proxy->audio_in_get_sample_rate(audio_in, &sample_rate))
return 0;
return LatencyInBytes(latency_milli, sample_rate, bytes_per_frame);
// FIXME: Find a way to get audio output device latency.
static int latency_milli = 0;
static int sample_rate = 0;
+ std::shared_ptr<platform::CapiMediaAudioIoProxy> proxy
+ = platform::CapiMediaAudioIoProxy::Get();
if (sample_rate == 0 &&
- AUDIO_IO_ERROR_NONE != audio_out_get_sample_rate(audio_out, &sample_rate))
+ AUDIO_IO_ERROR_NONE != proxy->audio_out_get_sample_rate(audio_out, &sample_rate))
return 0;
return LatencyInBytes(latency_milli, sample_rate, bytes_per_frame);
#ifndef MEDIA_AUDIO_TIZEN_CAPI_UTIL_H_
#define MEDIA_AUDIO_TIZEN_CAPI_UTIL_H_
-#include <audio_io.h>
-
#include "media/base/audio_parameters.h"
+#include "tizen_src/platform/capi-media-audio-io/capi_media_audio_io_proxy.h"
namespace media {
#include "media/audio/audio_manager_base.h"
#include "media/base/data_buffer.h"
#include "media/base/tizen/logger/media_logger.h"
+#include "tizen_src/platform/capi-media-audio-io/capi_media_audio_io_proxy.h"
namespace media {
channel_layout_{in_params_.channels() > 1 ? AUDIO_CHANNEL_STEREO
: AUDIO_CHANNEL_MONO},
manager_{manager},
- task_runner_{base::SingleThreadTaskRunner::GetCurrentDefault()} {
+ task_runner_{base::SingleThreadTaskRunner::GetCurrentDefault()},
+ proxy_(platform::CapiMediaAudioIoProxy::Get()) {
TIZEN_MEDIA_LOG(INFO) << "Configuration: "
<< in_params_.AsHumanReadableString();
in_audio_bus_ = AudioBus::Create(params);
bool SoftwareFallbackOutputStream::CreateAudioOut() {
TIZEN_MEDIA_LOG(INFO);
- int err = audio_out_create_new(out_params_.sample_rate(), channel_layout_,
+ int err = proxy_->audio_out_create_new(out_params_.sample_rate(), channel_layout_,
AUDIO_SAMPLE_TYPE_S16_LE, &audio_out_);
if (err != AUDIO_IO_ERROR_NONE) {
TIZEN_MEDIA_LOG(ERROR) << "Failed to create audio_io output: " << err;
return false;
}
- err = audio_out_set_stream_cb(audio_out_, &OnAudioIONeedDataCb, this);
+ err = proxy_->audio_out_set_stream_cb(audio_out_, &OnAudioIONeedDataCb, this);
if (err != AUDIO_IO_ERROR_NONE) {
TIZEN_MEDIA_LOG(ERROR) << "Fail to set audio output stream cb";
return false;
}
- // TODO(vd.wasm) audio_out_set_sound_stream_info
+ // TODO(vd.wasm) proxy_->audio_out_set_sound_stream_info
return true;
}
return;
}
- int err = audio_out_unset_stream_cb(audio_out_);
+ int err = proxy_->audio_out_unset_stream_cb(audio_out_);
if (err != AUDIO_IO_ERROR_NONE) {
TIZEN_MEDIA_LOG(WARNING) << "Fail to unset stream callback";
}
- err = audio_out_destroy(audio_out_);
+ err = proxy_->audio_out_destroy(audio_out_);
if (err != AUDIO_IO_ERROR_NONE) {
TIZEN_MEDIA_LOG(ERROR) << "Failed to create audio_io output: " << err;
}
return;
}
- int err = audio_out_prepare(audio_out_);
+ int err = proxy_->audio_out_prepare(audio_out_);
if (err != AUDIO_IO_ERROR_NONE) {
TIZEN_MEDIA_LOG(ERROR) << "Failed to prepare audio_out";
callback->OnError(AudioSourceCallback::ErrorType::kDeviceChange);
return;
}
- int err = audio_out_unprepare(audio_out_);
+ int err = proxy_->audio_out_unprepare(audio_out_);
if (err != AUDIO_IO_ERROR_NONE) {
TIZEN_MEDIA_LOG(WARNING) << "Failed to unprepare audio_out, err: " << err;
}
if (!written.is_positive()) break;
}
- int err = audio_out_drain(audio_out_);
+ int err = proxy_->audio_out_drain(audio_out_);
if (err != AUDIO_IO_ERROR_NONE) {
TIZEN_MEDIA_LOG(WARNING) << "Failed to drain audio_out, err: " << err;
}
(bytes_per_second * kDefaultChunkDuration.InMilliseconds()) /
base::Time::kMillisecondsPerSecond;
const int write_size = std::min(buffer_size, max_write_size);
- int write_ret = audio_out_write(
+ int write_ret = proxy_->audio_out_write(
audio_out_, const_cast<uint8_t*>(buffer_data), write_size);
if (write_ret > 0) {
bytes_written_ += write_ret;
#include "media/base/channel_mixer.h"
#include "media/base/seekable_buffer.h"
+namespace platform {
+class CapiMediaAudioIoProxy;
+}
+
namespace media {
class AudioManagerBase;
base::WeakPtrFactory<SoftwareFallbackOutputStream> weak_factory_{this};
const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+ std::shared_ptr<platform::CapiMediaAudioIoProxy> proxy_;
SEQUENCE_CHECKER(sequence_checker_);
};
}
if (tizen_audio_io) {
- external_media_efl_audio_io_config += [
- "//tizen_src/build:capi-media-audio-io",
- "//tizen_src/build:libcapi-media-audio-io",
- ]
-
external_media_efl_audio_io_sources += [
"//tizen_src/chromium_impl/media/audio/tizen/audio_manager_capi.cc",
"//tizen_src/chromium_impl/media/audio/tizen/audio_manager_capi.h",
"//tizen_src/chromium_impl/media/audio/tizen/capi_util.h",
]
+ external_media_efl_audio_io_deps += [
+ "//tizen_src/platform/capi-media-audio-io:capi-media-audio-io-proxy",
+ ]
+
if (tizen_product_tv) {
external_media_efl_audio_io_sources += [
"//tizen_src/chromium_impl/media/audio/tizen/audio_device_listener_tizen.cc",
if libname_match:
libname = "lib" + libname_match.group(1) + ".so"
+ for base_dir in base_dirs:
+ file_path = f"{base_dir}/{libname}"
+ if os.path.exists(file_path):
+ if os.path.islink(file_path):
+ target_path = os.readlink(file_path)
+ libname = os.path.basename(target_path)
+ break
+
if not includedir:
raise ValueError(f"includedir not found in pkg-config file: {pc_file}")
if not libname:
--- /dev/null
+# Copyright (c) 2025 Samsung Electronics. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//tizen_src/build/config/linux/pkg_config.gni")
+import("//tizen_src/platform/tizen_proxy_source_set.gni")
+
+tizen_pkg_config("capi-media-audio-io-config") {
+ packages = []
+ if (is_tizen) {
+ packages = [ "capi-media-audio-io" ]
+ # If ignore_libs true, it ignores explicit dynamic linking flag.
+ ignore_libs = true
+ }
+}
+
+tizen_proxy_source_set("capi-media-audio-io-proxy") {
+ public_configs = [ ":capi-media-audio-io-config" ]
+ config = "capi_media_audio_io_proxy.json"
+}
--- /dev/null
+{
+ "name": "CapiMediaAudioIoProxy",
+ "package": "capi-media-audio-io",
+ "headers": ["audio_io.h"],
+ "functions": [
+ "audio_in_create",
+ "audio_in_destroy",
+ "audio_in_drop",
+ "audio_in_get_buffer_size",
+ "audio_in_get_sample_rate",
+ "audio_in_peek",
+ "audio_in_prepare",
+ "audio_in_set_sound_stream_info",
+ "audio_in_set_stream_cb",
+ "audio_in_unprepare",
+ "audio_in_unset_stream_cb",
+ "audio_out_create_new",
+ "audio_out_destroy",
+ "audio_out_drain",
+ "audio_out_flush",
+ "audio_out_get_buffer_size",
+ "audio_out_get_sample_rate",
+ "audio_out_prepare",
+ "audio_out_set_sound_stream_info",
+ "audio_out_set_stream_cb",
+ "audio_out_unprepare",
+ "audio_out_unset_stream_cb",
+ "audio_out_write"
+ ]
+}