summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSeungbae Shin <seungbae.shin@samsung.com>2018-07-25 20:58:38 +0900
committerSeungbae Shin <seungbae.shin@samsung.com>2018-08-16 20:21:19 +0900
commita32a1e03387c57ce6c06ae9ca4fd976a17c9719e (patch)
tree810a466da47a684f31b76d9001fa008b0be16464
parentd06767768203168895ae22481b4090121924feb3 (diff)
downloadmm-hal-interface-a32a1e03387c57ce6c06ae9ca4fd976a17c9719e.tar.gz
mm-hal-interface-a32a1e03387c57ce6c06ae9ca4fd976a17c9719e.tar.bz2
mm-hal-interface-a32a1e03387c57ce6c06ae9ca4fd976a17c9719e.zip
[Version] 0.0.13 [Profile] Common [Issue Type] Add [Dependency module] N/A Change-Id: I1c3bc6f1b84242ee04a4cfa1b5d8fd0432f0295e
-rw-r--r--configure.ac2
-rw-r--r--include/audio/audio_hal_interface.h101
-rw-r--r--mm-hal-interface-audio.manifest5
-rw-r--r--packaging/mm-hal-interface.spec36
-rw-r--r--src/Makefile.am3
-rw-r--r--src/audio/Makefile.am6
-rw-r--r--src/audio/audio_hal_interface.c690
-rw-r--r--testcase/Makefile.am3
-rw-r--r--testcase/audio/Makefile.am18
-rw-r--r--testcase/audio/audio_haltests.cpp870
-rw-r--r--testcase/audio/dtmf_16le_44100_2ch.rawbin0 -> 882000 bytes
11 files changed, 1730 insertions, 4 deletions
diff --git a/configure.ac b/configure.ac
index 0c305a9..9616f12 100644
--- a/configure.ac
+++ b/configure.ac
@@ -36,9 +36,11 @@ Makefile
src/Makefile
src/camera/Makefile
src/radio/Makefile
+src/audio/Makefile
testcase/Makefile
testcase/camera/Makefile
testcase/radio/Makefile
+testcase/audio/Makefile
camera-hal-interface.pc
radio-hal-interface.pc
])
diff --git a/include/audio/audio_hal_interface.h b/include/audio/audio_hal_interface.h
new file mode 100644
index 0000000..e7bb157
--- /dev/null
+++ b/include/audio/audio_hal_interface.h
@@ -0,0 +1,101 @@
+/*
+ * audio_hal_interface.h
+ *
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Seungbae Shin <seungbae.shin@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <tizen-audio.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum _io_direction {
+ DIRECTION_IN,
+ DIRECTION_OUT,
+} io_direction_t;
+
+typedef enum _audio_hal_return {
+ AUDIO_HAL_ERROR = -1,
+ AUDIO_HAL_SUCCESS
+} audio_hal_return_t;
+
+typedef struct _hal_device_info {
+ const char *type;
+ uint32_t direction;
+ uint32_t id;
+} hal_device_info;
+
+typedef struct _hal_route_info {
+ const char *role;
+ hal_device_info *device_infos;
+ uint32_t num_of_devices;
+} hal_route_info;
+
+typedef struct _hal_route_option {
+ const char *role;
+ const char *name;
+ int32_t value;
+} hal_route_option;
+
+typedef struct _hal_stream_connection_info {
+ const char *role;
+ uint32_t direction;
+ uint32_t idx;
+ bool is_connected;
+} hal_stream_connection_info;
+
+typedef void* pcm_handle;
+typedef void (*hal_message_callback)(const char *name, int value, void *user_data);
+typedef struct _audio_hal_interface audio_hal_interface;
+
+int32_t audio_hal_interface_init(audio_hal_interface **h);
+int32_t audio_hal_interface_deinit(audio_hal_interface *h);
+int32_t audio_hal_interface_get_volume_level_max(audio_hal_interface *h, const char *volume_type, io_direction_t direction, uint32_t *level);
+int32_t audio_hal_interface_get_volume_level(audio_hal_interface *h, const char *volume_type, io_direction_t direction, uint32_t *level);
+int32_t audio_hal_interface_set_volume_level(audio_hal_interface *h, const char *volume_type, io_direction_t direction, uint32_t level);
+int32_t audio_hal_interface_get_volume_value(audio_hal_interface *h, const char *volume_type, const char *gain_type,
+ io_direction_t direction, uint32_t level, double *value);
+int32_t audio_hal_interface_get_volume_mute(audio_hal_interface *h, const char *volume_type, io_direction_t direction, uint32_t *mute);
+int32_t audio_hal_interface_set_volume_mute(audio_hal_interface *h, const char *volume_type, io_direction_t direction, uint32_t mute);
+int32_t audio_hal_interface_update_route(audio_hal_interface *h, hal_route_info *info);
+int32_t audio_hal_interface_update_route_option(audio_hal_interface *h, hal_route_option *option);
+int32_t audio_hal_interface_notify_stream_connection_changed(audio_hal_interface *h, hal_stream_connection_info *info);
+int32_t audio_hal_interface_pcm_open(audio_hal_interface *h, const char *card, const char *device, io_direction_t direction,
+ void *sample_spec, uint32_t period_size, uint32_t periods, pcm_handle *pcm_h);
+int32_t audio_hal_interface_pcm_start(audio_hal_interface *h, pcm_handle pcm_h);
+int32_t audio_hal_interface_pcm_stop(audio_hal_interface *h, pcm_handle pcm_h);
+int32_t audio_hal_interface_pcm_close(audio_hal_interface *h, pcm_handle pcm_h);
+int32_t audio_hal_interface_pcm_available(audio_hal_interface *h, pcm_handle pcm_h, uint32_t *available);
+int32_t audio_hal_interface_pcm_write(audio_hal_interface *h, pcm_handle pcm_h, const void *buffer, uint32_t frames);
+int32_t audio_hal_interface_pcm_read(audio_hal_interface *h, pcm_handle pcm_h, void *buffer, uint32_t frames);
+int32_t audio_hal_interface_pcm_get_fd(audio_hal_interface *h, pcm_handle pcm_h, int *fd);
+int32_t audio_hal_interface_pcm_recover(audio_hal_interface *h, pcm_handle pcm_h, int err);
+int32_t audio_hal_interface_pcm_get_params(audio_hal_interface *h, pcm_handle pcm_h, uint32_t direction, void **sample_spec,
+ uint32_t *period_size, uint32_t *periods);
+int32_t audio_hal_interface_pcm_set_params(audio_hal_interface *h, pcm_handle pcm_h, uint32_t direction, void *sample_spec,
+ uint32_t period_size, uint32_t periods);
+int32_t audio_hal_interface_add_message_callback(audio_hal_interface *h, hal_message_callback callback, void *user_data);
+int32_t audio_hal_interface_remove_message_callback(audio_hal_interface *h, hal_message_callback callback);
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/mm-hal-interface-audio.manifest b/mm-hal-interface-audio.manifest
new file mode 100644
index 0000000..a76fdba
--- /dev/null
+++ b/mm-hal-interface-audio.manifest
@@ -0,0 +1,5 @@
+<manifest>
+ <request>
+ <domain name="_" />
+ </request>
+</manifest>
diff --git a/packaging/mm-hal-interface.spec b/packaging/mm-hal-interface.spec
index 3c054f6..9d8fa87 100644
--- a/packaging/mm-hal-interface.spec
+++ b/packaging/mm-hal-interface.spec
@@ -1,7 +1,7 @@
Name: mm-hal-interface
Summary: Multimedia HAL Interface
-Version: 0.0.12
-Release: 1
+Version: 0.0.13
+Release: 0
Group: Multimedia/Development
License: Apache-2.0
Source0: %{name}-%{version}.tar.gz
@@ -32,7 +32,13 @@ Version: %{version}
%description radio
Multimedia framework hardware abstraction layer interface library for radio.
+%package audio
+Summary: Multimedia framework hardware abstraction layer interface library for audio
+Group: Multimedia/Libraries
+Version: %{version}
+%description audio
+Multimedia framework hardware abstraction layer interface library for audio.
%package devel
Summary: Multimedia framework hardware abstraction layer interface development package
@@ -40,6 +46,7 @@ Group: libdevel
Version: %{version}
Requires: %{name}-camera = %{version}-%{release}
Requires: %{name}-radio = %{version}-%{release}
+Requires: %{name}-audio = %{version}-%{release}
%description devel
Multimedia framework hardware abstraction layer interface development package.
@@ -53,6 +60,15 @@ Version: %{version}
%description -n camera-haltests
gtest for camera HAL APIs.
+%package -n audio-haltests
+Summary: gtest for audio HAL APIs
+Group: Development/Tools
+Version: %{version}
+
+%description -n audio-haltests
+gtest for audio HAL APIs.
+
+
%package -n radio-haltests
Summary: gtest for radio HAL APIs
@@ -78,6 +94,9 @@ install -d -m 755 %{buildroot}%{_includedir}
install -m 644 include/audio/*.h %{buildroot}%{_includedir}
install -m 644 include/camera/*.h %{buildroot}%{_includedir}
install -m 644 include/radio/*.h %{buildroot}%{_includedir}
+
+install -d -m 755 %{buildroot}%{_datadir}/testcase/res/audio/
+install -m 644 testcase/audio/*.raw %{buildroot}%{_datadir}/testcase/res/audio/
%make_install
%post -p /sbin/ldconfig
@@ -101,6 +120,12 @@ install -m 644 include/radio/*.h %{buildroot}%{_includedir}
%defattr(-,root,root,-)
%{_libdir}/libradio*.so.*
+%files audio
+%manifest mm-hal-interface-audio.manifest
+%license LICENSE.APLv2
+%defattr(-,root,root,-)
+%{_libdir}/libaudio*.so.*
+
%files devel
%defattr(-,root,root,-)
%{_includedir}/*.h
@@ -118,3 +143,10 @@ install -m 644 include/radio/*.h %{buildroot}%{_includedir}
%license LICENSE.APLv2
%defattr(-,root,root,-)
%{_bindir}/radio_*
+
+%files -n audio-haltests
+%manifest mm-haltests.manifest
+%license LICENSE.APLv2
+%defattr(-,root,root,-)
+%{_bindir}/audio_*
+%{_datadir}/testcase/res/audio/*
diff --git a/src/Makefile.am b/src/Makefile.am
index 1d5c729..4c6082d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,3 +1,4 @@
SUBDIRS = camera \
- radio
+ radio \
+ audio
diff --git a/src/audio/Makefile.am b/src/audio/Makefile.am
new file mode 100644
index 0000000..cecbb90
--- /dev/null
+++ b/src/audio/Makefile.am
@@ -0,0 +1,6 @@
+lib_LTLIBRARIES = libaudio_hal_interface.la
+
+libaudio_hal_interface_la_SOURCES = audio_hal_interface.c
+libaudio_hal_interface_la_CFLAGS = $(DLOG_CFLAGS) -I$(srcdir)/../../include/audio
+libaudio_hal_interface_la_LIBADD = $(DLOG_LIBS) -ldl
+
diff --git a/src/audio/audio_hal_interface.c b/src/audio/audio_hal_interface.c
new file mode 100644
index 0000000..f28ed65
--- /dev/null
+++ b/src/audio/audio_hal_interface.c
@@ -0,0 +1,690 @@
+/*
+ * audio_hal_interface.c
+ *
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Seungbae Shin <seungbae.shin@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <dlfcn.h>
+#include <dlog.h>
+#include <stdlib.h>
+#include <assert.h>
+#include "audio_hal_interface.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif /* LOG_TAG */
+#define LOG_TAG "AUDIO_HAL_INTF"
+
+#define LIB_TIZEN_AUDIO "libtizen-audio.so"
+
+struct _audio_hal_interface {
+ void *dl_handle;
+ void *ah_handle;
+ audio_interface_t intf;
+};
+
+int32_t audio_hal_interface_init(audio_hal_interface **h)
+{
+ int ret = AUDIO_RET_OK;
+ audio_hal_interface *tmp_h = NULL;
+
+ if (h == NULL) {
+ LOGE("invalid parameter for audio_hal_interface");
+ return AUDIO_HAL_ERROR;
+ }
+
+ tmp_h = (audio_hal_interface *)malloc(sizeof(struct _audio_hal_interface));
+ if (tmp_h == NULL) {
+ LOGE("failed to allocate hal interface");
+ return AUDIO_HAL_ERROR;
+ }
+
+ tmp_h->dl_handle = dlopen(LIB_TIZEN_AUDIO, RTLD_NOW);
+ if (!tmp_h->dl_handle) {
+ LOGE("dlopen %s failed :%s", LIB_TIZEN_AUDIO, dlerror());
+ free(tmp_h);
+ return AUDIO_HAL_ERROR;
+ }
+
+ tmp_h->intf.init = dlsym(tmp_h->dl_handle, "audio_init");
+ tmp_h->intf.deinit = dlsym(tmp_h->dl_handle, "audio_deinit");
+ tmp_h->intf.get_volume_level_max = dlsym(tmp_h->dl_handle, "audio_get_volume_level_max");
+ tmp_h->intf.get_volume_level = dlsym(tmp_h->dl_handle, "audio_get_volume_level");
+ tmp_h->intf.set_volume_level = dlsym(tmp_h->dl_handle, "audio_set_volume_level");
+ tmp_h->intf.get_volume_value = dlsym(tmp_h->dl_handle, "audio_get_volume_value");
+ tmp_h->intf.get_volume_mute = dlsym(tmp_h->dl_handle, "audio_get_volume_mute");
+ tmp_h->intf.set_volume_mute = dlsym(tmp_h->dl_handle, "audio_set_volume_mute");
+ tmp_h->intf.update_route = dlsym(tmp_h->dl_handle, "audio_update_route");
+ tmp_h->intf.update_route_option = dlsym(tmp_h->dl_handle, "audio_update_route_option");
+ tmp_h->intf.notify_stream_connection_changed = dlsym(tmp_h->dl_handle, "audio_notify_stream_connection_changed");
+ tmp_h->intf.pcm_open = dlsym(tmp_h->dl_handle, "audio_pcm_open");
+ tmp_h->intf.pcm_start = dlsym(tmp_h->dl_handle, "audio_pcm_start");
+ tmp_h->intf.pcm_stop = dlsym(tmp_h->dl_handle, "audio_pcm_stop");
+ tmp_h->intf.pcm_close = dlsym(tmp_h->dl_handle, "audio_pcm_close");
+ tmp_h->intf.pcm_avail = dlsym(tmp_h->dl_handle, "audio_pcm_avail");
+ tmp_h->intf.pcm_write = dlsym(tmp_h->dl_handle, "audio_pcm_write");
+ tmp_h->intf.pcm_read = dlsym(tmp_h->dl_handle, "audio_pcm_read");
+ tmp_h->intf.pcm_get_fd = dlsym(tmp_h->dl_handle, "audio_pcm_get_fd");
+ tmp_h->intf.pcm_recover = dlsym(tmp_h->dl_handle, "audio_pcm_recover");
+ tmp_h->intf.pcm_get_params = dlsym(tmp_h->dl_handle, "audio_pcm_get_params");
+ tmp_h->intf.pcm_set_params = dlsym(tmp_h->dl_handle, "audio_pcm_set_params");
+ tmp_h->intf.add_message_cb = dlsym(tmp_h->dl_handle, "audio_add_message_cb");
+ tmp_h->intf.remove_message_cb = dlsym(tmp_h->dl_handle, "audio_remove_message_cb");
+
+ if (tmp_h->intf.init) {
+ ret = tmp_h->intf.init(&tmp_h->ah_handle);
+ if (ret == AUDIO_RET_OK) {
+ LOGI("audio_init success!!!");
+ *h = tmp_h;
+ return AUDIO_HAL_SUCCESS;
+ }
+ LOGE("audio_init failed 0x%x", ret);
+ } else {
+ LOGE("no audio_init function");
+ }
+
+ dlclose(tmp_h->dl_handle);
+ free(tmp_h);
+
+ return AUDIO_HAL_ERROR;
+}
+
+
+int32_t audio_hal_interface_deinit(audio_hal_interface *h)
+{
+ int ret = AUDIO_RET_OK;
+
+ assert(h);
+ assert(h->dl_handle);
+ assert(h->ah_handle);
+
+ if (h->intf.deinit) {
+ ret = h->intf.deinit(h->ah_handle);
+ if (ret != AUDIO_RET_OK) {
+ LOGE("audio_deinit failed 0x%x", ret);
+ return AUDIO_HAL_ERROR;
+ }
+ LOGI("audio_deinit success!!!");
+ } else {
+ LOGE("Not implemented....");
+ }
+
+ dlclose(h->dl_handle);
+ free(h);
+
+ return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_get_volume_level_max(audio_hal_interface *h,
+ const char *volume_type,
+ io_direction_t direction,
+ uint32_t *level)
+{
+ audio_return_t ret = AUDIO_RET_OK;
+ audio_volume_info_t info = { NULL, NULL, 0 };
+
+ assert(h);
+ assert(h->ah_handle);
+
+ info.type = volume_type;
+ info.direction = direction;
+
+ if (!h->intf.get_volume_level_max) {
+ LOGE("Not implemented....");
+ return AUDIO_HAL_ERROR;
+ }
+
+ ret = h->intf.get_volume_level_max(h->ah_handle, &info, level);
+ if (ret != AUDIO_RET_OK) {
+ LOGE("get_volume_level_max returns error:0x%x", ret);
+ return AUDIO_HAL_ERROR;
+ }
+
+ return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_get_volume_level(audio_hal_interface *h,
+ const char *volume_type,
+ io_direction_t direction,
+ uint32_t *level)
+{
+ audio_return_t ret = AUDIO_RET_OK;
+ audio_volume_info_t info = { NULL, NULL, 0 };
+
+ assert(h);
+ assert(h->ah_handle);
+
+ info.type = volume_type;
+ info.direction = direction;
+
+ if (!h->intf.get_volume_level) {
+ LOGE("Not implemented....");
+ return AUDIO_HAL_ERROR;
+ }
+
+ ret = h->intf.get_volume_level(h->ah_handle, &info, level);
+ if (ret != AUDIO_RET_OK) {
+ LOGE("get_volume_level returns error:0x%x", ret);
+ return AUDIO_HAL_ERROR;
+ }
+
+ return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_set_volume_level(audio_hal_interface *h,
+ const char *volume_type,
+ io_direction_t direction,
+ uint32_t level)
+{
+ audio_return_t ret = AUDIO_RET_OK;
+ audio_volume_info_t info = { NULL, NULL, 0 };
+
+ assert(h);
+ assert(h->ah_handle);
+
+ info.type = volume_type;
+ info.direction = direction;
+
+ if (!h->intf.set_volume_level) {
+ LOGE("Not implemented....");
+ return AUDIO_HAL_ERROR;
+ }
+
+ ret = h->intf.set_volume_level(h->ah_handle, &info, level);
+ if (ret != AUDIO_RET_OK) {
+ LOGE("set_volume_level returns error:0x%x", ret);
+ return AUDIO_HAL_ERROR;
+ }
+
+ return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_get_volume_value(audio_hal_interface *h,
+ const char *volume_type,
+ const char *gain_type,
+ io_direction_t direction,
+ uint32_t level,
+ double *value)
+{
+ audio_return_t ret = AUDIO_RET_OK;
+ audio_volume_info_t info = { NULL, NULL, 0 };
+
+ assert(h);
+ assert(h->ah_handle);
+
+ info.type = volume_type;
+ info.gain = gain_type;
+ info.direction = direction;
+
+ if (!h->intf.get_volume_value) {
+ LOGE("Not implemented....");
+ return AUDIO_HAL_ERROR;
+ }
+
+ ret = h->intf.get_volume_value(h->ah_handle, &info, level, value);
+ if (ret != AUDIO_RET_OK) {
+ LOGE("get_volume_value returns error:0x%x", ret);
+ return AUDIO_HAL_ERROR;
+ }
+
+ return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_get_volume_mute(audio_hal_interface *h,
+ const char *volume_type,
+ io_direction_t direction,
+ uint32_t *mute)
+{
+ audio_return_t ret = AUDIO_RET_OK;
+ audio_volume_info_t info = { NULL, NULL, 0 };
+
+ assert(h);
+ assert(h->ah_handle);
+
+ info.type = volume_type;
+ info.direction = direction;
+
+ if (!h->intf.get_volume_mute) {
+ LOGE("Not implemented....");
+ return AUDIO_HAL_ERROR;
+ }
+
+ ret = h->intf.get_volume_mute(h->ah_handle, &info, mute);
+ if (ret != AUDIO_RET_OK) {
+ LOGE("get_volume_mute returns error:0x%x", ret);
+ return AUDIO_HAL_ERROR;
+ }
+
+ return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_set_volume_mute(audio_hal_interface *h,
+ const char *volume_type,
+ io_direction_t direction,
+ uint32_t mute)
+{
+ audio_return_t ret = AUDIO_RET_OK;
+ audio_volume_info_t info = { NULL, NULL, 0 };
+
+ assert(h);
+ assert(h->ah_handle);
+
+ info.type = volume_type;
+ info.direction = direction;
+
+ if (!h->intf.set_volume_mute) {
+ LOGE("Not implemented....");
+ return AUDIO_HAL_ERROR;
+ }
+
+ ret = h->intf.set_volume_mute(h->ah_handle, &info, mute);
+ if (ret != AUDIO_RET_OK) {
+ LOGE("set_volume_mute returns error:0x%x", ret);
+ return AUDIO_HAL_ERROR;
+ }
+
+ return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_update_route(audio_hal_interface *h,
+ hal_route_info *info)
+{
+ audio_return_t ret = AUDIO_RET_OK;
+
+ assert(h);
+ assert(h->ah_handle);
+
+ if (!h->intf.update_route) {
+ LOGE("Not implemented....");
+ return AUDIO_HAL_ERROR;
+ }
+
+ ret = h->intf.update_route(h->ah_handle, (audio_route_info_t *)info);
+ if (ret != AUDIO_RET_OK) {
+ LOGE("update_route returns error:0x%x", ret);
+ return AUDIO_HAL_ERROR;
+ }
+
+ return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_update_route_option(audio_hal_interface *h,
+ hal_route_option *option)
+{
+ audio_return_t ret = AUDIO_RET_OK;
+
+ assert(h);
+ assert(h->ah_handle);
+
+ if (!h->intf.update_route_option) {
+ LOGE("Not implemented....");
+ return AUDIO_HAL_ERROR;
+ }
+
+ ret = h->intf.update_route_option(h->ah_handle, (audio_route_option_t*)option);
+ if (ret != AUDIO_RET_OK) {
+ LOGE("update_route_option returns error:0x%x", ret);
+ return AUDIO_HAL_ERROR;
+ }
+
+ return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_notify_stream_connection_changed(audio_hal_interface *h,
+ hal_stream_connection_info *info)
+{
+ audio_return_t ret = AUDIO_RET_OK;
+ audio_stream_info_t hal_info;
+ uint32_t is_connected = 0;
+
+ assert(h);
+ assert(h->ah_handle);
+
+ if (info) {
+ hal_info.role = info->role;
+ hal_info.direction = info->direction;
+ hal_info.idx = info->idx;
+ is_connected = info->is_connected;
+ }
+
+ if (!h->intf.notify_stream_connection_changed) {
+ LOGE("Not implemented....");
+ return AUDIO_HAL_ERROR;
+ }
+
+ ret = h->intf.notify_stream_connection_changed(h->ah_handle, &hal_info, is_connected);
+ if (ret != AUDIO_RET_OK) {
+ LOGE("notify_stream_connection_changed returns error:0x%x", ret);
+ return AUDIO_HAL_ERROR;
+ }
+
+ return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_pcm_open(audio_hal_interface *h,
+ const char *card,
+ const char *device,
+ io_direction_t direction,
+ void *sample_spec,
+ uint32_t period_size,
+ uint32_t periods,
+ pcm_handle *pcm_h)
+{
+ audio_return_t ret = AUDIO_RET_OK;
+
+ assert(h);
+ assert(h->ah_handle);
+
+ if (!h->intf.pcm_open) {
+ LOGE("Not implemented....");
+ return AUDIO_HAL_ERROR;
+ }
+
+ ret = h->intf.pcm_open(h->ah_handle, card, device, direction, sample_spec, period_size, periods, pcm_h);
+ if (ret != AUDIO_RET_OK) {
+ LOGE("pcm_open returns error:0x%x", ret);
+ return AUDIO_HAL_ERROR;
+ }
+
+ return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_pcm_start(audio_hal_interface *h,
+ pcm_handle pcm_h)
+{
+ audio_return_t ret = AUDIO_RET_OK;
+
+ assert(h);
+ assert(h->ah_handle);
+
+ if (!h->intf.pcm_start) {
+ LOGE("Not implemented....");
+ return AUDIO_HAL_ERROR;
+ }
+
+ ret = h->intf.pcm_start(h->ah_handle, pcm_h);
+ if (ret != AUDIO_RET_OK) {
+ LOGE("pcm_start returns error:0x%x", ret);
+ return AUDIO_HAL_ERROR;
+ }
+
+ return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_pcm_stop(audio_hal_interface *h,
+ pcm_handle pcm_h)
+{
+ audio_return_t ret = AUDIO_RET_OK;
+
+ assert(h);
+ assert(h->ah_handle);
+
+ if (!h->intf.pcm_stop) {
+ LOGE("Not implemented....");
+ return AUDIO_HAL_ERROR;
+ }
+
+ ret = h->intf.pcm_stop(h->ah_handle, pcm_h);
+ if (ret != AUDIO_RET_OK) {
+ LOGE("pcm_stop returns error:0x%x", ret);
+ return AUDIO_HAL_ERROR;
+ }
+
+ return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_pcm_close(audio_hal_interface *h,
+ pcm_handle pcm_h)
+{
+ audio_return_t ret = AUDIO_RET_OK;
+
+ assert(h);
+ assert(h->ah_handle);
+
+ if (!h->intf.pcm_close) {
+ LOGE("Not implemented....");
+ return AUDIO_HAL_ERROR;
+ }
+
+ ret = h->intf.pcm_close(h->ah_handle, pcm_h);
+ if (ret != AUDIO_RET_OK) {
+ LOGE("pcm_close returns error:0x%x", ret);
+ return AUDIO_HAL_ERROR;
+ }
+
+ return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_pcm_available(audio_hal_interface *h,
+ pcm_handle pcm_h,
+ uint32_t *available)
+{
+ audio_return_t ret = AUDIO_RET_OK;
+
+ assert(h);
+ assert(h->ah_handle);
+
+ if (!h->intf.pcm_avail) {
+ LOGE("Not implemented....");
+ return AUDIO_HAL_ERROR;
+ }
+
+ ret = h->intf.pcm_avail(h->ah_handle, pcm_h, available);
+ if (ret != AUDIO_RET_OK) {
+ LOGE("pcm_avail returns error:0x%x", ret);
+ return AUDIO_HAL_ERROR;
+ }
+
+ return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_pcm_write(audio_hal_interface *h,
+ pcm_handle pcm_h,
+ const void *buffer,
+ uint32_t frames)
+{
+ audio_return_t ret = AUDIO_RET_OK;
+
+ assert(h);
+ assert(h->ah_handle);
+
+ if (!h->intf.pcm_write) {
+ LOGE("Not implemented....");
+ return AUDIO_HAL_ERROR;
+ }
+
+ ret = h->intf.pcm_write(h->ah_handle, pcm_h, buffer, frames);
+ if (ret != AUDIO_RET_OK) {
+ LOGE("pcm_write returns error:0x%x", ret);
+ return AUDIO_HAL_ERROR;
+ }
+
+ return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_pcm_read(audio_hal_interface *h,
+ pcm_handle pcm_h,
+ void *buffer,
+ uint32_t frames)
+{
+ audio_return_t ret = AUDIO_RET_OK;
+
+ assert(h);
+ assert(h->ah_handle);
+
+ if (!h->intf.pcm_read) {
+ LOGE("Not implemented....");
+ return AUDIO_HAL_ERROR;
+ }
+
+ ret = h->intf.pcm_read(h->ah_handle, pcm_h, buffer, frames);
+ if (ret != AUDIO_RET_OK) {
+ LOGE("pcm_read returns error:0x%x", ret);
+ return AUDIO_HAL_ERROR;
+ }
+
+ return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_pcm_get_fd(audio_hal_interface *h,
+ pcm_handle pcm_h,
+ int *fd)
+{
+ audio_return_t ret = AUDIO_RET_OK;
+
+ assert(h);
+ assert(h->ah_handle);
+
+ if (!h->intf.pcm_get_fd) {
+ LOGE("Not implemented....");
+ return AUDIO_HAL_ERROR;
+ }
+
+ ret = h->intf.pcm_get_fd(h->ah_handle, pcm_h, fd);
+ if (ret != AUDIO_RET_OK) {
+ LOGE("pcm_get_fd returns error:0x%x", ret);
+ return AUDIO_HAL_ERROR;
+ }
+
+ return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_pcm_recover(audio_hal_interface *h,
+ pcm_handle pcm_h,
+ int err)
+{
+ audio_return_t ret = AUDIO_RET_OK;
+
+ assert(h);
+ assert(h->ah_handle);
+
+ if (!h->intf.pcm_recover) {
+ LOGE("Not implemented....");
+ return AUDIO_HAL_ERROR;
+ }
+
+ ret = h->intf.pcm_recover(h->ah_handle, pcm_h, err);
+ if (ret != AUDIO_RET_OK) {
+ LOGE("pcm_recover returns error:0x%x", ret);
+ return AUDIO_HAL_ERROR;
+ }
+
+ return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_pcm_get_params(audio_hal_interface *h,
+ pcm_handle pcm_h,
+ uint32_t direction,
+ void **sample_spec,
+ uint32_t *period_size,
+ uint32_t *periods)
+{
+ audio_return_t ret = AUDIO_RET_OK;
+
+ assert(h);
+ assert(h->ah_handle);
+
+ if (!h->intf.pcm_get_params) {
+ LOGE("Not implemented....");
+ return AUDIO_HAL_ERROR;
+ }
+
+ ret = h->intf.pcm_get_params(h->ah_handle, pcm_h, direction, sample_spec, period_size, periods);
+ if (ret != AUDIO_RET_OK) {
+ LOGE("pcm_get_params returns error:0x%x", ret);
+ return AUDIO_HAL_ERROR;
+ }
+
+ return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_pcm_set_params(audio_hal_interface *h,
+ pcm_handle pcm_h,
+ uint32_t direction,
+ void *sample_spec,
+ uint32_t period_size,
+ uint32_t periods)
+{
+ audio_return_t ret = AUDIO_RET_OK;
+
+ assert(h);
+ assert(h->ah_handle);
+
+ if (!h->intf.pcm_set_params) {
+ LOGE("Not implemented....");
+ return AUDIO_HAL_ERROR;
+ }
+
+ ret = h->intf.pcm_set_params(h->ah_handle, pcm_h, direction, sample_spec, period_size, periods);
+ if (ret != AUDIO_RET_OK) {
+ LOGE("pcm_set_params returns error:0x%x", ret);
+ return AUDIO_HAL_ERROR;
+ }
+
+ return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_add_message_callback(audio_hal_interface *h,
+ hal_message_callback callback,
+ void *user_data)
+{
+ audio_return_t ret = AUDIO_RET_OK;
+
+ assert(h);
+ assert(h->ah_handle);
+
+ if (!h->intf.add_message_cb) {
+ LOGE("Not implemented....");
+ return AUDIO_HAL_ERROR;
+ }
+
+ ret = h->intf.add_message_cb(h->ah_handle, (message_cb)callback, user_data);
+ if (ret != AUDIO_RET_OK) {
+ LOGE("add_message_cb returns error:0x%x", ret);
+ return AUDIO_HAL_ERROR;
+ }
+
+ return AUDIO_HAL_SUCCESS;
+}
+
+int32_t audio_hal_interface_remove_message_callback(audio_hal_interface *h,
+ hal_message_callback callback)
+{
+ audio_return_t ret = AUDIO_RET_OK;
+
+ assert(h);
+ assert(h->ah_handle);
+
+ if (!h->intf.remove_message_cb) {
+ LOGE("Not implemented....");
+ return AUDIO_HAL_ERROR;
+ }
+
+ ret = h->intf.remove_message_cb(h->ah_handle, (message_cb)callback);
+ if (ret != AUDIO_RET_OK) {
+ LOGE("remove_message_cb returns error:0x%x", ret);
+ return AUDIO_HAL_ERROR;
+ }
+
+ return AUDIO_HAL_SUCCESS;
+}
diff --git a/testcase/Makefile.am b/testcase/Makefile.am
index 1d5c729..4c6082d 100644
--- a/testcase/Makefile.am
+++ b/testcase/Makefile.am
@@ -1,3 +1,4 @@
SUBDIRS = camera \
- radio
+ radio \
+ audio
diff --git a/testcase/audio/Makefile.am b/testcase/audio/Makefile.am
new file mode 100644
index 0000000..779de11
--- /dev/null
+++ b/testcase/audio/Makefile.am
@@ -0,0 +1,18 @@
+# with gtest
+bin_PROGRAMS = audio_haltests
+
+audio_haltests_SOURCES = \
+ audio_haltests.cpp
+
+audio_haltests_CPPFLAGS = \
+ $(DLOG_CFLAGS)\
+ $(SYSTEM_INFO_CFLAGS)\
+ -I$(srcdir)/../../include/audio
+
+audio_haltests_LDADD = \
+ -ldl\
+ -lgtest\
+ $(top_builddir)/src/audio/libaudio_hal_interface.la\
+ $(DLOG_LIBS)\
+ $(SYSTEM_INFO_LIBS)
+
diff --git a/testcase/audio/audio_haltests.cpp b/testcase/audio/audio_haltests.cpp
new file mode 100644
index 0000000..49fb907
--- /dev/null
+++ b/testcase/audio/audio_haltests.cpp
@@ -0,0 +1,870 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Seungbae Shin <seungbae.shin@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string.h>
+#include <unistd.h>
+#include <iostream>
+#include <array>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <gtest/gtest.h>
+
+#include <audio_hal_interface.h>
+#include <system_info.h>
+
+using namespace std;
+
+typedef enum audio_sample_format {
+ AUDIO_SAMPLE_U8,
+ AUDIO_SAMPLE_ALAW,
+ AUDIO_SAMPLE_ULAW,
+ AUDIO_SAMPLE_S16LE,
+ AUDIO_SAMPLE_S16BE,
+ AUDIO_SAMPLE_FLOAT32LE,
+ AUDIO_SAMPLE_FLOAT32BE,
+ AUDIO_SAMPLE_S32LE,
+ AUDIO_SAMPLE_S32BE,
+ AUDIO_SAMPLE_S24LE,
+ AUDIO_SAMPLE_S24BE,
+ AUDIO_SAMPLE_S24_32LE,
+ AUDIO_SAMPLE_S24_32BE,
+ AUDIO_SAMPLE_MAX,
+ AUDIO_SAMPLE_INVALID = -1
+} audio_sample_format_t;
+
+typedef struct {
+ audio_sample_format_t format;
+ uint32_t rate;
+ uint8_t channels;
+} audio_pcm_sample_spec_t;
+
+
+/*
+ * TestSuite Class
+ */
+class AudioHalTest : public testing::Test
+{
+ public:
+ virtual void SetUp();
+ virtual void TearDown();
+
+ protected:
+ void SetRouteToSpeaker();
+ int32_t WritePcmFromFile(pcm_handle pcm_h, audio_pcm_sample_spec_t *spec);
+ uint32_t BytesToFrames(uint32_t bytes, audio_pcm_sample_spec_t *spec);
+ uint32_t FramesToBytes(uint32_t frames, audio_pcm_sample_spec_t *spec);
+ static void HalMessageCallback(const char *name, int value, void *user_data);
+
+ audio_hal_interface *m_h;
+ const string default_card = "sprdphone";
+ const string default_device = "0";
+
+ private:
+};
+
+void AudioHalTest::SetUp()
+{
+ m_h = nullptr;
+
+ int32_t ret = audio_hal_interface_init(&m_h);
+ if (ret != AUDIO_HAL_SUCCESS)
+ cout << "audio hal init failed : " << ret << endl;
+}
+
+void AudioHalTest::TearDown()
+{
+ if (m_h == nullptr)
+ return;
+
+ int32_t ret = audio_hal_interface_deinit(m_h);
+ if (ret != AUDIO_HAL_SUCCESS)
+ cout << "audio hal deinit failed : " << ret << endl;
+
+ m_h = nullptr;
+}
+
+void AudioHalTest::SetRouteToSpeaker()
+{
+ hal_route_info info;
+ int32_t num_of_devices = 1;
+
+ memset(&info, 0, sizeof(hal_route_info));
+
+ info.role = "media";
+ info.device_infos = (hal_device_info*)malloc(sizeof(hal_device_info) * num_of_devices);
+ if (info.device_infos == nullptr) {
+ cout << "malloc error!!! : " << errno << endl;
+ return;
+ }
+ info.device_infos[0].direction = DIRECTION_OUT;
+ info.device_infos[0].type = "builtin-speaker";
+ info.device_infos[0].id = 100;
+ info.num_of_devices = num_of_devices;
+
+ int32_t ret = audio_hal_interface_update_route(m_h, &info);
+
+ cout << "update route : " << ret << endl;
+
+ free(info.device_infos);
+}
+
+int32_t AudioHalTest::WritePcmFromFile(pcm_handle pcm_h, audio_pcm_sample_spec_t *spec)
+{
+ int32_t ret = AUDIO_HAL_SUCCESS;
+ char buffer[65536];
+
+ const char res_path[] = "/usr/share/testcase/res/audio/dtmf_16le_44100_2ch.raw";
+
+ int fd = open(res_path, O_RDONLY);
+ cout << res_path << ", fd opened : " << fd << endl;
+
+ cout << "start to play dtmf sounds for 5 sec. " << endl;
+
+ while (fd != -1) {
+
+ uint32_t avail_frames = 0;
+ ret = audio_hal_interface_pcm_available(m_h, pcm_h, &avail_frames);
+
+ if (avail_frames == 0) {
+ usleep(20000); // 20ms
+ continue;
+ }
+
+ int bytes_read = read(fd, buffer, FramesToBytes(avail_frames, spec));
+ //cout << "avail frames : " << avail_frames << ", read_n : " << bytes_read << endl;
+
+ ret = audio_hal_interface_pcm_write(m_h, pcm_h, buffer, BytesToFrames(bytes_read, spec));
+ if (ret == AUDIO_HAL_ERROR)
+ break;
+
+ if (bytes_read < static_cast<int>(FramesToBytes(avail_frames, spec))) {
+ cout << "EOS!!!" << endl;
+ break;
+ }
+ }
+
+ cout << "Done!!!" << endl;
+
+ if (fd != -1)
+ close(fd);
+
+ return ret;
+}
+
+uint32_t AudioHalTest::BytesToFrames(uint32_t bytes, audio_pcm_sample_spec_t *spec)
+{
+ if (spec->format == AUDIO_SAMPLE_S16LE)
+ return bytes / spec->channels / 2;
+ else
+ return 0; // not supported yet.
+
+}
+
+uint32_t AudioHalTest::FramesToBytes(uint32_t frames, audio_pcm_sample_spec_t *spec)
+{
+ if (spec->format == AUDIO_SAMPLE_S16LE)
+ return frames * spec->channels * 2;
+ else
+ return 0; // not supported yet.
+}
+
+void AudioHalTest::HalMessageCallback(const char *name, int value, void *user_data)
+{
+ cout << name << "," << value << "," << user_data << endl;
+}
+
+/**
+ * @testcase InitP
+ * @sizen_tizen 4.0
+ * @author SR(seungbae.shin)
+ * @reviewer SR(sc11.lee)
+ * @type auto
+ * @description Positive, Initialize audio HAL handle
+ * @apicovered audio_init, audio_deinit
+ * @passcase XXX
+ * @failcase YYY
+ * @precondition None
+ * @postcondition None
+ */
+TEST(AudioHalPreTest, InitP)
+{
+ audio_hal_interface *h = nullptr;
+
+ int32_t ret = audio_hal_interface_init(&h);
+ ASSERT_EQ(ret, AUDIO_HAL_SUCCESS);
+ ASSERT_NE(h, nullptr);
+
+ ret = audio_hal_interface_deinit(h);
+ EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+}
+
+/**
+ * @testcase InitN
+ * @sizen_tizen 4.0
+ * @author SR(seungbae.shin)
+ * @reviewer SR(sc11.lee)
+ * @type auto
+ * @description Negative, Initialize audio HAL handle
+ * @apicovered audio_init
+ * @passcase XXX
+ * @failcase YYY
+ * @precondition None
+ * @postcondition None
+ */
+TEST(AudioHalPreTest, InitN)
+{
+ int32_t ret = audio_hal_interface_init(nullptr);
+ ASSERT_EQ(ret, AUDIO_HAL_ERROR);
+}
+
+/**
+ * @testcase DeinitP
+ * @sizen_tizen 4.0
+ * @author SR(seungbae.shin)
+ * @reviewer SR(sc11.lee)
+ * @type auto
+ * @description Positive, Deinitialize audio HAL handle
+ * @apicovered audio_init, audio_deinit
+ * @passcase XXX
+ * @failcase YYY
+ * @precondition None
+ * @postcondition None
+ */
+TEST(AudioHalPreTest, DeinitP)
+{
+ audio_hal_interface *h = nullptr;
+
+ int32_t ret = audio_hal_interface_init(&h);
+ ASSERT_EQ(ret, AUDIO_HAL_SUCCESS);
+ ASSERT_NE(h, nullptr);
+
+ ret = audio_hal_interface_deinit(h);
+ ASSERT_EQ(ret, AUDIO_HAL_SUCCESS);
+}
+
+/**
+ * @testcase GetVolumeLevelMaxP
+ * @sizen_tizen 4.0
+ * @author SR(seungbae.shin)
+ * @reviewer SR(sc11.lee)
+ * @type auto
+ * @description Positive, Get maximum volume level of each volume types
+ * @apicovered audio_get_volume_level_max
+ * @passcase XXX
+ * @failcase YYY
+ * @precondition None
+ * @postcondition None
+ */
+TEST_F(AudioHalTest, GetVolumeLevelMaxP)
+{
+ uint32_t level_max;
+ const array<string, 8> vol_types = { "system", "notification", "alarm", "ringtone",
+ "media", "call", "voip", "voice" };
+
+ for (const auto& i : vol_types) {
+ int32_t ret = audio_hal_interface_get_volume_level_max(m_h, i.c_str(), DIRECTION_OUT, &level_max);
+ cout << i << " : " << level_max << endl;
+ EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+ }
+}
+
+/**
+ * @testcase GetVolumeLevelMaxN
+ * @sizen_tizen 4.0
+ * @author SR(seungbae.shin)
+ * @reviewer SR(sc11.lee)
+ * @type auto
+ * @description Negative, Get maximum volume level of each volume types
+ * @apicovered audio_get_volume_level_max
+ * @passcase XXX
+ * @failcase YYY
+ * @precondition None
+ * @postcondition None
+ */
+TEST_F(AudioHalTest, GetVolumeLevelMaxN)
+{
+ int32_t ret = audio_hal_interface_get_volume_level_max(m_h, "media", DIRECTION_OUT, nullptr);
+ EXPECT_EQ(ret, AUDIO_HAL_ERROR);
+}
+
+/**
+ * @testcase GetVolumeLevelP
+ * @sizen_tizen 4.0
+ * @author SR(seungbae.shin)
+ * @reviewer SR(sc11.lee)
+ * @type auto
+ * @description Positive, Get volume level of each volume types
+ * @apicovered audio_get_volume_level
+ * @passcase XXX
+ * @failcase YYY
+ * @precondition None
+ * @postcondition None
+ */
+TEST_F(AudioHalTest, GetVolumeLevelP)
+{
+ uint32_t level;
+ const array<string, 8> vol_types = { "system", "notification", "alarm", "ringtone",
+ "media", "call", "voip", "voice" };
+
+ for (const auto& i : vol_types) {
+ int32_t ret = audio_hal_interface_get_volume_level(m_h, i.c_str(), DIRECTION_OUT, &level);
+ cout << i << " : " << level << endl;
+ EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+ }
+}
+
+/**
+ * @testcase GetVolumeLevelN
+ * @sizen_tizen 4.0
+ * @author SR(seungbae.shin)
+ * @reviewer SR(sc11.lee)
+ * @type auto
+ * @description Negative, Get volume level of each volume types
+ * @apicovered audio_get_volume_level
+ * @passcase XXX
+ * @failcase YYY
+ * @precondition None
+ * @postcondition None
+ */
+TEST_F(AudioHalTest, GetVolumeLevelN)
+{
+ int32_t ret = audio_hal_interface_get_volume_level(m_h, "media", DIRECTION_OUT, nullptr);
+ EXPECT_EQ(ret, AUDIO_HAL_ERROR);
+}
+
+/**
+ * @testcase SetVolumeLevelP
+ * @sizen_tizen 4.0
+ * @author SR(seungbae.shin)
+ * @reviewer SR(sc11.lee)
+ * @type auto
+ * @description Positive, Set volume level of each volume types
+ * @apicovered audio_set_volume_level
+ * @passcase XXX
+ * @failcase YYY
+ * @precondition None
+ * @postcondition None
+ */
+TEST_F(AudioHalTest, SetVolumeLevelP)
+{
+ /* FIXME : need to revise */
+ int32_t ret = audio_hal_interface_set_volume_level(m_h, "media", DIRECTION_OUT, 15);
+ EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+
+ ret = audio_hal_interface_set_volume_level(m_h, "media", DIRECTION_OUT, 7);
+ EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+}
+
+
+/**
+ * @testcase SetVolumeLevelN
+ * @sizen_tizen 4.0
+ * @author SR(seungbae.shin)
+ * @reviewer SR(sc11.lee)
+ * @type auto
+ * @description Negative, Set volume level of each volume types
+ * @apicovered audio_set_volume_level
+ * @passcase XXX
+ * @failcase YYY
+ * @precondition None
+ * @postcondition None
+ */
+TEST_F(AudioHalTest, SetVolumeLevelN)
+{
+ int32_t ret = audio_hal_interface_set_volume_level(m_h, "media", DIRECTION_OUT, 10000);
+ EXPECT_EQ(ret, AUDIO_HAL_ERROR);
+}
+
+
+/**
+ * @testcase GetVolumeValueP
+ * @sizen_tizen 4.0
+ * @author SR(seungbae.shin)
+ * @reviewer SR(sc11.lee)
+ * @type auto
+ * @description Positive, Get volume value of each volume types with given volume level
+ * @apicovered audio_get_volume_value
+ * @passcase XXX
+ * @failcase YYY
+ * @precondition None
+ * @postcondition None
+ */
+TEST_F(AudioHalTest, GetVolumeValueP)
+{
+ double value;
+
+ int32_t ret = audio_hal_interface_get_volume_value(m_h, "media", nullptr, DIRECTION_OUT, 15, &value);
+ EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+
+ cout << "media vol value : " << value << endl;
+}
+
+/**
+ * @testcase GetVolumeValueN
+ * @sizen_tizen 4.0
+ * @author SR(seungbae.shin)
+ * @reviewer SR(sc11.lee)
+ * @type auto
+ * @description Negative, Get volume value of each volume types with given volume level
+ * @apicovered audio_get_volume_value
+ * @passcase XXX
+ * @failcase YYY
+ * @precondition None
+ * @postcondition None
+ */
+TEST_F(AudioHalTest, GetVolumeValueN)
+{
+ int32_t ret = audio_hal_interface_get_volume_value(m_h, "media", nullptr, DIRECTION_OUT, 15, nullptr);
+ EXPECT_EQ(ret, AUDIO_HAL_ERROR);
+}
+
+/**
+ * @testcase GetVolumeMuteP
+ * @sizen_tizen 4.0
+ * @author SR(seungbae.shin)
+ * @reviewer SR(sc11.lee)
+ * @type auto
+ * @description Positive, Get volume mute of each volume types.
+ * @apicovered audio_get_volume_mute
+ * @passcase XXX
+ * @failcase YYY
+ * @precondition None
+ * @postcondition None
+ */
+TEST_F(AudioHalTest, GetVolumeMuteP)
+{
+ uint32_t mute;
+
+ int32_t ret = audio_hal_interface_get_volume_mute(m_h, "media", DIRECTION_OUT, &mute);
+ EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+
+ cout << "mute : " << mute << endl;
+}
+
+/**
+ * @testcase GetVolumeMuteN
+ * @sizen_tizen 4.0
+ * @author SR(seungbae.shin)
+ * @reviewer SR(sc11.lee)
+ * @type auto
+ * @description Negative, Get volume mute of each volume types.
+ * @apicovered audio_get_volume_mute
+ * @passcase XXX
+ * @failcase YYY
+ * @precondition None
+ * @postcondition None
+ */
+TEST_F(AudioHalTest, GetVolumeMuteN)
+{
+ int32_t ret = audio_hal_interface_get_volume_mute(m_h, "media", DIRECTION_OUT, nullptr);
+ EXPECT_EQ(ret, AUDIO_HAL_ERROR);
+}
+
+/**
+ * @testcase SetVolumeMuteP
+ * @sizen_tizen 4.0
+ * @author SR(seungbae.shin)
+ * @reviewer SR(sc11.lee)
+ * @type auto
+ * @description Positive, Set volume mute of each volume types.
+ * @apicovered audio_set_volume_mute
+ * @passcase XXX
+ * @failcase YYY
+ * @precondition None
+ * @postcondition None
+ */
+TEST_F(AudioHalTest, SetVolumeMuteP)
+{
+ int32_t ret = audio_hal_interface_set_volume_mute(m_h, "media", DIRECTION_OUT, 1);
+ EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+
+ ret = audio_hal_interface_set_volume_mute(m_h, "media", DIRECTION_OUT, 0);
+ EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+}
+
+#if 0 // can't test because mute is not implemented yet...
+TEST_F(AudioHalTest, SetVolumeMuteN)
+{
+ int32_t ret = audio_hal_interface_set_volume_mute(m_h, "media", DIRECTION_OUT, 10000);
+ EXPECT_EQ(ret, AUDIO_HAL_ERROR);
+}
+#endif
+
+/**
+ * @testcase UpdateRouteP
+ * @sizen_tizen 4.0
+ * @author SR(seungbae.shin)
+ * @reviewer SR(sc11.lee)
+ * @type auto
+ * @description Positive, Update route
+ * @apicovered audio_update_route
+ * @passcase XXX
+ * @failcase YYY
+ * @precondition None
+ * @postcondition None
+ */
+TEST_F(AudioHalTest, UpdateRouteP)
+{
+ hal_route_info info;
+ int32_t num_of_devices = 1;
+
+ memset(&info, 0, sizeof(hal_route_info));
+
+ info.role = "media";
+ info.device_infos = (hal_device_info*)malloc(sizeof(hal_device_info) * num_of_devices);
+ ASSERT_NE(info.device_infos, nullptr);
+ info.device_infos[0].direction = DIRECTION_OUT;
+ info.device_infos[0].type = "builtin-speaker";
+ info.device_infos[0].id = 100;
+ info.num_of_devices = num_of_devices;
+
+ int32_t ret = audio_hal_interface_update_route(m_h, &info);
+ EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+
+ free(info.device_infos);
+}
+
+
+/**
+ * @testcase UpdateRouteN
+ * @sizen_tizen 4.0
+ * @author SR(seungbae.shin)
+ * @reviewer SR(sc11.lee)
+ * @type auto
+ * @description Negative, Update route
+ * @apicovered audio_update_route
+ * @passcase XXX
+ * @failcase YYY
+ * @precondition None
+ * @postcondition None
+ */
+TEST_F(AudioHalTest, UpdateRouteN)
+{
+ int32_t ret = audio_hal_interface_update_route(m_h, nullptr);
+ EXPECT_EQ(ret, AUDIO_HAL_ERROR);
+
+ hal_route_info info;
+ memset(&info, 0, sizeof(hal_route_info));
+ info.role = nullptr;
+ ret = audio_hal_interface_update_route(m_h, &info);
+ EXPECT_EQ(ret, AUDIO_HAL_ERROR);
+}
+
+/**
+ * @testcase UpdateRouteOptionP
+ * @sizen_tizen 4.0
+ * @author SR(seungbae.shin)
+ * @reviewer SR(sc11.lee)
+ * @type auto
+ * @description Positive, Update route option
+ * @apicovered audio_update_route_option
+ * @passcase XXX
+ * @failcase YYY
+ * @precondition None
+ * @postcondition None
+ */
+TEST_F(AudioHalTest, UpdateRouteOptionP)
+{
+ hal_route_option option;
+
+ int32_t ret = audio_hal_interface_update_route_option(m_h, &option);
+ EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+}
+
+
+/**
+ * @testcase UpdateRouteOptionN
+ * @sizen_tizen 4.0
+ * @author SR(seungbae.shin)
+ * @reviewer SR(sc11.lee)
+ * @type auto
+ * @description Negative, Update route option
+ * @apicovered audio_update_route_option
+ * @passcase XXX
+ * @failcase YYY
+ * @precondition None
+ * @postcondition None
+ */
+TEST_F(AudioHalTest, UpdateRouteOptionN)
+{
+ int32_t ret = audio_hal_interface_update_route_option(m_h, nullptr);
+ EXPECT_EQ(ret, AUDIO_HAL_ERROR);
+}
+
+/**
+ * @testcase NotifyStreamConnectionChangedP
+ * @sizen_tizen 4.0
+ * @author SR(seungbae.shin)
+ * @reviewer SR(sc11.lee)
+ * @type auto
+ * @description Positive, Notify stream connection changed
+ * @apicovered audio_notify_stream_connection_changed
+ * @passcase XXX
+ * @failcase YYY
+ * @precondition None
+ * @postcondition None
+ */
+TEST_F(AudioHalTest, NotifyStreamConnectionChangedP)
+{
+ hal_stream_connection_info info;
+
+ memset(&info, 0, sizeof(hal_stream_connection_info));
+ info.role = "media";
+ info.direction = DIRECTION_OUT;
+ info.idx = 100;
+ info.is_connected = true;
+
+ int32_t ret = audio_hal_interface_notify_stream_connection_changed(m_h, &info);
+ EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+}
+
+/**
+ * @testcase NotifyStreamConnectionChangedN
+ * @sizen_tizen 4.0
+ * @author SR(seungbae.shin)
+ * @reviewer SR(sc11.lee)
+ * @type auto
+ * @description Negative, Notify stream connection changed
+ * @apicovered audio_notify_stream_connection_changed
+ * @passcase XXX
+ * @failcase YYY
+ * @precondition None
+ * @postcondition None
+ */
+TEST_F(AudioHalTest, NotifyStreamConnectionChangedN)
+{
+ // check for nullptr ptr
+ int32_t ret = audio_hal_interface_notify_stream_connection_changed(m_h, nullptr);
+ EXPECT_EQ(ret, AUDIO_HAL_ERROR);
+
+ // check for invalid role
+ hal_stream_connection_info info;
+ memset(&info, 0, sizeof(hal_stream_connection_info));
+ info.role = nullptr;
+ info.direction = DIRECTION_OUT;
+ info.idx = 100;
+ info.is_connected = true;
+
+ ret = audio_hal_interface_notify_stream_connection_changed(m_h, &info);
+ EXPECT_EQ(ret, AUDIO_HAL_ERROR);
+}
+
+/**
+ * @testcase MessageCallbackP
+ * @sizen_tizen 4.0
+ * @author SR(seungbae.shin)
+ * @reviewer SR(sc11.lee)
+ * @type auto
+ * @description Positive, add/remove message callback
+ * @apicovered audio_add_message_cb, audio_remove_message_cb
+ * @passcase XXX
+ * @failcase YYY
+ * @precondition None
+ * @postcondition None
+ */
+TEST_F(AudioHalTest, MessageCallbackP)
+{
+ int32_t ret = audio_hal_interface_add_message_callback(m_h, HalMessageCallback, nullptr);
+ ASSERT_EQ(ret, AUDIO_HAL_SUCCESS);
+
+ ret = audio_hal_interface_remove_message_callback(m_h, HalMessageCallback);
+ EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+}
+
+/**
+ * @testcase MessageCallbackN
+ * @sizen_tizen 4.0
+ * @author SR(seungbae.shin)
+ * @reviewer SR(sc11.lee)
+ * @type auto
+ * @description Negative, add/remove message callback
+ * @apicovered audio_add_message_cb, audio_remove_message_cb
+ * @passcase XXX
+ * @failcase YYY
+ * @precondition None
+ * @postcondition None
+ */
+TEST_F(AudioHalTest, MessageCallbackN)
+{
+ int32_t ret = audio_hal_interface_add_message_callback(m_h, nullptr, nullptr);
+ EXPECT_EQ(ret, AUDIO_HAL_ERROR);
+
+ ret = audio_hal_interface_remove_message_callback(m_h, nullptr);
+ EXPECT_EQ(ret, AUDIO_HAL_ERROR);
+}
+
+
+/**
+ * @testcase PcmGetFdP
+ * @sizen_tizen 4.0
+ * @author SR(seungbae.shin)
+ * @reviewer SR(sc11.lee)
+ * @type auto
+ * @description Positive, get fd from the pcm handle
+ * @apicovered audio_pcm_get_fd, audio_pcm_open, audio_pcm_close
+ * @passcase XXX
+ * @failcase YYY
+ * @precondition None
+ * @postcondition None
+ */
+TEST_F(AudioHalTest, PcmGetFdP)
+{
+ pcm_handle pcm_h = nullptr;
+
+ audio_pcm_sample_spec_t sample_spec;
+ sample_spec.format = AUDIO_SAMPLE_S16LE;
+ sample_spec.rate = 44100;
+ sample_spec.channels = 2;
+
+ SetRouteToSpeaker();
+
+ int32_t ret = audio_hal_interface_pcm_open(m_h, default_card.c_str(), default_device.c_str(), DIRECTION_OUT, &sample_spec,
+ BytesToFrames(6400, &sample_spec), 5, &pcm_h);
+ ASSERT_EQ(ret, AUDIO_HAL_SUCCESS);
+
+ int pcm_fd = 0;
+ ret = audio_hal_interface_pcm_get_fd(m_h, pcm_h, &pcm_fd);
+ EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+ cout << "pcm fd : " << pcm_fd << endl;
+
+ ret = audio_hal_interface_pcm_close(m_h, pcm_h);
+ EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+}
+
+/**
+ * @testcase PcmGetFdN
+ * @sizen_tizen 4.0
+ * @author SR(seungbae.shin)
+ * @reviewer SR(sc11.lee)
+ * @type auto
+ * @description Negative, get fd from the pcm handle
+ * @apicovered audio_pcm_get_fd, audio_pcm_open, audio_pcm_close
+ * @passcase XXX
+ * @failcase YYY
+ * @precondition None
+ * @postcondition None
+ */
+TEST_F(AudioHalTest, PcmGetFdN)
+{
+ // check for pcm handle
+ int pcm_fd = 0;
+ int32_t ret = audio_hal_interface_pcm_get_fd(m_h, nullptr, &pcm_fd);
+ EXPECT_EQ(ret, AUDIO_HAL_ERROR);
+
+ // check for fd
+ pcm_handle pcm_h = nullptr;
+
+ audio_pcm_sample_spec_t sample_spec;
+ sample_spec.format = AUDIO_SAMPLE_S16LE;
+ sample_spec.rate = 44100;
+ sample_spec.channels = 2;
+
+ SetRouteToSpeaker();
+
+ ret = audio_hal_interface_pcm_open(m_h, default_card.c_str(), default_device.c_str(), DIRECTION_OUT, &sample_spec,
+ BytesToFrames(6400, &sample_spec), 5, &pcm_h);
+ ASSERT_EQ(ret, AUDIO_HAL_SUCCESS);
+
+ ret = audio_hal_interface_pcm_get_fd(m_h, pcm_h, nullptr);
+ EXPECT_EQ(ret, AUDIO_HAL_ERROR);
+
+ ret = audio_hal_interface_pcm_close(m_h, pcm_h);
+ EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+}
+
+/**
+ * @testcase PcmOpenWriteCloseP
+ * @sizen_tizen 4.0
+ * @author SR(seungbae.shin)
+ * @reviewer SR(sc11.lee)
+ * @type auto
+ * @description Positive, open pcm handle, start pcm handle, write pcm buffers, stop pcm handle and close pcm_handle
+ * @apicovered audio_pcm_open, audio_pcm_start, audio_pcm_avail, audio_pcm_write, audio_pcm_stop, audio_pcm_close
+ * @passcase XXX
+ * @failcase YYY
+ * @precondition None
+ * @postcondition None
+ */
+TEST_F(AudioHalTest, PcmOpenWriteCloseP)
+{
+ pcm_handle pcm_h = nullptr;
+
+ audio_pcm_sample_spec_t sample_spec;
+ sample_spec.format = AUDIO_SAMPLE_S16LE;
+ sample_spec.rate = 44100;
+ sample_spec.channels = 2;
+
+ SetRouteToSpeaker();
+
+ int32_t ret = audio_hal_interface_pcm_open(m_h, default_card.c_str(), default_device.c_str(), DIRECTION_OUT, &sample_spec,
+ BytesToFrames(6400, &sample_spec), 5, &pcm_h);
+ ASSERT_EQ(ret, AUDIO_HAL_SUCCESS);
+
+ ret = audio_hal_interface_pcm_start(m_h, pcm_h);
+ EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+
+ ret = WritePcmFromFile(pcm_h, &sample_spec);
+ EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+
+ ret = audio_hal_interface_pcm_stop(m_h, pcm_h);
+ EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+
+ ret = audio_hal_interface_pcm_close(m_h, pcm_h);
+ EXPECT_EQ(ret, AUDIO_HAL_SUCCESS);
+}
+
+/**
+ * @testcase PcmRecoverN
+ * @sizen_tizen 4.0
+ * @author SR(seungbae.shin)
+ * @reviewer SR(sc11.lee)
+ * @type auto
+ * @description Negative, pcm recovery
+ * @apicovered audio_pcm_recover
+ * @passcase XXX
+ * @failcase YYY
+ * @precondition None
+ * @postcondition None
+ */
+TEST_F(AudioHalTest, PcmRecoverN)
+{
+ int32_t ret = audio_hal_interface_pcm_recover(m_h, nullptr, 0);
+ EXPECT_EQ(ret, AUDIO_HAL_ERROR);
+}
+
+/* // ToDo :
+int32_t audio_hal_interface_pcm_read(audio_hal_interface *h, pcm_handle pcm_h, void *buffer, uint32_t frames);
+*/
+
+/* This is not used */
+#if 0
+int32_t audio_hal_interface_pcm_get_params(audio_hal_interface *h, pcm_handle pcm_h, uint32_t direction, void **sample_spec,
+ uint32_t *period_size, uint32_t *periods);
+int32_t audio_hal_interface_pcm_set_params(audio_hal_interface *h, pcm_handle pcm_h, uint32_t direction, void *sample_spec,
+ uint32_t period_size, uint32_t periods);
+#endif
+
+int main(int argc, char **argv)
+{
+ testing::InitGoogleTest(&argc, argv);
+
+ return RUN_ALL_TESTS();
+}
diff --git a/testcase/audio/dtmf_16le_44100_2ch.raw b/testcase/audio/dtmf_16le_44100_2ch.raw
new file mode 100644
index 0000000..99a20f7
--- /dev/null
+++ b/testcase/audio/dtmf_16le_44100_2ch.raw
Binary files differ