diff options
author | Seungbae Shin <seungbae.shin@samsung.com> | 2018-07-25 20:58:38 +0900 |
---|---|---|
committer | Seungbae Shin <seungbae.shin@samsung.com> | 2018-08-16 20:21:19 +0900 |
commit | a32a1e03387c57ce6c06ae9ca4fd976a17c9719e (patch) | |
tree | 810a466da47a684f31b76d9001fa008b0be16464 | |
parent | d06767768203168895ae22481b4090121924feb3 (diff) | |
download | mm-hal-interface-a32a1e03387c57ce6c06ae9ca4fd976a17c9719e.tar.gz mm-hal-interface-a32a1e03387c57ce6c06ae9ca4fd976a17c9719e.tar.bz2 mm-hal-interface-a32a1e03387c57ce6c06ae9ca4fd976a17c9719e.zip |
Add audio hal testcasessubmit/tizen/20180817.064104accepted/tizen/unified/20180817.140839
[Version] 0.0.13
[Profile] Common
[Issue Type] Add
[Dependency module] N/A
Change-Id: I1c3bc6f1b84242ee04a4cfa1b5d8fd0432f0295e
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | include/audio/audio_hal_interface.h | 101 | ||||
-rw-r--r-- | mm-hal-interface-audio.manifest | 5 | ||||
-rw-r--r-- | packaging/mm-hal-interface.spec | 36 | ||||
-rw-r--r-- | src/Makefile.am | 3 | ||||
-rw-r--r-- | src/audio/Makefile.am | 6 | ||||
-rw-r--r-- | src/audio/audio_hal_interface.c | 690 | ||||
-rw-r--r-- | testcase/Makefile.am | 3 | ||||
-rw-r--r-- | testcase/audio/Makefile.am | 18 | ||||
-rw-r--r-- | testcase/audio/audio_haltests.cpp | 870 | ||||
-rw-r--r-- | testcase/audio/dtmf_16le_44100_2ch.raw | bin | 0 -> 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 Binary files differnew file mode 100644 index 0000000..99a20f7 --- /dev/null +++ b/testcase/audio/dtmf_16le_44100_2ch.raw |