From e45889da6772a61c7ce273af584f15c1d4229f58 Mon Sep 17 00:00:00 2001 From: Sehong Na Date: Sat, 31 May 2014 12:29:58 +0900 Subject: [PATCH] Initialize Tizen 2.3 --- .gitignore | 43 + LICENSE.APLv2 | 206 ++++ Makefile.am | 80 ++ NOTICE | 3 + audiotest/avsys-audio-test.c | 305 ++++++ autogen.sh | 6 + avsys-audio-alsa.c | 451 ++++++++ avsys-audio-ascenario-ymu831.c | 1127 +++++++++++++++++++ avsys-audio-ascenario.c | 306 ++++++ avsys-audio-handle.c | 1070 ++++++++++++++++++ avsys-audio-pactrl.c | 2191 +++++++++++++++++++++++++++++++++++++ avsys-audio-pasimple.c | 696 ++++++++++++ avsys-audio-path-msm8x74.c | 1546 ++++++++++++++++++++++++++ avsys-audio-path.c | 1174 ++++++++++++++++++++ avsys-audio-shm.c | 70 ++ avsys-audio-sync.c | 242 ++++ avsys-audio.c | 1240 +++++++++++++++++++++ avsys-common.c | 370 +++++++ avsystem-ymu831.manifest | 8 + configure.ac | 154 +++ depcomp | 589 ++++++++++ include/alsa-ucm-constants.h | 164 +++ include/avsys-audio-alsa.h | 63 ++ include/avsys-audio-ascenario.h | 179 +++ include/avsys-audio-handle.h | 132 +++ include/avsys-audio-pactrl.h | 86 ++ include/avsys-audio-pasimple.h | 61 ++ include/avsys-audio-path.h | 135 +++ include/avsys-audio-shm.h | 44 + include/avsys-audio-sync.h | 45 + include/avsys-audio.h | 760 +++++++++++++ include/avsys-common.h | 80 ++ include/avsys-debug.h | 93 ++ include/avsys-error.h | 130 +++ include/avsys-types.h | 41 + include/avsystem.h | 37 + install-sh | 519 +++++++++ missing | 367 +++++++ packaging/avsystem-ymu831.spec | 87 ++ pkgconfig-arm/Makefile.am | 16 + pkgconfig-arm/avsysaudio.pc.in | 11 + pkgconfig-arm/avsystem.pc.in | 11 + pkgconfig-arm/avsystem.pc.in.all | 11 + pkgconfig-i386/Makefile.am | 15 + pkgconfig-i386/avsysaudio.pc.in | 11 + pkgconfig-i386/avsystem.pc.in | 11 + pkgconfig-i386/avsystem.pc.in.all | 11 + 47 files changed, 14997 insertions(+) create mode 100755 .gitignore create mode 100644 LICENSE.APLv2 create mode 100644 Makefile.am create mode 100644 NOTICE create mode 100644 audiotest/avsys-audio-test.c create mode 100755 autogen.sh create mode 100644 avsys-audio-alsa.c create mode 100755 avsys-audio-ascenario-ymu831.c create mode 100644 avsys-audio-ascenario.c create mode 100644 avsys-audio-handle.c create mode 100644 avsys-audio-pactrl.c create mode 100755 avsys-audio-pasimple.c create mode 100644 avsys-audio-path-msm8x74.c create mode 100755 avsys-audio-path.c create mode 100644 avsys-audio-shm.c create mode 100644 avsys-audio-sync.c create mode 100755 avsys-audio.c create mode 100644 avsys-common.c create mode 100755 avsystem-ymu831.manifest create mode 100644 configure.ac create mode 100755 depcomp create mode 100755 include/alsa-ucm-constants.h create mode 100644 include/avsys-audio-alsa.h create mode 100755 include/avsys-audio-ascenario.h create mode 100644 include/avsys-audio-handle.h create mode 100644 include/avsys-audio-pactrl.h create mode 100644 include/avsys-audio-pasimple.h create mode 100755 include/avsys-audio-path.h create mode 100644 include/avsys-audio-shm.h create mode 100644 include/avsys-audio-sync.h create mode 100755 include/avsys-audio.h create mode 100644 include/avsys-common.h create mode 100644 include/avsys-debug.h create mode 100644 include/avsys-error.h create mode 100644 include/avsys-types.h create mode 100644 include/avsystem.h create mode 100755 install-sh create mode 100755 missing create mode 100644 packaging/avsystem-ymu831.spec create mode 100644 pkgconfig-arm/Makefile.am create mode 100644 pkgconfig-arm/avsysaudio.pc.in create mode 100755 pkgconfig-arm/avsystem.pc.in create mode 100644 pkgconfig-arm/avsystem.pc.in.all create mode 100644 pkgconfig-i386/Makefile.am create mode 100644 pkgconfig-i386/avsysaudio.pc.in create mode 100755 pkgconfig-i386/avsystem.pc.in create mode 100644 pkgconfig-i386/avsystem.pc.in.all diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..ed02b77 --- /dev/null +++ b/.gitignore @@ -0,0 +1,43 @@ +*.a +*.o +*.la +*.lo +.deps/ +.libs/ +Makefile +aclocal.m4 +build-stamp +camera_caps_generator +config.h +config.status +debian/files +debian/*.substvars +debian/*.install +debian/*.debhelper +debian/*.log +debian/libavsystem-0-dbg/ +debian/libavsystem-0/ +debian/libavsystem-dev/ +debian/libavsystem-sdk-dev/ +debian/tmp/ +fwupdater/ +init/Makefile +libtool +m4/ +pkgconfig-arm/Makefile +pkgconfig-arm/avsysaudio.pc +pkgconfig-arm/avsyscamera.pc +pkgconfig-arm/avsystem.pc +pkgconfig-i386/Makefile +pkgconfig-i386/avsysaudio.pc +pkgconfig-i386/avsyscamera.pc +pkgconfig-i386/avsystem.pc +sound_initializer +stamp-h1 +config.log +Makefile.in +config.guess +config.hin +config.sub +configure +ltmain.sh diff --git a/LICENSE.APLv2 b/LICENSE.APLv2 new file mode 100644 index 0000000..bbe9d02 --- /dev/null +++ b/LICENSE.APLv2 @@ -0,0 +1,206 @@ +Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. + + + diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..5cce019 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,80 @@ +if IS_SDK +SUBDIRS = pkgconfig-i386 +else +SUBDIRS = pkgconfig-arm +endif + +lib_LTLIBRARIES = libavsysaudio.la + +includelibavsysaudiodir = $(includedir)/avsystem +includelibavsysaudio_HEADERS = include/avsystem.h \ + include/avsys-types.h \ + include/avsys-error.h \ + include/avsys-audio.h + + +libavsysaudio_la_SOURCES = avsys-common.c \ + avsys-audio-handle.c \ + avsys-audio-shm.c \ + avsys-audio-sync.c \ + avsys-audio.c \ + avsys-audio-ascenario.c \ + avsys-audio-path.c \ + avsys-audio-alsa.c \ + avsys-audio-pactrl.c + +libavsysaudio_la_CFLAGS = $(ALSA_CFLAGS) -I$(srcdir)/include + +libavsysaudio_la_LIBADD = $(ALSA_LIBS) -ldl -lrt -lpthread +libavsysaudio_la_LDFLAGS = -Wl,-init, __init_module +libavsysaudio_la_LDFLAGS += -Wl,-fini, __fini_module -version-info 0:1:0 + +libavsysaudio_la_SOURCES += avsys-audio-pasimple.c +libavsysaudio_la_CFLAGS += $(PASIMPLE_CFLAGS) $(PA_CFLAGS) +libavsysaudio_la_LIBADD += $(PASIMPLE_LIBS) $(PA_LIBS) + +libavsysaudio_la_CFLAGS += $(ASCN_CFLAGS) +libavsysaudio_la_LIBADD += $(ASCN_LIBS) + +libavsysaudio_la_CFLAGS += $(VCONF_CFLAGS) +libavsysaudio_la_LIBADD += $(VCONF_LIBS) + + +if USE_YMU831 +libavsysaudio_la_SOURCES += avsys-audio-ascenario-ymu831.c +libavsysaudio_la_CFLAGS += -DUSE_YMU831 +endif + +if TIZEN_MOBILE +libavsysaudio_la_SOURCES += avsys-audio-path-msm8x74.c \ + include/alsa-ucm-constants.h +libavsysaudio_la_CFLAGS += -DTIZEN_MOBILE +endif + +if IS_SDK +libavsysaudio_la_CFLAGS += -DAUDIO_SDK_BUILD \ + -D_MMFW_I386_ALL_SIMULATOR +endif + +if PCM_DUMP_ENABLE +libavsysaudio_la_CFLAGS += $(VCONF_CFLAGS) -DPCM_DUMP_ENABLE +libavsysaudio_la_LIBADD += $(VCONF_LIBS) +endif + +libavsysaudio_la_CFLAGS += $(MMLOG_CFLAGS) \ + -D__DEBUG_MODE__ \ + -D__USE_LOGMANAGER__ \ + -DTIZEN_MICRO \ + -DMM_DEBUG_FLAG + +libavsysaudio_la_LIBADD += $(MMLOG_LIBS) \ + $(INIPARSER_LIBS) + +if WITH_AUDIOTEST +bin_PROGRAMS = avsys_audio_test +avsys_audio_test_SOURCES = audiotest/avsys-audio-test.c +avsys_audio_test_CFLAGS = -I$(srcdir)/include +avsys_audio_test_LDADD = libavsysaudio.la +avsys_audio_test_DEPENDENCIES = libavsysaudio.la + +endif diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..0e0f016 --- /dev/null +++ b/NOTICE @@ -0,0 +1,3 @@ +Copyright (c) Samsung Electronics Co., Ltd. All rights reserved. +Except as noted, this software is licensed under Apache License, Version 2. +Please, see the LICENSE.APLv2 file for Apache License terms and conditions. diff --git a/audiotest/avsys-audio-test.c b/audiotest/avsys-audio-test.c new file mode 100644 index 0000000..7c03835 --- /dev/null +++ b/audiotest/avsys-audio-test.c @@ -0,0 +1,305 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define VERSION (0001) + +void usage(char *name) +{ + printf("Usage: %s [OPTION]... [FILE]...\n\n", name); + printf("-h\t\thelp\n"); + printf("-p\t\tplay raw file (default mode 0) \n"); + printf("-c\t\tcapture audio to raw file (default mode 0)\n"); + printf("-m\t\tmode\n"); + printf("\t\tmode 0 : S16LE / Stereo / 44100Hz\n"); + printf("\t\tmode 1 : S16LE / Mono / 8000Hz\n"); + printf("\t\tmode 2 : S16LE / Mono / 22050Hz\n"); + printf("\t\tmode 3 : U8 / Mono / 8000Hz\n"); + printf("-r\t\trouting\n"); + printf("\t\trouting 0 : following policy\n"); + printf("\t\trouting 1 : forced set to alsa\n"); + printf("\n"); + return; +} + +enum { + OP_NONE = -1, + OP_PLAYBACK, + OP_CAPTURE, +}; + +#define MODE_MIN 0 +#define MODE_MAX 3 + +static struct sigaction sigterm_action; /* Backup pointer of SIGTERM signal handler */ +int g_interrupted; + +int __make_param(int op, int mode, int routing, avsys_audio_param_t *param) +{ + if (!param) + return -1; + + if (op == OP_PLAYBACK) + param->mode = AVSYS_AUDIO_MODE_OUTPUT; + else if (op == OP_CAPTURE) + param->mode = AVSYS_AUDIO_MODE_INPUT; + else + return -1; + + param->priority = AVSYS_AUDIO_PRIORITY_NORMAL; + param->vol_type = AVSYS_AUDIO_VOLUME_TYPE_SYSTEM; + param->handle_route = routing; + + switch (mode) { + case 0: + param->format = AVSYS_AUDIO_FORMAT_16BIT; + param->samplerate = 44100; + param->channels = 2; + break; + case 1: + param->format = AVSYS_AUDIO_FORMAT_16BIT; + param->samplerate = 8000; + param->channels = 1; + break; + case 2: + param->format = AVSYS_AUDIO_FORMAT_16BIT; + param->samplerate = 22050; + param->channels = 1; + break; + case 3: + param->format = AVSYS_AUDIO_FORMAT_8BIT; + param->samplerate = 8000; + param->channels = 1; + break; + default: + return -1; + break; + } + return 0; +} +int _playback(int mode, int routing, char *filename) +{ + int res = 0; + avsys_audio_param_t param; + avsys_handle_t handle = -1; + int recommended_period_size = 0; + int fd = -1; + char *pcmbuf = NULL; + int size = 0; + + if (!filename) + return -1; + + memset(¶m, '\0', sizeof(avsys_audio_param_t)); + + if (__make_param(OP_PLAYBACK, mode, routing, ¶m)) { + printf("Can not make audio parameter\n"); + return -1; + } + + res = avsys_audio_open(¶m, &handle, &recommended_period_size); + if (res != 0) { + printf("Can not open handle 0x%x\n", res); + goto FAIL; + } + + pcmbuf = alloca(recommended_period_size); + if (!pcmbuf) + goto FAIL; + + fd = open(filename, O_RDONLY); + if (fd == -1) + goto FAIL; + + while (((size = read(fd, pcmbuf, recommended_period_size)) > 0) && !g_interrupted) { + if (AVSYS_FAIL(avsys_audio_write(handle, pcmbuf, recommended_period_size))) { + printf("Oops!! audio play fail\n"); + break; + } + } + + close(fd); + avsys_audio_close(handle); + return 0; +FAIL: + if (handle != -1) + avsys_audio_close(handle); + + return res; +} + +int _capture(int mode, int routing, char *filename) +{ + int res = 0; + avsys_audio_param_t param; + avsys_handle_t handle = -1; + int recommended_period_size = 0; + int fd = -1; + char *pcmbuf = NULL; + int size = 0; + char namebuffer[64]= {0,}; + + if (!filename) + return -1; + else + snprintf(namebuffer, sizeof(namebuffer)-1, "%s.raw_%1d", filename, mode); + + printf("[%s] real filename :%s\n", __func__, namebuffer); + + memset(¶m, '\0', sizeof(avsys_audio_param_t)); + + if (__make_param(OP_CAPTURE, mode, routing, ¶m)) { + printf("Can not make audio parameter\n"); + return -1; + } + + res = avsys_audio_open(¶m, &handle, &recommended_period_size); + if (res != 0) { + printf("Can not open handle 0x%x\n", res); + goto FAIL; + } + + pcmbuf = alloca(recommended_period_size); + if (!pcmbuf) { + printf("Can not alloca pcm buffer\n"); + goto FAIL; + } + + fd = open(namebuffer, O_WRONLY | O_CREAT, 0644); + if (fd == -1) { + printf("Can not open file %s, %s\n", namebuffer, strerror(errno)); + goto FAIL; + } + + while (((size = avsys_audio_read(handle, pcmbuf, recommended_period_size)) > 0) && !g_interrupted) { + if (-1 == write(fd, pcmbuf, size)) + break; + } + + close(fd); + avsys_audio_close(handle); + return 0; +FAIL: + printf("[%s] FAIL\n",__func__); + if (handle != -1) + avsys_audio_close(handle); + + if (fd != -1) + close(fd); + + return res; +} + +void sig_handler(int signo) +{ + g_interrupted = 1; +} + +int main(int argc, char *argv[]) +{ + int opt = 0; + int operation = OP_NONE; + int mode = 0; + int tmp = 0; + int routing = 0; + struct sigaction action; + + while ((opt = getopt(argc, argv, "hpcm:r:")) != -1) { + switch (opt) { + case 'h': + usage(argv[0]); + return 0; + break; + case 'p': + if (operation != OP_NONE) { + usage(argv[0]); + return 0; + } + operation = OP_PLAYBACK; + break; + case 'c': + if (operation != OP_NONE) { + usage(argv[0]); + return 0; + } + operation = OP_CAPTURE; + break; + case 'm': + tmp = atoi(optarg); + if (tmp < MODE_MIN || tmp > MODE_MAX) { + usage(argv[0]); + printf("MESSAGE : Unsupported mode number\n"); + return -1; + } + mode = tmp; + break; + case 'r': + tmp = atoi(optarg); + if (tmp < 0 || tmp > 1) { + usage(argv[0]); + printf("MESSAGE : Unsupported mode number\n"); + return -1; + } + routing = tmp; + break; + default: + usage(argv[0]); + break; + } + } + + action.sa_handler = sig_handler; + action.sa_flags = 0; + sigemptyset(&action.sa_mask); + sigaction(SIGINT, &action, &sigterm_action); + + if (operation == OP_NONE) { + usage(argv[0]); + printf("MESSAGE : Operation is not determined\n"); + return -1; + } else if (operation == OP_PLAYBACK) { + char *name = NULL; + name = argv[optind++]; + printf("op %u, mode %u, routing %d, name %s\n", operation, mode, routing, name); + _playback(mode, routing, name); + } else if (operation == OP_CAPTURE) { + char *name = NULL; + name = argv[optind++]; + if (strlen(name) < 2) { + printf("Insufficient filename length\n"); + return -2; + } + printf("op %u, mode %u, routing %d, name %s\n", operation, mode, routing, name); + _capture(mode, routing, name); + } + + return 0; +} diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..a2bf629 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,6 @@ +aclocal +libtoolize --copy +autoheader +autoconf +automake --add-missing --copy --foreign +#./configure --with-xo-machine=W1 diff --git a/avsys-audio-alsa.c b/avsys-audio-alsa.c new file mode 100644 index 0000000..e2338fe --- /dev/null +++ b/avsys-audio-alsa.c @@ -0,0 +1,451 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi + * + * 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 + +#include "avsys-audio-alsa.h" +#include "avsys-types.h" +#include "avsys-error.h" +#include "avsys-debug.h" + +#if defined(_MMFW_I386_ALL_SIMULATOR) +#define AIF_CP_DEVICE_NAME "default" +#define AIF_BT_DEVICE_NAME "default" +#define AIF_RADIO_DEVICE_NAME "default" +#else +#define AIF_CP_DEVICE_NAME "AIF2" +#define AIF_BT_DEVICE_NAME "AIF3" +#define AIF_RADIO_DEVICE_NAME "AIF4" +#endif + +int avsys_audio_alsa_open_AIF_device(aif_device_type_t aif_type, avsys_audio_alsa_aif_handle_t *handle) +{ + snd_pcm_t *ahandle = NULL; + int err = -1; + char dev_name[16] = { 0, }; + snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK; + + avsys_info(AVAUDIO, "\n"); + if (!handle) + return AVSYS_STATE_ERR_NULL_POINTER; + + memset(dev_name, '\0', sizeof(dev_name)); + switch (aif_type) { + case AIF_CP_CAPTURE: + strncpy(dev_name, AIF_CP_DEVICE_NAME, sizeof(dev_name) - 1); + stream = SND_PCM_STREAM_CAPTURE; + break; + case AIF_CP_PLAYBACK: + strncpy(dev_name, AIF_CP_DEVICE_NAME, sizeof(dev_name) - 1); + stream = SND_PCM_STREAM_PLAYBACK; + break; + case AIF_BT_CAPTURE: + strncpy(dev_name, AIF_BT_DEVICE_NAME, sizeof(dev_name) - 1); + stream = SND_PCM_STREAM_CAPTURE; + break; + case AIF_BT_PLAYBACK: + strncpy(dev_name, AIF_BT_DEVICE_NAME, sizeof(dev_name) - 1); + stream = SND_PCM_STREAM_PLAYBACK; + break; + case AIF_RADIO_PLAYBACK: + strncpy(dev_name, AIF_RADIO_DEVICE_NAME, sizeof(dev_name) - 1); + stream = SND_PCM_STREAM_PLAYBACK; + break; + default: + avsys_critical_r(AVAUDIO, "Invalid AIF device %d\n", aif_type); + return AVSYS_STATE_ERR_INVALID_MODE; + break; + } +#if !defined(_MMFW_I386_ALL_SIMULATOR) + err = snd_pcm_open(&ahandle, dev_name, stream, 0); + if (err < 0) { + avsys_error_r(AVAUDIO, "unable to open AIF device: %s\n", snd_strerror(err)); + return AVSYS_STATE_ERR_INTERNAL; + } +#else + avsys_warning_r(AVAUDIO, "Skip real device open in SDK\n"); +#endif + + + handle->alsa_handle = (void *)ahandle; + handle->type = aif_type; + + return AVSYS_STATE_SUCCESS; +} + +int avsys_audio_alsa_close_AIF_device(avsys_audio_alsa_aif_handle_t* handle) +{ + int err = 0; + snd_pcm_t *ahandle = NULL; + + avsys_info(AVAUDIO, "\n"); +#if defined(_MMFW_I386_ALL_SIMULATOR) + avsys_warning(AVAUDIO, "Skip close call device in SDK"); + return AVSYS_STATE_SUCCESS; +#else + if (!handle) + return AVSYS_STATE_ERR_NULL_POINTER; + + ahandle = (snd_pcm_t *)handle->alsa_handle; + if (!ahandle) { + avsys_error_r(AVAUDIO, "alsa handle is null\n"); + return AVSYS_STATE_ERR_NULL_POINTER; + } + + err = snd_pcm_close(ahandle); + if (err < 0) { + avsys_critical_r(AVAUDIO, "unable to close pcm device: %s\n", snd_strerror(err)); + return AVSYS_STATE_ERR_INTERNAL; + } + + handle->alsa_handle = NULL; + + return AVSYS_STATE_SUCCESS; +#endif +} + +int avsys_audio_alsa_set_AIF_params(avsys_audio_alsa_aif_handle_t *handle, aif_rate_t rate) +{ +#if defined(_MMFW_I386_ALL_SIMULATOR) + return AVSYS_STATE_SUCCESS; +#else + int err = 0; + snd_pcm_t *ahandle = NULL; + snd_pcm_hw_params_t *params; + unsigned int val = 0; + int dir = 0; + + avsys_info(AVAUDIO, "\n"); + if (!handle) + return AVSYS_STATE_ERR_NULL_POINTER; + + ahandle = (snd_pcm_t *)handle->alsa_handle; + if (!ahandle) + return AVSYS_STATE_ERR_NULL_POINTER; + + /* Skip parameter setting to null device. */ + if (snd_pcm_type(ahandle) == SND_PCM_TYPE_NULL) + return AVSYS_STATE_SUCCESS; + + /* Allocate a hardware parameters object. */ + snd_pcm_hw_params_alloca(¶ms); + /* Fill it in with default values. */ + err = snd_pcm_hw_params_any(ahandle, params); + if (err < 0) { + avsys_error_r(AVAUDIO, "snd_pcm_hw_params_any() : failed! - %s\n", snd_strerror(err)); + return AVSYS_STATE_ERR_INTERNAL; + } + + /* Set the desired hardware parameters. */ + /* Interleaved mode */ + err = snd_pcm_hw_params_set_access(ahandle, params, SND_PCM_ACCESS_RW_INTERLEAVED); + if (err < 0) { + avsys_error_r(AVAUDIO, "snd_pcm_hw_params_set_access() : failed! - %s\n", snd_strerror(err)); + return AVSYS_STATE_ERR_INTERNAL; + } + + if (rate == AIF_CONF_RATE) { + /* Auto rate by conf */ + avsys_info(AVAUDIO, "Let rate by configuration\n"); + } else { + /* Force input rate */ + avsys_info(AVAUDIO, "Force rate (%d)\n", rate); + err = snd_pcm_hw_params_set_rate(ahandle, params, rate, 0); + if (err < 0) { + avsys_error_r(AVAUDIO, "snd_pcm_hw_params_set_rate() : failed! - %s\n", snd_strerror(err)); + return AVSYS_STATE_ERR_INTERNAL; + } + } + + err = snd_pcm_hw_params(ahandle, params); + if (err < 0) { + avsys_error_r(AVAUDIO, "snd_pcm_hw_params() : failed! - %s\n", snd_strerror(err)); + return AVSYS_STATE_ERR_INTERNAL; + } + + /* Dump current param */ + snd_pcm_hw_params_get_access(params, (snd_pcm_access_t *) &val); + avsys_info(AVAUDIO, "access type = %s\n", snd_pcm_access_name((snd_pcm_access_t)val)); + + snd_pcm_hw_params_get_format(params, &val); + avsys_info(AVAUDIO, "format = '%s' (%s)\n", + snd_pcm_format_name((snd_pcm_format_t)val), + snd_pcm_format_description((snd_pcm_format_t)val)); + + snd_pcm_hw_params_get_subformat(params, (snd_pcm_subformat_t *)&val); + avsys_info(AVAUDIO, "subformat = '%s' (%s)\n", + snd_pcm_subformat_name((snd_pcm_subformat_t)val), + snd_pcm_subformat_description((snd_pcm_subformat_t)val)); + + snd_pcm_hw_params_get_channels(params, &val); + avsys_info(AVAUDIO, "channels = %d\n", val); + + snd_pcm_hw_params_get_rate(params, &val, &dir); + avsys_info(AVAUDIO, "rate = %d(%d) Hz\n", val, dir); + + /* Save current rate for later check */ + handle->rate = val; + + return AVSYS_STATE_SUCCESS; +#endif /* _MMFW_I386_ALL_SIMULATOR */ +} + + +int avsys_audio_alsa_set_mixer_control(const char *ctl_name, int val) +{ + snd_ctl_t *handle; + snd_ctl_elem_value_t *control; + snd_ctl_elem_id_t *id; + snd_ctl_elem_info_t *info; + snd_ctl_elem_type_t type; + + char *card_name = 0; + int ret = 0, count = 0, i = 0; + + avsys_info(AVAUDIO, "Enter\n"); + + snd_card_get_name(0, &card_name); + if(!card_name) + card_name = "default"; + + ret = snd_ctl_open(&handle, card_name, 0); + if (ret < 0) { + avsys_error(AVAUDIO, "snd_ctl_open error, card: %s: %s\n", card_name, snd_strerror(ret)); + return AVSYS_STATE_ERR_IO_CONTROL; + } + + // Get Element Info + + snd_ctl_elem_id_alloca(&id); + snd_ctl_elem_info_alloca(&info); + snd_ctl_elem_value_alloca(&control); + + snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); + snd_ctl_elem_id_set_name(id, ctl_name); + + snd_ctl_elem_info_set_id(info, id); + if(snd_ctl_elem_info(handle, info) < 0 ) { + avsys_error(AVAUDIO, "Cannot find control element: %s\n", ctl_name); + goto close; + } + snd_ctl_elem_info_get_id(info, id); + + type = snd_ctl_elem_info_get_type(info); + count = snd_ctl_elem_info_get_count(info); + + snd_ctl_elem_value_set_id(control, id); + + snd_ctl_elem_read(handle, control); + + avsys_info(AVAUDIO, "type(%d), count(%d): \n", type, count); + + switch (type) { + case SND_CTL_ELEM_TYPE_BOOLEAN: + for (i = 0; i < count; i++) + snd_ctl_elem_value_set_boolean(control, i, val); + break; + case SND_CTL_ELEM_TYPE_INTEGER: + for (i = 0; i < count; i++) + snd_ctl_elem_value_set_integer(control, i,val); + break; + case SND_CTL_ELEM_TYPE_ENUMERATED: + for (i = 0; i < count; i++) + snd_ctl_elem_value_set_enumerated(control, i,val); + break; + default: + avsys_warning(AVAUDIO, "unsupported control element type\n"); + goto close; + } + + snd_ctl_elem_write(handle, control); + + snd_ctl_close(handle); + + avsys_info(AVAUDIO, "Leave\n"); + + return AVSYS_STATE_SUCCESS; + +close: + avsys_error(AVAUDIO, "Error\n"); + snd_ctl_close(handle); + return AVSYS_STATE_ERR_IO_CONTROL; +} + + + +int avsys_audio_alsa_get_mixer_control(const char *ctl_name, int *val) +{ + snd_ctl_t *handle; + snd_ctl_elem_value_t *control; + snd_ctl_elem_id_t *id; + snd_ctl_elem_info_t *info; + snd_ctl_elem_type_t type; + + char *card_name = 0; + int ret = 0, count = 0, i = 0; + + avsys_info(AVAUDIO, "Enter\n"); + + snd_card_get_name(0, &card_name); + if(!card_name) + card_name = "default"; + + ret = snd_ctl_open(&handle, card_name, 0); + if (ret < 0) { + avsys_error(AVAUDIO, "snd_ctl_open error, card: %s: %s\n", card_name, snd_strerror(ret)); + return AVSYS_STATE_ERR_IO_CONTROL; + } + + // Get Element Info + + snd_ctl_elem_id_alloca(&id); + snd_ctl_elem_info_alloca(&info); + snd_ctl_elem_value_alloca(&control); + + snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); + snd_ctl_elem_id_set_name(id, ctl_name); + + snd_ctl_elem_info_set_id(info, id); + if(snd_ctl_elem_info(handle, info) < 0 ) { + avsys_error(AVAUDIO, "Cannot find control element: %s\n", ctl_name); + goto close; + } + snd_ctl_elem_info_get_id(info, id); + + type = snd_ctl_elem_info_get_type(info); + count = snd_ctl_elem_info_get_count(info); + + snd_ctl_elem_value_set_id(control, id); + + if(snd_ctl_elem_read(handle, control) < 0) { + avsys_error(AVAUDIO, "snd_ctl_elem_read failed \n"); + goto close; + } + + avsys_info(AVAUDIO, "type(%d), count(%d): \n", type, count); + + switch (type) { + case SND_CTL_ELEM_TYPE_BOOLEAN: + *val = snd_ctl_elem_value_get_boolean(control, i); + break; + case SND_CTL_ELEM_TYPE_INTEGER: + for (i = 0; i < count; i++) + *val = snd_ctl_elem_value_get_integer(control, i); + break; + default: + avsys_warning(AVAUDIO, "unsupported control element type\n"); + goto close; + } + + snd_ctl_close(handle); + + avsys_info(AVAUDIO, "Leave\n"); + + return AVSYS_STATE_SUCCESS; + +close: + avsys_error(AVAUDIO, "Error\n"); + snd_ctl_close(handle); + return AVSYS_STATE_ERR_IO_CONTROL; +} + +int avsys_audio_alsa_multi_set_mixer_control(const char *ctl_name, void *val) +{ + snd_ctl_t *handle; + snd_ctl_elem_value_t *control; + snd_ctl_elem_id_t *id; + snd_ctl_elem_info_t *info; + snd_ctl_elem_type_t type; + + char *card_name = 0; + int ret = 0, count = 0, i = 0; + unsigned short *param = NULL; + + avsys_info(AVAUDIO, "Enter\n"); + + snd_card_get_name(0, &card_name); + if(!card_name) + card_name = "default"; + + ret = snd_ctl_open(&handle, card_name, 0); + if (ret < 0) { + avsys_error(AVAUDIO, "snd_ctl_open error, card: %s: %s\n", card_name, snd_strerror(ret)); + return AVSYS_STATE_ERR_IO_CONTROL; + } + + // Get Element Info + + snd_ctl_elem_id_alloca(&id); + snd_ctl_elem_info_alloca(&info); + snd_ctl_elem_value_alloca(&control); + + snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); + snd_ctl_elem_id_set_name(id, ctl_name); + + snd_ctl_elem_info_set_id(info, id); + if(snd_ctl_elem_info(handle, info) < 0 ) { + avsys_error(AVAUDIO, "Cannot find control element: %s\n", ctl_name); + goto close; + } + snd_ctl_elem_info_get_id(info, id); + + type = snd_ctl_elem_info_get_type(info); + count = snd_ctl_elem_info_get_count(info); + + snd_ctl_elem_value_set_id(control, id); + + snd_ctl_elem_read(handle, control); + + avsys_info(AVAUDIO, "type(%d), count(%d): \n", type, count); + + switch (type) { + case SND_CTL_ELEM_TYPE_BOOLEAN: + param = (unsigned short*)val; + for (i = 0; i < count; i++) { + snd_ctl_elem_value_set_boolean(control, i, param[i]); + } + break; + case SND_CTL_ELEM_TYPE_INTEGER: + param = (unsigned short*)val; + for (i = 0; i < count; i++) { + avsys_info(AVAUDIO, "array[%d]:[%d]\n", i, param[i]); + snd_ctl_elem_value_set_integer(control, i, param[i]); + } + break; + default: + avsys_warning(AVAUDIO, "unsupported control element type\n"); + goto close; + } + + snd_ctl_elem_write(handle, control); + + snd_ctl_close(handle); + + avsys_info(AVAUDIO, "Leave\n"); + + return AVSYS_STATE_SUCCESS; + + close: + avsys_error(AVAUDIO, "Error\n"); + snd_ctl_close(handle); + return AVSYS_STATE_ERR_IO_CONTROL; +} + diff --git a/avsys-audio-ascenario-ymu831.c b/avsys-audio-ascenario-ymu831.c new file mode 100755 index 0000000..12c6e18 --- /dev/null +++ b/avsys-audio-ascenario-ymu831.c @@ -0,0 +1,1127 @@ +/* + * Copyright(c) 2012 Yamaha Corporation + * + * 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 +#include +#include +#include +#include +#include +#include "avsys-audio-ascenario.h" +#include "avsys-debug.h" +#include + +#define USE_SCN_TO_GRP_FILE + +//#define YSOUND_CONF "/usr/etc/sound/ymu831/ysound.conf" +#define YSOUND_CONF "ysound.conf" +#define DEF_CARD_NAME "ymu831" +#define CSC_YSOUND_PATH "/opt/system/csc-default/usr/tuning" +#define DEF_YSOUND_PATH "/usr/etc/sound" + +static char csc_conf_data; + +#define MIXER_NAME_OUT "default" +#define DEVFILE_HW_CARD_NUMBER 0 +#define DEVFILE_HW_DEVICE_NUMBER 0 + +#define MAX_NAME (64) +#define MAX_PATH_NAME (256) +#define MAX_VALUE_LEN (16) +#define ERROR (-1) +#define TARGET_PARAMETER (1) +#define TARGET_MIXER (2) +#define NOT_FINED (-1) +#define MC_ASOC_MAGIC 'N' +#define MC_ASOC_IOCTL_SET_CTRL (1) +#define YMC_IOCTL_SET_CTRL \ + _IOW(MC_ASOC_MAGIC, MC_ASOC_IOCTL_SET_CTRL, ymc_ctrl_args_t) +#define FILE_OPEN_MODE "rb" +#define USE_FOPEN (0) + +#define YMC_DSP_OUTPUT_BASE 0x00000000 +#define YMC_DSP_INPUT_BASE 0x00000010 +#define YMC_DSP_VOICECALL_BASE_1MIC 0x00000100 +#define YMC_DSP_VOICECALL_BASE_2MIC 0x00000200 +#define YMC_DSP_VOICECALL_BASE_COMMON 0x00000F00 +#define YMC_DSP_OPTION_ERROR 0xFFFFFFFF + +#define DSP_OUTPUT_NAME "DSP (Output)" +#define DSP_INPUT_NAME "DSP (Input)" +#define DSP_VOICECALL_NAME "VoiceCall" +#define DSP_VOICECALL_1MIC_NAME "VoiceCall (1MIC)" +#define DSP_VOICECALL_2MIC_NAME "VoiceCall (2MIC)" + +struct GROUP_INFO { + char abName[MAX_NAME]; + int nStartPos; + int nEndPos; +}; + +typedef struct _ymc_ctrl_args { + void *param; + unsigned long size; + unsigned long option; +} ymc_ctrl_args_t; + +struct FILE_DATA { + char *pbData; + int nSize; +}; + +struct SCENARIO_GROUP { + char *pbScenario; + char *pbGroup; +#ifdef USE_SCN_TO_GRP_FILE + void *pNext; +#endif +}; + +#ifndef USE_SCN_TO_GRP_FILE +static struct SCENARIO_GROUP gaScnToGrp[] = { + /* AP PLAYBACK */ + {STR_AP_SPK, "AP_SP"}, + {STR_AP_HEADSET, "AP_HS"}, + {STR_AP_RECV, "AP_RS"}, + {STR_AP_BT, "AP_BT"}, + {STR_AP_HDMI, "AP_SP"}, + {STR_AP_DOCK, "AP_LO1"}, + {STR_AP_SP_HS, "AP_SP_HS"}, + /* AP CAPTURE */ + {STR_MIC1_AP, "GENERIC_AP"}, + {STR_MIC2_AP, "GENERIC_AP"}, + {STR_STEREO_MIC_AP, "GENERIC_AP"}, + {STR_EARMIC_AP, "GENERIC_AP"}, + {STR_STEREO_REC, "GENERIC_AP"}, + {STR_BT_AP, "BT_AP"}, + {STR_CP_AP, "CP_AP"}, + /* CP PLAYBACK */ + {STR_CP_SPK, "CP_SP"}, + {STR_CP_HEADSET, "CP_HS"}, + {STR_CP_HEADPHONE, "CP_HP"}, + {STR_CP_RECV_2MIC, "CP_RC"}, + {STR_CP_RECV, "CP_RC"}, + {STR_CP_BT, "CP_BT"}, + /* CP CAPTURE */ + {STR_MIC1_CP, "MIC_CP"}, + {STR_MIC2_CP, "MIC_CP"}, + {STR_EARMIC_CP, "HS_CP"}, + {STR_BT_CP, "BT_CP"}, + /* FMRADIO */ + {STR_FM_AP, "GENERIC_AP"}, + {STR_FM_SPEAKER, "FM_SP"}, + {STR_FM_HEADSET, "FM_HS"}, + /* VOICECALL */ + {STR_VOICECALL_SPK, "VC_SP"}, + {STR_VOICECALL_SPK_EXTVOL, "VC_SP_EXT_VOL"}, + {STR_VOICECALL_SPK_NB, "VC_SP"}, + {STR_VOICECALL_SPK_NB_EXTVOL, "VC_SP_EXT_VOL"}, + {STR_VOICECALL_SPK_2MIC, "VC_SP_2MIC"}, + {STR_VOICECALL_SPK_2MIC_EXTVOL, "VC_SP_2MIC_EXT_VOL"}, + {STR_VOICECALL_SPK_2MIC_NB, "VC_SP_2MIC"}, + {STR_VOICECALL_SPK_2MIC_NB_EXTVOL, "VC_SP_2MIC_EXT_VOL"}, + {STR_VOICECALL_RCV, "VC_RCV"}, + {STR_VOICECALL_RCV_EXTVOL, "VC_RCV_EXT_VOL"}, + {STR_VOICECALL_RCV_NB, "VC_RCV"}, + {STR_VOICECALL_RCV_NB_EXTVOL, "VC_RCV_EXT_VOL"}, + {STR_VOICECALL_RCV_2MIC, "VC_RCV_2MIC"}, + {STR_VOICECALL_RCV_2MIC_EXTVOL, "VC_RCV_2MIC_EXT_VOL"}, + {STR_VOICECALL_RCV_2MIC_NB, "VC_RCV_2MIC"}, + {STR_VOICECALL_RCV_2MIC_NB_EXTVOL, "VC_RCV_2MIC_EXT_VOL"}, + {STR_VOICECALL_HEADPHONE, "VC_HP"}, + {STR_VOICECALL_HEADPHONE_NB, "VC_HP"}, + {STR_VOICECALL_HEADSET, "VC_HS"}, + {STR_VOICECALL_HEADSET_NB, "VC_HS"}, + {STR_VOICECALL_BLUETOOTH, "VC_BT_WB"}, + {STR_VOICECALL_BLUETOOTH_NREC, "VC_BT_WB"}, + /* VIDEOCALL */ + {STR_VIDEOCALL_SPK_2MIC, "VT_SP"}, + {STR_VIDEOCALL_SPK_2MIC_NB, "VT_SP"}, + {STR_VIDEOCALL_RCV_2MIC, "VT_RCV"}, + {STR_VIDEOCALL_RCV_2MIC_NB, "VT_RCV"}, + {STR_VIDEOCALL_HEADPHONE, "VT_HP"}, + {STR_VIDEOCALL_HEADPHONE_NB, "VT_HP"}, + {STR_VIDEOCALL_HEADSET, "VT_HS"}, + {STR_VIDEOCALL_HEADSET_NB, "VT_HS"}, + {STR_VIDEOCALL_BLUETOOTH, "VT_BT_WB"}, + {STR_VIDEOCALL_BLUETOOTH_NREC, "VT_BT_WB"}, + /* INCALL ADDON */ + {STR_INCALL_ADDON, "AP_INCALL"}, + {STR_INCALL_1MIC_ADDON, "AP_INCALL_1MIC"}, + {STR_INCALL_BT_ADDON, "AP_INCALL_BT"}, + /* VOIP */ + {STR_CHATON_SPK, "CHATON_SP"}, + {STR_CHATON_RCV, "CHATON_RCV"}, + {STR_CHATON_HEADPHONE, "CHATON_HP"}, + {STR_CHATON_HEADSET, "CHATON_HS"}, + {STR_CHATON_BLUETOOTH, "CHATON_BT"}, + /* S-VOICE */ + {STR_WAKEUP_NORMAL, "SVOICE_NORMAL"}, + {STR_WAKEUP_EARMIC_NORMAL, "GENERIC_AP"}, + {STR_WAKEUP_BTMIC_NORMAL, "BT_AP"}, + {STR_WAKEUP_DRIVING, "SVOICE_DRIVING"}, + {STR_SVOICE_NORMAL, "SVOICE_NORMAL"}, + {STR_SVOICE_EARMIC_NORMAL, "GENERIC_AP"}, + {STR_SVOICE_BTMIC_NORMAL, "BT_AP"}, + {STR_SVOICE_DRIVING, "SVOICE_DRIVING"}, +}; +#endif + +static struct FILE_DATA gsFileData = {NULL, 0}; +static int gnGroupInfoNum = 0; +static int gnAllocGroupInfoNum = 0; +static char gabRootDir[MAX_PATH_NAME]; +static struct GROUP_INFO *gpGroupInfo; + + +#ifdef USE_SCN_TO_GRP_FILE +#define MAX_BUFFER_SIZE 256 +#define SCENARIO_GROUP_MATCHING_TABLE "/usr/etc/sound/ymu831/matching_table" +static int initialized = 0; +static struct SCENARIO_GROUP *gpScnToGrp = NULL; + +static int InitScenarioGroup(void) +{ + FILE *fp = NULL; + struct SCENARIO_GROUP *pScnToGrp = NULL; + char line_buffer[MAX_BUFFER_SIZE] = {0,}; + + fp = fopen(SCENARIO_GROUP_MATCHING_TABLE, FILE_OPEN_MODE); + + if (!fp) + return errno; + + while (fgets(line_buffer, sizeof(line_buffer), fp) != NULL) { + char *p_start = NULL, *p_end = NULL; + + if (gpScnToGrp == NULL) { + gpScnToGrp = malloc(sizeof(struct SCENARIO_GROUP)); + pScnToGrp = gpScnToGrp; + } else { + pScnToGrp->pNext = malloc(sizeof(struct SCENARIO_GROUP)); + pScnToGrp = pScnToGrp->pNext; + } + memset(pScnToGrp, 0x00, sizeof(struct SCENARIO_GROUP)); + + /* Skip comment */ + if ((line_buffer[0] == '#') || + ((line_buffer[0] == '/') && (line_buffer[1] == '/'))) { + continue; + } + + /* Parse Scenario */ + p_start = p_end = line_buffer; + while (!isspace(*p_end)) + p_end++; + pScnToGrp->pbScenario = malloc(p_end - p_start + 1); + strncpy(pScnToGrp->pbScenario, p_start, p_end - p_start); + pScnToGrp->pbScenario[p_end - p_start] = '\0'; + + /* Parse Group */ + p_start = p_end; + while (isspace(*p_start)) + p_start++; + p_end = p_start; + while (!isspace(*p_end)) + p_end++; + pScnToGrp->pbGroup = malloc(p_end - p_start + 1); + strncpy(pScnToGrp->pbGroup, p_start, p_end - p_start); + pScnToGrp->pbGroup[p_end - p_start] = '\0'; + } + fclose(fp); + + return 0; +} +#endif + +static int GetValue(char *pbStart, int nSize, char *pbBuff, int nBuffSize) +{ + int nPos; + int nValueSize; + int nValidValue; + + memset(pbBuff, 0x00, nBuffSize); + + nBuffSize--; + if (nBuffSize <= 0) + return ERROR; + + nPos = 0; + while (nPos < nSize) { + if (!isblank(pbStart[nPos])) + break; + nPos++; + } + + if ((nPos == nSize) || (pbStart[nPos] != '"')) + return ERROR; + nPos++; + + nValueSize = 0; + nValidValue = 0; + while (nPos < nSize) { + if ((pbStart[nPos] == '\r') || (pbStart[nPos] == '\n')) + return ERROR; + + if (pbStart[nPos] == '"') { + nPos++; + nValidValue = 1; + break; + } + + if (nValueSize < nBuffSize) { + pbBuff[nValueSize] = pbStart[nPos]; + nValueSize++; + } + + nPos++; + } + + if (nValidValue == 0) + return ERROR; + + return nPos; +} + +static int ReadFileData(FILE *pFile, struct FILE_DATA *pFileData) +{ + int nSize; + int nReadSize; + char *pbData; + long pos = 0; + + pFileData->pbData = NULL; + pFileData->nSize = 0; + + fseek(pFile, 0, SEEK_END); + pos = ftell(pFile); + fseek(pFile, 0, SEEK_SET); + pos -= ftell(pFile); + + if (pos <= 0) + return ERROR; + + nSize = (int)pos; + pbData = malloc(nSize); + if (pbData == NULL) + return ERROR; + + nReadSize = (int)fread(pbData, 1, nSize, pFile); + if (nReadSize != nSize) { + free(pbData); + return ERROR; + } + + pFileData->pbData = pbData; + pFileData->nSize = nSize; + + return nSize; +} + +#ifdef USE_FOPEN +static int ReadFile(char *pbPathName, struct FILE_DATA *pFileData) +{ + int nResult = 0; + FILE *pFile; + + pFile = fopen(pbPathName, FILE_OPEN_MODE); + if (pFile == NULL) + return errno; + + nResult = ReadFileData(pFile, pFileData); + + fclose(pFile); + + return nResult; +} +#else +static int ReadFile(char *pbPathName, struct FILE_DATA *pFileData) +{ + int nResult; + int nFd; + FILE *pFile; + + nFd = open(pbPathName, O_RDONLY); + if (nFd < 0) + return nFd; + + pFile = fdopen(nFd, FILE_OPEN_MODE); + if (pFile == NULL) { + close(nFd); + return errno; + } + + nResult = ReadFileData(pFile, pFileData); + + fclose(pFile); + close(nFd); + + return nResult; +} +#endif + +static void ReleaseFileData(struct FILE_DATA *pFileData) +{ + if (pFileData->pbData != NULL) + free(pFileData->pbData); + + pFileData->pbData = NULL; + pFileData->nSize = 0; +} + +static int AddGroupInfo(char *pbName, int nStartPos, int nEndPos) +{ + int i; + struct GROUP_INFO *pTemp; + + avsys_info(AVAUDIO, "%s\n", pbName); + + if (gnAllocGroupInfoNum <= (gnGroupInfoNum + 1)) { + gnAllocGroupInfoNum = gnGroupInfoNum * 2; + pTemp = malloc( + sizeof(struct GROUP_INFO) * gnAllocGroupInfoNum); + if (pTemp == NULL) + return ERROR; + + for (i = 0; i < gnGroupInfoNum; ++i) { + strncpy(pTemp[i].abName, + gpGroupInfo[i].abName, MAX_NAME); + pTemp[i].nStartPos = gpGroupInfo[i].nStartPos; + pTemp[i].nEndPos = gpGroupInfo[i].nEndPos; + avsys_info(AVAUDIO, "abName[%s]:nStartPos[%d]:nEndPos[%d]\n", + gpGroupInfo[i].abName, + gpGroupInfo[i].nStartPos, + gpGroupInfo[i].nEndPos); + } + + free(gpGroupInfo); + gpGroupInfo = pTemp; + } + + strncpy(gpGroupInfo[gnGroupInfoNum].abName, pbName, MAX_NAME-1); + gpGroupInfo[gnGroupInfoNum].abName[MAX_NAME-1] = '\0'; + gpGroupInfo[gnGroupInfoNum].nStartPos = nStartPos; + gpGroupInfo[gnGroupInfoNum].nEndPos = nEndPos; + + gnGroupInfoNum++; + return gnGroupInfoNum; +} + +static int ConfigAnalyze(struct FILE_DATA *pFileData, + char *pbRootDir, int nRootDirSize) +{ + int nPos; + int nRemain; + int nResult; + int nYmcStart; + int nGroupStart; + char abName[MAX_NAME]; + char *pbStart; + int nSize; + + pbStart = pFileData->pbData; + nSize = pFileData->nSize; + + nPos = 0; + nYmcStart = 0; + nGroupStart = 0; + while (nPos < nSize) { + nRemain = (nSize - nPos); + if (isblank(pbStart[nPos])) { + nPos++; + } else if ((5 <= nRemain) && + (strncmp(&pbStart[nPos], "", 5) == 0)) { + if (nYmcStart != 0) + return ERROR; + nPos += 5; + nYmcStart = nPos; + } else if ((6 <= nRemain) && + (strncmp(&pbStart[nPos], "", 6) == 0)) { + if (nYmcStart == 0) + return ERROR; + nPos += 6; + nYmcStart = 0; + } else if (nYmcStart == 0) { + nPos++; + } else if ((19 <= nRemain) && + (strncmp(&pbStart[nPos], + "", 2) == 0)) { + nPos += 2; + break; + } else { + return ERROR; + } + } + } else if ((12 <= nRemain) && + (strncmp(&pbStart[nPos], "') { + nPos++; + break; + } else { + return ERROR; + } + } + nGroupStart = nPos; + } else if ((8 <= nRemain) && + (strncmp(&pbStart[nPos], "", 8) == 0)) { + if (nGroupStart == 0) + return ERROR; + if (nPos <= 0) + return ERROR; + + nResult = AddGroupInfo(abName, + nGroupStart, (nPos - 1)); + if (nResult < 0) + return nResult; + + nPos += 8; + nGroupStart = 0; + } else { + nPos++; + } + } + + if ((nGroupStart != 0) || (nYmcStart != 0)) + return ERROR; + + return 0; +} + +static int HwdevOpen() +{ + int handle; + char hwdev_path[MAX_NAME]; + + snprintf(hwdev_path, MAX_NAME, "/dev/snd/hwC%uD%u", + DEVFILE_HW_CARD_NUMBER, DEVFILE_HW_DEVICE_NUMBER); + handle = open(hwdev_path, O_RDWR); + return handle; +} + +static void HwdevClose(int handle) +{ + close(handle); +} + +static unsigned long GetOption(char *pbName) +{ + unsigned long dResult; + dResult = YMC_DSP_OPTION_ERROR; + + if (strcasecmp(pbName, DSP_OUTPUT_NAME) == 0) + dResult = YMC_DSP_OUTPUT_BASE; + else if (strcasecmp(pbName, DSP_INPUT_NAME) == 0) + dResult = YMC_DSP_INPUT_BASE; + else if (strcasecmp(pbName, DSP_VOICECALL_NAME) == 0) + dResult = YMC_DSP_VOICECALL_BASE_COMMON; + else if (strcasecmp(pbName, DSP_VOICECALL_1MIC_NAME) == 0) + dResult = YMC_DSP_VOICECALL_BASE_1MIC; + else if (strcasecmp(pbName, DSP_VOICECALL_2MIC_NAME) == 0) + dResult = YMC_DSP_VOICECALL_BASE_2MIC; + + return dResult; +} + +static int SetParameter(char *pbName, char *pbPathName) +{ + int nResult; + int handle; + struct FILE_DATA Parameter; + ymc_ctrl_args_t args; + + avsys_warning(AVAUDIO,"Name[%s] PathName[%s]\n", pbName, pbPathName); + + args.option = GetOption(pbName); + if (args.option == YMC_DSP_OPTION_ERROR) + return ERROR; + + nResult = ReadFile(pbPathName, &Parameter); + if (nResult < 0) + return nResult; + else + avsys_info(AVAUDIO,"Read %s %d bytes done\n", + pbPathName, Parameter.nSize); + + args.param = Parameter.pbData; + args.size = Parameter.nSize; + + handle = HwdevOpen(); + if (handle >= 0) { + nResult = ioctl(handle, YMC_IOCTL_SET_CTRL, &args); + if (nResult < 0) + avsys_error(AVAUDIO, "ioctl YMC_IOCTL_SET_CTRL has failed with %s", strerror(errno)); + HwdevClose(handle); + } else { + avsys_error(AVAUDIO, "HwdevOpen failed, ret handle is %d, err is %s", handle, strerror(errno)); + } + + ReleaseFileData(&Parameter); + + return nResult; +} + +static snd_mixer_t *MixOpen(char* ifaceName) +{ + int nResult; + snd_mixer_t *handle; + + nResult = snd_mixer_open(&handle, 0); + if (nResult < 0) + return NULL; + + nResult = snd_mixer_attach(handle, ifaceName); + if (nResult < 0) { + snd_mixer_close(handle); + return NULL; + } + + nResult = snd_mixer_selem_register(handle, NULL, NULL); + if (nResult < 0) { + snd_mixer_close(handle); + return NULL; + } + + nResult = snd_mixer_load(handle); + if (nResult < 0) { + snd_mixer_close(handle); + return NULL; + } + + return handle; +} + +static int get_mixer_elem(snd_mixer_t *handle, + char *name, snd_mixer_elem_t **elem) +{ + int nResult; + snd_mixer_selem_id_t* sid; + sid = NULL; + + nResult = snd_mixer_selem_id_malloc(&sid); + if (nResult < 0) + return ERROR; + + snd_mixer_selem_id_set_index(sid, 0); + snd_mixer_selem_id_set_name(sid, name); + *elem = snd_mixer_find_selem(handle, sid); + snd_mixer_selem_id_free(sid); + if (*elem == NULL) + return ERROR; + + return 0; +} + +static int IsNumber(char *value) +{ + int i; + int is_str = 0; + + if (!value) + return ERROR; + + for (i = 0; i < strlen(value); i++) { + if (!isdigit(value[i])) { + is_str = 1; + break; + } + } + if (is_str) + return 0; + else + return 1; +} + +static int FindIndexFromName(snd_mixer_elem_t *elem, int items, char *enum_name) +{ + int i; + char buffer[32] = {0,}; + char *mixer_name = NULL; + + mixer_name = (char*) snd_mixer_selem_get_name(elem); + + for (i = 0; i < items; i++) { + if (snd_mixer_selem_get_enum_item_name(elem, i, sizeof(buffer)-1, buffer) < 0) { + avsys_debug(AVAUDIO, ">> [%s] Get item name failure %s [%d]", + mixer_name, enum_name, i); + return ERROR; + } + if (strlen(buffer) != strlen(enum_name)) + continue; + + if (!strncmp(buffer, enum_name, strlen(buffer))) { + avsys_debug(AVAUDIO, ">> [%s] Found %s [%d]", + mixer_name, enum_name, i); + return i; + } + } + return ERROR; +} + +static int SetMixEnum(snd_mixer_t *handle, char *name, char *value) +{ + int nResult; + int items, index; + snd_mixer_elem_t *elem; + + nResult = get_mixer_elem(handle, name, &elem); + if (nResult < 0) + return nResult; + + if (!snd_mixer_selem_is_enumerated(elem)) { + return ERROR; + } + + items = snd_mixer_selem_get_enum_items(elem); + if (items <= 0) + return ERROR; + + nResult = IsNumber(value); + if (nResult < 0) + return nResult; + + if (nResult > 0) + index = atoi(value); + else + index = FindIndexFromName(elem, items, value); + + if (index < 0) + return ERROR; + + if (items <= index) + return ERROR; + + avsys_debug(AVAUDIO, ">> Mixer [%s] Index[%d]",snd_mixer_selem_get_name(elem), index); + nResult = snd_mixer_selem_set_enum_item(elem, 0, index); + + return nResult; +} + +static void MixClose(snd_mixer_t *handle) +{ + snd_mixer_close(handle); +} + +static int SetMixer(char *pbName, char *pbValue0, char *pbValue1) +{ + int nResult; + snd_mixer_t *handle; + + (void)pbValue1; + + if (!pbValue0) { + avsys_error(AVAUDIO, "NULL parameter"); + return ERROR; + } + + handle = MixOpen(MIXER_NAME_OUT); + if (handle == NULL) + return ERROR; + + nResult = SetMixEnum(handle, pbName, pbValue0); + + MixClose(handle); + + return nResult; +} + +static int SetParamMix(char *pbStart, int nSize, char *pbRootDir, int nTarget) +{ + int nPos; + int nResult; + int nRootDirSize; + int nValidValue; + int nRemain; + char abName[MAX_NAME]; + char abPathName[MAX_PATH_NAME]; + char abValue0[MAX_VALUE_LEN]; + char abValue1[MAX_VALUE_LEN]; + + memset(abName, 0x00, sizeof(abName)); + memset(abPathName, 0x00, sizeof(abPathName)); + memset(abValue0, 0x00, sizeof(abValue0)); + memset(abValue1, 0x00, sizeof(abValue1)); + + snprintf(abPathName, MAX_PATH_NAME, "%s/", pbRootDir); + nRootDirSize = (int)strlen(abPathName); + + nPos = 0; + nValidValue = 0; + while (nPos < nSize) { + if ((pbStart[nPos] == '\r') || (pbStart[nPos] == '\n')) + return ERROR; + + nRemain = (nSize - nPos); + if (isblank(pbStart[nPos])) { + nPos++; + } else if ((2 <= nRemain) && + (strncmp(&pbStart[nPos], "/>", 2) == 0)) { + nPos += 2; + nValidValue = 1; + break; + + } else if ((5 <= nRemain) && + (strncmp(&pbStart[nPos], "name=", 5) == 0)) { + if (strlen(abName) != 0) + return ERROR; + + nPos += 5; + nRemain = (nSize - nPos); + nResult = GetValue(&pbStart[nPos], nRemain, + abName, sizeof(abName)); + if (nResult < 0) + return nResult; + + nPos += nResult; + } else if ((5 <= nRemain) && + (strncmp(&pbStart[nPos], "file=", 5) == 0)) { + if (nRootDirSize < (int)strlen(abPathName)) + return ERROR; + + nPos += 5; + nRemain = (nSize - nPos); + nResult = GetValue(&pbStart[nPos], nRemain, + &abPathName[nRootDirSize], + (sizeof(abPathName) - nRootDirSize)); + if (nResult < 0) + return nResult; + + nPos += nResult; + } else if ((7 <= nRemain) && + (strncmp(&pbStart[nPos], "value0=", 7) == 0)) { + + if (strlen(abValue0) != 0) + return ERROR; + + nPos += 7; + nRemain = (nSize - nPos); + nResult = GetValue(&pbStart[nPos], nRemain, + abValue0, sizeof(abValue0)); + if (nResult < 0) + return nResult; + + nPos += nResult; + } else if ((7 <= nRemain) && + (strncmp(&pbStart[nPos], "value1=", 7) == 0)) { + + if (strlen(abValue1) != 0) + return ERROR; + + nPos += 7; + nRemain = (nSize - nPos); + nResult = GetValue(&pbStart[nPos], nRemain, + abValue1, sizeof(abValue1)); + if (nResult < 0) + return nResult; + + nPos += nResult; + } else { + return ERROR; + } + } + + if (nValidValue == 0) + return ERROR; + + switch(nTarget) { + case TARGET_PARAMETER: + nResult = SetParameter(abName, abPathName); + break; + + case TARGET_MIXER: + nResult = SetMixer(abName, abValue0, abValue1); + break; + + default: + nResult = ERROR; + break; + } + + return (nResult < 0) ? nResult : nPos; +} + +static int SetGroup(char *pbStart, int nSize, char *pbRootDir) +{ + int nPos; + int nRemain; + int nResult; + + nPos = 0; + while (nPos < nSize) { + nRemain = (nSize - nPos); + if (isblank(pbStart[nPos]) || + pbStart[nPos] == '\r' || pbStart[nPos] == '\n') { + nPos++; + } else if ((11 <= nRemain) && + (strncmp(&pbStart[nPos], "pNext) { + if (strncmp(ascn_str, pScnToGrp->pbScenario, MAX_NAME) == 0) + return pScnToGrp->pbGroup; + } + return NULL; +} +#else +static int GetGroup(char *ascn_str) +{ + int i = 0; + int nNum = sizeof(gaScnToGrp) / sizeof(struct SCENARIO_GROUP); + + for (i = 0; i < nNum; ++i) + if (strncmp(ascn_str, gaScnToGrp[i].pbScenario, MAX_NAME) == 0) + break; + + return (i == nNum) ? NOT_FINED : i; +} +#endif + +static int check_csc_conf(char *filename) +{ + int ret; + FILE *f; + + if (!filename) + return -ENOENT; + + f = fopen(filename, "r"); + if (f == NULL) { + csc_conf_data = 0; + return -errno; + } + csc_conf_data = 1; + fclose(f); + return 0; +} + +static int Init(int verbose, char *card) +{ + int nResult; + char card_name[MAX_PATH_NAME] = {0,}; + + gnGroupInfoNum = 0; + gnAllocGroupInfoNum = 64; + gpGroupInfo = malloc( + sizeof(struct GROUP_INFO) * gnAllocGroupInfoNum); + if (gpGroupInfo == NULL) + return ERROR; + + memset(gpGroupInfo, 0x00, + sizeof(struct GROUP_INFO) * gnAllocGroupInfoNum); + + if (!card) { + snprintf(card_name, MAX_PATH_NAME, "%s/%s/%s", + CSC_YSOUND_PATH, DEF_CARD_NAME, YSOUND_CONF); + } else { + snprintf(card_name, MAX_PATH_NAME, "%s/%s/%s", + CSC_YSOUND_PATH, card, YSOUND_CONF); + } + + nResult = check_csc_conf(card_name); + if (!nResult) + fprintf(stderr, "Use CSC ysound.conf [%d]\n", nResult); + else + fprintf(stderr, "Use default ysound.conf [%d]\n", nResult); + + if (!csc_conf_data) { + if (!card) + snprintf(card_name, MAX_PATH_NAME, "%s/%s/%s", + DEF_YSOUND_PATH, DEF_CARD_NAME, YSOUND_CONF); + else + snprintf(card_name, MAX_PATH_NAME, "%s/%s/%s", + DEF_YSOUND_PATH, card, YSOUND_CONF); + } + + nResult = ReadFile(card_name, &gsFileData); + if (nResult < 0) { + free(gpGroupInfo); + gpGroupInfo = NULL; + return nResult; + } + + nResult = ConfigAnalyze( + &gsFileData, gabRootDir, sizeof(gabRootDir)); + if (nResult < 0) { + free(gpGroupInfo); + gpGroupInfo = NULL; + return nResult; + } + + return nResult; +} + +static void Term() +{ + if (gsFileData.pbData != NULL) + free(gsFileData.pbData); + + gsFileData.pbData = NULL; + gsFileData.nSize = 0; + + free(gpGroupInfo); + gpGroupInfo = NULL; +} + +void print_groups(char *cardname) +{ + if (Init(1, cardname) < 0) { + fprintf(stderr, ">> Init failed\n"); + return; + } + Term(); +} + +int ymu831_set_scenario(char *str_route) +{ + char *pbData, *cardname; + int nGroup; + int nSize; + int i; + int nResult; + + cardname = NULL; +#ifdef USE_SCN_TO_GRP_FILE + char *pbGroup; + + if (!initialized) { + avsys_warning(AVAUDIO, "Initialize ymu831 scenario files\n"); + snd_card_get_name(0, &cardname); + nResult = Init(0, cardname); + if (nResult < 0) { + avsys_error(AVAUDIO, "Init() failed with %d\n", nResult); + free(cardname); + return nResult; + } + InitScenarioGroup(); + initialized = 1; + free(cardname); + } + + pbGroup = FindGroup(str_route); + if (!pbGroup) + return 0; + + avsys_warning(AVAUDIO, "scn:%s grp:%s\n", str_route, pbGroup); + + for (i = 0; i < gnGroupInfoNum; ++i) + if (strncmp(gpGroupInfo[i].abName, pbGroup, MAX_NAME) == 0) + break; + + if (gnGroupInfoNum <= i) + return ERROR; + +#else + /* scenario->group */ + nGroup = GetGroup(str_route); + if (nGroup == NOT_FINED) + return 0; + + avsys_warning(AVAUDIO, "%s\n", gaScnToGrp[nGroup].pbScenario); + + snd_card_get_name(0, &cardname); + nResult = Init(0, cardname); + if (nResult < 0) { + avsys_error(AVAUDIO, "Init() failed with %d\n", nResult); + free(cardname); + return nResult; + } + free(cardname); + + for (i = 0; i < gnGroupInfoNum; ++i) + if (strncmp(gpGroupInfo[i].abName, + gaScnToGrp[nGroup].pbGroup, MAX_NAME) == 0) + break; + + if (gnGroupInfoNum <= i) { + Term(); + return ERROR; + } +#endif + + pbData = &gsFileData.pbData[gpGroupInfo[i].nStartPos]; + nSize = gpGroupInfo[i].nEndPos - gpGroupInfo[i].nStartPos + 1; + nResult = SetGroup(pbData, nSize, gabRootDir); + +#ifndef USE_SCN_TO_GRP_FILE + Term(); +#endif + return nResult; +} diff --git a/avsys-audio-ascenario.c b/avsys-audio-ascenario.c new file mode 100644 index 0000000..a0ccc6f --- /dev/null +++ b/avsys-audio-ascenario.c @@ -0,0 +1,306 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi + * + * 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. + * + */ + +#if !defined(_MMFW_I386_ALL_SIMULATOR) +#include +#endif +#include + +#include "avsys-audio-ascenario.h" +#include "avsys-types.h" +#include "avsys-error.h" +#include "avsys-debug.h" +#if defined(TIME_CHECK) +#include +#include +#endif +#include + +#define STR_BUFF_MAX 128 +#define P_STR_MAX 42 +#define O_STR_MAX 44 +#define CARD_NUMBER 0 /* ALSA card number */ + +#ifdef USE_YMU831 +extern int ymu831_set_scenario(int bulk); +#endif + +#define VCONF_KEY_SOUND_GAIN_PLAYBACK "memory/private/sound/path/gain_playback" +#define VCONF_KEY_SOUND_PATH_PLAYBACK "memory/private/sound/path/path_playback" +#define VCONF_KEY_SOUND_GAIN_CAPTURE "memory/private/sound/path/gain_capture" +#define VCONF_KEY_SOUND_PATH_CAPTURE "memory/private/sound/path/path_capture" + +const char* mode_str[] = {"gain", "path"}; +const char* type_str[] = {"playback", "capture"}; + +static struct snd_scenario *scn = NULL; + +int avsys_audio_ascn_str_route_set_vconf (char *str_route[], int route_cnt, ASCN_MODE_T mode, ASCN_TYPE_T type) +{ + char vconf_buf[STR_BUFF_MAX] = { 0, }; + char vconf_str[STR_BUFF_MAX] = { 0, }; + int err = AVSYS_STATE_SUCCESS; + int i = 0; + + if (str_route == NULL) { + avsys_error_r(AVAUDIO, "input string route is null\n"); + return AVSYS_STATE_ERR_NULL_POINTER; + } + if (route_cnt < 0) { + avsys_error_r(AVAUDIO, "route count is negative\n"); + return AVSYS_STATE_ERR_RANGE_OVER; + } + + for (i = 0; i < route_cnt; i++) { + avsys_warning (AVAUDIO, "%s\n", str_route[i]); + strcat (vconf_buf, str_route[i]); + strcat (vconf_buf, ";"); + } + + sprintf (vconf_str, "memory/private/sound/path/%s_%s", mode_str[mode], type_str[type]); + vconf_set_str(vconf_str, vconf_buf); + avsys_audio_pa_ctrl_set_info((mode << 4 | type)); + + return err; +} + +int avsys_audio_ascn_str_route_set_vconf_lazy (char *str_route[], int route_cnt, ASCN_MODE_T mode, ASCN_TYPE_T type) +{ + char vconf_buf[STR_BUFF_MAX] = { 0, }; + char vconf_str[STR_BUFF_MAX] = { 0, }; + int err = AVSYS_STATE_SUCCESS; + int i = 0; + + if (str_route == NULL) { + avsys_error_r(AVAUDIO, "input string route is null\n"); + return AVSYS_STATE_ERR_NULL_POINTER; + } + if (route_cnt < 0) { + avsys_error_r(AVAUDIO, "route count is negative\n"); + return AVSYS_STATE_ERR_RANGE_OVER; + } + + for (i = 0; i < route_cnt; i++) { + avsys_warning (AVAUDIO, "%s\n", str_route[i]); + strcat (vconf_buf, str_route[i]); + strcat (vconf_buf, ";"); + } + + sprintf (vconf_str, "memory/private/sound/path/%s_%s", mode_str[mode], type_str[type]); + vconf_set_str(vconf_str, vconf_buf); + + return err; +} + +int avsys_audio_ascn_str_route_set(int *str_route[], int route_cnt, AscnResetType clear) +{ + char reset_str[STR_BUFF_MAX] = { 0, }; + int err = AVSYS_STATE_SUCCESS; + int i = 0; +#if defined(TIME_CHECK) + struct timeval t_start, t_stop; + unsigned long check = 0; +#endif + + avsys_info(AVAUDIO, "<< clear = %d\n", clear); + + if (clear < ASCN_RESET_NONE || clear > ASCN_RESET_MODEM) { + avsys_error_r(AVAUDIO, "invalid clear type %d\n", clear); + return AVSYS_STATE_ERR_RANGE_OVER; + } + + if (str_route == NULL) { + avsys_error_r(AVAUDIO, "string route is null\n"); + return AVSYS_STATE_ERR_NULL_POINTER; + } + if (route_cnt < 0) { + avsys_error_r(AVAUDIO, "route count is negative\n"); + return AVSYS_STATE_ERR_RANGE_OVER; + } + + if (clear != ASCN_RESET_NONE) { + switch (clear) { + case ASCN_RESET_ALL: + snprintf(reset_str, sizeof(reset_str) - 1, "%s", ASCN_STR_RESET); + break; + case ASCN_RESET_PLAYBACK: + snprintf(reset_str, sizeof(reset_str) - 1, "%s", ASCN_STR_RESET_PLAYBACK); + break; + case ASCN_RESET_CAPTURE: + snprintf(reset_str, sizeof(reset_str) - 1, "%s", ASCN_STR_RESET_CAPTURE); + break; + } +#if defined(TIME_CHECK) + gettimeofday(&t_start, NULL); +#endif + err = snd_scenario_set_scn(scn, reset_str); +#if defined(TIME_CHECK) + gettimeofday(&t_stop, NULL); + if (t_stop.tv_sec == t_start.tv_sec) + check = (t_stop.tv_usec - t_start.tv_usec) / 1000; + else + check = (t_stop.tv_sec - t_start.tv_sec) * 1000 + (t_stop.tv_usec - t_start.tv_usec) / 1000; + avsys_warning(AVAUDIO, "[%s] takes %u msec\n", reset_str, check); +#endif + if (err < 0) { + avsys_error(AVAUDIO, "Alsa sceanrio [%s] failed\n", reset_str); + } else { + avsys_warning(AVAUDIO, "Set [%s] success\n", reset_str); + } + } + + for (i = 0; i < route_cnt; i++) { +#if defined(TIME_CHECK) + gettimeofday(&t_start, NULL); +#endif + err = snd_scenario_set_scn(scn, str_route[i]); +#if defined(TIME_CHECK) + gettimeofday(&t_stop, NULL); + if (t_stop.tv_sec == t_start.tv_sec) + check = (t_stop.tv_usec - t_start.tv_usec) / 1000; + else + check = (t_stop.tv_sec - t_start.tv_sec) * 1000 + (t_stop.tv_usec - t_start.tv_usec) / 1000; + avsys_warning(AVAUDIO, "[%s] takes %u msec\n", str_route[i], check); +#endif + if (err < 0) { + avsys_error_r(AVAUDIO, "snd_scenario_set_scn(%s) failed with %d\n", str_route, err); + goto bulk_error; + } + avsys_warning(AVAUDIO, "* Set [%s] success\n", str_route[i]); +#ifdef USE_YMU831 + err = ymu831_set_scenario(str_route[i]); + if (err < 0) { + avsys_error(AVAUDIO,"ymu831_set_scenario(%s) has failed\n", str_route[i]); + goto bulk_error; + } +#endif + } + +bulk_error: +#if defined(TIME_CHECK) + gettimeofday(&t_start, NULL); +#endif +#if defined(TIME_CHECK) + gettimeofday(&t_stop, NULL); + if (t_stop.tv_sec == t_start.tv_sec) + check = (t_stop.tv_usec - t_start.tv_usec) / 1000; + else + check = (t_stop.tv_sec - t_start.tv_sec) * 1000 + (t_stop.tv_usec - t_start.tv_usec) / 1000; + avsys_warning(AVAUDIO, "[snd_scenario_close()] takes %u msec\n", check); +#endif + return err; +} + +int avsys_audio_ascn_single_set(char * str) +{ + char cmd_str[STR_BUFF_MAX] = { 0, }; + int err = AVSYS_STATE_SUCCESS; +#if defined(TIME_CHECK) + struct timeval t_start, t_stop; + unsigned long check = 0; +#endif + + if (str == NULL) { + avsys_error_r(AVAUDIO, "input str is null\n"); + return AVSYS_STATE_ERR_NULL_POINTER; + } + +#if defined(TIME_CHECK) + gettimeofday(&t_start, NULL); +#endif + + /* Set scenario */ + strncpy(cmd_str, str, sizeof(cmd_str) - 1); + err = snd_scenario_set_scn(scn, str); + avsys_warning(AVAUDIO, "alsa scenario set [%s]\n", str); + + if (err < 0) { + avsys_error(AVAUDIO, "snd_scenario_set(%s) failed\n", str); + } + +#if defined(TIME_CHECK) + gettimeofday(&t_stop, NULL); + if (t_stop.tv_sec == t_start.tv_sec) + check = (t_stop.tv_usec - t_start.tv_usec) / 1000; + else + check = (t_stop.tv_sec - t_start.tv_sec) * 1000 + (t_stop.tv_usec - t_start.tv_usec) / 1000; + avsys_warning(AVAUDIO, "[%s] takes %u msec\n", str, check); +#endif + + return err; +} + +int avsys_audio_ascn_open(void) +{ + int card = CARD_NUMBER; + char *name = NULL; +#if defined(TIME_CHECK) + struct timeval t_start, t_stop; + unsigned long check = 0; +#endif + + /* Try to get card name from CARD_NUMBER. */ + snd_card_get_name(card, &name); +#if defined(TIME_CHECK) + gettimeofday(&t_start, NULL); +#endif + if (name == NULL) { + if (scn == NULL) { + scn = snd_scenario_open("default"); + if (scn == NULL) { + avsys_error(AVAUDIO, "snd_scenario_open() failed to open with default\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + } + } else { + if (scn == NULL) { + scn = snd_scenario_open(name); + } + free(name); + if (scn == NULL) + { + scn = snd_scenario_open("default"); + if (scn == NULL) + { + avsys_error(AVAUDIO, "snd_scenario_open() failed to open with default\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + } + } +#if defined(TIME_CHECK) + gettimeofday(&t_stop, NULL); + if (t_stop.tv_sec == t_start.tv_sec) + check = (t_stop.tv_usec - t_start.tv_usec) / 1000; + else + check = (t_stop.tv_sec - t_start.tv_sec) * 1000 + (t_stop.tv_usec - t_start.tv_usec) / 1000; + avsys_warning(AVAUDIO, "[snd_scenario_open()] takes %u msec\n", check); +#endif + return AVSYS_STATE_SUCCESS; +} + +void avsys_audio_ascn_close(void) +{ + if (scn) { + /* Close scenario manager core */ + snd_scenario_close(scn); + scn = NULL; + } +} diff --git a/avsys-audio-handle.c b/avsys-audio-handle.c new file mode 100644 index 0000000..3c6bc4a --- /dev/null +++ b/avsys-audio-handle.c @@ -0,0 +1,1070 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi + * + * 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 +#include +#include +#include + +#include "avsys-common.h" +#include "avsys-audio-shm.h" +#include "avsys-audio-sync.h" +#include "avsys-debug.h" +#include "avsys-audio-handle.h" +#include "avsys-audio-shm.h" +#include "avsys-audio-path.h" +#include "avsys-audio-pactrl.h" + +#define AVSYS_GET_SHM(SHM,ERROR) do { \ + if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_HANDLE, (void **)SHM))) { \ + avsys_error(AVAUDIO,"avsys_audio_get_shm() failed\n"); \ + return ERROR; \ + } \ +} while (0) + +#define AVSYS_LOCK_SYNC() do { \ + if (AVSYS_FAIL(avsys_audio_lock_sync(AVSYS_AUDIO_SYNC_IDEN_HANDLE))) { \ + avsys_error(AVAUDIO,"avsys_audio_lock_sync() failed\n"); \ + return AVSYS_STATE_ERR_INTERNAL; \ + } \ +} while (0) + +#define AVSYS_UNLOCK_SYNC() do { \ + if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_HANDLE))) { \ + avsys_error(AVAUDIO,"avsys_audio_unlock_sync() failed\n"); \ + return AVSYS_STATE_ERR_INTERNAL; \ + } \ +} while (0) + +EXPORT_API +int avsys_audio_handle_init(void) +{ + int i, err = 0; + avsys_audio_handle_info_t *control = NULL; + avsys_audio_handle_info_t **temp = NULL; + + /* Check root user */ + err = avsys_check_root_privilege(); + if (AVSYS_FAIL(err)) { + return err; + } + + if (AVSYS_FAIL(avsys_audio_create_sync(AVSYS_AUDIO_SYNC_IDEN_HANDLE))) { + avsys_error(AVAUDIO, "avsys_audio_create_sync() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + if (AVSYS_FAIL(avsys_audio_create_shm(AVSYS_AUDIO_SHM_IDEN_HANDLE))) { + avsys_error(AVAUDIO, "avsys_audio_create_shm() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + + temp = &control; + AVSYS_GET_SHM(temp,AVSYS_STATE_ERR_INTERNAL); + if (control == NULL) { + avsys_error(AVAUDIO, "control is null\n"); + return AVSYS_STATE_ERR_NULL_POINTER; + } + + /* init allocted bits */ + control->allocated = 0; + control->handle_amp = 0; + control->ext_device_amp = AVSYS_AUDIO_HANDLE_EXT_DEV_NONE; + control->primary_volume_pid = 0; + control->primary_volume_type = -1; + for (i = 0; i < AVSYS_AUDIO_HANDLE_MAX; i++) { + control->handle_priority[i] = AVSYS_AUDIO_HANDLE_PRIORITY_TYPE_0; + } + + for (i = 0; i < AVSYS_AUDIO_LOCK_SLOT_MAX; i++) { + control->handlelock_pid[i] = -1; + } + return AVSYS_STATE_SUCCESS; +} + +EXPORT_API +int avsys_audio_handle_fini(void) +{ + + AVSYS_LOCK_SYNC(); + + if (AVSYS_FAIL(avsys_audio_remove_shm(AVSYS_AUDIO_SHM_IDEN_HANDLE))) { + avsys_error(AVAUDIO, "avsys_audio_remove_shm() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + + AVSYS_UNLOCK_SYNC(); + + if (AVSYS_FAIL(avsys_audio_remove_sync(AVSYS_AUDIO_SYNC_IDEN_HANDLE))) { + avsys_error(AVAUDIO, "avsys_audio_remove_sync() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + + return AVSYS_STATE_SUCCESS; +} + +EXPORT_API +int avsys_audio_handle_reset(int *volume_value) +{ + int i = 0, err = 0; + long long int flag = 0x01; + avsys_audio_handle_info_t *control = NULL; + avsys_audio_handle_info_t **temp = NULL; + temp = &control; + + /* Check root user */ + err = avsys_check_root_privilege(); + if (AVSYS_FAIL(err)) { + return err; + } + + AVSYS_GET_SHM(temp,AVSYS_STATE_ERR_INTERNAL); + if (control == NULL) { + avsys_error(AVAUDIO, "control is null\n"); + return AVSYS_STATE_ERR_NULL_POINTER; + } + + for (i = 0; i < AVSYS_AUDIO_HANDLE_MAX; i++) { + if (control->allocated & (flag << i)) { /* allocated condition */ + if (AVSYS_FAIL(avsys_check_process(control->handles[i].pid))) { + /* process dead */ + if (AVSYS_FAIL(avsys_audio_handle_free(i))) { + avsys_error(AVAUDIO, "Cleanup handle %d failed\n", i); + } + } + } + } + +#ifdef USE_HIBERNATION + while (control->allocated) { + if (++i > 5) + break; + avsys_warning(AVAUDIO, "(%d)Waiting...0.5 sec for resume from hibernation\n", i); + printf("(%d)Waiting...0.5 sec for resume from hibernation\n", i); + usleep(500); + } +#endif + + AVSYS_LOCK_SYNC(); + if (volume_value == NULL) { + control->allocated = 0; + control->handle_amp = 0; + } + control->ext_device_amp = AVSYS_AUDIO_HANDLE_EXT_DEV_NONE; + control->primary_volume_pid = 0; + control->primary_volume_type = -1; + for (i = 0; i < AVSYS_AUDIO_HANDLE_MAX; i++) { + control->handle_priority[i] = AVSYS_AUDIO_HANDLE_PRIORITY_TYPE_0; + } + /* Clear semaphore condition */ + for (i = 0; i < AVSYS_AUDIO_LOCK_SLOT_MAX; i++) { + control->handlelock_pid[i] = -1; + } + + AVSYS_UNLOCK_SYNC(); + + return AVSYS_STATE_SUCCESS; +} + +EXPORT_API +int avsys_audio_handle_rejuvenation(void) +{ + int i = 0; + long long int flag = 0x01; + long long int dead_flag = 0x01; + + avsys_audio_handle_info_t *control = NULL; + avsys_audio_handle_info_t **temp = NULL; + + temp = &control; + + AVSYS_GET_SHM(temp,AVSYS_STATE_ERR_INTERNAL); + if (control == NULL) { + avsys_error(AVAUDIO, "control is null\n"); + return AVSYS_STATE_ERR_NULL_POINTER; + } + + AVSYS_LOCK_SYNC(); + + /* Clear semaphore condition */ + + for (i = 0; i < AVSYS_AUDIO_HANDLE_MAX; i++) { + if (control->allocated & (flag << i)) { /* allocated condition */ + /* check pid of handle... still alive? */ + if (AVSYS_FAIL(avsys_check_process(control->handles[i].pid))) { + avsys_error(AVAUDIO, "handle %d is dead, so cleanup this handle\n", i); + + /* Just cleanup this dead handle here. */ + /* set priority of dead handle as lowest */ + control->handle_priority[i] = AVSYS_AUDIO_HANDLE_PRIORITY_TYPE_0; + dead_flag = flag << i; + control->allocated &= ~dead_flag; + /* clear handle mute field */ + if (control->handle_amp & dead_flag) { + control->handle_amp &= ~dead_flag; + } + } + } + } + + AVSYS_UNLOCK_SYNC(); + + return AVSYS_STATE_SUCCESS; +} + +EXPORT_API +int avsys_audio_handle_dump(void) +{ + avsys_audio_handle_info_t *control = NULL; + avsys_audio_handle_info_t **temp = NULL; + char *vol_str[] = { "System", "Notification", "Alarm", "Ringtone", "Media", "Call", "Fixed", "Java", "Media-HL" }; + char *dev_str[] = { "Speaker", "Headset", "BTHeadset" }; + int i = 0; + long long int flag = 0x01; + + temp = &control; + AVSYS_GET_SHM(temp,AVSYS_STATE_ERR_INTERNAL); + if (control == NULL) { + avsys_error(AVAUDIO, "control is null\n"); + return AVSYS_STATE_ERR_NULL_POINTER; + } + + fprintf(stdout, "======================================================================\n"); + fprintf(stdout, " Opened Handles Information \n"); + fprintf(stdout, "======================================================================\n"); + fprintf(stdout, " Avsystem Handle alloc : %016x\n", control->allocated); + for (i = 0; i < AVSYS_AUDIO_LOCK_SLOT_MAX; i++) { + if (control->handlelock_pid[i] > 0) { + fprintf(stdout, " Handle Lock PIDs : %d\n", control->handlelock_pid[i]); + } + } + fprintf(stdout, "----------------------------------------------------------------------\n"); + for (i = 0; i < AVSYS_AUDIO_HANDLE_MAX; i++) { + if (control->allocated & (flag << i)) { /* allocated condition */ + fprintf(stdout, " Avsystem Handle ID : %2d\n", i); + fprintf(stdout, " Run Process ID : 0x%08X (%d)\n", control->handles[i].pid, control->handles[i].pid); + fprintf(stdout, " Run Thread ID : 0x%08X (%d)\n", control->handles[i].tid, control->handles[i].tid); + fprintf(stdout, " Open Mode : %2d\n", control->handles[i].mode); + fprintf(stdout, " Format : %2d\n", control->handles[i].format); + fprintf(stdout, " Channels : %2d\n", control->handles[i].channels); + fprintf(stdout, " Samplerate : %2d\n", control->handles[i].samplerate); + fprintf(stdout, " Priority : %2d\n", control->handle_priority[i]); + if(control->handles[i].mode == AVSYS_AUDIO_MODE_OUTPUT || control->handles[i].mode == AVSYS_AUDIO_MODE_OUTPUT_CLOCK || + control->handles[i].mode == AVSYS_AUDIO_MODE_OUTPUT_VIDEO || control->handles[i].mode == AVSYS_AUDIO_MODE_OUTPUT_LOW_LATENCY + || control->handles[i].mode == AVSYS_AUDIO_MODE_OUTPUT_AP_CALL) { + int vol_conf_type = AVSYS_AUDIO_VOLUME_CONFIG_TYPE(control->handles[i].gain_setting.volume_config); + if (control->handles[i].dirty_volume) { + fprintf(stdout, " Dirty volume : %s\n", vol_str[vol_conf_type]); + } else { + fprintf(stdout, " Volume Type : %s\n", vol_str[vol_conf_type]); + } + } + fprintf(stdout, " ----------------------------------------------------------------------\n"); + } + } + + fprintf(stdout, " ----------------------------------------------------------------------\n"); + fprintf(stdout, " External dev amp : 0x%08X\n", control->ext_device_amp); + fprintf(stdout, " External dev status : 0x%08X\n", control->ext_device_status); + if (control->primary_volume_type >= 0) { + fprintf(stdout, " Primary Volume type : %s\n", vol_str[control->primary_volume_type]); + } + fprintf(stdout, "======================================================================\n"); + + return AVSYS_STATE_SUCCESS; +} + +int avsys_audio_handle_alloc(int *handle) +{ + long long int flag = 0x01; + int i; + avsys_audio_handle_info_t *control = NULL; + avsys_audio_handle_info_t **temp = NULL; + temp = &control; + + avsys_info(AVAUDIO, "\n"); + AVSYS_GET_SHM(temp,AVSYS_STATE_ERR_INTERNAL); + + AVSYS_LOCK_SYNC(); + for (i = 0; i < AVSYS_AUDIO_HANDLE_MAX; i++) { + if ((control->allocated & flag) == 0) { /* alloc condition */ + control->allocated |= flag; + break; + } else { + flag <<= 1; + } + } + + AVSYS_UNLOCK_SYNC(); + + if (i == AVSYS_AUDIO_HANDLE_MAX) { + *handle = -1; + return AVSYS_STATE_ERR_RANGE_OVER; + } else { + avsys_info(AVAUDIO, "handle allocated %d\n", i); + memset(&control->handles[i], 0, sizeof(avsys_audio_handle_t)); + control->handles[i].pid = getpid(); + control->handles[i].tid = avsys_gettid(); + *handle = i; + return AVSYS_STATE_SUCCESS; + } +} + +int avsys_audio_handle_alloc_unlocked(int *handle) +{ + long long int flag = 0x01; + int i; + avsys_audio_handle_info_t *control = NULL; + avsys_audio_handle_info_t **temp = NULL; + temp = &control; + + AVSYS_GET_SHM(temp,AVSYS_STATE_ERR_INTERNAL); + + for (i = 0; i < AVSYS_AUDIO_HANDLE_MAX; i++) { + if ((control->allocated & flag) == 0) { /* alloc condition */ + control->allocated |= flag; + break; + } else { + flag <<= 1; + } + } + + if (i == AVSYS_AUDIO_HANDLE_MAX) { + avsys_error(AVAUDIO, "handle is already MAX[%d]\n", i); + *handle = -1; + return AVSYS_STATE_ERR_RANGE_OVER; + } else { + memset(&control->handles[i], 0, sizeof(avsys_audio_handle_t)); + control->handles[i].pid = getpid(); + control->handles[i].tid = avsys_gettid(); + *handle = i; + return AVSYS_STATE_SUCCESS; + } +} + +int avsys_audio_handle_free(int handle) +{ + long long int flag = 0x01; + avsys_audio_handle_info_t *control = NULL; + avsys_audio_handle_info_t **temp = NULL; + temp = &control; + + avsys_info(AVAUDIO, "handle=[%d]\n", handle); + + AVSYS_GET_SHM(temp,AVSYS_STATE_ERR_INTERNAL); + + flag <<= handle; + + AVSYS_LOCK_SYNC(); + if (control->allocated & flag) { /* find condition */ + control->allocated &= ~flag; + /* clear handle mute field */ + if (control->handle_amp & flag) { + control->handle_amp &= ~flag; + } + AVSYS_UNLOCK_SYNC(); + return AVSYS_STATE_SUCCESS; + } else { + AVSYS_UNLOCK_SYNC(); + return AVSYS_STATE_ERR_INVALID_VALUE; + } +} + +int avsys_audio_handle_get_ptr(int handle, avsys_audio_handle_t **ptr, const int mode) +{ + long long int flag = 0x01; + avsys_audio_handle_info_t *control = NULL; + avsys_audio_handle_info_t **temp = NULL; + int ret = AVSYS_STATE_SUCCESS; + + //avsys_info(AVAUDIO, "handle %d\n", handle); + + if (handle < 0 || handle >= AVSYS_AUDIO_HANDLE_MAX) { + *ptr = NULL; + return AVSYS_STATE_ERR_INVALID_HANDLE; + } + + if (mode < 0 || mode >= HANDLE_PTR_MODE_NUM) { + *ptr = NULL; + return AVSYS_STATE_ERR_INVALID_PARAMETER; + } + + temp = &control; + if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_HANDLE, (void **)temp))) { + avsys_error(AVAUDIO, "avsys_audio_get_shm() failed\n"); + *ptr = NULL; + return AVSYS_STATE_ERR_INTERNAL; + } + + flag <<= handle; + + if (mode == HANDLE_PTR_MODE_NORMAL) { + if (AVSYS_FAIL(avsys_audio_lock_sync(AVSYS_AUDIO_SYNC_IDEN_HANDLE))) { + avsys_error(AVAUDIO, "avsys_audio_lock_sync() failed\n"); + *ptr = NULL; + return AVSYS_STATE_ERR_INTERNAL; + } + } + + if (control->allocated & flag) { + //avsys_info(AVAUDIO, "input handle %d flag %x allocated %x\n", handle, flag, control->allocated); + *ptr = &(control->handles[handle]); + ret = AVSYS_STATE_SUCCESS; + } else { + *ptr = NULL; + ret = AVSYS_STATE_ERR_INVALID_VALUE; + } + + if (mode == HANDLE_PTR_MODE_NORMAL) { + if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_HANDLE))) { + avsys_error(AVAUDIO, "avsys_audio_unlock_sync() failed\n"); + *ptr = NULL; + return AVSYS_STATE_ERR_INTERNAL; + } + } + + return ret; +} + +int avsys_audio_handle_get_ptr_unlocked(int handle, avsys_audio_handle_t **ptr, const int mode) +{ + long long int flag = 0x01; + avsys_audio_handle_info_t *control = NULL; + avsys_audio_handle_info_t **temp = NULL; + int ret = AVSYS_STATE_SUCCESS; + + if (handle < 0 || handle >= AVSYS_AUDIO_HANDLE_MAX) { + *ptr = NULL; + return AVSYS_STATE_ERR_INVALID_HANDLE; + } + + if (mode < 0 || mode >= HANDLE_PTR_MODE_NUM) { + *ptr = NULL; + return AVSYS_STATE_ERR_INVALID_PARAMETER; + } + + temp = &control; + if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_HANDLE, (void **)temp))) { + avsys_error(AVAUDIO, "avsys_audio_get_shm() failed\n"); + *ptr = NULL; + return AVSYS_STATE_ERR_INTERNAL; + } + + flag <<= handle; + + if (control->allocated & flag) { + *ptr = &(control->handles[handle]); + ret = AVSYS_STATE_SUCCESS; + } else { + *ptr = NULL; + ret = AVSYS_STATE_ERR_INVALID_VALUE; + } + + return ret; +} + +int avsys_audio_handle_release_ptr(int handle, const int mode) +{ + long long int flag = 0x01; + avsys_audio_handle_info_t *control = NULL; + avsys_audio_handle_info_t **temp = NULL; + int ret = AVSYS_STATE_SUCCESS; + + //avsys_info(AVAUDIO, "handle %d\n", handle); + + if (handle < 0 || handle >= AVSYS_AUDIO_HANDLE_MAX) { + return AVSYS_STATE_ERR_INVALID_HANDLE; + } + + if (mode < 0 || mode >= HANDLE_PTR_MODE_NUM) { + return AVSYS_STATE_ERR_INVALID_PARAMETER; + } + + temp = &control; + AVSYS_GET_SHM(temp,AVSYS_STATE_ERR_INTERNAL); + + flag <<= handle; + + //avsys_info(AVAUDIO, "input handle %d flag %x allocated %x\n", handle, flag, control->allocated); + if (mode == HANDLE_PTR_MODE_NORMAL) { + AVSYS_LOCK_SYNC(); + } + + if (control->allocated & flag) { + ret = AVSYS_STATE_SUCCESS; + } else { + ret = AVSYS_STATE_ERR_INVALID_VALUE; + } + + if (mode == HANDLE_PTR_MODE_NORMAL) { + AVSYS_UNLOCK_SYNC(); + } + + return ret; +} + +int avsys_audio_handle_set_mute(int handle, int mute) +{ + long long int flag = 0x01; + int result = AVSYS_STATE_SUCCESS; + int path_mute = 0; + avsys_audio_handle_info_t *control = NULL; + avsys_audio_handle_info_t **temp = NULL; + avsys_audio_handle_t *ptr = NULL; + temp = &control; + + avsys_info(AVAUDIO, "handle=[%d], mute=[%d]\n", handle, mute); + if (mute > AVSYS_AUDIO_MUTE || mute < AVSYS_AUDIO_UNMUTE) { + avsys_error_r(AVAUDIO, "input parameter range error : mute %d\n", mute); + return AVSYS_STATE_ERR_INVALID_PARAMETER; + } + + AVSYS_GET_SHM(temp,AVSYS_STATE_ERR_INTERNAL); + + flag <<= handle; + + AVSYS_LOCK_SYNC(); + + if (control->allocated & flag) { /* find condition */ + /* update mute information for input handle parameter */ + ptr = &(control->handles[handle]); + ptr->mute = mute; + avsys_audio_pa_ctrl_set_mute(ptr->stream_index, (-1), AVSYS_AUDIO_DIRECTION_OUT, mute); + + /* update handle amp information */ + if (mute == AVSYS_AUDIO_UNMUTE) { +#ifdef _VERBOSE_ + if (control->handle_amp & flag) + avsys_warning(AVAUDIO, "handle 0x%x already powered\n"); + else + control->handle_amp |= flag; +#else + if (!(control->handle_amp & flag)) + control->handle_amp |= flag; +#endif + } else if (mute == AVSYS_AUDIO_MUTE) { + /* clear handle amp field */ + if (control->handle_amp & flag) + control->handle_amp &= ~flag; +#ifdef _VERBOSE_ + else + avsys_warning(AVAUDIO, "handle 0x%x already off\n"); +#endif + } + + /* reset fade */ + ptr->fadeup_vol = -1; + + result = AVSYS_STATE_SUCCESS; + } else { + avsys_warning(AVAUDIO, "handle %d does not allocated\n", handle); + if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_HANDLE))) { + avsys_error(AVAUDIO, "avsys_audio_unlock_sync() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + return AVSYS_STATE_ERR_INVALID_VALUE; + } + + if (control->handle_amp | control->ext_device_amp) + path_mute = AVSYS_AUDIO_UNMUTE; + else + path_mute = AVSYS_AUDIO_MUTE; + + AVSYS_UNLOCK_SYNC(); + + if (AVSYS_FAIL(avsys_audio_path_ex_set_mute(path_mute))) { + avsys_error_r(AVAUDIO, "Path mute control failed. %d\n", path_mute); + result = AVSYS_STATE_ERR_IO_CONTROL; + } + return result; +} + +int avsys_audio_handle_ext_dev_set_mute(avsysaudio_ext_device_t device_type, int mute) +{ + int bit = 0; + int result = AVSYS_STATE_SUCCESS; + int path_mute = 0; + avsys_audio_handle_info_t *control = NULL; + avsys_audio_handle_info_t **temp = NULL; + temp = &control; + + avsys_info(AVAUDIO, "%d_%d\n", (int)device_type, mute); + if (mute > AVSYS_AUDIO_MUTE || mute < AVSYS_AUDIO_UNMUTE) { + avsys_error_r(AVAUDIO, "input parameter range error : mute %d\n", mute); + return AVSYS_STATE_ERR_INVALID_PARAMETER; + } + + switch (device_type) { + case AVSYS_AUDIO_EXT_DEVICE_FMRADIO: + bit = AVSYS_AUDIO_HANDLE_EXT_DEV_FMRADIO; + break; + default: + avsys_error(AVAUDIO, "Unknown device type %d\n", (int)device_type); + return AVSYS_STATE_ERR_INVALID_PARAMETER; + } + + AVSYS_GET_SHM(temp,AVSYS_STATE_ERR_INTERNAL); + + AVSYS_LOCK_SYNC(); + + if (mute == AVSYS_AUDIO_MUTE) { + control->ext_device_amp |= bit; + } else { + control->ext_device_amp &= ~bit; + } + + if (control->handle_amp | control->ext_device_amp) + path_mute = AVSYS_AUDIO_UNMUTE; + else + path_mute = AVSYS_AUDIO_MUTE; + + AVSYS_UNLOCK_SYNC(); + + if (AVSYS_FAIL(avsys_audio_path_ex_set_mute(path_mute))) { + avsys_error_r(AVAUDIO, "Path mute control failed. %d\n", path_mute); + result = AVSYS_STATE_ERR_IO_CONTROL; + } + return result; +} + +int avsys_audio_handle_ext_dev_status(avsysaudio_ext_device_t device_type, int *onoff) +{ + int result = AVSYS_STATE_SUCCESS; + int ext_dev_state = 0; + + avsys_audio_handle_info_t *control = NULL; + avsys_audio_handle_info_t **temp = NULL; + temp = &control; + + avsys_info(AVAUDIO, "\n"); + + if (onoff == NULL) { + avsys_error(AVAUDIO, "Null pointer input parameter\n"); + return AVSYS_STATE_ERR_NULL_POINTER; + } + + AVSYS_GET_SHM(temp,AVSYS_STATE_ERR_INTERNAL); + + AVSYS_LOCK_SYNC(); + + switch (device_type) { + case AVSYS_AUDIO_EXT_DEVICE_FMRADIO: + if (control->ext_device_status & AVSYS_AUDIO_HANDLE_EXT_DEV_FMRADIO) { + ext_dev_state = 1; + } else { + ext_dev_state = 0; + } + *onoff = ext_dev_state; + break; + default: + avsys_error(AVAUDIO, "Invalid device type %d\n", device_type); + result = AVSYS_STATE_ERR_INTERNAL; + break; + } + + AVSYS_UNLOCK_SYNC(); + return result; +} + +int avsys_audio_handle_ext_dev_status_update(avsysaudio_ext_device_t device_type, int onoff) +{ + int bit = 0; + int result = AVSYS_STATE_SUCCESS; + avsys_audio_handle_info_t *control = NULL; + avsys_audio_handle_info_t **temp = NULL; + temp = &control; + + avsys_info(AVAUDIO, "%d_%d\n", (int)device_type, onoff); + + switch (device_type) { + case AVSYS_AUDIO_EXT_DEVICE_FMRADIO: + bit = AVSYS_AUDIO_HANDLE_EXT_DEV_FMRADIO; + break; + default: + avsys_error(AVAUDIO, "Unknown device type %d\n", (int)device_type); + return AVSYS_STATE_ERR_INVALID_PARAMETER; + } + + AVSYS_GET_SHM(temp,AVSYS_STATE_ERR_INTERNAL); + + AVSYS_LOCK_SYNC(); + + if (onoff > 0) { + control->ext_device_status |= bit; + } else if (onoff == 0) { + control->ext_device_status &= ~bit; + } else { + avsys_error(AVAUDIO, "Unknown parameter %d. To nothing\n", onoff); + } + + AVSYS_UNLOCK_SYNC(); + return result; +} + +int avsys_audio_handle_current_playing_volume_type(int *type) +{ + int result = AVSYS_STATE_SUCCESS; + int i = 0; + char used_table[AVSYS_AUDIO_VOLUME_TYPE_MAX] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + char capture_used = 0; + avsys_audio_handle_info_t *control = NULL; + avsys_audio_handle_info_t **temp = NULL; + temp = &control; + + result = avsys_audio_handle_rejuvenation(); + if (AVSYS_FAIL(result)) { + avsys_warning(AVAUDIO, "avsys_audio_handle_rejuvenation() failed, ret = %d\n", result); + } + + AVSYS_GET_SHM(temp,AVSYS_STATE_ERR_INTERNAL); + + AVSYS_LOCK_SYNC(); + + for (i = 0; i < AVSYS_AUDIO_HANDLE_MAX; i++) { + long long int flag = 0x01; + flag <<= i; + if (control->allocated & flag) { + int vol_conf_type = AVSYS_AUDIO_VOLUME_CONFIG_TYPE(control->handles[i].gain_setting.volume_config); + if(control->handles[i].mode == AVSYS_AUDIO_MODE_OUTPUT || + control->handles[i].mode == AVSYS_AUDIO_MODE_OUTPUT_CLOCK || + control->handles[i].mode == AVSYS_AUDIO_MODE_OUTPUT_VIDEO || + control->handles[i].mode == AVSYS_AUDIO_MODE_OUTPUT_LOW_LATENCY ) { + if(control->handles[i].corked != true) + used_table[vol_conf_type] = 1; + } + else if(control->handles[i].mode == AVSYS_AUDIO_MODE_INPUT || + control->handles[i].mode == AVSYS_AUDIO_MODE_INPUT_HIGH_LATENCY || + control->handles[i].mode == AVSYS_AUDIO_MODE_INPUT_LOW_LATENCY) { + capture_used = 1; + } + } + } + if (control->ext_device_status & AVSYS_AUDIO_HANDLE_EXT_DEV_FMRADIO) { + used_table[AVSYS_AUDIO_VOLUME_TYPE_MEDIA] = 1; + } + + avsys_warning(AVAUDIO,"Call[%d] VOIP[%d] Ringtone[%d] Media[%d] S-Voice[%d] Alarm[%d] Notification[%d] System[%d] Android[%d] Java[%d] Capture[%d]\n", + used_table[AVSYS_AUDIO_VOLUME_TYPE_CALL], + used_table[AVSYS_AUDIO_VOLUME_TYPE_VOIP], + used_table[AVSYS_AUDIO_VOLUME_TYPE_RINGTONE], + used_table[AVSYS_AUDIO_VOLUME_TYPE_MEDIA], + used_table[AVSYS_AUDIO_VOLUME_TYPE_SVOICE], + used_table[AVSYS_AUDIO_VOLUME_TYPE_ALARM], + used_table[AVSYS_AUDIO_VOLUME_TYPE_NOTIFICATION], + used_table[AVSYS_AUDIO_VOLUME_TYPE_SYSTEM], + used_table[AVSYS_AUDIO_VOLUME_TYPE_EXT_SYSTEM_ANDROID], + used_table[AVSYS_AUDIO_VOLUME_TYPE_EXT_SYSTEM_JAVA], + capture_used); + + if (control->primary_volume_pid > 2 && AVSYS_FAIL(avsys_check_process(control->primary_volume_pid))) { + avsys_warning(AVAUDIO, "Primary volume set pid does not exist anymore. clean primary volume\n"); + control->primary_volume_type = -1; + control->primary_volume_pid = 0; + } + + if (control->primary_volume_type != -1) { + *type = control->primary_volume_type; + avsys_warning(AVAUDIO, "Primary volume is %d\n", control->primary_volume_type); + } else if (used_table[AVSYS_AUDIO_VOLUME_TYPE_CALL]) { + *type = AVSYS_AUDIO_VOLUME_TYPE_CALL; + } else if (used_table[AVSYS_AUDIO_VOLUME_TYPE_VOIP]) { + *type = AVSYS_AUDIO_VOLUME_TYPE_VOIP; + } else if (used_table[AVSYS_AUDIO_VOLUME_TYPE_RINGTONE]) { + *type = AVSYS_AUDIO_VOLUME_TYPE_RINGTONE; + } else if (used_table[AVSYS_AUDIO_VOLUME_TYPE_MEDIA]) { + *type = AVSYS_AUDIO_VOLUME_TYPE_MEDIA; + } else if (used_table[AVSYS_AUDIO_VOLUME_TYPE_SVOICE]) { + *type = AVSYS_AUDIO_VOLUME_TYPE_SVOICE; + } else if (used_table[AVSYS_AUDIO_VOLUME_TYPE_ALARM]) { + *type = AVSYS_AUDIO_VOLUME_TYPE_ALARM; + } else if (used_table[AVSYS_AUDIO_VOLUME_TYPE_NOTIFICATION]) { + *type = AVSYS_AUDIO_VOLUME_TYPE_NOTIFICATION; + } else if (used_table[AVSYS_AUDIO_VOLUME_TYPE_SYSTEM]) { + *type = AVSYS_AUDIO_VOLUME_TYPE_SYSTEM; + } else if (used_table[AVSYS_AUDIO_VOLUME_TYPE_EXT_SYSTEM_JAVA]) { + *type = AVSYS_AUDIO_VOLUME_TYPE_EXT_SYSTEM_JAVA; + } else if (capture_used) { + /* No Playing instance just capture only. */ + result = AVSYS_STATE_ERR_INVALID_MODE; + avsys_error(AVAUDIO, "Capture handle only...\n"); + } else { + /* not playing */ + result = AVSYS_STATE_ERR_ALLOCATION; + avsys_error(AVAUDIO, "There is no running handles...\n"); + } + + AVSYS_UNLOCK_SYNC(); + + return result; +} + +int avsys_audio_handle_get_mute_all_status(avsys_audio_handle_t *p) +{ + int result = AVSYS_STATE_SUCCESS; + avsys_audio_handle_info_t *control = NULL; + avsys_audio_handle_info_t **temp = NULL; + + temp = &control; + AVSYS_GET_SHM(temp,AVSYS_STATE_ERR_INTERNAL); + + AVSYS_LOCK_SYNC(); + + result = control->mute_all; + + AVSYS_UNLOCK_SYNC(); + + return result; +} + +int avsys_audio_handle_update_mute_all(int onoff) +{ + int i; + int mute = AVSYS_AUDIO_UNMUTE; + int result = AVSYS_STATE_SUCCESS; + avsys_audio_handle_info_t *control = NULL; + avsys_audio_handle_info_t **temp = NULL; + avsys_audio_handle_t *ptr = NULL; + temp = &control; + + avsys_info(AVAUDIO, "\n"); + AVSYS_GET_SHM(temp,AVSYS_STATE_ERR_INTERNAL); + + AVSYS_LOCK_SYNC(); + + control->mute_all = onoff; + AVSYS_UNLOCK_SYNC(); + + avsys_info(AVAUDIO, "avsys_audio_handle_update_mute_all control->mute_all=%d",control->mute_all); + return result; +} + +int avsys_audio_handle_set_primary_volume_type(const int pid, const int type, const int command) +{ + int result = AVSYS_STATE_SUCCESS; + avsys_audio_handle_info_t *control = NULL; + avsys_audio_handle_info_t **temp = NULL; + temp = &control; + + avsys_info(AVAUDIO, "\n"); + if (type < AVSYS_AUDIO_VOLUME_TYPE_SYSTEM || type >= AVSYS_AUDIO_VOLUME_TYPE_MAX || type == AVSYS_AUDIO_VOLUME_TYPE_FIXED) { + avsys_error(AVAUDIO, "Invalid primary type primary type\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + + AVSYS_GET_SHM(temp,AVSYS_STATE_ERR_INTERNAL); + + AVSYS_LOCK_SYNC(); + + if (command == AVSYS_AUDIO_PRIMARY_VOLUME_SET) { + if (control->primary_volume_type != -1) { + avsys_warning(AVAUDIO,"Previous primary volume set by %d to %d\n", + control->primary_volume_pid, + control->primary_volume_type + ); + } + avsys_warning(AVAUDIO, "Primary Volume Type Set to %d [%d]\n", type, pid); + control->primary_volume_pid = pid; + control->primary_volume_type = type; + } else if (command == AVSYS_AUDIO_PRIMARY_VOLUME_CLEAR) { + if (pid != control->primary_volume_pid) { + avsys_error(AVAUDIO, "Primary volume set api pair is not matched [%d] [%d]\n", control->primary_volume_pid, pid); + } else { + avsys_warning(AVAUDIO, "Primary Volume Type Clear [%d]\n", pid); + control->primary_volume_pid = 0; + control->primary_volume_type = -1; + } + } else { + avsys_error(AVAUDIO, "Unknown Parameter : %d\n", command); + result = AVSYS_STATE_ERR_INVALID_PARAMETER; + } + + AVSYS_UNLOCK_SYNC(); + + return result; +} + +static int __avsys_audio_handle_is_output_mode(int mode) +{ + if (mode == AVSYS_AUDIO_MODE_OUTPUT || mode == AVSYS_AUDIO_MODE_OUTPUT_CLOCK || + mode == AVSYS_AUDIO_MODE_OUTPUT_LOW_LATENCY || mode == AVSYS_AUDIO_MODE_OUTPUT_AP_CALL || + mode == AVSYS_AUDIO_MODE_OUTPUT_VIDEO) + return 1; + else + return 0; +} + +int avsys_audio_handle_update_priority(int handle, int priority, int handle_route, int cmd) +{ + long long int flag = 0x01; + int i = 0; + char high_priority_exist = 0; + char transition_effect = 0; + int lpriority = AVSYS_AUDIO_HANDLE_PRIORITY_TYPE_0; + avsys_audio_handle_info_t *control = NULL; + avsys_audio_handle_info_t **temp = NULL; + + temp = &control; + + if (cmd < AVSYS_AUDIO_SET_PRIORITY || cmd > AVSYS_AUDIO_UNSET_PRIORITY) { + avsys_error_r(AVAUDIO, "Invalid command\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + + if (priority >= AVSYS_AUDIO_HANDLE_PRIORITY_TYPE_MAX || priority < AVSYS_AUDIO_HANDLE_PRIORITY_TYPE_0) { + avsys_error(AVAUDIO, "input parameter range error : priority %d. set lowest\n", priority); + lpriority = AVSYS_AUDIO_HANDLE_PRIORITY_TYPE_0; + } else { + lpriority = priority; + } + + AVSYS_GET_SHM(temp,AVSYS_STATE_ERR_INTERNAL); + + flag <<= handle; + + AVSYS_LOCK_SYNC(); + + if (control->allocated & flag) { /* find condition */ + /* update for allocated handle */ + if (cmd == AVSYS_AUDIO_SET_PRIORITY) { + control->handle_priority[handle] = lpriority; + } else if (cmd == AVSYS_AUDIO_UNSET_PRIORITY) { + control->handle_priority[handle] = AVSYS_AUDIO_HANDLE_PRIORITY_TYPE_0; + if (lpriority == AVSYS_AUDIO_HANDLE_PRIORITY_TYPE_2) { /* unset with priority 2 */ + transition_effect = 0; /* FIXME : Disable transition effect for now */ + } + } + } else { + avsys_warning(AVAUDIO, "handle %d does not allocated\n", handle); + AVSYS_UNLOCK_SYNC(); + return AVSYS_STATE_ERR_INVALID_VALUE; + } + + for (i = 0; i < AVSYS_AUDIO_HANDLE_MAX; i++) { + if (control->handle_priority[i] == AVSYS_AUDIO_HANDLE_PRIORITY_TYPE_1) { + high_priority_exist = 1; + } else if (control->handle_priority[i] == AVSYS_AUDIO_HANDLE_PRIORITY_TYPE_2) { + high_priority_exist = 1; + transition_effect = 0; /* FIXME : Disable transition effect for now */ + } + } + + for (i = 0; i < AVSYS_AUDIO_HANDLE_MAX; i++) { + flag = 0x01; + flag <<= i; + if (!(control->allocated & flag)) + continue; + + if (control->handles[i].stream_index == 0 || __avsys_audio_handle_is_output_mode(control->handles[i].mode) == 0) { + /* skip mono sink-input & source-output */ + continue; + } + + if (control->handle_priority[i] == AVSYS_AUDIO_HANDLE_PRIORITY_TYPE_0) { + + if (high_priority_exist || ((handle == i) && (cmd == AVSYS_AUDIO_UNSET_PRIORITY))) { /* mute */ + if (transition_effect) { + /* set fade out */ + avsys_audio_pa_ctrl_get_volume_level(control->handles[i].stream_index, (-1), &control->handles[i].fadeup_vol_current); + control->handles[i].fadeup_vol = 0; + control->handles[i].fadeup_multiplier = 0; + } else { + /* mute immediately */ + if (AVSYS_FAIL(avsys_audio_pa_ctrl_set_mute(control->handles[i].stream_index, (-1), AVSYS_AUDIO_DIRECTION_OUT, AVSYS_AUDIO_MUTE))) { + avsys_error(AVAUDIO, "set sink input mute for %d failed\n", control->handles[i].stream_index); + } else { + avsys_debug(AVAUDIO, "set sink input mute for %d success\n", control->handles[i].stream_index); + } + control->handles[i].mute = AVSYS_AUDIO_PRIORITY_MUTE; + } + } else { /* unmute */ + if (transition_effect) { + /* set fade in */ + avsys_audio_pa_ctrl_get_volume_level(control->handles[i].stream_index, (-1), &control->handles[i].fadeup_vol); + control->handles[i].fadeup_vol_current = 0; + control->handles[i].fadeup_multiplier = 0; + } else { + /* unmute immediately */ + if (control->handles[i].mute == AVSYS_AUDIO_PRIORITY_MUTE) { + if (AVSYS_FAIL(avsys_audio_pa_ctrl_set_mute(control->handles[i].stream_index, (-1), AVSYS_AUDIO_DIRECTION_OUT, AVSYS_AUDIO_UNMUTE))) { + avsys_error(AVAUDIO, "set sink input unmute for %d failed\n", control->handles[i].stream_index); + } else { + avsys_debug(AVAUDIO, "set sink input unmute for %d success\n", control->handles[i].stream_index); + } + control->handles[i].mute = AVSYS_AUDIO_PRIORITY_UNMUTE; + } + } + } + + } else if (control->handle_priority[i] == AVSYS_AUDIO_HANDLE_PRIORITY_TYPE_3) { + /* do nothing, always mix with others, no effect */ + avsys_warning(AVAUDIO, "mix with others for %d\n", control->handles[i].stream_index); + } + } + + AVSYS_UNLOCK_SYNC(); + + if (transition_effect) + sleep(1); + else if (!transition_effect && high_priority_exist) + usleep(20); + + return AVSYS_STATE_SUCCESS; +} + +int avsys_audio_handle_current_capture_status(int *on_capture) +{ + int i = 0; + char capture_used = 0; + avsys_audio_handle_info_t *control = NULL; + avsys_audio_handle_info_t **temp = NULL; + + if (!on_capture) + return AVSYS_STATE_ERR_INVALID_PARAMETER; + + temp = &control; + + AVSYS_GET_SHM(temp,AVSYS_STATE_ERR_INTERNAL); + + AVSYS_LOCK_SYNC(); + + for (i = 0; i < AVSYS_AUDIO_HANDLE_MAX; i++) { + long long int flag = 0x01; + flag <<= i; + if (control->allocated & flag) { + if(control->handles[i].mode == AVSYS_AUDIO_MODE_INPUT || + control->handles[i].mode == AVSYS_AUDIO_MODE_INPUT_HIGH_LATENCY || + control->handles[i].mode == AVSYS_AUDIO_MODE_INPUT_LOW_LATENCY || + control->handles[i].mode == AVSYS_AUDIO_MODE_INPUT_AP_CALL) { + capture_used = 1; + break; + } + } + } + if (capture_used) { + avsys_info(AVAUDIO, "Audio capture is running\n"); + *on_capture = 1; + } else { + *on_capture = 0; + } + + AVSYS_UNLOCK_SYNC(); + + return AVSYS_STATE_SUCCESS; +} diff --git a/avsys-audio-pactrl.c b/avsys-audio-pactrl.c new file mode 100644 index 0000000..b8f623d --- /dev/null +++ b/avsys-audio-pactrl.c @@ -0,0 +1,2191 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi + * + * 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 +#include + +#include "avsys-audio-pactrl.h" +#include "avsys-debug.h" +#include + +enum { + AVSYS_PA_CTL_CMD_GET_VOLUME_LEVEL_MAX, + AVSYS_PA_CTL_CMD_GET_VOLUME_LEVEL, + AVSYS_PA_CTL_CMD_SET_VOLUME_LEVEL, + AVSYS_PA_CTL_CMD_GET_MUTE, + AVSYS_PA_CTL_CMD_SET_MUTE, + AVSYS_PA_CTL_CMD_GET_SINK_INFO, + AVSYS_PA_CTL_CMD_GET_DEFAULT_SINK, + AVSYS_PA_CTL_CMD_SUSPEND_SINK, + AVSYS_PA_CTL_CMD_LOAD_AECLOOPBACK_MODULE, + AVSYS_PA_CTL_CMD_UNLOAD_AECLOOPBACK_MODULE, + AVSYS_PA_CTL_CMD_SET_INFO, + AVSYS_PA_CTL_CMD_UPDATE_SCN, + AVSYS_PA_CTL_CMD_LOAD_LOOPBACK_MODULE, + AVSYS_PA_CTL_CMD_UNLOAD_LOOPBACK_MODULE, + AVSYS_PA_CTL_CMD_IS_AVAILABLE_HIGH_LATENCY, + AVSYS_PA_CTL_CMD_VSP_SPEED, + AVSYS_PA_CTL_CMD_SOUNDALIVE_FILTER_ACTION, + AVSYS_PA_CTL_CMD_SOUNDALIVE_PRESET_MODE, + AVSYS_PA_CTL_CMD_SOUNDALIVE_EQ, + AVSYS_PA_CTL_CMD_SOUNDALIVE_EXT, + AVSYS_PA_CTL_CMD_SOUNDALIVE_DEVICE, + AVSYS_PA_CTL_CMD_DHA, + AVSYS_PA_CTL_CMD_CORK_ALL, + AVSYS_PA_CTL_CMD_UNCORK_ALL, + AVSYS_PA_CTL_CMD_MAX, +}; + +#define EQ_MAX_NUM 7 +#define EXT_MAX_NUM 5 +#define DHA_MAX_NUM 12 + +typedef struct avsys_pa_ctrl_info { + pa_threaded_mainloop *m; + pa_operation *o; + int cmd; + int mute; + int idx; + int type; + int vol; + int ch; + int res; + int info; + int filter_action; + int preset_mode; + int eq[EQ_MAX_NUM]; + int ext[EXT_MAX_NUM]; + int dha_onoff; + int dha_gain[DHA_MAX_NUM]; + int dev; + int speed; + char *sink_name; + int suspend; +} avsys_pa_ctrl_info_t; + +typedef struct avsys_pa_ctrl_loadmodule_info { + int aec_module_idx; + int aec_init; + int aecloopback_module_idx; + int aecloopback_init; + int loopback_module_idx; + int loopback_init; +} avsys_pa_ctrl_loadmodule_info_t; + +static avsys_pa_ctrl_loadmodule_info_t loadmodule_info = {PA_INVALID_INDEX,0,PA_INVALID_INDEX,0, PA_INVALID_INDEX,0}; + +static void __avsys_audio_pa_ctrl_success_cb(pa_context *c, int success, void *userdata) +{ + pa_threaded_mainloop *mainloop = (pa_threaded_mainloop *)userdata; + avsys_assert_r(c); + avsys_assert_r(mainloop); + + if (!success) { + avsys_error(AVAUDIO, "pa control failed: %s\n", pa_strerror(pa_context_errno(c))); + } else { + avsys_debug(AVAUDIO, "pa control success\n"); + } + pa_threaded_mainloop_signal(mainloop, 0); +} + +static void __avsys_audio_pa_ctrl_get_sink_info_cb(pa_context *c, const pa_sink_info *i, int is_last, void *userdata) +{ + avsys_pa_ctrl_info_t *info = NULL; + avsys_assert_r(userdata); + info = (avsys_pa_ctrl_info_t *)userdata; + int sink_state; + int sink_name; + + if (is_last < 0) { + avsys_error(AVAUDIO, "Failed to get sink information: %s", pa_strerror(pa_context_errno(c))); + return; + } + + if (is_last) { + pa_threaded_mainloop_signal(info->m, 0); + return; + } + + avsys_assert_r(i); + + if (!strncmp(i->name, "alsa_", 4)) { + sink_name = ALSA_SINK; + } else if (!strncmp(i->name, "bluez", 5)) { + sink_name = BLUEZ_SINK; + } else { + return; + } + + switch (i->state) { + case PA_SINK_RUNNING: + sink_state = _ACTIVE; + break; + case PA_SINK_IDLE: + case PA_SINK_SUSPENDED: + sink_state = _DEACTIVE; + break; + default: + sink_state = _EXIST; + break; + } + + info->res |= ((1 << (sink_state + sink_name))); +} + +static void __avsys_audio_pa_ctrl_unload_success_cb(pa_context *c, int success, void *userdata) +{ + avsys_pa_ctrl_info_t *info = NULL; + avsys_assert_r(userdata); + info = (avsys_pa_ctrl_info_t *)userdata; + + if (!success) { + avsys_error(AVAUDIO, "pa control unloadmodule failed\n"); + } else { + avsys_info(AVAUDIO, "pa control unloadmodule success\n"); + } + pa_threaded_mainloop_signal(info->m, 0); +} + +static void __avsys_audio_pa_ctrl_unloadmodule_success_cb(pa_context *c, int success, void *userdata) +{ + avsys_pa_ctrl_info_t *info = NULL; + avsys_assert_r(userdata); + info = (avsys_pa_ctrl_info_t *)userdata; + + if (!success) { + avsys_error(AVAUDIO, "pa control unloadmodule failed\n"); + } else { + avsys_info(AVAUDIO, "pa control unloadmodule success\n"); + } + if (loadmodule_info.aec_module_idx != PA_INVALID_INDEX) { + /* UnLoad AEC Module */ + pa_operation_unref(pa_context_unload_module(c, loadmodule_info.aec_module_idx, __avsys_audio_pa_ctrl_unload_success_cb, (void*)info)); + loadmodule_info.aec_module_idx = PA_INVALID_INDEX; + loadmodule_info.aec_init = 0; + } +} + +static void __avsys_audio_pa_ctrl_get_server_info_cb(pa_context *c, const pa_server_info *i, void *userdata) +{ + avsys_pa_ctrl_info_t *info = NULL; + avsys_assert_r(userdata); + info = (avsys_pa_ctrl_info_t *)userdata; + + if (!i) { + info->res = AVSYS_AUDIO_PA_CTL_SINK_UNKNOWN; + } else { + if (strstr(i->default_sink_name, "alsa_")) + info->res = AVSYS_AUDIO_PA_CTL_SINK_ALSA; + else if (strstr(i->default_sink_name, "bluez")) + info->res = AVSYS_AUDIO_PA_CTL_SINK_BLUEZ; + else + info->res = AVSYS_AUDIO_PA_CTL_SINK_UNKNOWN; + } + pa_threaded_mainloop_signal(info->m, 0); +} + +static void __avsys_audio_pa_ctrl_aec_loopback_index_callback(pa_context *c, uint32_t idx, void *userdata) +{ + avsys_pa_ctrl_info_t *info = NULL; + avsys_assert_r(userdata); + info = (avsys_pa_ctrl_info_t *)userdata; + + if (idx == PA_INVALID_INDEX) { + avsys_error(AVAUDIO, "Failure: %s", pa_strerror(pa_context_errno(c))); + return; + } + avsys_info (AVAUDIO, "aecloopback module index = %d",idx); + loadmodule_info.aecloopback_module_idx = idx; + + pa_threaded_mainloop_signal(info->m, 0); +} + +static void __avsys_audio_pa_ctrl_index_callback(pa_context *c, uint32_t idx, void *userdata) +{ + avsys_pa_ctrl_info_t *info = NULL; + avsys_assert_r(userdata); + info = (avsys_pa_ctrl_info_t *)userdata; + + if (idx == PA_INVALID_INDEX) { + avsys_error(AVAUDIO, "Failure: %s", pa_strerror(pa_context_errno(c))); + return; + } + + if (info->cmd == AVSYS_PA_CTL_CMD_LOAD_AECLOOPBACK_MODULE) { + avsys_info (AVAUDIO, "aecloopback module index = %d",idx); + loadmodule_info.aec_module_idx = idx; + + if(loadmodule_info.aecloopback_module_idx == PA_INVALID_INDEX) { + /* Load module-loopback */ + pa_operation_unref(pa_context_load_module(c, "module-loopback", "source=alsa_output.0.analog-stereo.monitor sink=null.echo-cancel", __avsys_audio_pa_ctrl_aec_loopback_index_callback, (void*)info)); + }else { + avsys_info (AVAUDIO, "aecloopback module is already loaded"); + } + } else if (info->cmd == AVSYS_PA_CTL_CMD_LOAD_LOOPBACK_MODULE) { + avsys_info (AVAUDIO, "loopback module index = %d",idx); + loadmodule_info.loopback_module_idx = idx; + + pa_threaded_mainloop_signal(info->m, 0); + } +} + +static void __avsys_audio_pa_ctrl_get_volume_level_max_cb(pa_context *c, uint32_t volume_level, void *userdata) +{ + avsys_pa_ctrl_info_t *info = (avsys_pa_ctrl_info_t *)userdata; + pa_threaded_mainloop *mainloop; + + avsys_assert_r(c); + avsys_assert_r(userdata); + + mainloop = (pa_threaded_mainloop *)info->m; + info->vol = (int)volume_level; + pa_threaded_mainloop_signal(mainloop, 0); +} + +static void __avsys_audio_pa_ctrl_get_volume_level_cb(pa_context *c, uint32_t volume_level, void *userdata) +{ + avsys_pa_ctrl_info_t *info = (avsys_pa_ctrl_info_t *)userdata; + pa_threaded_mainloop *mainloop; + + avsys_assert_r(c); + avsys_assert_r(userdata); + + mainloop = (pa_threaded_mainloop *)info->m; + info->vol = (int)volume_level; + pa_threaded_mainloop_signal(mainloop, 0); +} + +static void __avsys_audio_pa_ctrl_get_mute_cb(pa_context *c, uint32_t mute, void *userdata) +{ + avsys_pa_ctrl_info_t *info = (avsys_pa_ctrl_info_t *)userdata; + pa_threaded_mainloop *mainloop; + + avsys_assert_r(c); + avsys_assert_r(userdata); + + mainloop = (pa_threaded_mainloop *)info->m; + info->mute = (int)mute; + pa_threaded_mainloop_signal(mainloop, 0); +} + +static void __avsys_audio_pa_ctrl_is_available_high_latency_cb(pa_context *c, uint32_t available, void *userdata) +{ + avsys_pa_ctrl_info_t *info = (avsys_pa_ctrl_info_t *)userdata; + pa_threaded_mainloop *mainloop; + + avsys_assert_r(c); + avsys_assert_r(userdata); + + mainloop = (pa_threaded_mainloop *)info->m; + info->res = (int)available; + pa_threaded_mainloop_signal(mainloop, 0); +} + +static void __avsys_audio_pa_ctrl_cork_success_cb(pa_context *c, int success, void *userdata) +{ + pa_threaded_mainloop *mainloop = (pa_threaded_mainloop *)userdata; + avsys_assert_r(c); + avsys_assert_r(mainloop); + + if (!success) { + avsys_error(AVAUDIO, "pa control failed: %s\n", pa_strerror(pa_context_errno(c))); + } else { + avsys_debug(AVAUDIO, "pa control success\n"); + } + pa_threaded_mainloop_signal(mainloop, 0); +} + +static void __avsys_audio_pa_ctrl_state_cb(pa_context *c, void *userdata) +{ + pa_cvolume cv; + avsys_pa_ctrl_info_t *info = NULL; + + avsys_assert_r(c); + info = (avsys_pa_ctrl_info_t *)userdata; + avsys_assert_r(info); + avsys_assert_r(info->m); + + switch (pa_context_get_state(c)) { + case PA_CONTEXT_READY: + if (info->cmd == AVSYS_PA_CTL_CMD_GET_VOLUME_LEVEL_MAX) { + info->o = pa_ext_policy_get_volume_level_max(c, (uint32_t)info->type, __avsys_audio_pa_ctrl_get_volume_level_max_cb, (void *)info); + } else if (info->cmd == AVSYS_PA_CTL_CMD_GET_VOLUME_LEVEL) { + info->o = pa_ext_policy_get_volume_level(c, (uint32_t)info->idx, (uint32_t)info->type, __avsys_audio_pa_ctrl_get_volume_level_cb, (void *)info); + } else if (info->cmd == AVSYS_PA_CTL_CMD_SET_VOLUME_LEVEL) { + info->o = pa_ext_policy_set_volume_level(c, (uint32_t)info->idx, (uint32_t)info->type, (uint32_t)info->vol, __avsys_audio_pa_ctrl_success_cb, (void *)info->m); + } else if (info->cmd == AVSYS_PA_CTL_CMD_GET_MUTE) { + info->o = pa_ext_policy_get_mute(c, (uint32_t)info->idx, (uint32_t)info->type, (uint32_t)info->ch, __avsys_audio_pa_ctrl_get_mute_cb, (void *)info); + } else if (info->cmd == AVSYS_PA_CTL_CMD_SET_MUTE) { + info->o = pa_ext_policy_set_mute(c, (uint32_t)info->idx, (uint32_t)info->type, (uint32_t)info->ch, (uint32_t)info->mute, __avsys_audio_pa_ctrl_success_cb, (void *)info->m); + } else if (info->cmd == AVSYS_PA_CTL_CMD_GET_SINK_INFO) { + info->o = pa_context_get_sink_info_list(c, __avsys_audio_pa_ctrl_get_sink_info_cb, (void *)info); + } else if (info->cmd == AVSYS_PA_CTL_CMD_GET_DEFAULT_SINK) { + info->o = pa_context_get_server_info(c, __avsys_audio_pa_ctrl_get_server_info_cb, (void *)info); + } else if (info->cmd == AVSYS_PA_CTL_CMD_SUSPEND_SINK) { + avsys_info(AVAUDIO, "suspend (%d) sink: %s",info->suspend, info->sink_name); + info->o = pa_context_suspend_sink_by_name(c, info->sink_name, info->suspend, __avsys_audio_pa_ctrl_success_cb, (void *)info->m); + } else if (info->cmd == AVSYS_PA_CTL_CMD_SET_INFO) { + info->o = pa_ext_suspend_on_idle_set_info (c, info->info, __avsys_audio_pa_ctrl_success_cb, (void *)info->m); + } else if (info->cmd == AVSYS_PA_CTL_CMD_UPDATE_SCN) { + info->o = pa_ext_suspend_on_idle_update_scn (c, __avsys_audio_pa_ctrl_success_cb, (void *)info->m); + } else if (info->cmd == AVSYS_PA_CTL_CMD_LOAD_AECLOOPBACK_MODULE && loadmodule_info.aec_module_idx == PA_INVALID_INDEX) { + /* Load AEC Module */ + avsys_info (AVAUDIO, "Echo cancel module will be loaded,loadmodule_info.aec_module_idx =%d ",loadmodule_info.aec_module_idx); + info->o = pa_context_load_module(c, "module-echo-cancel", "aec_method=lvvefs sink_master=null", __avsys_audio_pa_ctrl_index_callback, (void *)info); + } else if (info->cmd == AVSYS_PA_CTL_CMD_UNLOAD_AECLOOPBACK_MODULE && loadmodule_info.aecloopback_module_idx != PA_INVALID_INDEX) { + /* UnLoad loopback module */ + info->o = pa_context_unload_module(c, loadmodule_info.aecloopback_module_idx, __avsys_audio_pa_ctrl_unloadmodule_success_cb, info); + avsys_info (AVAUDIO, "UnLoad module-loopback info->aecloopback_module_idx = %d",loadmodule_info.aecloopback_module_idx); + loadmodule_info.aecloopback_module_idx = PA_INVALID_INDEX; + loadmodule_info.aecloopback_init = 0; + } else if (info->cmd == AVSYS_PA_CTL_CMD_LOAD_LOOPBACK_MODULE && loadmodule_info.loopback_module_idx == PA_INVALID_INDEX) { + /* Load Loopback Module */ + avsys_info (AVAUDIO, "Loopback module will be loaded,loadmodule_info.loopback_module_idx =%d ",loadmodule_info.loopback_module_idx); + info->o = pa_context_load_module(c, "module-loopback", "latency_msec=500", __avsys_audio_pa_ctrl_index_callback, (void *)info); + } else if (info->cmd == AVSYS_PA_CTL_CMD_UNLOAD_LOOPBACK_MODULE && loadmodule_info.loopback_module_idx != PA_INVALID_INDEX) { + /* UnLoad loopback module */ + info->o = pa_context_unload_module(c, loadmodule_info.loopback_module_idx, __avsys_audio_pa_ctrl_unload_success_cb, info); + avsys_info (AVAUDIO, "UnLoad module-loopback info->loopback_module_idx = %d",loadmodule_info.loopback_module_idx); + loadmodule_info.loopback_module_idx = PA_INVALID_INDEX; + loadmodule_info.loopback_init = 0; + } else if (info->cmd == AVSYS_PA_CTL_CMD_IS_AVAILABLE_HIGH_LATENCY) { + info->o = pa_ext_policy_is_available_high_latency(c, __avsys_audio_pa_ctrl_is_available_high_latency_cb, (void *)info); + } else if (info->cmd == AVSYS_PA_CTL_CMD_VSP_SPEED) { + info->o = pa_ext_policy_vsp_set_speed(c, info->idx, info->speed, __avsys_audio_pa_ctrl_success_cb, (void *)info->m); + } else if (info->cmd == AVSYS_PA_CTL_CMD_SOUNDALIVE_FILTER_ACTION) { + info->o = pa_ext_policy_sa_set_filter_action(c, info->idx, info->filter_action, __avsys_audio_pa_ctrl_success_cb, (void *)info->m); + } else if (info->cmd == AVSYS_PA_CTL_CMD_SOUNDALIVE_PRESET_MODE) { + info->o = pa_ext_policy_sa_set_preset_mode(c, info->idx, info->preset_mode, __avsys_audio_pa_ctrl_success_cb, (void *)info->m); + } else if (info->cmd == AVSYS_PA_CTL_CMD_SOUNDALIVE_EQ) { + info->o = pa_ext_policy_sa_set_eq(c, info->idx, info->eq, __avsys_audio_pa_ctrl_success_cb, (void *)info->m); + } else if (info->cmd == AVSYS_PA_CTL_CMD_SOUNDALIVE_EXT) { + info->o = pa_ext_policy_sa_set_extend(c, info->idx, info->ext, __avsys_audio_pa_ctrl_success_cb, (void *)info->m); + } else if (info->cmd == AVSYS_PA_CTL_CMD_SOUNDALIVE_DEVICE) { + info->o = pa_ext_policy_sa_set_device(c, info->idx, info->dev, __avsys_audio_pa_ctrl_success_cb, (void *)info->m); + } else if (info->cmd == AVSYS_PA_CTL_CMD_DHA) { + info->o = pa_ext_policy_dha_set_param(c, info->idx, info->dha_onoff, info->dha_gain, __avsys_audio_pa_ctrl_success_cb, (void *)info->m); + } else if (info->cmd == AVSYS_PA_CTL_CMD_CORK_ALL) { + info->o = pa_context_set_cork_all(c, true, __avsys_audio_pa_ctrl_cork_success_cb, (void *)info->m); + } else if (info->cmd == AVSYS_PA_CTL_CMD_UNCORK_ALL) { + info->o = pa_context_set_cork_all(c, false, __avsys_audio_pa_ctrl_cork_success_cb, (void *)info->m); + } else { + avsys_info (AVAUDIO, "signal mainloop, cmd=%d", info->cmd); + pa_threaded_mainloop_signal(info->m, 0); + } + break; + case PA_CONTEXT_TERMINATED: + case PA_CONTEXT_FAILED: + pa_threaded_mainloop_signal(info->m, 0); + break; + + case PA_CONTEXT_UNCONNECTED: + case PA_CONTEXT_CONNECTING: + case PA_CONTEXT_AUTHORIZING: + case PA_CONTEXT_SETTING_NAME: + break; + } +} + +int avsys_audio_pa_ctrl_get_volume_level_max(int volume_type, int *level) +{ + pa_threaded_mainloop *mainloop = NULL; + pa_context *context = NULL; + int error = PA_ERR_INTERNAL; + avsys_pa_ctrl_info_t *info = NULL; + + if (!(mainloop = pa_threaded_mainloop_new())) + goto fail; + + if (!(context = pa_context_new(pa_threaded_mainloop_get_api(mainloop), NULL))) + goto fail; + + if (!(info = (avsys_pa_ctrl_info_t *)calloc(sizeof(avsys_pa_ctrl_info_t), 1))) + goto fail; + + info->m = mainloop; + info->cmd = AVSYS_PA_CTL_CMD_GET_VOLUME_LEVEL_MAX; + info->type = volume_type; + info->o = NULL; + + pa_context_set_state_callback(context, __avsys_audio_pa_ctrl_state_cb, (void *)info); + + if (pa_context_connect(context, NULL, 0, NULL) < 0) { + error = pa_context_errno(context); + goto fail; + } + + pa_threaded_mainloop_lock(mainloop); + + if (pa_threaded_mainloop_start(mainloop) < 0) + goto unlock_and_fail; + + for (;;) { + pa_context_state_t state; + + state = pa_context_get_state(context); + + if (state == PA_CONTEXT_READY) + break; + + if (!PA_CONTEXT_IS_GOOD(state)) { + error = pa_context_errno(context); + goto unlock_and_fail; + } + + /* Wait until the context is ready */ + pa_threaded_mainloop_wait(mainloop); + } + + *level = info->vol; + + if(info->o && pa_operation_get_state(info->o) == PA_OPERATION_DONE) + pa_operation_unref(info->o); + + pa_threaded_mainloop_unlock(mainloop); + + pa_threaded_mainloop_stop(mainloop); + pa_context_disconnect(context); + pa_context_unref(context); + pa_threaded_mainloop_free(mainloop); + free(info); + + return AVSYS_STATE_SUCCESS; /* for success */ + +unlock_and_fail: + pa_threaded_mainloop_unlock(mainloop); + + if (mainloop) + pa_threaded_mainloop_stop(mainloop); + + if (context) + pa_context_disconnect(context); + +fail: + avsys_error(AVAUDIO, "pa error : %s\n", pa_strerror(error)); + + if (context) + pa_context_unref(context); + + if (mainloop) + pa_threaded_mainloop_free(mainloop); + + if (info) + free(info); + + return AVSYS_STATE_ERR_INTERNAL; +} + +int avsys_audio_pa_ctrl_get_volume_level(int idx, int volume_type, int *level) +{ + pa_threaded_mainloop *mainloop = NULL; + pa_context *context = NULL; + int error = PA_ERR_INTERNAL; + avsys_pa_ctrl_info_t *info = NULL; + + if (!(mainloop = pa_threaded_mainloop_new())) + goto fail; + + if (!(context = pa_context_new(pa_threaded_mainloop_get_api(mainloop), NULL))) + goto fail; + + if (!(info = (avsys_pa_ctrl_info_t *)calloc(sizeof(avsys_pa_ctrl_info_t), 1))) + goto fail; + + info->m = mainloop; + info->cmd = AVSYS_PA_CTL_CMD_GET_VOLUME_LEVEL; + info->idx = idx; + info->type = volume_type; + info->o = NULL; + + pa_context_set_state_callback(context, __avsys_audio_pa_ctrl_state_cb, (void *)info); + + if (pa_context_connect(context, NULL, 0, NULL) < 0) { + error = pa_context_errno(context); + goto fail; + } + + pa_threaded_mainloop_lock(mainloop); + + if (pa_threaded_mainloop_start(mainloop) < 0) + goto unlock_and_fail; + + for (;;) { + pa_context_state_t state; + + state = pa_context_get_state(context); + + if (state == PA_CONTEXT_READY) + break; + + if (!PA_CONTEXT_IS_GOOD(state)) { + error = pa_context_errno(context); + goto unlock_and_fail; + } + + /* Wait until the context is ready */ + pa_threaded_mainloop_wait(mainloop); + } + + *level = info->vol; + + if(info->o && pa_operation_get_state(info->o) == PA_OPERATION_DONE) + pa_operation_unref(info->o); + + pa_threaded_mainloop_unlock(mainloop); + + pa_threaded_mainloop_stop(mainloop); + pa_context_disconnect(context); + pa_context_unref(context); + pa_threaded_mainloop_free(mainloop); + free(info); + + return AVSYS_STATE_SUCCESS; /* for success */ + +unlock_and_fail: + pa_threaded_mainloop_unlock(mainloop); + + if (mainloop) + pa_threaded_mainloop_stop(mainloop); + + if (context) + pa_context_disconnect(context); + +fail: + avsys_error(AVAUDIO, "pa error : %s\n", pa_strerror(error)); + + if (context) + pa_context_unref(context); + + if (mainloop) + pa_threaded_mainloop_free(mainloop); + + if (info) + free(info); + + return AVSYS_STATE_ERR_INTERNAL; +} + +int avsys_audio_pa_ctrl_set_volume_level(int idx, int volume_type, int level) +{ + pa_threaded_mainloop *mainloop = NULL; + pa_context *context = NULL; + int error = PA_ERR_INTERNAL; + avsys_pa_ctrl_info_t *info = NULL; + + if (!(mainloop = pa_threaded_mainloop_new())) + goto fail; + + if (!(context = pa_context_new(pa_threaded_mainloop_get_api(mainloop), NULL))) + goto fail; + + if (!(info = (avsys_pa_ctrl_info_t *)calloc(sizeof(avsys_pa_ctrl_info_t), 1))) + goto fail; + + info->m = mainloop; + info->cmd = AVSYS_PA_CTL_CMD_SET_VOLUME_LEVEL; + info->idx = idx; + info->type = volume_type; + info->vol = level; + info->o = NULL; + + pa_context_set_state_callback(context, __avsys_audio_pa_ctrl_state_cb, (void *)info); + + if (pa_context_connect(context, NULL, 0, NULL) < 0) { + error = pa_context_errno(context); + goto fail; + } + + pa_threaded_mainloop_lock(mainloop); + + if (pa_threaded_mainloop_start(mainloop) < 0) + goto unlock_and_fail; + + for (;;) { + pa_context_state_t state; + + state = pa_context_get_state(context); + + if (state == PA_CONTEXT_READY) + break; + + if (!PA_CONTEXT_IS_GOOD(state)) { + error = pa_context_errno(context); + goto unlock_and_fail; + } + + /* Wait until the context is ready */ + pa_threaded_mainloop_wait(mainloop); + } + + if(info->o && pa_operation_get_state(info->o) == PA_OPERATION_DONE) + pa_operation_unref(info->o); + + pa_threaded_mainloop_unlock(mainloop); + + pa_threaded_mainloop_stop(mainloop); + pa_context_disconnect(context); + pa_context_unref(context); + pa_threaded_mainloop_free(mainloop); + free(info); + + return AVSYS_STATE_SUCCESS; /* for success */ + +unlock_and_fail: + pa_threaded_mainloop_unlock(mainloop); + + if (mainloop) + pa_threaded_mainloop_stop(mainloop); + + if (context) + pa_context_disconnect(context); + +fail: + avsys_error(AVAUDIO, "pa error : %s\n", pa_strerror(error)); + + if (context) + pa_context_unref(context); + + if (mainloop) + pa_threaded_mainloop_free(mainloop); + + if (info) + free(info); + + return AVSYS_STATE_ERR_INTERNAL; +} + +int avsys_audio_pa_ctrl_get_mute(int idx, int volume_type, int direction, int *mute) +{ + pa_threaded_mainloop *mainloop = NULL; + pa_context *context = NULL; + int error = PA_ERR_INTERNAL; + avsys_pa_ctrl_info_t *info = NULL; + + if (!(mainloop = pa_threaded_mainloop_new())) + goto fail; + + if (!(context = pa_context_new(pa_threaded_mainloop_get_api(mainloop), NULL))) + goto fail; + + if (!(info = (avsys_pa_ctrl_info_t *)calloc(sizeof(avsys_pa_ctrl_info_t), 1))) + goto fail; + + info->m = mainloop; + info->cmd = AVSYS_PA_CTL_CMD_GET_MUTE; + info->idx = idx; + info->type = volume_type; + info->ch = direction; + info->o = NULL; + + pa_context_set_state_callback(context, __avsys_audio_pa_ctrl_state_cb, (void *)info); + + if (pa_context_connect(context, NULL, 0, NULL) < 0) { + error = pa_context_errno(context); + goto fail; + } + + pa_threaded_mainloop_lock(mainloop); + + if (pa_threaded_mainloop_start(mainloop) < 0) + goto unlock_and_fail; + + for (;;) { + pa_context_state_t state; + + state = pa_context_get_state(context); + + if (state == PA_CONTEXT_READY) + break; + + if (!PA_CONTEXT_IS_GOOD(state)) { + error = pa_context_errno(context); + goto unlock_and_fail; + } + + /* Wait until the context is ready */ + pa_threaded_mainloop_wait(mainloop); + } + + *mute = info->mute; + + if(info->o && pa_operation_get_state(info->o) == PA_OPERATION_DONE) + pa_operation_unref(info->o); + + pa_threaded_mainloop_unlock(mainloop); + + pa_threaded_mainloop_stop(mainloop); + pa_context_disconnect(context); + pa_context_unref(context); + pa_threaded_mainloop_free(mainloop); + free(info); + + return AVSYS_STATE_SUCCESS; /* for success */ + +unlock_and_fail: + pa_threaded_mainloop_unlock(mainloop); + + if (mainloop) + pa_threaded_mainloop_stop(mainloop); + + if (context) + pa_context_disconnect(context); + +fail: + avsys_error(AVAUDIO, "pa error : %s\n", pa_strerror(error)); + + if (context) + pa_context_unref(context); + + if (mainloop) + pa_threaded_mainloop_free(mainloop); + + if (info) + free(info); + + return AVSYS_STATE_ERR_INTERNAL; +} + +int avsys_audio_pa_ctrl_set_mute(int idx, int volume_type, int direction, int mute) +{ + pa_threaded_mainloop *mainloop = NULL; + pa_context *context = NULL; + int error = PA_ERR_INTERNAL; + avsys_pa_ctrl_info_t *info = NULL; + + if (!(mainloop = pa_threaded_mainloop_new())) + goto fail; + + if (!(context = pa_context_new(pa_threaded_mainloop_get_api(mainloop), NULL))) + goto fail; + + if (!(info = (avsys_pa_ctrl_info_t *)calloc(sizeof(avsys_pa_ctrl_info_t), 1))) + goto fail; + + info->m = mainloop; + info->cmd = AVSYS_PA_CTL_CMD_SET_MUTE; + info->idx = idx; + info->type = volume_type; + info->ch = direction; + info->mute = mute; + info->o = NULL; + + pa_context_set_state_callback(context, __avsys_audio_pa_ctrl_state_cb, (void *)info); + + if (pa_context_connect(context, NULL, 0, NULL) < 0) { + error = pa_context_errno(context); + goto fail; + } + + pa_threaded_mainloop_lock(mainloop); + + if (pa_threaded_mainloop_start(mainloop) < 0) + goto unlock_and_fail; + + for (;;) { + pa_context_state_t state; + + state = pa_context_get_state(context); + + if (state == PA_CONTEXT_READY) + break; + + if (!PA_CONTEXT_IS_GOOD(state)) { + error = pa_context_errno(context); + goto unlock_and_fail; + } + + /* Wait until the context is ready */ + pa_threaded_mainloop_wait(mainloop); + } + + if(info->o && pa_operation_get_state(info->o) == PA_OPERATION_DONE) + pa_operation_unref(info->o); + + pa_threaded_mainloop_unlock(mainloop); + + pa_threaded_mainloop_stop(mainloop); + pa_context_disconnect(context); + pa_context_unref(context); + pa_threaded_mainloop_free(mainloop); + free(info); + + return AVSYS_STATE_SUCCESS; /* for success */ + +unlock_and_fail: + pa_threaded_mainloop_unlock(mainloop); + + if (mainloop) + pa_threaded_mainloop_stop(mainloop); + + if (context) + pa_context_disconnect(context); + +fail: + avsys_error(AVAUDIO, "pa error : %s\n", pa_strerror(error)); + + if (context) + pa_context_unref(context); + + if (mainloop) + pa_threaded_mainloop_free(mainloop); + + if (info) + free(info); + + return AVSYS_STATE_ERR_INTERNAL; +} + +int avsys_audio_pa_ctrl_load_loopback_module(bool is_aec) +{ + pa_threaded_mainloop *mainloop = NULL; + pa_context *context = NULL; + int error = PA_ERR_INTERNAL; + avsys_pa_ctrl_info_t *info = NULL; + + if (!(mainloop = pa_threaded_mainloop_new())) + goto fail; + + if (!(context = pa_context_new(pa_threaded_mainloop_get_api(mainloop), NULL))) + goto fail; + + if (!(info = (avsys_pa_ctrl_info_t *)calloc(sizeof(avsys_pa_ctrl_info_t), 1))) + goto fail; + + info->m = mainloop; + info->cmd = (is_aec)? AVSYS_PA_CTL_CMD_LOAD_AECLOOPBACK_MODULE : AVSYS_PA_CTL_CMD_LOAD_LOOPBACK_MODULE; + info->o = NULL; + + pa_context_set_state_callback(context, __avsys_audio_pa_ctrl_state_cb, (void *)info); + + if (pa_context_connect(context, NULL, 0, NULL) < 0) { + error = pa_context_errno(context); + goto fail; + } + + pa_threaded_mainloop_lock(mainloop); + + if (pa_threaded_mainloop_start(mainloop) < 0) + goto unlock_and_fail; + + for (;;) { + pa_context_state_t state; + + state = pa_context_get_state(context); + + if (state == PA_CONTEXT_READY) + break; + + if (!PA_CONTEXT_IS_GOOD(state)) { + error = pa_context_errno(context); + goto unlock_and_fail; + } + + /* Wait until the context is ready */ + pa_threaded_mainloop_wait(mainloop); + } + + if(info->o && pa_operation_get_state(info->o) == PA_OPERATION_DONE) + pa_operation_unref(info->o); + + pa_threaded_mainloop_unlock(mainloop); + + pa_threaded_mainloop_stop(mainloop); + pa_context_disconnect(context); + pa_context_unref(context); + pa_threaded_mainloop_free(mainloop); + free(info); + + return AVSYS_STATE_SUCCESS; /* for success */ + +unlock_and_fail: + pa_threaded_mainloop_unlock(mainloop); + + if (mainloop) + pa_threaded_mainloop_stop(mainloop); + + if (context) + pa_context_disconnect(context); + +fail: + avsys_error(AVAUDIO, "pa error : %s\n", pa_strerror(error)); + + if (context) + pa_context_unref(context); + + if (mainloop) + pa_threaded_mainloop_free(mainloop); + + if (info) + free(info); + + return AVSYS_STATE_ERR_INTERNAL; +} + +int avsys_audio_pa_ctrl_unload_loopback_module(bool is_aec) +{ + pa_threaded_mainloop *mainloop = NULL; + pa_context *context = NULL; + int error = PA_ERR_INTERNAL; + avsys_pa_ctrl_info_t *info = NULL; + + /* check loopback module index first */ + if ((is_aec && loadmodule_info.aecloopback_module_idx == PA_INVALID_INDEX) || + (!is_aec && loadmodule_info.loopback_module_idx == PA_INVALID_INDEX)) { + avsys_info(AVAUDIO, "[%d] no loopback module exists to unload", is_aec); + return AVSYS_STATE_ERR_INVALID_STATE; + } + + if (!(mainloop = pa_threaded_mainloop_new())) + goto fail; + + if (!(context = pa_context_new(pa_threaded_mainloop_get_api(mainloop), NULL))) + goto fail; + + if (!(info = (avsys_pa_ctrl_info_t *)calloc(sizeof(avsys_pa_ctrl_info_t), 1))) + goto fail; + + info->m = mainloop; + info->cmd = (is_aec)? AVSYS_PA_CTL_CMD_UNLOAD_AECLOOPBACK_MODULE : AVSYS_PA_CTL_CMD_UNLOAD_LOOPBACK_MODULE; + info->o = NULL; + + pa_context_set_state_callback(context, __avsys_audio_pa_ctrl_state_cb, (void *)info); + + if (pa_context_connect(context, NULL, 0, NULL) < 0) { + error = pa_context_errno(context); + goto fail; + } + + pa_threaded_mainloop_lock(mainloop); + + if (pa_threaded_mainloop_start(mainloop) < 0) + goto unlock_and_fail; + + for (;;) { + pa_context_state_t state; + + state = pa_context_get_state(context); + + if (state == PA_CONTEXT_READY) + break; + + if (!PA_CONTEXT_IS_GOOD(state)) { + error = pa_context_errno(context); + goto unlock_and_fail; + } + + /* Wait until the context is ready */ + pa_threaded_mainloop_wait(mainloop); + } + + if(info->o && pa_operation_get_state(info->o) == PA_OPERATION_DONE) + pa_operation_unref(info->o); + pa_threaded_mainloop_unlock(mainloop); + + pa_threaded_mainloop_stop(mainloop); + pa_context_disconnect(context); + pa_context_unref(context); + pa_threaded_mainloop_free(mainloop); + free(info); + + return AVSYS_STATE_SUCCESS; /* for success */ + +unlock_and_fail: + pa_threaded_mainloop_unlock(mainloop); + + if (mainloop) + pa_threaded_mainloop_stop(mainloop); + + if (context) + pa_context_disconnect(context); + +fail: + avsys_error(AVAUDIO, "pa error : %s\n", pa_strerror(error)); + + if (context) + pa_context_unref(context); + + if (mainloop) + pa_threaded_mainloop_free(mainloop); + + if (info) + free(info); + + return AVSYS_STATE_ERR_INTERNAL; +} + +int avsys_audio_pa_ctrl_get_default_sink(int *sink) +{ + pa_threaded_mainloop *mainloop = NULL; + pa_context *context = NULL; + int error = PA_ERR_INTERNAL; + avsys_pa_ctrl_info_t *info = NULL; + + if (!sink) + return AVSYS_STATE_ERR_INVALID_PARAMETER; + + if (!(mainloop = pa_threaded_mainloop_new())) + goto fail; + + if (!(context = pa_context_new(pa_threaded_mainloop_get_api(mainloop), NULL))) + goto fail; + + if (!(info = (avsys_pa_ctrl_info_t *)calloc(sizeof(avsys_pa_ctrl_info_t), 1))) + goto fail; + + info->m = mainloop; + info->cmd = AVSYS_PA_CTL_CMD_GET_DEFAULT_SINK; + info->o = NULL; + + pa_context_set_state_callback(context, __avsys_audio_pa_ctrl_state_cb, (void *)info); + + if (pa_context_connect(context, NULL, 0, NULL) < 0) { + error = pa_context_errno(context); + goto fail; + } + + pa_threaded_mainloop_lock(mainloop); + + if (pa_threaded_mainloop_start(mainloop) < 0) + goto unlock_and_fail; + + for (;;) { + pa_context_state_t state; + + state = pa_context_get_state(context); + + if (state == PA_CONTEXT_READY) + break; + + if (!PA_CONTEXT_IS_GOOD(state)) { + error = pa_context_errno(context); + goto unlock_and_fail; + } + + /* Wait until the context is ready */ + pa_threaded_mainloop_wait(mainloop); + } + + *sink = info->res; + + if(info->o && pa_operation_get_state(info->o) == PA_OPERATION_DONE) + pa_operation_unref(info->o); + + pa_threaded_mainloop_unlock(mainloop); + + pa_threaded_mainloop_stop(mainloop); + pa_context_disconnect(context); + pa_context_unref(context); + pa_threaded_mainloop_free(mainloop); + free(info); + + return AVSYS_STATE_SUCCESS; /* for success */ + +unlock_and_fail: + pa_threaded_mainloop_unlock(mainloop); + + if (mainloop) + pa_threaded_mainloop_stop(mainloop); + + if (context) + pa_context_disconnect(context); + +fail: + avsys_error(AVAUDIO, "pa error : %s\n", pa_strerror(error)); + + if (context) + pa_context_unref(context); + + if (mainloop) + pa_threaded_mainloop_free(mainloop); + + if (info) + free(info); + + return AVSYS_STATE_ERR_INTERNAL; +} + + +int avsys_audio_pa_ctrl_suspend_sink(const char *sink_name, int suspend) +{ + pa_threaded_mainloop *mainloop = NULL; + pa_context *context = NULL; + int error = PA_ERR_INTERNAL; + avsys_pa_ctrl_info_t *info = NULL; + + avsys_info(AVAUDIO, "avsys_audio_pa_ctrl_suspend_sink"); + + if (!(mainloop = pa_threaded_mainloop_new())) + goto fail; + + if (!(context = pa_context_new(pa_threaded_mainloop_get_api(mainloop), NULL))) + goto fail; + + if (!(info = (avsys_pa_ctrl_info_t *)calloc(sizeof(avsys_pa_ctrl_info_t), 1))) + goto fail; + + info->m = mainloop; + info->cmd = AVSYS_PA_CTL_CMD_SUSPEND_SINK; + info->sink_name = sink_name; + info->suspend = suspend; + info->o = NULL; + + pa_context_set_state_callback(context, __avsys_audio_pa_ctrl_state_cb, (void *)info); + + if (pa_context_connect(context, NULL, 0, NULL) < 0) { + error = pa_context_errno(context); + goto fail; + } + + pa_threaded_mainloop_lock(mainloop); + + if (pa_threaded_mainloop_start(mainloop) < 0) + goto unlock_and_fail; + + for (;;) { + pa_context_state_t state; + + state = pa_context_get_state(context); + + if (state == PA_CONTEXT_READY) + break; + + if (!PA_CONTEXT_IS_GOOD(state)) { + error = pa_context_errno(context); + goto unlock_and_fail; + } + + /* Wait until the context is ready */ + pa_threaded_mainloop_wait(mainloop); + } + + if(info->o && pa_operation_get_state(info->o) == PA_OPERATION_DONE) + pa_operation_unref(info->o); + + pa_threaded_mainloop_unlock(mainloop); + + pa_threaded_mainloop_stop(mainloop); + pa_context_disconnect(context); + pa_context_unref(context); + pa_threaded_mainloop_free(mainloop); + free(info); + + avsys_info(AVAUDIO, "avsys_audio_pa_ctrl_suspend_sink success"); + + return AVSYS_STATE_SUCCESS; /* for success */ + +unlock_and_fail: + pa_threaded_mainloop_unlock(mainloop); + + if (mainloop) + pa_threaded_mainloop_stop(mainloop); + + if (context) + pa_context_disconnect(context); + +fail: + avsys_error(AVAUDIO, "pa error : %s\n", pa_strerror(error)); + + if (context) + pa_context_unref(context); + + if (mainloop) + pa_threaded_mainloop_free(mainloop); + + if (info) + free(info); + + return AVSYS_STATE_ERR_INTERNAL; +} + + +int avsys_audio_pa_ctrl_set_info(int input_info) +{ + pa_threaded_mainloop *mainloop = NULL; + pa_context *context = NULL; + int error = PA_ERR_INTERNAL; + avsys_pa_ctrl_info_t *info = NULL; + + if (!(mainloop = pa_threaded_mainloop_new())) + goto fail; + + if (!(context = pa_context_new(pa_threaded_mainloop_get_api(mainloop), NULL))) + goto fail; + + if (!(info = (avsys_pa_ctrl_info_t *)calloc(sizeof(avsys_pa_ctrl_info_t), 1))) + goto fail; + + info->m = mainloop; + info->cmd = AVSYS_PA_CTL_CMD_SET_INFO; + info->info = input_info; + info->o = NULL; + + pa_context_set_state_callback(context, __avsys_audio_pa_ctrl_state_cb, (void *)info); + + if (pa_context_connect(context, NULL, 0, NULL) < 0) { + error = pa_context_errno(context); + goto fail; + } + + pa_threaded_mainloop_lock(mainloop); + + if (pa_threaded_mainloop_start(mainloop) < 0) + goto unlock_and_fail; + + for (;;) { + pa_context_state_t state; + + state = pa_context_get_state(context); + + if (state == PA_CONTEXT_READY) + break; + + if (!PA_CONTEXT_IS_GOOD(state)) { + error = pa_context_errno(context); + goto unlock_and_fail; + } + + /* Wait until the context is ready */ + pa_threaded_mainloop_wait(mainloop); + } + + if(info->o && pa_operation_get_state(info->o) == PA_OPERATION_DONE) + pa_operation_unref(info->o); + + pa_threaded_mainloop_unlock(mainloop); + + pa_threaded_mainloop_stop(mainloop); + pa_context_disconnect(context); + pa_context_unref(context); + pa_threaded_mainloop_free(mainloop); + free(info); + + return AVSYS_STATE_SUCCESS; /* for success */ + +unlock_and_fail: + pa_threaded_mainloop_unlock(mainloop); + + if (mainloop) + pa_threaded_mainloop_stop(mainloop); + + if (context) + pa_context_disconnect(context); + +fail: + avsys_error(AVAUDIO, "pa error : %s\n", pa_strerror(error)); + + if (context) + pa_context_unref(context); + + if (mainloop) + pa_threaded_mainloop_free(mainloop); + + if (info) + free(info); + + return AVSYS_STATE_ERR_INTERNAL; +} + +int avsys_audio_pa_ctrl_update_scn() +{ + pa_threaded_mainloop *mainloop = NULL; + pa_context *context = NULL; + int error = PA_ERR_INTERNAL; + avsys_pa_ctrl_info_t *info = NULL; + + if (!(mainloop = pa_threaded_mainloop_new())) + goto fail; + + if (!(context = pa_context_new(pa_threaded_mainloop_get_api(mainloop), NULL))) + goto fail; + + if (!(info = (avsys_pa_ctrl_info_t *)calloc(sizeof(avsys_pa_ctrl_info_t), 1))) + goto fail; + + info->m = mainloop; + info->cmd = AVSYS_PA_CTL_CMD_UPDATE_SCN; + info->o = NULL; + + pa_context_set_state_callback(context, __avsys_audio_pa_ctrl_state_cb, (void *)info); + + if (pa_context_connect(context, NULL, 0, NULL) < 0) { + error = pa_context_errno(context); + goto fail; + } + + pa_threaded_mainloop_lock(mainloop); + + if (pa_threaded_mainloop_start(mainloop) < 0) + goto unlock_and_fail; + + for (;;) { + pa_context_state_t state; + + state = pa_context_get_state(context); + + if (state == PA_CONTEXT_READY) + break; + + if (!PA_CONTEXT_IS_GOOD(state)) { + error = pa_context_errno(context); + goto unlock_and_fail; + } + + /* Wait until the context is ready */ + pa_threaded_mainloop_wait(mainloop); + } + + if(info->o && pa_operation_get_state(info->o) == PA_OPERATION_DONE) + pa_operation_unref(info->o); + + pa_threaded_mainloop_unlock(mainloop); + + pa_threaded_mainloop_stop(mainloop); + pa_context_disconnect(context); + pa_context_unref(context); + pa_threaded_mainloop_free(mainloop); + free(info); + + return AVSYS_STATE_SUCCESS; /* for success */ + +unlock_and_fail: + pa_threaded_mainloop_unlock(mainloop); + + if (mainloop) + pa_threaded_mainloop_stop(mainloop); + + if (context) + pa_context_disconnect(context); + +fail: + avsys_error(AVAUDIO, "pa error : %s\n", pa_strerror(error)); + + if (context) + pa_context_unref(context); + + if (mainloop) + pa_threaded_mainloop_free(mainloop); + + if (info) + free(info); + + return AVSYS_STATE_ERR_INTERNAL; +} + +int avsys_audio_pa_ctrl_is_available_high_latency(int *available) +{ + pa_threaded_mainloop *mainloop = NULL; + pa_context *context = NULL; + int error = PA_ERR_INTERNAL; + avsys_pa_ctrl_info_t *info = NULL; + + if (!(mainloop = pa_threaded_mainloop_new())) + goto fail; + + if (!(context = pa_context_new(pa_threaded_mainloop_get_api(mainloop), NULL))) + goto fail; + + if (!(info = (avsys_pa_ctrl_info_t *)calloc(sizeof(avsys_pa_ctrl_info_t), 1))) + goto fail; + + info->m = mainloop; + info->cmd = AVSYS_PA_CTL_CMD_IS_AVAILABLE_HIGH_LATENCY; + info->o = NULL; + + pa_context_set_state_callback(context, __avsys_audio_pa_ctrl_state_cb, (void *)info); + + if (pa_context_connect(context, NULL, 0, NULL) < 0) { + error = pa_context_errno(context); + goto fail; + } + + pa_threaded_mainloop_lock(mainloop); + + if (pa_threaded_mainloop_start(mainloop) < 0) + goto unlock_and_fail; + + for (;;) { + pa_context_state_t state; + + state = pa_context_get_state(context); + + if (state == PA_CONTEXT_READY) + break; + + if (!PA_CONTEXT_IS_GOOD(state)) { + error = pa_context_errno(context); + goto unlock_and_fail; + } + + /* Wait until the context is ready */ + pa_threaded_mainloop_wait(mainloop); + } + + *available = info->res; + + if(info->o && pa_operation_get_state(info->o) == PA_OPERATION_DONE) + pa_operation_unref(info->o); + + pa_threaded_mainloop_unlock(mainloop); + + pa_threaded_mainloop_stop(mainloop); + pa_context_disconnect(context); + pa_context_unref(context); + pa_threaded_mainloop_free(mainloop); + free(info); + + return AVSYS_STATE_SUCCESS; /* for success */ + +unlock_and_fail: + pa_threaded_mainloop_unlock(mainloop); + + if (mainloop) + pa_threaded_mainloop_stop(mainloop); + + if (context) + pa_context_disconnect(context); + +fail: + avsys_error(AVAUDIO, "pa error : %s\n", pa_strerror(error)); + + if (context) + pa_context_unref(context); + + if (mainloop) + pa_threaded_mainloop_free(mainloop); + + if (info) + free(info); + + return AVSYS_STATE_ERR_INTERNAL; +} + +int avsys_audio_pa_ctrl_set_vsp_speed(int idx, int speed) +{ + pa_threaded_mainloop *mainloop = NULL; + pa_context *context = NULL; + int error = PA_ERR_INTERNAL; + avsys_pa_ctrl_info_t *info = NULL; + + if (!(mainloop = pa_threaded_mainloop_new())) + goto fail; + + if (!(context = pa_context_new(pa_threaded_mainloop_get_api(mainloop), NULL))) + goto fail; + + if (!(info = (avsys_pa_ctrl_info_t *)calloc(sizeof(avsys_pa_ctrl_info_t), 1))) + goto fail; + + info->m = mainloop; + info->cmd = AVSYS_PA_CTL_CMD_VSP_SPEED; + info->idx = idx; + info->speed = speed; + info->o = NULL; + + pa_context_set_state_callback(context, __avsys_audio_pa_ctrl_state_cb, (void *)info); + + if (pa_context_connect(context, NULL, 0, NULL) < 0) { + error = pa_context_errno(context); + goto fail; + } + + pa_threaded_mainloop_lock(mainloop); + + if (pa_threaded_mainloop_start(mainloop) < 0) + goto unlock_and_fail; + + for (;;) { + pa_context_state_t state; + + state = pa_context_get_state(context); + + if (state == PA_CONTEXT_READY) + break; + + if (!PA_CONTEXT_IS_GOOD(state)) { + error = pa_context_errno(context); + goto unlock_and_fail; + } + + /* Wait until the context is ready */ + pa_threaded_mainloop_wait(mainloop); + } + + if(info->o && pa_operation_get_state(info->o) == PA_OPERATION_DONE) + pa_operation_unref(info->o); + + pa_threaded_mainloop_unlock(mainloop); + + pa_threaded_mainloop_stop(mainloop); + pa_context_disconnect(context); + pa_context_unref(context); + pa_threaded_mainloop_free(mainloop); + free(info); + + return AVSYS_STATE_SUCCESS; /* for success */ + +unlock_and_fail: + pa_threaded_mainloop_unlock(mainloop); + + if (mainloop) + pa_threaded_mainloop_stop(mainloop); + + if (context) + pa_context_disconnect(context); + +fail: + avsys_error(AVAUDIO, "pa error : %s\n", pa_strerror(error)); + + if (context) + pa_context_unref(context); + + if (mainloop) + pa_threaded_mainloop_free(mainloop); + + if (info) + free(info); + + return AVSYS_STATE_ERR_INTERNAL; +} + +int avsys_audio_pa_ctrl_set_soundalive_filter_action(int idx, int filter_action) +{ + pa_threaded_mainloop *mainloop = NULL; + pa_context *context = NULL; + int error = PA_ERR_INTERNAL; + avsys_pa_ctrl_info_t *info = NULL; + + if (!(mainloop = pa_threaded_mainloop_new())) + goto fail; + + if (!(context = pa_context_new(pa_threaded_mainloop_get_api(mainloop), NULL))) + goto fail; + + if (!(info = (avsys_pa_ctrl_info_t *)calloc(sizeof(avsys_pa_ctrl_info_t), 1))) + goto fail; + + info->m = mainloop; + info->cmd = AVSYS_PA_CTL_CMD_SOUNDALIVE_FILTER_ACTION; + info->idx = idx; + info->filter_action = filter_action; + info->o = NULL; + + pa_context_set_state_callback(context, __avsys_audio_pa_ctrl_state_cb, (void *)info); + + if (pa_context_connect(context, NULL, 0, NULL) < 0) { + error = pa_context_errno(context); + goto fail; + } + + pa_threaded_mainloop_lock(mainloop); + + if (pa_threaded_mainloop_start(mainloop) < 0) + goto unlock_and_fail; + + for (;;) { + pa_context_state_t state; + + state = pa_context_get_state(context); + + if (state == PA_CONTEXT_READY) + break; + + if (!PA_CONTEXT_IS_GOOD(state)) { + error = pa_context_errno(context); + goto unlock_and_fail; + } + + /* Wait until the context is ready */ + pa_threaded_mainloop_wait(mainloop); + } + + if(info->o && pa_operation_get_state(info->o) == PA_OPERATION_DONE) + pa_operation_unref(info->o); + + pa_threaded_mainloop_unlock(mainloop); + + pa_threaded_mainloop_stop(mainloop); + pa_context_disconnect(context); + pa_context_unref(context); + pa_threaded_mainloop_free(mainloop); + free(info); + + return AVSYS_STATE_SUCCESS; /* for success */ + +unlock_and_fail: + pa_threaded_mainloop_unlock(mainloop); + + if (mainloop) + pa_threaded_mainloop_stop(mainloop); + + if (context) + pa_context_disconnect(context); + +fail: + avsys_error(AVAUDIO, "pa error : %s\n", pa_strerror(error)); + + if (context) + pa_context_unref(context); + + if (mainloop) + pa_threaded_mainloop_free(mainloop); + + if (info) + free(info); + + return AVSYS_STATE_ERR_INTERNAL; +} + +int avsys_audio_pa_ctrl_set_soundalive_preset_mode(int idx, int preset_mode) +{ + pa_threaded_mainloop *mainloop = NULL; + pa_context *context = NULL; + int error = PA_ERR_INTERNAL; + avsys_pa_ctrl_info_t *info = NULL; + + if (!(mainloop = pa_threaded_mainloop_new())) + goto fail; + + if (!(context = pa_context_new(pa_threaded_mainloop_get_api(mainloop), NULL))) + goto fail; + + if (!(info = (avsys_pa_ctrl_info_t *)calloc(sizeof(avsys_pa_ctrl_info_t), 1))) + goto fail; + + info->m = mainloop; + info->cmd = AVSYS_PA_CTL_CMD_SOUNDALIVE_PRESET_MODE; + info->idx = idx; + info->preset_mode = preset_mode; + info->o = NULL; + + pa_context_set_state_callback(context, __avsys_audio_pa_ctrl_state_cb, (void *)info); + + if (pa_context_connect(context, NULL, 0, NULL) < 0) { + error = pa_context_errno(context); + goto fail; + } + + pa_threaded_mainloop_lock(mainloop); + + if (pa_threaded_mainloop_start(mainloop) < 0) + goto unlock_and_fail; + + for (;;) { + pa_context_state_t state; + + state = pa_context_get_state(context); + + if (state == PA_CONTEXT_READY) + break; + + if (!PA_CONTEXT_IS_GOOD(state)) { + error = pa_context_errno(context); + goto unlock_and_fail; + } + + /* Wait until the context is ready */ + pa_threaded_mainloop_wait(mainloop); + } + + if(info->o && pa_operation_get_state(info->o) == PA_OPERATION_DONE) + pa_operation_unref(info->o); + + pa_threaded_mainloop_unlock(mainloop); + + pa_threaded_mainloop_stop(mainloop); + pa_context_disconnect(context); + pa_context_unref(context); + pa_threaded_mainloop_free(mainloop); + free(info); + + return AVSYS_STATE_SUCCESS; /* for success */ + +unlock_and_fail: + pa_threaded_mainloop_unlock(mainloop); + + if (mainloop) + pa_threaded_mainloop_stop(mainloop); + + if (context) + pa_context_disconnect(context); + +fail: + avsys_error(AVAUDIO, "pa error : %s\n", pa_strerror(error)); + + if (context) + pa_context_unref(context); + + if (mainloop) + pa_threaded_mainloop_free(mainloop); + + if (info) + free(info); + + return AVSYS_STATE_ERR_INTERNAL; +} + +int avsys_audio_pa_ctrl_set_soundalive_eq(int idx, int eq[]) +{ + pa_threaded_mainloop *mainloop = NULL; + pa_context *context = NULL; + int error = PA_ERR_INTERNAL; + int i = 0; + avsys_pa_ctrl_info_t *info = NULL; + + if (!(mainloop = pa_threaded_mainloop_new())) + goto fail; + + if (!(context = pa_context_new(pa_threaded_mainloop_get_api(mainloop), NULL))) + goto fail; + + if (!(info = (avsys_pa_ctrl_info_t *)calloc(sizeof(avsys_pa_ctrl_info_t), 1))) + goto fail; + + info->m = mainloop; + info->cmd = AVSYS_PA_CTL_CMD_SOUNDALIVE_EQ; + info->idx = idx; + for (i=0;ieq[i] = eq[i]; + } + info->o = NULL; + + pa_context_set_state_callback(context, __avsys_audio_pa_ctrl_state_cb, (void *)info); + + if (pa_context_connect(context, NULL, 0, NULL) < 0) { + error = pa_context_errno(context); + goto fail; + } + + pa_threaded_mainloop_lock(mainloop); + + if (pa_threaded_mainloop_start(mainloop) < 0) + goto unlock_and_fail; + + for (;;) { + pa_context_state_t state; + + state = pa_context_get_state(context); + + if (state == PA_CONTEXT_READY) + break; + + if (!PA_CONTEXT_IS_GOOD(state)) { + error = pa_context_errno(context); + goto unlock_and_fail; + } + + /* Wait until the context is ready */ + pa_threaded_mainloop_wait(mainloop); + } + + if(info->o && pa_operation_get_state(info->o) == PA_OPERATION_DONE) + pa_operation_unref(info->o); + + pa_threaded_mainloop_unlock(mainloop); + + pa_threaded_mainloop_stop(mainloop); + pa_context_disconnect(context); + pa_context_unref(context); + pa_threaded_mainloop_free(mainloop); + free(info); + + return AVSYS_STATE_SUCCESS; /* for success */ + +unlock_and_fail: + pa_threaded_mainloop_unlock(mainloop); + + if (mainloop) + pa_threaded_mainloop_stop(mainloop); + + if (context) + pa_context_disconnect(context); + +fail: + avsys_error(AVAUDIO, "pa error : %s\n", pa_strerror(error)); + + if (context) + pa_context_unref(context); + + if (mainloop) + pa_threaded_mainloop_free(mainloop); + + if (info) + free(info); + + return AVSYS_STATE_ERR_INTERNAL; +} + +int avsys_audio_pa_ctrl_set_soundalive_ext(int idx, int ext[]) +{ + pa_threaded_mainloop *mainloop = NULL; + pa_context *context = NULL; + int error = PA_ERR_INTERNAL; + int i = 0; + avsys_pa_ctrl_info_t *info = NULL; + + if (!(mainloop = pa_threaded_mainloop_new())) + goto fail; + + if (!(context = pa_context_new(pa_threaded_mainloop_get_api(mainloop), NULL))) + goto fail; + + if (!(info = (avsys_pa_ctrl_info_t *)calloc(sizeof(avsys_pa_ctrl_info_t), 1))) + goto fail; + + info->m = mainloop; + info->cmd = AVSYS_PA_CTL_CMD_SOUNDALIVE_EXT; + info->idx = idx; + for (i=0;iext[i] = ext[i]; + } + info->o = NULL; + + pa_context_set_state_callback(context, __avsys_audio_pa_ctrl_state_cb, (void *)info); + + if (pa_context_connect(context, NULL, 0, NULL) < 0) { + error = pa_context_errno(context); + goto fail; + } + + pa_threaded_mainloop_lock(mainloop); + + if (pa_threaded_mainloop_start(mainloop) < 0) + goto unlock_and_fail; + + for (;;) { + pa_context_state_t state; + + state = pa_context_get_state(context); + + if (state == PA_CONTEXT_READY) + break; + + if (!PA_CONTEXT_IS_GOOD(state)) { + error = pa_context_errno(context); + goto unlock_and_fail; + } + + /* Wait until the context is ready */ + pa_threaded_mainloop_wait(mainloop); + } + + if(info->o && pa_operation_get_state(info->o) == PA_OPERATION_DONE) + pa_operation_unref(info->o); + + pa_threaded_mainloop_unlock(mainloop); + + pa_threaded_mainloop_stop(mainloop); + pa_context_disconnect(context); + pa_context_unref(context); + pa_threaded_mainloop_free(mainloop); + free(info); + + return AVSYS_STATE_SUCCESS; /* for success */ + +unlock_and_fail: + pa_threaded_mainloop_unlock(mainloop); + + if (mainloop) + pa_threaded_mainloop_stop(mainloop); + + if (context) + pa_context_disconnect(context); + +fail: + avsys_error(AVAUDIO, "pa error : %s\n", pa_strerror(error)); + + if (context) + pa_context_unref(context); + + if (mainloop) + pa_threaded_mainloop_free(mainloop); + + if (info) + free(info); + + return AVSYS_STATE_ERR_INTERNAL; +} + +int avsys_audio_pa_ctrl_set_soundalive_device(int idx, int device) +{ + pa_threaded_mainloop *mainloop = NULL; + pa_context *context = NULL; + int error = PA_ERR_INTERNAL; + int i = 0; + avsys_pa_ctrl_info_t *info = NULL; + + if (!(mainloop = pa_threaded_mainloop_new())) + goto fail; + + if (!(context = pa_context_new(pa_threaded_mainloop_get_api(mainloop), NULL))) + goto fail; + + if (!(info = (avsys_pa_ctrl_info_t *)calloc(sizeof(avsys_pa_ctrl_info_t), 1))) + goto fail; + + info->m = mainloop; + info->cmd = AVSYS_PA_CTL_CMD_SOUNDALIVE_DEVICE; + info->idx = idx; + info->dev = device; + info->o = NULL; + + pa_context_set_state_callback(context, __avsys_audio_pa_ctrl_state_cb, (void *)info); + + if (pa_context_connect(context, NULL, 0, NULL) < 0) { + error = pa_context_errno(context); + goto fail; + } + + pa_threaded_mainloop_lock(mainloop); + + if (pa_threaded_mainloop_start(mainloop) < 0) + goto unlock_and_fail; + + for (;;) { + pa_context_state_t state; + + state = pa_context_get_state(context); + + if (state == PA_CONTEXT_READY) + break; + + if (!PA_CONTEXT_IS_GOOD(state)) { + error = pa_context_errno(context); + goto unlock_and_fail; + } + + /* Wait until the context is ready */ + pa_threaded_mainloop_wait(mainloop); + } + + if(info->o && pa_operation_get_state(info->o) == PA_OPERATION_DONE) + pa_operation_unref(info->o); + + pa_threaded_mainloop_unlock(mainloop); + + pa_threaded_mainloop_stop(mainloop); + pa_context_disconnect(context); + pa_context_unref(context); + pa_threaded_mainloop_free(mainloop); + free(info); + + return AVSYS_STATE_SUCCESS; /* for success */ + +unlock_and_fail: + pa_threaded_mainloop_unlock(mainloop); + + if (mainloop) + pa_threaded_mainloop_stop(mainloop); + + if (context) + pa_context_disconnect(context); + +fail: + avsys_error(AVAUDIO, "pa error : %s\n", pa_strerror(error)); + + if (context) + pa_context_unref(context); + + if (mainloop) + pa_threaded_mainloop_free(mainloop); + + if (info) + free(info); + + return AVSYS_STATE_ERR_INTERNAL; +} + +int avsys_audio_pa_ctrl_set_dha(int idx, int onoff, int gain[]) +{ + pa_threaded_mainloop *mainloop = NULL; + pa_context *context = NULL; + int error = PA_ERR_INTERNAL; + int i = 0; + avsys_pa_ctrl_info_t *info = NULL; + + if (!(mainloop = pa_threaded_mainloop_new())) + goto fail; + + if (!(context = pa_context_new(pa_threaded_mainloop_get_api(mainloop), NULL))) + goto fail; + + if (!(info = (avsys_pa_ctrl_info_t *)calloc(sizeof(avsys_pa_ctrl_info_t), 1))) + goto fail; + + info->m = mainloop; + info->cmd = AVSYS_PA_CTL_CMD_DHA; + info->idx = idx; + info->dha_onoff = onoff; + for (i = 0; i < DHA_MAX_NUM; i++) { + info->dha_gain[i] = gain[i]; + } + info->o = NULL; + + pa_context_set_state_callback(context, __avsys_audio_pa_ctrl_state_cb, (void *)info); + + if (pa_context_connect(context, NULL, 0, NULL) < 0) { + error = pa_context_errno(context); + goto fail; + } + + pa_threaded_mainloop_lock(mainloop); + + if (pa_threaded_mainloop_start(mainloop) < 0) + goto unlock_and_fail; + + for (;;) { + pa_context_state_t state; + + state = pa_context_get_state(context); + + if (state == PA_CONTEXT_READY) + break; + + if (!PA_CONTEXT_IS_GOOD(state)) { + error = pa_context_errno(context); + goto unlock_and_fail; + } + + /* Wait until the context is ready */ + pa_threaded_mainloop_wait(mainloop); + } + + if(info->o && pa_operation_get_state(info->o) == PA_OPERATION_DONE) + pa_operation_unref(info->o); + + pa_threaded_mainloop_unlock(mainloop); + + pa_threaded_mainloop_stop(mainloop); + pa_context_disconnect(context); + pa_context_unref(context); + pa_threaded_mainloop_free(mainloop); + free(info); + + return AVSYS_STATE_SUCCESS; /* for success */ + +unlock_and_fail: + pa_threaded_mainloop_unlock(mainloop); + + if (mainloop) + pa_threaded_mainloop_stop(mainloop); + + if (context) + pa_context_disconnect(context); + +fail: + avsys_error(AVAUDIO, "pa error : %s\n", pa_strerror(error)); + + if (context) + pa_context_unref(context); + + if (mainloop) + pa_threaded_mainloop_free(mainloop); + + if (info) + free(info); + + return AVSYS_STATE_ERR_INTERNAL; +} + +int avsys_audio_pa_ctrl_cork_all(bool cork) +{ + pa_threaded_mainloop *mainloop = NULL; + pa_context *context = NULL; + int error = PA_ERR_INTERNAL; + avsys_pa_ctrl_info_t *info = NULL; + + if (!(mainloop = pa_threaded_mainloop_new())) + goto fail; + + if (!(context = pa_context_new(pa_threaded_mainloop_get_api(mainloop), NULL))) + goto fail; + + if (!(info = (avsys_pa_ctrl_info_t *)calloc(sizeof(avsys_pa_ctrl_info_t), 1))) + goto fail; + + info->m = mainloop; + info->cmd = (cork)? AVSYS_PA_CTL_CMD_CORK_ALL : AVSYS_PA_CTL_CMD_UNCORK_ALL; + info->o = NULL; + + pa_context_set_state_callback(context, __avsys_audio_pa_ctrl_state_cb, (void *)info); + + if (pa_context_connect(context, NULL, 0, NULL) < 0) { + error = pa_context_errno(context); + goto fail; + } + + pa_threaded_mainloop_lock(mainloop); + + if (pa_threaded_mainloop_start(mainloop) < 0) + goto unlock_and_fail; + + for (;;) { + pa_context_state_t state; + + state = pa_context_get_state(context); + + if (state == PA_CONTEXT_READY) + break; + + if (!PA_CONTEXT_IS_GOOD(state)) { + error = pa_context_errno(context); + goto unlock_and_fail; + } + + /* Wait until the context is ready */ + pa_threaded_mainloop_wait(mainloop); + } + + if(info->o && pa_operation_get_state(info->o) == PA_OPERATION_DONE) + pa_operation_unref(info->o); + + pa_threaded_mainloop_unlock(mainloop); + + pa_threaded_mainloop_stop(mainloop); + pa_context_disconnect(context); + pa_context_unref(context); + pa_threaded_mainloop_free(mainloop); + free(info); + + return AVSYS_STATE_SUCCESS; /* for success */ + +unlock_and_fail: + pa_threaded_mainloop_unlock(mainloop); + + if (mainloop) + pa_threaded_mainloop_stop(mainloop); + + if (context) + pa_context_disconnect(context); + +fail: + avsys_error(AVAUDIO, "pa error : %s\n", pa_strerror(error)); + + if (context) + pa_context_unref(context); + + if (mainloop) + pa_threaded_mainloop_free(mainloop); + + if (info) + free(info); + + return AVSYS_STATE_ERR_INTERNAL; +} diff --git a/avsys-audio-pasimple.c b/avsys-audio-pasimple.c new file mode 100755 index 0000000..58dd7d7 --- /dev/null +++ b/avsys-audio-pasimple.c @@ -0,0 +1,696 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi + * + * 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 +#include + +#include +#include + +#include "avsys-audio-pasimple.h" +#include "avsys-types.h" +#include "avsys-error.h" +#include "avsys-debug.h" +#include "avsys-audio.h" +#include "avsys-audio-handle.h" + +#include +#define VCONFKEY_SOUND_CAPTURE_STATUS "memory/Sound/SoundCaptureStatus" + +#define PA_SIMPLE_FADE_INTERVAL_USEC 20000 + +#define PA_SIMPLE_SAMPLES_PER_PERIOD_DEFAULT 1536 /* frames */ +#define PA_SIMPLE_PERIODS_PER_BUFFER_FASTMODE 4 +#define PA_SIMPLE_PERIODS_PER_BUFFER_DEFAULT 6 +#define PA_SIMPLE_PERIODS_PER_BUFFER_VOIP 2 +#define PA_SIMPLE_PERIODS_PER_BUFFER_PLAYBACK 8 +#define PA_SIMPLE_PERIODS_PER_BUFFER_MUSIC_PLAYER 12 +#define PA_SIMPLE_PERIODS_PER_BUFFER_CAPTURE 12 +#define PA_SIMPLE_PERIODS_PER_BUFFER_VIDEO 10 + +#define PA_SIMPLE_PERIOD_TIME_FOR_ULOW_LATENCY_MSEC 20 +#define PA_SIMPLE_PERIOD_TIME_FOR_LOW_LATENCY_MSEC 25 +#define PA_SIMPLE_PERIOD_TIME_FOR_MID_LATENCY_MSEC 50 +#define PA_SIMPLE_PERIOD_TIME_FOR_HIGH_LATENCY_MSEC 75 +#define PA_SIMPLE_PERIOD_TIME_FOR_VERY_HIGH_LATENCY_MSEC 150 +#define PA_SIMPLE_PERIOD_TIME_FOR_VOIP_LATENCY_MSEC 20 + +#define MSEC_TO_SAMPLE(samplerate,period_time) (samplerate*period_time/1000) + +#define CHECK_VALID_HANDLE(handle) \ +do { \ + if (handle == NULL) { \ + return AVSYS_STATE_ERR_NULL_POINTER; \ + } \ + device = (avsys_audio_pasimple_handle_t *)handle->device; \ + if (device == NULL) { \ + return AVSYS_STATE_ERR_NULL_POINTER; \ + } \ + if (device->pasimple_handle == NULL) { \ + return AVSYS_STATE_ERR_NULL_POINTER; \ + } \ +} while (0) + +#define SET_PA_ATTR(pt,spp,ppb,pb,mr,tl,ml,fs) \ +do { \ + period_time = pt; \ + samples_per_period = spp; \ + periods_per_buffer = ppb; \ + attr.prebuf = pb; \ + attr.minreq = mr; \ + attr.tlength = tl; \ + attr.maxlength = ml; \ + attr.fragsize = fs; \ +} while (0) + +#define IS_INPUT_HANDLE(x) \ + if( x == AVSYS_AUDIO_MODE_INPUT || x == AVSYS_AUDIO_MODE_INPUT_HIGH_LATENCY || \ + x == AVSYS_AUDIO_MODE_INPUT_LOW_LATENCY || x == AVSYS_AUDIO_MODE_INPUT_AP_CALL ) + + +#define MEDIA_POLICY_AUTO "auto" +#define MEDIA_POLICY_PHONE "phone" +#define MEDIA_POLICY_ALL "all" +#define MEDIA_POLICY_VOIP "voip" +#define MEDIA_POLICY_MIRRORING "mirroring" +#define MEDIA_POLICY_HIGH_LATENCY "high-latency" + +static const pa_channel_position_t avsys_pos_to_pa[AVSYS_AUDIO_CHANNEL_POSITION_NUM] = { + [AVSYS_AUDIO_CHANNEL_POSITION_MONO] = PA_CHANNEL_POSITION_MONO, + [AVSYS_AUDIO_CHANNEL_POSITION_FRONT_LEFT] = PA_CHANNEL_POSITION_FRONT_LEFT, + [AVSYS_AUDIO_CHANNEL_POSITION_FRONT_RIGHT] = PA_CHANNEL_POSITION_FRONT_RIGHT, + [AVSYS_AUDIO_CHANNEL_POSITION_REAR_CENTER] = PA_CHANNEL_POSITION_REAR_CENTER, + [AVSYS_AUDIO_CHANNEL_POSITION_REAR_LEFT] = PA_CHANNEL_POSITION_REAR_LEFT, + [AVSYS_AUDIO_CHANNEL_POSITION_REAR_RIGHT] = PA_CHANNEL_POSITION_REAR_RIGHT, + [AVSYS_AUDIO_CHANNEL_POSITION_LFE] = PA_CHANNEL_POSITION_LFE, + [AVSYS_AUDIO_CHANNEL_POSITION_FRONT_CENTER] = PA_CHANNEL_POSITION_FRONT_CENTER, + [AVSYS_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER] = PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, + [AVSYS_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER] = PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, + [AVSYS_AUDIO_CHANNEL_POSITION_SIDE_LEFT] = PA_CHANNEL_POSITION_SIDE_LEFT, + [AVSYS_AUDIO_CHANNEL_POSITION_SIDE_RIGHT] = PA_CHANNEL_POSITION_SIDE_RIGHT, + [AVSYS_AUDIO_CHANNEL_POSITION_INVALID] = PA_CHANNEL_POSITION_INVALID +}; + +static const pa_tizen_volume_type_t avsys_volume_type_to_pa[AVSYS_AUDIO_VOLUME_TYPE_MAX] = { + [AVSYS_AUDIO_VOLUME_TYPE_SYSTEM] = PA_TIZEN_VOLUME_TYPE_SYSTEM, + [AVSYS_AUDIO_VOLUME_TYPE_NOTIFICATION] = PA_TIZEN_VOLUME_TYPE_NOTIFICATION, + [AVSYS_AUDIO_VOLUME_TYPE_ALARM] = PA_TIZEN_VOLUME_TYPE_ALARM, + [AVSYS_AUDIO_VOLUME_TYPE_RINGTONE] = PA_TIZEN_VOLUME_TYPE_RINGTONE, + [AVSYS_AUDIO_VOLUME_TYPE_MEDIA] = PA_TIZEN_VOLUME_TYPE_MEDIA, + [AVSYS_AUDIO_VOLUME_TYPE_CALL] = PA_TIZEN_VOLUME_TYPE_CALL, + [AVSYS_AUDIO_VOLUME_TYPE_VOIP] = PA_TIZEN_VOLUME_TYPE_VOIP, + [AVSYS_AUDIO_VOLUME_TYPE_SVOICE] = PA_TIZEN_VOLUME_TYPE_SVOICE, + [AVSYS_AUDIO_VOLUME_TYPE_FIXED] = PA_TIZEN_VOLUME_TYPE_FIXED, + [AVSYS_AUDIO_VOLUME_TYPE_EXT_SYSTEM_JAVA] = PA_TIZEN_VOLUME_TYPE_EXT_JAVA, +}; + +int avsys_audio_pasimple_open_device(const int mode, const unsigned int format, const unsigned int channel, const unsigned int samplerate, avsys_audio_handle_t *handle, int policy, avsys_audio_channel_pos_t *map) +{ + pa_simple *s = NULL; + pa_sample_spec ss; + avsys_audio_pasimple_handle_t *device = NULL; + pa_buffer_attr attr; + int err = AVSYS_STATE_SUCCESS; + int period_time = PA_SIMPLE_PERIOD_TIME_FOR_MID_LATENCY_MSEC; + int samples_per_period = PA_SIMPLE_SAMPLES_PER_PERIOD_DEFAULT; + int periods_per_buffer = PA_SIMPLE_PERIODS_PER_BUFFER_DEFAULT; + pa_channel_map channel_map; + const char *prop_policy; + int vol_conf_type, vol_conf_gain; + int prop_vol_type, prop_gain_type; + + unsigned long latency = 0; + int handle_mode = mode; + + avsys_assert(handle != NULL); + + if (channel < AVSYS_CHANNEL_MIN || channel > AVSYS_CHANNEL_MAX) + return AVSYS_STATE_ERR_DEVICE_NOT_SUPPORT; + + device = (avsys_audio_pasimple_handle_t *)malloc(sizeof(avsys_audio_pasimple_handle_t)); + if (device == NULL) { + avsys_critical(AVAUDIO, "PA Simple handle alloc fail\n"); + return AVSYS_STATE_ERR_ALLOCATION; + } + + ss.rate = samplerate; + ss.channels = channel; + + if (map[0] == AVSYS_AUDIO_CHANNEL_POSITION_INVALID) { + pa_channel_map_init_auto(&channel_map, ss.channels, PA_CHANNEL_MAP_ALSA); + } else { + int i; + pa_channel_map_init(&channel_map); + channel_map.channels = channel; + for (i = 0; i < channel; i++) { + if (map[i] < AVSYS_AUDIO_CHANNEL_POSITION_NUM) + channel_map.map[i] = avsys_pos_to_pa[map[i]]; + else + channel_map.map[i] = PA_CHANNEL_POSITION_INVALID; + } + } + + switch (format) { + case AVSYS_AUDIO_FORMAT_8BIT: + ss.format = PA_SAMPLE_U8; + device->samplesize = 1 * channel; + break; + case AVSYS_AUDIO_FORMAT_16BIT: + + ss.format = PA_SAMPLE_S16LE; + device->samplesize = 2 * channel; + break; + default: + free(device); + avsys_error(AVAUDIO, "Invalid format\n"); + return AVSYS_STATE_ERR_DEVICE_NOT_SUPPORT; + } + handle->device = (void *)device; + + pa_proplist *proplist = pa_proplist_new(); + + /* Set volume type of stream */ + vol_conf_type = AVSYS_AUDIO_VOLUME_CONFIG_TYPE(handle->gain_setting.volume_config); + prop_vol_type = avsys_volume_type_to_pa[vol_conf_type]; + pa_proplist_setf(proplist, PA_PROP_MEDIA_TIZEN_VOLUME_TYPE, "%d", prop_vol_type); + + /* Set gain type of stream */ + vol_conf_gain = AVSYS_AUDIO_VOLUME_CONFIG_GAIN(handle->gain_setting.volume_config); + prop_gain_type = vol_conf_gain >> 8; + pa_proplist_setf(proplist, PA_PROP_MEDIA_TIZEN_GAIN_TYPE, "%d", prop_gain_type); + + /* Set policy property*/ + if (policy == AVSYS_AUDIO_HANDLE_ROUTE_HANDSET_ONLY) { + prop_policy = MEDIA_POLICY_PHONE; + } else if (policy == AVSYS_AUDIO_HANDLE_ROUTE_ALL) { + prop_policy = MEDIA_POLICY_ALL; + } else if (handle->source_type == AVSYS_AUDIO_SUPPORT_TYPE_MIRRORING) { + prop_policy = MEDIA_POLICY_MIRRORING; + } else if (handle->source_type == AVSYS_AUDIO_SUPPORT_TYPE_VIDEOCALL) { + prop_policy = MEDIA_POLICY_VOIP; + + // set AP_CALL mode for VT call. + IS_INPUT_HANDLE(handle_mode) { + handle_mode = AVSYS_AUDIO_MODE_INPUT_AP_CALL; + } else { + handle_mode = AVSYS_AUDIO_MODE_OUTPUT_AP_CALL; + } + avsys_info(AVAUDIO, "source_type(VIDEOCALL) mode(%d)\n", handle_mode); + + } else { + /* check stream type (vol type) */ + switch (vol_conf_type) + { + case AVSYS_AUDIO_VOLUME_TYPE_NOTIFICATION: + { + int capture_status = 0; + int setting_sound_status = 1; + + /* Check whether audio is recording */ + vconf_get_int(VCONFKEY_SOUND_CAPTURE_STATUS, &capture_status); + /* If sound is mute mode, force notification path to headset */ + vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &setting_sound_status); + avsys_info (AVAUDIO, "capture status=%d, setting_sound_status=%d (mute:0)\n", capture_status, setting_sound_status); + if (capture_status || !setting_sound_status) { + prop_policy = MEDIA_POLICY_AUTO; + } else { + prop_policy = MEDIA_POLICY_ALL; + } + break; + } + case AVSYS_AUDIO_VOLUME_TYPE_ALARM: + prop_policy = MEDIA_POLICY_ALL; + break; + + case AVSYS_AUDIO_VOLUME_TYPE_MEDIA: + /* Set High-Latency for Music stream */ + if (handle_mode == AVSYS_AUDIO_MODE_OUTPUT_CLOCK) { + latency = PA_SIMPLE_PERIOD_TIME_FOR_VERY_HIGH_LATENCY_MSEC; + prop_policy = MEDIA_POLICY_HIGH_LATENCY; + } else { + prop_policy = MEDIA_POLICY_AUTO; + } + break; + + case AVSYS_AUDIO_VOLUME_TYPE_CALL: + case AVSYS_AUDIO_VOLUME_TYPE_RINGTONE: + case AVSYS_AUDIO_VOLUME_TYPE_FIXED: /* Used for Emergency */ + prop_policy = MEDIA_POLICY_PHONE; + break; + + case AVSYS_AUDIO_VOLUME_TYPE_VOIP: + prop_policy = MEDIA_POLICY_VOIP; + + IS_INPUT_HANDLE(handle_mode) { + handle_mode = AVSYS_AUDIO_MODE_INPUT_AP_CALL; + } else { + handle_mode = AVSYS_AUDIO_MODE_OUTPUT_AP_CALL; + } + break; + + default: + prop_policy = MEDIA_POLICY_AUTO; + break; + } + } + pa_proplist_sets(proplist, PA_PROP_MEDIA_POLICY, prop_policy); + + handle->handle_route = policy; + + memset(&attr, '\0', sizeof(attr)); + + switch (handle_mode) { + case AVSYS_AUDIO_MODE_INPUT: + SET_PA_ATTR(PA_SIMPLE_PERIOD_TIME_FOR_MID_LATENCY_MSEC, + MSEC_TO_SAMPLE(samplerate,period_time), + PA_SIMPLE_PERIODS_PER_BUFFER_DEFAULT, + 0, -1, -1, -1, samples_per_period * device->samplesize); + s = pa_simple_new_proplist(NULL, "AVSYSTEM", PA_STREAM_RECORD, NULL, "CAPTURE", &ss, &channel_map, &attr, proplist, &err); + break; + + case AVSYS_AUDIO_MODE_INPUT_LOW_LATENCY: + SET_PA_ATTR(PA_SIMPLE_PERIOD_TIME_FOR_ULOW_LATENCY_MSEC, + MSEC_TO_SAMPLE(samplerate,period_time), + PA_SIMPLE_PERIODS_PER_BUFFER_FASTMODE, + 0, -1, -1, -1, samples_per_period * device->samplesize); + + s = pa_simple_new_proplist(NULL, "AVSYSTEM", PA_STREAM_RECORD, NULL, "LOW LATENCY CAPTURE", &ss, &channel_map, &attr, proplist, &err); + break; + + case AVSYS_AUDIO_MODE_INPUT_HIGH_LATENCY: + SET_PA_ATTR(PA_SIMPLE_PERIOD_TIME_FOR_HIGH_LATENCY_MSEC, + MSEC_TO_SAMPLE(samplerate,period_time), + PA_SIMPLE_PERIODS_PER_BUFFER_CAPTURE, + 0, -1, -1, -1, samples_per_period * device->samplesize); + + s = pa_simple_new_proplist(NULL, "AVSYSTEM", PA_STREAM_RECORD, NULL, "HIGH LATENCY CAPTURE", &ss, &channel_map, &attr, proplist, &err); + break; + + case AVSYS_AUDIO_MODE_OUTPUT: /* mid latency playback for normal audio case. */ + SET_PA_ATTR(PA_SIMPLE_PERIOD_TIME_FOR_MID_LATENCY_MSEC, + MSEC_TO_SAMPLE(samplerate,period_time), + PA_SIMPLE_PERIODS_PER_BUFFER_DEFAULT, + -1, -1, (samplerate / 10) * pa_sample_size(&ss) * ss.channels, (uint32_t)-1, 0); + + s = pa_simple_new_proplist(NULL, "AVSYSTEM", PA_STREAM_PLAYBACK, NULL, "PLAYBACK", &ss, &channel_map, &attr, proplist, &err); + break; + + case AVSYS_AUDIO_MODE_OUTPUT_LOW_LATENCY: /* This is special case for touch sound playback */ + SET_PA_ATTR(PA_SIMPLE_PERIOD_TIME_FOR_LOW_LATENCY_MSEC, + MSEC_TO_SAMPLE(samplerate,period_time), + PA_SIMPLE_PERIODS_PER_BUFFER_FASTMODE, + -1, + -1, + pa_usec_to_bytes(50*PA_USEC_PER_MSEC, &ss), + (uint32_t)-1, 0); + + s = pa_simple_new_proplist(NULL,"AVSYSTEM", PA_STREAM_PLAYBACK, NULL, "LOW LATENCY PLAYBACK", &ss, &channel_map, &attr, proplist, &err); + break; + + case AVSYS_AUDIO_MODE_OUTPUT_CLOCK: /* high latency playback - lager buffer size */ + SET_PA_ATTR(PA_SIMPLE_PERIOD_TIME_FOR_HIGH_LATENCY_MSEC, + MSEC_TO_SAMPLE(samplerate,period_time), + PA_SIMPLE_PERIODS_PER_BUFFER_MUSIC_PLAYER, + -1, + -1, + pa_usec_to_bytes(200*PA_USEC_PER_MSEC, &ss), + (uint32_t)-1, 0); + + s = pa_simple_new_proplist(NULL, "AVSYSTEM", PA_STREAM_PLAYBACK, NULL, "HIGH LATENCY PLAYBACK", &ss, &channel_map, &attr, proplist, &err); + break; + + case AVSYS_AUDIO_MODE_OUTPUT_VIDEO: /* low latency playback */ + SET_PA_ATTR(PA_SIMPLE_PERIOD_TIME_FOR_LOW_LATENCY_MSEC, + MSEC_TO_SAMPLE(samplerate,period_time), + PA_SIMPLE_PERIODS_PER_BUFFER_VIDEO, + 4*(samples_per_period * device->samplesize), samples_per_period * device->samplesize, periods_per_buffer * samples_per_period * device->samplesize, (uint32_t)-1, 0); + + s = pa_simple_new_proplist(NULL, "AVSYSTEM", PA_STREAM_PLAYBACK, NULL, "LOW LATENCY PLAYBACK", &ss, &channel_map, &attr, proplist, &err); + break; + + case AVSYS_AUDIO_MODE_OUTPUT_AP_CALL: +#if defined(_MMFW_I386_ALL_SIMULATOR) + avsys_warning(AVAUDIO, "Does not support AP call mode at i386 simulator\n"); + s = NULL; +#else + SET_PA_ATTR(PA_SIMPLE_PERIOD_TIME_FOR_VOIP_LATENCY_MSEC, + MSEC_TO_SAMPLE(samplerate,period_time), + PA_SIMPLE_PERIODS_PER_BUFFER_VOIP, + -1, pa_usec_to_bytes(20*PA_USEC_PER_MSEC, &ss), pa_usec_to_bytes(100*PA_USEC_PER_MSEC, &ss), -1, 0); + + s = pa_simple_new_proplist(NULL, "AVSYSTEM", PA_STREAM_PLAYBACK, NULL, "VoIP PLAYBACK", &ss, &channel_map, &attr, proplist, &err); +#endif + break; + case AVSYS_AUDIO_MODE_INPUT_AP_CALL: +#if defined(_MMFW_I386_ALL_SIMULATOR) + avsys_warning(AVAUDIO, "Does not support AP call mode at i386 simulator\n"); + s = NULL; +#else + SET_PA_ATTR(PA_SIMPLE_PERIOD_TIME_FOR_VOIP_LATENCY_MSEC, + MSEC_TO_SAMPLE(samplerate,period_time), + PA_SIMPLE_PERIODS_PER_BUFFER_VOIP, + 0, -1, -1, -1, samples_per_period * device->samplesize); + + s = pa_simple_new_proplist(NULL, "AVSYSTEM", PA_STREAM_RECORD, NULL, "VoIP CAPTURE", &ss, &channel_map, &attr, proplist, &err); +#endif + break; + case AVSYS_AUDIO_MODE_CALL_OUT: + case AVSYS_AUDIO_MODE_CALL_IN: + //TODO + avsys_error(AVAUDIO, "Does not support call device handling\n"); + avsys_assert_r(0); + break; + default: + avsys_critical_r(AVAUDIO, "Invalid open mode %d\n", handle_mode); + avsys_assert_r(0); + return AVSYS_STATE_ERR_INVALID_MODE; + break; + } + + if (!s) { + avsys_error_r(AVAUDIO, "Open pulseaudio handle has failed - %s\n", pa_strerror(err)); + err = AVSYS_STATE_ERR_INTERNAL; + goto fail; + } + + device->pasimple_handle = (void *)s; + device->mode = handle_mode; + device->period_frames = samples_per_period; + device->buffer_frames = periods_per_buffer * device->period_frames; + device->periods_per_buffer = periods_per_buffer; + handle->period = device->period_frames * device->samplesize; + handle->msec_per_period = period_time; + if (0 > pa_simple_get_stream_index(s, &handle->stream_index, &err)) { + avsys_error(AVAUDIO, "Can not get stream index %s\n", pa_strerror(err)); + err = AVSYS_STATE_ERR_INVALID_HANDLE; + } + + avsys_debug(AVAUDIO, "sample/period[%d] period/buffer[%d] policy[%s] vol[%d] gain[%d]\n", + samples_per_period, periods_per_buffer, prop_policy, prop_vol_type, prop_gain_type); + +fail: + if (proplist) + pa_proplist_free(proplist); + + return err; +} + +int avsys_audio_pasimple_close_device(avsys_audio_handle_t *handle) +{ + int err = 0; + avsys_audio_pasimple_handle_t *device = NULL; + pa_simple *s = NULL; + + avsys_assert(handle != NULL); + CHECK_VALID_HANDLE(handle); + + switch (handle->mode) { + case AVSYS_AUDIO_MODE_CALL_OUT: + case AVSYS_AUDIO_MODE_CALL_IN: + avsys_warning(AVAUDIO, "Unsupported close mode in pa function\n"); + return AVSYS_STATE_ERR_INVALID_MODE; + case AVSYS_AUDIO_MODE_OUTPUT_AP_CALL: + case AVSYS_AUDIO_MODE_INPUT_AP_CALL: +#if defined(_MMFW_I386_ALL_SIMULATOR) + avsys_warning(AVAUDIO, "Skip close call device in SDK"); + return AVSYS_STATE_SUCCESS; +#endif + default: + break; + } + + s = (pa_simple *)device->pasimple_handle; + avsys_assert(s != NULL); + + /* for fading */ +// usleep(PA_SIMPLE_FADE_INTERVAL_USEC); + + switch (handle->mode) { + case AVSYS_AUDIO_MODE_OUTPUT_LOW_LATENCY: + if (0 > pa_simple_drain(s, &err)) { + avsys_error(AVAUDIO, "pa_simple_flush() failed with %s\n", pa_strerror(err)); + } + break; + case AVSYS_AUDIO_MODE_OUTPUT: + case AVSYS_AUDIO_MODE_OUTPUT_CLOCK: + case AVSYS_AUDIO_MODE_OUTPUT_AP_CALL: + case AVSYS_AUDIO_MODE_OUTPUT_VIDEO: + if (0 > pa_simple_flush(s, &err)) { + avsys_error(AVAUDIO, "pa_simple_flush() failed with %s\n", pa_strerror(err)); + } + break; + default: + break; + } + + pa_simple_free(s); + + device->pasimple_handle = NULL; + free(device); + + return AVSYS_STATE_SUCCESS; +} + +int avsys_audio_pasimple_write(avsys_audio_handle_t *handle, const void *buf, int size) +{ + pa_simple *s = NULL; + avsys_audio_pasimple_handle_t *device = NULL; + int err = 0; + + if (buf == NULL) + return AVSYS_STATE_ERR_NULL_POINTER; + CHECK_VALID_HANDLE(handle); + + if (size < 0) + return AVSYS_STATE_ERR_INVALID_PARAMETER; + else if (size == 0) + return 0; + + s = (pa_simple *)device->pasimple_handle; + + if (0 > pa_simple_write(s, buf, size, &err)) { + avsys_error(AVAUDIO, "pa_simple_write() failed with %s\n", pa_strerror(err)); + return AVSYS_STATE_ERR_INTERNAL; + } + + return size; +} + +int avsys_audio_pasimple_read(avsys_audio_handle_t *handle, void *buf, int size) +{ + pa_simple *s = NULL; + avsys_audio_pasimple_handle_t *device = NULL; + int err = 0; + + if (buf == NULL) + return AVSYS_STATE_ERR_NULL_POINTER; + CHECK_VALID_HANDLE(handle); + + if (size < 0) + return AVSYS_STATE_ERR_INVALID_PARAMETER; + else if (size == 0) + return 0; + + s = (pa_simple *)device->pasimple_handle; + + if (0 > pa_simple_read(s, buf, size, &err)) { + avsys_error(AVAUDIO, "pa_simple_read() failed with %s\n", pa_strerror(err)); + return AVSYS_STATE_ERR_INTERNAL; + } + + return size; +} + +int avsys_audio_pasimple_reset(avsys_audio_handle_t *handle) +{ + pa_simple *s = NULL; + avsys_audio_pasimple_handle_t *device = NULL; + int err = 0; + + CHECK_VALID_HANDLE(handle); + + if (handle->mode == AVSYS_AUDIO_MODE_INPUT || handle->mode == AVSYS_AUDIO_MODE_INPUT_LOW_LATENCY) { + avsys_warning(AVAUDIO, "Skip pa_simple_flush() when input mode\n"); + return AVSYS_STATE_SUCCESS; + } + + s = (pa_simple *)device->pasimple_handle; + + if (0 > pa_simple_flush(s, &err)) { + avsys_error(AVAUDIO, "pa_simple_flush() failed with %s\n", pa_strerror(err)); + return AVSYS_STATE_ERR_INTERNAL; + } + + return AVSYS_STATE_SUCCESS; +} + +int avsys_audio_pasimple_drain(avsys_audio_handle_t *handle) +{ + pa_simple *s = NULL; + avsys_audio_pasimple_handle_t *device = NULL; + int err = 0; + + CHECK_VALID_HANDLE(handle); + + s = (pa_simple *)device->pasimple_handle; + + if (0 > pa_simple_drain(s, &err)) { + avsys_error(AVAUDIO, "pa_simple_drain() failed with %s\n", pa_strerror(err)); + return AVSYS_STATE_ERR_INTERNAL; + } + + return AVSYS_STATE_SUCCESS; +} + +int avsys_audio_pasimple_set_volume(avsys_audio_handle_t *handle, int volume) +{ + pa_simple *s = NULL; + avsys_audio_pasimple_handle_t *device = NULL; + int err = 0; + + CHECK_VALID_HANDLE(handle); + + s = (pa_simple *)device->pasimple_handle; + if(avsys_audio_handle_get_mute_all_status(handle)) { + int vol_conf_type = AVSYS_AUDIO_VOLUME_CONFIG_TYPE(handle->gain_setting.volume_config); + avsys_warning(AVAUDIO, "vol_conf_type = %d\n",vol_conf_type); + if (vol_conf_type != AVSYS_AUDIO_VOLUME_TYPE_FIXED) { + volume = 0; + } + } + if (0 > pa_simple_set_volume(s, volume, &err)) { + avsys_error(AVAUDIO, "pa_simple_set_volume() failed with %s\n", pa_strerror(err)); + return AVSYS_STATE_ERR_INTERNAL; + } + + return AVSYS_STATE_SUCCESS; +} + +#define USEC_TO_MSEC(usec) (usec/1000) +#define USEC_TO_SAMPLE(usec, rate) ((usec*rate)/1000000) +#define SAMPLES_TO_USEC(samples,rate) ((samples*1000000)/rate) +#define BYTES_TO_USEC(bytes,size_per_sample,rate) ((bytes*1000000)/(size_per_sample*rate)) + +int avsys_audio_pasimple_delay(avsys_audio_handle_t *handle, int *delay) +{ + pa_simple *s = NULL; + avsys_audio_pasimple_handle_t *device = NULL; + int err = 0; + pa_usec_t latency_time = 0; + unsigned int latency_frames = 0; + + if (delay == NULL) { + return AVSYS_STATE_ERR_NULL_POINTER; + } + CHECK_VALID_HANDLE(handle); + + s = (pa_simple *)device->pasimple_handle; + + latency_time = pa_simple_get_latency(s, &err); + if (err > 0 && latency_time == 0) { + avsys_error(AVAUDIO, "pa_simple_get_latency() failed with %s\n", pa_strerror(err)); + return AVSYS_STATE_ERR_INTERNAL; + } + /* convert time to sample */ + latency_frames = USEC_TO_SAMPLE(latency_time, handle->samplerate); + *delay = latency_frames; + + return AVSYS_STATE_SUCCESS; +} + +int avsys_audio_pasimple_latency(avsys_audio_handle_t *handle, int *latency) +{ + pa_simple *s = NULL; + avsys_audio_pasimple_handle_t *device = NULL; + int err = 0; + pa_usec_t latency_time = 0; + + if (latency == NULL) { + return AVSYS_STATE_ERR_NULL_POINTER; + } + CHECK_VALID_HANDLE(handle); + + s = (pa_simple *)device->pasimple_handle; + + latency_time = pa_simple_get_final_latency(s, &err); + if (err > 0 && latency_time == 0) { + avsys_error(AVAUDIO, "pa_simple_get_latency() failed with %s\n", pa_strerror(err)); + return AVSYS_STATE_ERR_INTERNAL; + } + *latency = USEC_TO_MSEC(latency_time); + + return AVSYS_STATE_SUCCESS; +} + +int avsys_audio_pasimple_get_period_buffer_time(avsys_audio_handle_t *handle, unsigned int *period_time, unsigned int *buffer_time) +{ + avsys_audio_pasimple_handle_t *device = NULL; + + if ((period_time == NULL) || (buffer_time == NULL)) + return AVSYS_STATE_ERR_INTERNAL; + + CHECK_VALID_HANDLE(handle); + + *period_time = SAMPLES_TO_USEC(device->period_frames,handle->samplerate); + *buffer_time = *period_time * device->periods_per_buffer; + + avsys_info(AVAUDIO, "period = %d, buffer = %d\n", *period_time, *buffer_time); + + return AVSYS_STATE_SUCCESS; +} + +int avsys_audio_pasimple_cork(avsys_audio_handle_t *handle, int cork) +{ + pa_simple *s = NULL; + avsys_audio_pasimple_handle_t *device = NULL; + int err = 0; + + CHECK_VALID_HANDLE(handle); + + s = (pa_simple *)device->pasimple_handle; + + if (0 > pa_simple_cork(s, cork, &err)) { + avsys_error(AVAUDIO, "pa_simple_cork() failed with %s\n", pa_strerror(err)); + return AVSYS_STATE_ERR_INTERNAL; + } + + return AVSYS_STATE_SUCCESS; +} + +int avsys_audio_pasimple_is_corked(avsys_audio_handle_t *handle, int *is_corked) +{ + pa_simple *s = NULL; + avsys_audio_pasimple_handle_t *device = NULL; + int err = 0; + + if (is_corked == NULL) + return AVSYS_STATE_ERR_INTERNAL; + + CHECK_VALID_HANDLE(handle); + + s = (pa_simple *)device->pasimple_handle; + + *is_corked = pa_simple_is_corked(s); + + return AVSYS_STATE_SUCCESS; +} + + diff --git a/avsys-audio-path-msm8x74.c b/avsys-audio-path-msm8x74.c new file mode 100644 index 0000000..c1fd550 --- /dev/null +++ b/avsys-audio-path-msm8x74.c @@ -0,0 +1,1546 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "avsys-audio-shm.h" +#include "avsys-audio-sync.h" +#include "avsys-audio-path.h" +#include "avsys-audio-shm.h" +#include "avsys-debug.h" +#include "avsys-common.h" +#include "avsys-audio-handle.h" +#include "avsys-audio-alsa.h" +#include "alsa-ucm-constants.h" + +#define EXPORT_API __attribute__((__visibility__("default"))) + +#define RET_IO_CTL_ERR_IF_FAIL(SECTION) { if(AVSYS_FAIL(SECTION)) { \ + avsys_error_r(AVAUDIO,"%s %d\n",__func__,__LINE__); \ + return AVSYS_STATE_ERR_IO_CONTROL; \ + } } + +#define MAX_DEVICES 10 + + +static int g_playback_path_select_data[AVSYS_AUDIO_PLAYBACK_GAIN_MAX][AVSYS_AUDIO_PATH_EX_OUTMAX] = { + { /* AVSYS_AUDIO_PLAYBACK_GAIN_AP */ + /* NONE SPK RECV HEADSET BTHEADSET A2DP HANDSFREE HDMI DOCK USBAUDIO WFD */ + 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1 + }, + { /* AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO */ + /* NONE SPK RECV HEADSET BTHEADSET A2DP HANDSFREE HDMI WFD */ + 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0 + }, + { /* AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL */ + /* NONE SPK RECV HEADSET BTHEADSET A2DP HANDSFREE HDMI WFD */ + 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 + }, + { /* AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL */ + /* NONE SPK RECV HEADSET BTHEADSET A2DP HANDSFREE HDMI WFD */ + 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 + }, + { /* AVSYS_AUDIO_PLAYBACK_GAIN_VOIP */ + /* NONE SPK RECV HEADSET BTHEADSET A2DP HANDSFREE HDMI WFD */ + 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 + }, + { /* AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT */ + /* NONE SPK RECV HEADSET BTHEADSET A2DP HANDSFREE HDMI WFD*/ + 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 + } +}; + +static int g_capture_path_select_data[AVSYS_AUDIO_CAPTURE_GAIN_MAX][AVSYS_AUDIO_PATH_EX_INMAX] = { + { /* AVSYS_AUDIO_CAPTURE_GAIN_AP */ + /* NONE MIC HMIC BMIC FMIN HFREE */ + 1, 1, 1, 1, 0, 0 + }, + { /* AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO */ + /* NONE MIC HMIC BMIC FMIN HFREE */ + 1, 0, 0, 0, 1, 0 + }, + { /* AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL */ + /* NONE MIC HMIC BMIC FMIN HFREE */ + 1, 1, 1, 1, 0, 0 + }, + { /* AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL */ + /* NONE MIC HMIC BMIC FMIN HFREE */ + 1, 1, 1, 1, 0, 0 + }, + { /* AVSYS_AUDIO_CAPTURE_GAIN_VOIP */ + /* NONE MIC HMIC BMIC FMIN HFREE */ + 1, 1, 1, 1, 0, 0 + }, + { /* AVSYS_AUDIO_CAPTURE_GAIN_VOICERECOGNITION */ + /* NONE MIC HMIC BMIC FMIN HFREE */ + 0, 1, 1, 1, 0, 0 + }, +}; + +static int g_playback_gain_select_data[AVSYS_AUDIO_PLAYBACK_GAIN_MAX][AVSYS_AUDIO_PLAYBACK_GAIN_MAX] = { + { /* AVSYS_AUDIO_PLAYBACK_GAIN_AP */ + AVSYS_AUDIO_PLAYBACK_GAIN_AP, /* AVSYS_AUDIO_PLAYBACK_GAIN_AP */ + AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO, /* AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO */ + AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL, /* AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL */ + AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL, /* AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL */ + AVSYS_AUDIO_PLAYBACK_GAIN_VOIP, /* AVSYS_AUDIO_PLAYBACK_GAIN_VOIP */ + AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT, /* AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT */ + }, + { /* AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO */ + AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO, /* AVSYS_AUDIO_PLAYBACK_GAIN_AP */ + AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO, /* AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO */ + AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL, /* AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL */ + AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL, /* AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL */ + AVSYS_AUDIO_PLAYBACK_GAIN_VOIP, /* AVSYS_AUDIO_PLAYBACK_GAIN_VOIP */ + AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO, /* AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT */ + }, + { /* AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL */ + AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL, /* AVSYS_AUDIO_PLAYBACK_GAIN_AP */ + AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL, /* AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO */ + AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL, /* AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL */ + AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL, /* AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL */ + AVSYS_AUDIO_PLAYBACK_GAIN_VOIP, /* AVSYS_AUDIO_PLAYBACK_GAIN_VOIP */ + AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT, /* AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT */ + }, + { /* AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL */ + AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL, /* AVSYS_AUDIO_PLAYBACK_GAIN_AP */ + AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL, /* AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO */ + AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL, /* AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL */ + AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL, /* AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL */ + AVSYS_AUDIO_PLAYBACK_GAIN_VOIP, /* AVSYS_AUDIO_PLAYBACK_GAIN_VOIP */ + AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT, /* AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT */ + }, + { /* AVSYS_AUDIO_PLAYBACK_GAIN_VOIP */ + AVSYS_AUDIO_PLAYBACK_GAIN_VOIP, /* AVSYS_AUDIO_PLAYBACK_GAIN_AP */ + AVSYS_AUDIO_PLAYBACK_GAIN_VOIP, /* AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO */ + AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL, /* AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL */ + AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL, /* AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL */ + AVSYS_AUDIO_PLAYBACK_GAIN_VOIP, /* AVSYS_AUDIO_PLAYBACK_GAIN_VOIP */ + AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT, /* AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT */ + }, + { /* AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT */ + AVSYS_AUDIO_PLAYBACK_GAIN_AP, /* AVSYS_AUDIO_PLAYBACK_GAIN_AP */ + AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO, /* AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO */ + AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL, /* AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL */ + AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL, /* AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL */ + AVSYS_AUDIO_PLAYBACK_GAIN_VOIP, /* AVSYS_AUDIO_PLAYBACK_GAIN_VOIP */ + AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT, /* AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT */ + }, +}; + +static int g_capture_gain_select_data[AVSYS_AUDIO_CAPTURE_GAIN_MAX][AVSYS_AUDIO_CAPTURE_GAIN_MAX] = { + { /* AVSYS_AUDIO_CAPTURE_GAIN_AP */ + AVSYS_AUDIO_CAPTURE_GAIN_AP, /* AVSYS_AUDIO_CAPTURE_GAIN_AP */ + AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO, /* AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO */ + AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL, /* AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL */ + AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL, /* AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL */ + AVSYS_AUDIO_CAPTURE_GAIN_VOIP, /* AVSYS_AUDIO_CAPTURE_GAIN_VOIP */ + }, + { /* AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO */ + AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO, /* AVSYS_AUDIO_CAPTURE_GAIN_AP */ + AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO, /* AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO */ + AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL, /* AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL */ + AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL, /* AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL */ + AVSYS_AUDIO_CAPTURE_GAIN_VOIP, /* AVSYS_AUDIO_CAPTURE_GAIN_VOIP */ + }, + { /* AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL */ + AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL, /* AVSYS_AUDIO_CAPTURE_GAIN_AP */ + AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL, /* AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO */ + AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL, /* AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL */ + AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL, /* AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL */ + AVSYS_AUDIO_CAPTURE_GAIN_VOIP, /* AVSYS_AUDIO_CAPTURE_GAIN_VOIP */ + }, + { /* AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL */ + AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL, /* AVSYS_AUDIO_CAPTURE_GAIN_AP */ + AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL, /* AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO */ + AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL, /* AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL */ + AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL, /* AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL */ + AVSYS_AUDIO_CAPTURE_GAIN_VOIP, /* AVSYS_AUDIO_CAPTURE_GAIN_VOIP */ + }, + { /* AVSYS_AUDIO_CAPTURE_GAIN_VOIP */ + AVSYS_AUDIO_CAPTURE_GAIN_VOIP, /* AVSYS_AUDIO_CAPTURE_GAIN_AP */ + AVSYS_AUDIO_CAPTURE_GAIN_VOIP, /* AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO */ + AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL, /* AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL */ + AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL, /* AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL */ + AVSYS_AUDIO_CAPTURE_GAIN_VOIP, /* AVSYS_AUDIO_CAPTURE_GAIN_VOIP */ + }, +}; + + +static int __avsys_audio_path_set_ap_playback(avsys_audio_path_ex_info_t *control); +static int __avsys_audio_path_set_voicecall(avsys_audio_path_ex_info_t *control); +static int __avsys_audio_path_set_voip(avsys_audio_path_ex_info_t *control); +static int __avsys_audio_path_set_fmradio(avsys_audio_path_ex_info_t *control); +static int __avsys_audio_path_set_ap_capture(avsys_audio_path_ex_info_t *control); +static int __avsys_audio_path_set_ap_voicerecognition(avsys_audio_path_ex_info_t *control); +static inline int __reset_ucm_controls(); + + + +#define MIXER_CTL_VOICE_RX_VOLUME "Voice Rx Volume" +#define MIXER_CTL_VOIP_RX_VOLUME "Voip Rx Volume" +#define MIXER_CTL_VOICE_TX_MUTE "Voice Tx Mute" +#define MIXER_CTL_VOIP_TX_MUTE "Voip Tx Mute" +#define MIXER_CTL_LOOPBACK_ENABLE "Loopback Enable" +#define MIXER_CTL_AUX_PCM_SAMPLERATE "AUX PCM SampleRate" + +static char *verb = NULL; +static char *devices[MAX_DEVICES] = {0}; +static char *modifiers[MAX_DEVICES] = {0}; + +static int dev_idx = 0, mod_idx = 0; + + +static inline int __reset_ucm_controls() +{ + int i = 0; + verb = NULL; + for(; i < MAX_DEVICES; i++) { + devices[i] = 0; + modifiers[i] = 0; + } + dev_idx = mod_idx = 0; + return 0; +} + +EXPORT_API +int avsys_audio_path_ex_init(void) +{ + avsys_audio_path_ex_info_t *control = NULL; + avsys_audio_path_ex_info_t **temp = NULL; + gain_info_t default_gain = { AVSYS_AUDIO_PLAYBACK_GAIN_AP, AVSYS_AUDIO_CAPTURE_GAIN_AP }; + path_info_t default_path = { AVSYS_AUDIO_PATH_EX_SPK, AVSYS_AUDIO_PATH_EX_MIC }; + int default_option = AVSYS_AUDIO_PATH_OPTION_NONE; + int index = 0; + int err = AVSYS_STATE_SUCCESS; + + /* Check root user */ + err = avsys_check_root_privilege(); + if (AVSYS_FAIL(err)) { + return err; + } + + temp = &control; + avsys_assert(AVSYS_SUCCESS(avsys_audio_create_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))); + avsys_assert(AVSYS_SUCCESS(avsys_audio_create_shm(AVSYS_AUDIO_SHM_IDEN_PATH))); + + avsys_assert(AVSYS_SUCCESS(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp))); + if (control == NULL) + return AVSYS_STATE_ERR_NULL_POINTER; + + /* init values */ + control->pregain = default_gain; + control->gain = default_gain; + control->reqgain = default_gain; + control->path = default_path; + control->option = default_option; + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + control->mute = AVSYS_AUDIO_UNMUTE; + control->path_fixed = PATH_FIXED_NONE; + + index = 0; + do { + control->pathlock_pid[index] = -1; + index++; + } while (index < AVSYS_AUDIO_LOCK_SLOT_MAX); + + index = 0; + do { + control->path_fixed_pid[index] = -1; + index++; + } while (index < PATH_FIXED_TYPE_MAX); + + /* call path control */ + err = __avsys_audio_path_set_ap_playback(control); + if (AVSYS_SUCCESS(err)) + err = __avsys_audio_path_set_ap_capture(control); + + avsys_audio_pa_ctrl_set_use_case(verb, devices, dev_idx, modifiers, mod_idx); + + __reset_ucm_controls(); + + return err; +} + +EXPORT_API +int avsys_audio_path_ex_fini(void) +{ + if (AVSYS_FAIL(avsys_audio_remove_shm(AVSYS_AUDIO_SHM_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_remove_shm() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + if (AVSYS_FAIL(avsys_audio_remove_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_remove_sync() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + + return AVSYS_STATE_SUCCESS; +} + +EXPORT_API +int avsys_audio_path_ex_reset(int forced) +{ + avsys_audio_path_ex_info_t *control = NULL; + avsys_audio_path_ex_info_t **temp = NULL; + gain_info_t default_gain = { AVSYS_AUDIO_PLAYBACK_GAIN_AP, AVSYS_AUDIO_CAPTURE_GAIN_AP }; + path_info_t default_path = { AVSYS_AUDIO_PATH_EX_SPK, AVSYS_AUDIO_PATH_EX_MIC }; + int default_option = AVSYS_AUDIO_PATH_OPTION_NONE; + int index = 0; + int err = AVSYS_STATE_SUCCESS; + + /* Check root user */ + err = avsys_check_root_privilege(); + if (AVSYS_FAIL(err)) { + return err; + } + + temp = &control; + if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp))) { + avsys_error_r(AVAUDIO, "avsys_audio_get_shm() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + if (control == NULL) + return AVSYS_STATE_ERR_NULL_POINTER; + + if (AVSYS_FAIL(avsys_audio_lock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_lock_sync() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + + /* init values */ + control->pregain = default_gain; + control->gain = default_gain; + control->reqgain = default_gain; + control->path = default_path; + control->option = default_option; + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + control->mute = AVSYS_AUDIO_UNMUTE; + control->path_fixed = PATH_FIXED_NONE; + + index = 0; + do { + control->pathlock_pid[index] = -1; + index++; + } while (index < AVSYS_AUDIO_LOCK_SLOT_MAX); + + index = 0; + do { + control->path_fixed_pid[index] = -1; + index++; + } while (index < PATH_FIXED_TYPE_MAX); + + /* call path control */ + err = __avsys_audio_path_set_ap_playback(control); + if (AVSYS_SUCCESS(err)) + err = __avsys_audio_path_set_ap_capture(control); + + avsys_audio_pa_ctrl_set_use_case(verb, devices, dev_idx, modifiers, mod_idx); + + __reset_ucm_controls(); + + if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + + return err; +} + +EXPORT_API +int avsys_audio_path_ex_dump(void) +{ + avsys_audio_path_ex_info_t *control = NULL; + avsys_audio_path_ex_info_t **temp = NULL; + const static char *str_earType[] = { "None", "EarOnly", "EarMic", "TVout" }; + const static char *str_yn[] = { "NO", "YES" }; + const static char *str_ear[] = { "MANUAL", "AUTO_MUTE", "AUTO_NOMUTE" }; + const static char *str_out[AVSYS_AUDIO_PATH_EX_OUTMAX] = { + "NONE", "SPK", "RECV", "HEADSET", "BTHEADSET", "A2DP", "HANSFREE", "HDMI", "DOCK", "USBAUDIO" + }; + const static char *str_in[AVSYS_AUDIO_PATH_EX_INMAX] = { + "NONE", "MIC", "HEADMIC", "BTMIC", "FMINPUT", "HANSFREEMIC" + }; + + const static char *str_playback_gain[AVSYS_AUDIO_PLAYBACK_GAIN_MAX] = { + "AP", "FMRADIO", "VOICECALL", "VIDEOCALL", "VOIP", "CALLALERT", + }; + const static char *str_capture_gain[AVSYS_AUDIO_CAPTURE_GAIN_MAX] = { + "AP", "FMRADIO", "VOICECALL", "VIDEOCALL", "VOIP" + }; + + int index = 0; + + temp = &control; + + if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp))) { + avsys_error_r(AVAUDIO, "avsys_audio_get_shm() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + if (control == NULL) + return AVSYS_STATE_ERR_NULL_POINTER; + + fprintf(stdout, "======================================================================\n"); + fprintf(stdout, " Avsystem Audio Path Control Information \n"); + fprintf(stdout, "======================================================================\n"); +#if defined(_MMFW_I386_ALL_SIMULATOR) + fprintf(stdout, " In simulator, follow informations don`t have means.\n"); +#endif + + fprintf(stdout, " GAIN : P (%-s / %-s) - R (%-s / %-s) - C (%-s / %-s)\n", + str_playback_gain[control->pregain.playback], str_capture_gain[control->pregain.capture], + str_playback_gain[control->reqgain.playback], str_capture_gain[control->reqgain.capture], + str_playback_gain[control->gain.playback], str_capture_gain[control->gain.capture]); + fprintf(stdout, " Current Out / In : %-s / %-s\n", str_out[control->path.playback], str_in[control->path.capture] ); + fprintf(stdout, " Path Fixed State : 0x%-x\n", control->path_fixed); + fprintf(stdout, " Mute status : %d\n", control->mute); + if (control->path_fixed_pid[PATH_FIXED_TYPE_FMRADIO] != -1) + fprintf(stdout, " FM Radio path pid : %d\n", control->path_fixed_pid[PATH_FIXED_TYPE_FMRADIO]); + if (control->path_fixed_pid[PATH_FIXED_TYPE_CALL] != -1) + fprintf(stdout, " Call path pid : %d\n", control->path_fixed_pid[PATH_FIXED_TYPE_CALL]); + + index = 0; + do { + if (control->pathlock_pid[index] != -1) + fprintf(stdout, " Path sync lock required PIDs : %d\n", control->pathlock_pid[index]); + index++; + } while (index < AVSYS_AUDIO_LOCK_SLOT_MAX); + fprintf(stdout, " Option Dual out : %-s\n", str_yn[(control->option & AVSYS_AUDIO_PATH_OPTION_DUAL_OUT) ? 1 : 0]); + fprintf(stdout, " Option Forced : %-s\n", str_yn[(control->option & AVSYS_AUDIO_PATH_OPTION_FORCED) ? 1 : 0]); + + return AVSYS_STATE_SUCCESS; +} + +#define DO_IF_VALID(c, p) { if(c > -1) p; } +#define DO_IF_INVALID(c, p) { if(c == -1) p; } +#define CHECK_VALID(c) (c>-1 ? 1 : 0) + +enum { + CMD_DEVICE_NONE = 0, + CMD_DEVICE_OPEN, + CMD_DEVICE_CLOSE, /* Not used */ + CMD_DEVICE_MAX +}; + +static int __avsys_audio_release_path (gain_info_t local_gain, avsys_audio_path_ex_info_t *control) +{ + int err = AVSYS_STATE_SUCCESS; + + avsys_warning(AVAUDIO, "Release path for %d %d\n", local_gain.playback, local_gain.capture); + + switch (local_gain.playback) { + case AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL: + case AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL: + case AVSYS_AUDIO_PLAYBACK_GAIN_VOIP: + if ((control->path_fixed & PATH_FIXED_WITH_CALL) == 0) { + avsys_error(AVAUDIO, "Call path release without call path request\n"); + } + control->path_fixed &= ~PATH_FIXED_WITH_CALL; + control->path_fixed_pid[PATH_FIXED_TYPE_CALL] = -1; + + break; + + case AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO: + /* FIXME: Diable Codec on Suspend */ + break; + + default: + avsys_warning(AVAUDIO, "unexpected path release\n"); + break; + } + + if (control->path_fixed != PATH_FIXED_NONE) { + avsys_error(AVAUDIO, "Still remain another path_fixed request : 0x%08X\n", control->path_fixed); + avsys_error(AVAUDIO, "This is not expected condition\n"); + } else { + avsys_warning(AVAUDIO, "Path Release to default condition....\n"); + control->gain.playback = AVSYS_AUDIO_PLAYBACK_GAIN_AP; + control->gain.capture = AVSYS_AUDIO_CAPTURE_GAIN_AP; + control->path.playback = AVSYS_AUDIO_PATH_EX_SPK; + control->path.capture = AVSYS_AUDIO_PATH_EX_MIC; + + /* Playback */ + err = __avsys_audio_path_set_ap_playback(control); + if (AVSYS_FAIL(err)) { + avsys_error(AVAUDIO, "Set ap playback failure\n"); + } + + /* Capture */ + err = __avsys_audio_path_set_ap_capture(control); + if (AVSYS_FAIL(err)) { + avsys_error(AVAUDIO, "Set ap capture failure\n"); + } + + avsys_audio_pa_ctrl_set_use_case(verb, devices, dev_idx, modifiers, mod_idx); + + __reset_ucm_controls(); + } + + return err; +} + +int avsys_audio_path_ex_set_path(int gain, int out, int in, int option) +{ + avsys_audio_path_ex_info_t *control = NULL; + avsys_audio_path_ex_info_t **temp = NULL; + gain_info_t local_gain = { -1, -1 }; + gain_info_t req_gain = { -1, -1 }; + pid_t current_pid; + int err = AVSYS_STATE_SUCCESS; + char req_release_path = 0; + bool skip_playback_setting = false; + bool skip_capture_setting = false; + + avsys_warning(AVAUDIO, "=================== [Input Param] gain %d, out %d, in %d, opt 0x%x ====================\n", gain, out, in, option); + + /* Determine REQUESTs */ + switch (gain) { + case AVSYS_AUDIO_GAIN_EX_KEYTONE: + case AVSYS_AUDIO_GAIN_EX_ALARMTONE: + case AVSYS_AUDIO_GAIN_EX_AUDIOPLAYER: + case AVSYS_AUDIO_GAIN_EX_VIDEOPLAYER: + case AVSYS_AUDIO_GAIN_EX_CAMERA: + case AVSYS_AUDIO_GAIN_EX_GAME: + case AVSYS_AUDIO_GAIN_EX_STEREO_REC: + case AVSYS_AUDIO_GAIN_EX_VOICEREC: + if(out == AVSYS_AUDIO_PATH_EX_NONE && in != AVSYS_AUDIO_PATH_EX_NONE) { + req_gain.capture = AVSYS_AUDIO_CAPTURE_GAIN_AP; + } else { + req_gain.playback = AVSYS_AUDIO_PLAYBACK_GAIN_AP; + req_gain.capture = AVSYS_AUDIO_CAPTURE_GAIN_AP; + } + break; + + case AVSYS_AUDIO_GAIN_EX_RINGTONE: + case AVSYS_AUDIO_GAIN_EX_CALLTONE: + req_gain.playback = AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT; + break; + +#if 0 + case AVSYS_AUDIO_GAIN_EX_VOICEREC: + req_gain.capture = AVSYS_AUDIO_CAPTURE_GAIN_AP; + break; +#endif + + case AVSYS_AUDIO_GAIN_EX_VOICERECOGNITION: + req_gain.playback = AVSYS_AUDIO_PLAYBACK_GAIN_AP; + req_gain.capture = AVSYS_AUDIO_CAPTURE_GAIN_VOICERECOGNITION; + break; + + case AVSYS_AUDIO_GAIN_EX_VOICECALL: + req_gain.playback = AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL; + req_gain.capture = AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL; + if (out == AVSYS_AUDIO_PATH_EX_NONE && in == AVSYS_AUDIO_PATH_EX_NONE) + req_release_path = 1; + break; + + case AVSYS_AUDIO_GAIN_EX_VIDEOCALL: + req_gain.playback = AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL; + req_gain.capture = AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL; + if (out == AVSYS_AUDIO_PATH_EX_NONE && in == AVSYS_AUDIO_PATH_EX_NONE) + req_release_path = 1; + break; + + case AVSYS_AUDIO_GAIN_EX_VOIP: + req_gain.playback = AVSYS_AUDIO_PLAYBACK_GAIN_VOIP; + req_gain.capture = AVSYS_AUDIO_CAPTURE_GAIN_VOIP; + if (out == AVSYS_AUDIO_PATH_EX_NONE && in == AVSYS_AUDIO_PATH_EX_NONE) + req_release_path = 1; + break; + + case AVSYS_AUDIO_GAIN_EX_FMRADIO: + req_gain.playback = AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO; + req_gain.capture = AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO; + if (out == AVSYS_AUDIO_PATH_EX_NONE && in == AVSYS_AUDIO_PATH_EX_NONE) + req_release_path = 1; + break; + } + + /* Get avsys shared memeory */ + temp = &control; + if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp))) { + avsys_error_r(AVAUDIO, "avsys_audio_get_shm() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + /* LOCK */ + if (AVSYS_FAIL(avsys_audio_lock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_lock_sync() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + + current_pid = getpid(); /* moved from below */ + + /* Check FORCED option */ + if (option & AVSYS_AUDIO_PATH_OPTION_FORCED) { + DO_IF_VALID(req_gain.playback, local_gain.playback = req_gain.playback) + DO_IF_VALID(req_gain.capture, local_gain.capture = req_gain.capture) + } else { + DO_IF_VALID(req_gain.playback, local_gain.playback = g_playback_gain_select_data[control->gain.playback][req_gain.playback]) + DO_IF_VALID(req_gain.capture, local_gain.capture = g_capture_gain_select_data[control->gain.capture][req_gain.capture]) + } + + avsys_info(AVAUDIO, "Gain : req(%d,%d) local(%d,%d)\n", req_gain.playback, req_gain.capture, local_gain.playback, local_gain.capture); + + /* Check path fixed process alive. */ + if (control->path_fixed & PATH_FIXED_WITH_CALL) { + if (AVSYS_FAIL(avsys_check_process(control->path_fixed_pid[PATH_FIXED_TYPE_CALL]))) { + control->path_fixed &= ~PATH_FIXED_WITH_CALL; + } + } + if (control->path_fixed == PATH_FIXED_NONE) { + /* forced gain setting when path fixed by dead process */ + if (req_gain.playback != local_gain.playback) { + local_gain.playback = req_gain.playback; + } + if (req_gain.capture != local_gain.capture) { + local_gain.capture = req_gain.capture; + } + } + + if (CHECK_VALID(local_gain.playback)) { + if (g_playback_path_select_data[local_gain.playback][out] == 0) { + avsys_error(AVAUDIO, "[PLAYBACK] Does not support request sound path : conv gain %d, out path %d\n", local_gain.playback, out); + if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + return AVSYS_STATE_ERR_INVALID_STATE; + } + } + if (CHECK_VALID(local_gain.capture)) { + if (g_capture_path_select_data[local_gain.capture][in] == 0) { + avsys_error(AVAUDIO, "[CAPTURE] Does not support request sound path : conv gain %d, in path %d\n", local_gain.capture, in); + if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + return AVSYS_STATE_ERR_INVALID_STATE; + } + } + + /* Check duplicated path */ + /* Check duplicated request for playback */ + if ((control->gain.playback == local_gain.playback) && (control->path.playback == out) && (control->option == option)) { + avsys_warning(AVAUDIO, "skip duplicated playback gain:%d out:%x option:%x", local_gain.playback, out, option); + skip_playback_setting = true; + } + /* Check duplicated request for capture */ + if ((control->gain.capture == local_gain.capture) && (control->path.capture == in) && (control->option == option)) { + avsys_warning(AVAUDIO, "skip duplicated capture gain:%d in:%x option:%x", local_gain.capture, in, option); + skip_capture_setting = true; + } + if (skip_playback_setting && skip_capture_setting) { + goto FINISHED; + } +#if 0 /* This function is moved to libmm-sound */ + if ((control->gain.playback == local_gain.playback) && (control->gain.capture == local_gain.capture) + && (control->path.playback == out) && (control->path.capture == in) && (control->option == option)) { + avsys_warning(AVAUDIO, "skip duplicated path request playback:%d capture:%x in:%x out:%x option:%x", + local_gain.playback, local_gain.capture, in, out, option); + goto FINISHED; + } +#endif + + /* overwrite local_gain with current gain if it is simplex sound path */ + if(!(out == AVSYS_AUDIO_PATH_EX_NONE && !req_release_path)) { + DO_IF_INVALID(local_gain.playback, local_gain.playback = control->gain.playback) + } + DO_IF_INVALID(local_gain.capture, local_gain.capture = control->gain.capture) + control->pregain = control->gain; + control->gain = local_gain; + + DO_IF_VALID(req_gain.playback, control->reqgain.playback = req_gain.playback) + DO_IF_VALID(req_gain.capture, control->reqgain.capture = req_gain.capture) + control->option = option; + + /* Check for Release PATH */ + if (req_release_path && (req_gain.playback == local_gain.playback) && (req_gain.capture == local_gain.capture)) { + avsys_warning(AVAUDIO,"Release path for %d %d\n", local_gain.playback, local_gain.capture); + + err = __avsys_audio_release_path(local_gain, control); + goto FINISHED; + } + if (CHECK_VALID(req_gain.playback)) { + if(req_gain.playback != local_gain.playback) { + avsys_warning(AVAUDIO, "Sound Path is protected. use current configuration (playback_gain %d, out %d, opt 0x%x)\n", + local_gain.playback, control->path.playback, control->option); + } else { + control->path.playback = out; + + switch (local_gain.playback) { + case AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT: + break; + + case AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL: + case AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL: + case AVSYS_AUDIO_PLAYBACK_GAIN_VOIP: + /* Voicecall / Videocall Common setting */ + control->path_fixed_pid[PATH_FIXED_TYPE_CALL] = current_pid; + break; + + case AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO: + control->path_fixed_pid[PATH_FIXED_TYPE_FMRADIO] = current_pid; + break; + } + } + } + + if (CHECK_VALID(req_gain.capture)) { + if (req_gain.capture != local_gain.capture) { + avsys_warning(AVAUDIO, "Sound Path is protected. use current configuration (capture_gain %d, in %d, opt 0x%x)\n", + local_gain.capture, control->path.capture, control->option); + } else { + control->path.capture = in; + + switch (local_gain.capture) { + case AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL: + case AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL: + case AVSYS_AUDIO_CAPTURE_GAIN_VOIP: + /* Voicecall / Videocall Common setting */ + control->path_fixed_pid[PATH_FIXED_TYPE_CALL] = current_pid; + break; + + case AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO: + control->path_fixed_pid[PATH_FIXED_TYPE_FMRADIO] = current_pid; + break; + } + } + } + + /* Do use case control based on gain */ + /* Playback */ + if (local_gain.playback == AVSYS_AUDIO_PLAYBACK_GAIN_AP) { + avsys_warning(AVAUDIO, "playback gain : ap\n"); + err = __avsys_audio_path_set_ap_playback(control); + } else if(local_gain.playback == AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT) { + avsys_warning(AVAUDIO,"playback gain : callalert\n"); + err = __avsys_audio_path_set_ap_playback(control); + } else if (local_gain.playback == AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO && + local_gain.capture == AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO) { + avsys_warning(AVAUDIO, "fmradio gain\n"); + err = __avsys_audio_path_set_fmradio(control); + } else if (local_gain.playback == AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL && + local_gain.capture == AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL) { + avsys_warning(AVAUDIO, "voicecall gain\n"); + err = __avsys_audio_path_set_voicecall(control); + } else if (local_gain.playback == AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL && + local_gain.capture == AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL) { + avsys_warning(AVAUDIO, "videocall gain\n"); + /* FIXME : VT call using VOIP UCM,So re-using the same function */ + err = __avsys_audio_path_set_voip(control); + } else if (local_gain.playback == AVSYS_AUDIO_PLAYBACK_GAIN_VOIP && + local_gain.capture == AVSYS_AUDIO_CAPTURE_GAIN_VOIP) { + avsys_warning(AVAUDIO, "voip gain\n"); + err = __avsys_audio_path_set_voip(control); + } + /* Capture */ + if (local_gain.capture == AVSYS_AUDIO_CAPTURE_GAIN_AP) { + avsys_warning(AVAUDIO, "capture gain : ap\n"); + err = __avsys_audio_path_set_ap_capture(control); + } else if (local_gain.capture == AVSYS_AUDIO_CAPTURE_GAIN_VOICERECOGNITION) { + avsys_warning(AVAUDIO, "capture gain : voicerecognition\n"); + err = __avsys_audio_path_set_ap_voicerecognition(control); + } + + avsys_audio_pa_ctrl_set_use_case(verb, devices, dev_idx, modifiers, mod_idx); + + __reset_ucm_controls(); + +FINISHED: + /* UnLOCK */ + if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + avsys_info(AVAUDIO, "------------------------------------------------\n"); + return err; +} + +int avsys_audio_path_ex_get_path(int *gain, int *out, int *in, int *option) +{ + avsys_audio_path_ex_info_t *control = NULL; + avsys_audio_path_ex_info_t ** temp = NULL; + + if(gain == NULL || out == NULL || in == NULL || option == NULL) { + avsys_error(AVAUDIO,"Invalid parameter\n"); + return AVSYS_STATE_ERR_NULL_POINTER; + } + + temp = &control; + + if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp))) { + avsys_error_r(AVAUDIO, "avsys_audio_get_shm() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + if (AVSYS_FAIL(avsys_audio_lock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_lock_sync() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + + *out = control->path.playback; + *in = control->path.capture; + *option = control->option; + + switch (control->gain.playback) { + case AVSYS_AUDIO_PLAYBACK_GAIN_AP: + *gain = AVSYS_AUDIO_GAIN_EX_KEYTONE; + break; + case AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT: + *gain = AVSYS_AUDIO_GAIN_EX_RINGTONE; + break; + case AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL: + *gain = AVSYS_AUDIO_GAIN_EX_VOICECALL; + break; + case AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL: + *gain = AVSYS_AUDIO_GAIN_EX_VIDEOCALL; + break; + case AVSYS_AUDIO_PLAYBACK_GAIN_VOIP: + *gain = AVSYS_AUDIO_GAIN_EX_VOIP; + break; + case AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO: + *gain = AVSYS_AUDIO_GAIN_EX_FMRADIO; + break; + } + + if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + + return AVSYS_STATE_SUCCESS; +} + +int avsys_audio_path_ex_set_amp(const int onoff) +{ + //not yet implemented. + return AVSYS_STATE_SUCCESS; +} + +int avsys_audio_path_ex_set_mute(const int mute) +{ + avsys_audio_path_ex_info_t *control = NULL; + avsys_audio_path_ex_info_t **temp = NULL; + + temp = &control; + + if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp))) { + avsys_error_r(AVAUDIO, "avsys_audio_get_shm() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + + if (control == NULL) { + return AVSYS_STATE_ERR_NULL_POINTER; + } + + if (mute == AVSYS_AUDIO_UNMUTE || mute == AVSYS_AUDIO_MUTE) { + if (AVSYS_FAIL(avsys_audio_lock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_lock_sync() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + + if (control->mute == mute) { + if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() 2 failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + return AVSYS_STATE_SUCCESS; + } else { + control->mute = mute; + } +#if 0 // FIXME + if (control->mute) { + if (AVSYS_FAIL(avsys_audio_ascn_single_set(ASCN_STR_PLAYBACK_MUTE))) { + if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() 1 failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + avsys_error(AVAUDIO, "Mute fail\n"); + return AVSYS_STATE_ERR_IO_CONTROL; + } + } else { + if (AVSYS_FAIL(avsys_audio_ascn_single_set(ASCN_STR_PLAYBACK_UNMUTE))) { + if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() 1 failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + avsys_error(AVAUDIO, "Unmute fail\n"); + return AVSYS_STATE_ERR_IO_CONTROL; + } + } +#endif + if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() 2 failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + } else { + int mute_nolock; + if (mute == AVSYS_AUDIO_UNMUTE_NOLOCK) /* set nomalize */ + mute_nolock = AVSYS_AUDIO_UNMUTE; + else + mute_nolock = AVSYS_AUDIO_MUTE; + + if (control->mute == mute_nolock) { + return AVSYS_STATE_SUCCESS; + } else { + control->mute = mute_nolock; + } +#if 0 // FIXME + if (control->mute) { + if (AVSYS_FAIL(avsys_audio_ascn_single_set(ASCN_STR_PLAYBACK_MUTE))) { + avsys_error(AVAUDIO, "Mute fail\n"); + return AVSYS_STATE_ERR_IO_CONTROL; + } + } else { + if (AVSYS_FAIL(avsys_audio_ascn_single_set(ASCN_STR_PLAYBACK_UNMUTE))) { + avsys_error(AVAUDIO, "Unmute fail\n"); + return AVSYS_STATE_ERR_IO_CONTROL; + } + } +#endif + } + + if (mute == AVSYS_AUDIO_UNMUTE || mute == AVSYS_AUDIO_UNMUTE_NOLOCK) + avsys_info_r(AVAUDIO, "Global Mute Disabled\n"); + else if (mute == AVSYS_AUDIO_MUTE || mute == AVSYS_AUDIO_MUTE_NOLOCK) + avsys_info_r(AVAUDIO, "Global Mute Enabled\n"); + return AVSYS_STATE_SUCCESS; +} + +int avsys_audio_path_ex_get_mute(int *mute) +{ + avsys_audio_path_ex_info_t *control = NULL; + avsys_audio_path_ex_info_t **temp = NULL; + + temp = &control; + + if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp))) { + avsys_error_r(AVAUDIO, "avsys_audio_get_shm() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + + if (control == NULL) { + return AVSYS_STATE_ERR_NULL_POINTER; + } + + if (AVSYS_FAIL(avsys_audio_lock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_lock_sync() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + + *mute = control->mute; + + if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + + return AVSYS_STATE_SUCCESS; +} + +int avsys_audio_path_ex_set_factory_loopback_test(int loopback) +{ + return avsys_audio_alsa_set_mixer_control(MIXER_CTL_LOOPBACK_ENABLE, loopback); +} + +int avsys_audio_path_ex_get_factory_loopback_test(int *loopback) +{ + return avsys_audio_alsa_get_mixer_control(MIXER_CTL_LOOPBACK_ENABLE, loopback); +} + +static int __avsys_audio_path_set_ap_playback(avsys_audio_path_ex_info_t *control) +{ + verb = UC_VERB_HIFI; + + avsys_info(AVAUDIO, "<< path.playback = %d, option = %x, gain.playback = %d\n", + control->path.playback, control->option, control->gain.playback); + + control->path_fixed = PATH_FIXED_NONE; + + switch (control->path.playback) { + case AVSYS_AUDIO_PATH_EX_SPK: + if (control->option & AVSYS_AUDIO_PATH_OPTION_DUAL_OUT) { + devices[dev_idx++] = UC_OUT_DEV_SPEAKER_HEADSET; + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + } else { + devices[dev_idx++] = UC_OUT_DEV_SPEAKER; + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + } + break; + + case AVSYS_AUDIO_PATH_EX_RECV: + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + devices[dev_idx++] = UC_OUT_DEV_HANDSET; + break; + + case AVSYS_AUDIO_PATH_EX_HEADSET: + devices[dev_idx++] = UC_OUT_DEV_HEADSET; + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET; + break; + + case AVSYS_AUDIO_PATH_EX_HDMI: + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_HDMI; + devices[dev_idx++] = UC_OUT_DEV_HDMI; + modifiers[mod_idx++] = UC_MODIFIER_PLAY_MULTICH_HDMI; + break; + + case AVSYS_AUDIO_PATH_EX_DOCK: + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + devices[dev_idx++] = UC_OUT_DEV_DOCK; + break; + + case AVSYS_AUDIO_PATH_EX_BTHEADSET: + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_BTHEADSET; + if (control->option & AVSYS_AUDIO_PATH_OPTION_BT_NREC) { + if (control->option & AVSYS_AUDIO_PATH_OPTION_BT_WB) { + devices[dev_idx++] = UC_OUT_DEV_BT_NREC_HEADSET_16K; + } else { + devices[dev_idx++] = UC_OUT_DEV_BT_NREC_HEADSET; + } + } else { + if (control->option & AVSYS_AUDIO_PATH_OPTION_BT_WB) { + devices[dev_idx++] = UC_OUT_DEV_BT_HEADSET_16K; + } else { + devices[dev_idx++] = UC_OUT_DEV_BT_HEADSET; + } + } + avsys_audio_alsa_set_mixer_control(MIXER_CTL_AUX_PCM_SAMPLERATE, (control->option & AVSYS_AUDIO_PATH_OPTION_BT_WB)? 1:0); + break; + + case AVSYS_AUDIO_PATH_EX_WFD: + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + devices[dev_idx++] = UC_OUT_DEV_WIFI_DISPLAY; + break; + + case AVSYS_AUDIO_PATH_EX_HANDSFREE: + default: + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + break; + } + + modifiers[mod_idx++] = UC_MODIFIER_PLAY_LPA; + + if (control->option & AVSYS_AUDIO_PATH_OPTION_MIRRORING) { + if (control->option & AVSYS_AUDIO_PATH_OPTION_DUAL_OUT) { + avsys_info(AVAUDIO, "Skip WFD enable during DUAL path"); + } else { + modifiers[mod_idx++] = UC_MODIFIER_PLAY_WIFI_DISPLAY; + } + } + + avsys_info(AVAUDIO, ">> leave"); + return AVSYS_STATE_SUCCESS; +} + +static int __avsys_audio_path_set_voicecall(avsys_audio_path_ex_info_t *control) +{ + int is_loopback = 0; + + if(control->gain.playback == AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL) + verb = UC_VERB_VOICE_CALL; + else if(control->gain.playback == AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL) + verb = UC_VERB_VIDEO_CALL; + + control->path_fixed = PATH_FIXED_WITH_CALL; + + avsys_info(AVAUDIO, "<< path.playback = %d, option = %x, gain.playback = %d\n", + control->path.playback, control->option, control->gain.playback); + + /* get loopback status and if enabled, set loopback device */ + avsys_audio_path_ex_get_factory_loopback_test(&is_loopback); + avsys_info(AVAUDIO, "is_loopback = %d\n", is_loopback); + /* msm8x74 DSP loopback has dependency of VoIP verb. */ + if (is_loopback) + verb = UC_VERB_LOOPBACK; + + /* PLAYBACK */ + switch (control->path.playback) { + case AVSYS_AUDIO_PATH_EX_NONE: + avsys_warning(AVAUDIO, "[SZ] playback AVSYS_AUDIO_PATH_EX_NONE\n"); + break; + + case AVSYS_AUDIO_PATH_EX_SPK: + /* Note: Dual Mic is not avilable for speaker in MSM8x74 */ + /* FIXME: WB handling is needed */ + if (control->reqgain.playback == control->gain.playback) { + if (control->option & AVSYS_AUDIO_PATH_OPTION_CALL_EXTRA_VOL) { + devices[dev_idx++] = UC_OUT_DEV_CALL_SPEAKER_EXTRA_VOL; + } else { + devices[dev_idx++] = (is_loopback)? UC_OUT_DEV_LOOPBACK_SPEAKER : UC_OUT_DEV_CALL_SPEAKER; + } + } else { + avsys_warning(AVAUDIO, "Ignore another path setting request during voicecall\n"); + } + break; + + case AVSYS_AUDIO_PATH_EX_RECV: + if (control->gain.playback == control->reqgain.playback) { + /* FIXME: WB handling is needed */ + + if (control->option & AVSYS_AUDIO_PATH_OPTION_CALL_EXTRA_VOL) { + devices[dev_idx++] = UC_OUT_DEV_CALL_HANDSET_EXTRA_VOL; + } else { + devices[dev_idx++] = (is_loopback)? UC_OUT_DEV_LOOPBACK_HANDSET : UC_OUT_DEV_CALL_HANDSET; + } + } + break; + + case AVSYS_AUDIO_PATH_EX_HEADSET: + if (control->reqgain.playback == control->gain.playback) { + devices[dev_idx++] = (is_loopback)? UC_OUT_DEV_LOOPBACK_HEADSET : UC_OUT_DEV_CALL_HEADSET; + } else { + avsys_warning(AVAUDIO, "Ignore another path setting request during voicecall\n"); + } + break; + + case AVSYS_AUDIO_PATH_EX_BTHEADSET: + if (control->reqgain.playback == control->gain.playback) { + if (control->option & AVSYS_AUDIO_PATH_OPTION_BT_NREC) { + if (control->option & AVSYS_AUDIO_PATH_OPTION_BT_WB) { + devices[dev_idx++] = UC_OUT_DEV_BT_NREC_HEADSET_16K; + } else { + devices[dev_idx++] = UC_OUT_DEV_BT_NREC_HEADSET; + } + } else { + if (control->option & AVSYS_AUDIO_PATH_OPTION_BT_WB) { + devices[dev_idx++] = UC_OUT_DEV_BT_HEADSET_16K; + } else { + devices[dev_idx++] = UC_OUT_DEV_BT_HEADSET; + } + } + avsys_audio_alsa_set_mixer_control(MIXER_CTL_AUX_PCM_SAMPLERATE, (control->option & AVSYS_AUDIO_PATH_OPTION_BT_WB)? 1:0); + } else { + avsys_warning(AVAUDIO, "Ignore another path setting request during voicecall\n"); + } + break; + + case AVSYS_AUDIO_PATH_EX_HANDSFREE: + default: + if (control->reqgain.playback == control->gain.playback) { + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + } + break; + } + + modifiers[mod_idx++] = UC_MODIFIER_PLAY_MUSIC; + /* PLAY_LPA modifier does not need on loopback test */ + /* remove + if (!is_loopback) { + modifiers[mod_idx++] = UC_MODIFIER_PLAY_LPA; + } + */ + + /* UPLINK_DOWNLINK modifier does not need on loopback test */ + if (!is_loopback) { + modifiers[mod_idx++] = UC_MODIFIER_CAPTURE_CALL_UPLINK_DOWNLINK; + } + + if(control->option & AVSYS_AUDIO_PATH_OPTION_VOICECALL_REC_AM) { + modifiers[mod_idx++] = UC_MODIFIER_CAPTURE_CALL_DOWNLINK; + avsys_info(AVAUDIO, "answering memo record\n"); + } + + if(control->option & AVSYS_AUDIO_PATH_OPTION_VOICECALL_PLAY_AM) { + modifiers[mod_idx++] = UC_MODIFIER_PLAY_VOICE_CALL_MUSIC; + avsys_info(AVAUDIO, "answering memo play\n"); + } + + /* CAPTURE */ + switch (control->path.capture) { + case AVSYS_AUDIO_PATH_EX_NONE: + avsys_warning(AVAUDIO, "[SZ] capture AVSYS_AUDIO_PATH_EX_NONE\n"); + break; + + case AVSYS_AUDIO_PATH_EX_MIC: + if (control->reqgain.capture == control->gain.capture) { + if (control->option & AVSYS_AUDIO_PATH_OPTION_USE_2MIC) { + devices[dev_idx++] = UC_IN_DEV_DUAL_MIC_RCV; + } else { + if (control->path.playback == AVSYS_AUDIO_PATH_EX_SPK) + devices[dev_idx++] = (is_loopback)? UC_IN_DEV_LOOPBACK_SUB_MIC : UC_IN_DEV_CALL_SUB_MIC; + else if (control->path.playback == AVSYS_AUDIO_PATH_EX_HEADSET) + devices[dev_idx++] = (is_loopback)? UC_IN_DEV_LOOPBACK_HEADSET_MIC : UC_IN_DEV_CALL_HEADPHONE_MIC; + else + devices[dev_idx++] = (is_loopback)? UC_IN_DEV_LOOPBACK_MAIN_MIC : UC_IN_DEV_CALL_MAIN_MIC; + } + } + break; + + case AVSYS_AUDIO_PATH_EX_HEADSETMIC: + if (control->reqgain.capture == control->gain.capture) { + devices[dev_idx++] = (is_loopback)? UC_IN_DEV_LOOPBACK_HEADSET_MIC : UC_IN_DEV_CALL_HEADSET_MIC; + } + break; + + case AVSYS_AUDIO_PATH_EX_BTMIC: + if (control->reqgain.capture == control->gain.capture) { + if (control->option & AVSYS_AUDIO_PATH_OPTION_BT_NREC) { + if (control->option & AVSYS_AUDIO_PATH_OPTION_BT_WB) { + devices[dev_idx++] = UC_IN_DEV_CALL_BT_NREC_MIC_16K; + } else { + devices[dev_idx++] = UC_IN_DEV_CALL_BT_NREC_MIC; + } + } else { + if (control->option & AVSYS_AUDIO_PATH_OPTION_BT_WB) { + devices[dev_idx++] = UC_IN_DEV_CALL_BT_MIC_16K; + } else { + devices[dev_idx++] = UC_IN_DEV_CALL_BT_MIC; + } + } + avsys_audio_alsa_set_mixer_control(MIXER_CTL_AUX_PCM_SAMPLERATE, (control->option & AVSYS_AUDIO_PATH_OPTION_BT_WB)? 1:0); + } + break; + case AVSYS_AUDIO_PATH_EX_HANDSFREE: + default: + break; + } + + // Should be set only 2 devices "Call Handset AM", "Call Main Mic AM" + if(control->option & AVSYS_AUDIO_PATH_OPTION_VOICECALL_PLAY_AM || + control->option & AVSYS_AUDIO_PATH_OPTION_VOICECALL_REC_AM) { + dev_idx = 0; + devices[dev_idx++] = UC_IN_DEV_CALL_HANDSET_AM; + devices[dev_idx++] = UC_IN_DEV_CALL_MAN_MIC_AM; + avsys_info(AVAUDIO, "set answering memo devices\n"); + } + + avsys_info(AVAUDIO, ">> leave"); + return AVSYS_STATE_SUCCESS; +} + +static int __avsys_audio_path_set_voip(avsys_audio_path_ex_info_t *control) +{ +#if USE_HIFI_FOR_VOIP + verb = UC_VERB_HIFI; + modifiers[mod_idx++] = UC_MODIFIER_VOIP; + modifiers[mod_idx++] = UC_MODIFIER_CAPTURE_MUSIC; +#else + verb = UC_VERB_VOIP; + modifiers[mod_idx++] = UC_MODIFIER_PLAY_MUSIC; + modifiers[mod_idx++] = UC_MODIFIER_CAPTURE_MUSIC; +#endif + + control->path_fixed = PATH_FIXED_WITH_CALL; + + /* Playback */ + switch (control->path.playback) { + case AVSYS_AUDIO_PATH_EX_NONE: + avsys_warning(AVAUDIO, "[SZ] playback AVSYS_AUDIO_PATH_EX_NONE\n"); + break; + + case AVSYS_AUDIO_PATH_EX_SPK: + if (control->reqgain.playback == control->gain.playback) { + devices[dev_idx++] = UC_OUT_DEV_VOIP_SEC_SPEAKER; + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + } else { + avsys_warning(AVAUDIO, "Sound Path request during VT call ignored."); + } + break; + + case AVSYS_AUDIO_PATH_EX_RECV: + if (control->gain.playback == control->reqgain.playback) { + devices[dev_idx++] = UC_OUT_DEV_VOIP_SEC_HANDSET; + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + } else { + avsys_warning(AVAUDIO, "Sound Path request during VT call ignored."); + } + break; + + case AVSYS_AUDIO_PATH_EX_HEADSET: + if (control->reqgain.playback == control->gain.playback) { + devices[dev_idx++] = UC_OUT_DEV_VOIP_SEC_HEADSET; + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET; + } else { + avsys_warning(AVAUDIO, "Sound Path request during VT call ignored."); + } + break; + + case AVSYS_AUDIO_PATH_EX_BTHEADSET: + if (control->reqgain.playback == control->gain.playback) { + if (control->option & AVSYS_AUDIO_PATH_OPTION_BT_NREC) + devices[dev_idx++] = UC_OUT_DEV_VOIP_SEC_BT_NREC_HEADSET; + else + devices[dev_idx++] = UC_OUT_DEV_VOIP_SEC_BT_HEADSET; + + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_BTHEADSET; + } else { + avsys_warning(AVAUDIO, "Sound Path request during VT call ignored."); + } + break; + + case AVSYS_AUDIO_PATH_EX_HANDSFREE: + default: + if (control->reqgain.playback == control->gain.playback) { + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + } + break; + } + + switch (control->path.capture) { + case AVSYS_AUDIO_PATH_EX_NONE: + avsys_warning(AVAUDIO, "[SZ] capture AVSYS_AUDIO_PATH_EX_NONE\n"); + break; + + case AVSYS_AUDIO_PATH_EX_MIC: + if (control->path.playback == AVSYS_AUDIO_PATH_EX_SPK) + devices[dev_idx++] = UC_IN_DEV_VOIP_SEC_SUB_MIC; + else if (control->path.playback == AVSYS_AUDIO_PATH_EX_HEADSET) + devices[dev_idx++] = UC_IN_DEV_VOIP_SEC_HEADPHONE_MIC; + else + devices[dev_idx++] = UC_IN_DEV_VOIP_SEC_MAIN_MIC; + break; + + case AVSYS_AUDIO_PATH_EX_HEADSETMIC: + devices[dev_idx++] = UC_IN_DEV_VOIP_SEC_HEADSET_MIC; + break; + + case AVSYS_AUDIO_PATH_EX_BTMIC: + if (control->option & AVSYS_AUDIO_PATH_OPTION_BT_NREC) { + if (control->option & AVSYS_AUDIO_PATH_OPTION_BT_WB) { + devices[dev_idx++] = UC_IN_DEV_VOIP_SEC_BT_NREC_MIC_16K; + } else { + devices[dev_idx++] = UC_IN_DEV_VOIP_SEC_BT_NREC_MIC; + } + } else { + if (control->option & AVSYS_AUDIO_PATH_OPTION_BT_WB) { + devices[dev_idx++] = UC_IN_DEV_VOIP_SEC_BT_MIC_16K; + } else { + devices[dev_idx++] = UC_IN_DEV_VOIP_SEC_BT_MIC; + } + } + avsys_audio_alsa_set_mixer_control(MIXER_CTL_AUX_PCM_SAMPLERATE, (control->option & AVSYS_AUDIO_PATH_OPTION_BT_WB)? 1:0); + break; + + case AVSYS_AUDIO_PATH_EX_HANDSFREE: + default: + break; + } + + return AVSYS_STATE_SUCCESS; +} + + +static int __avsys_audio_path_set_fmradio(avsys_audio_path_ex_info_t *control) +{ + verb = UC_VERB_FMRADIO; + + avsys_warning(AVAUDIO, "req gain playback [%x], control gain playback [%x]\n", + control->reqgain.playback, control->gain.playback); + avsys_warning(AVAUDIO, "req gain capture [%x], control gain capture [%x]\n", + control->reqgain.capture, control->gain.capture); + + switch (control->path.playback) { + case AVSYS_AUDIO_PATH_EX_NONE: + avsys_warning(AVAUDIO, "[SZ] playback AVSYS_AUDIO_PATH_EX_NONE\n"); + break; + + case AVSYS_AUDIO_PATH_EX_SPK: + if (control->reqgain.playback == control->gain.playback) { + avsys_warning(AVAUDIO, "req gain playback == control gain playback\n"); + devices[dev_idx++] = UC_OUT_DEV_SPEAKER; + } else { + avsys_warning(AVAUDIO, "req gain playback != control gain playback\n"); + /* append ap playback sound path */ + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + devices[dev_idx++] = UC_OUT_DEV_SPEAKER; + } + break; + + case AVSYS_AUDIO_PATH_EX_HEADSET: + if (control->reqgain.playback == control->gain.playback) { + avsys_warning(AVAUDIO, "req gain playback == control gain playback\n"); + devices[dev_idx++] = UC_OUT_DEV_HEADSET; + } else { + //append ap playback + avsys_warning(AVAUDIO, "req gain playback != control gain playback\n"); + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET; + devices[dev_idx++] = UC_OUT_DEV_HEADSET; + } + break; + + case AVSYS_AUDIO_PATH_EX_A2DP: + if (control->reqgain.playback == control->gain.playback) { + avsys_warning(AVAUDIO, "req gain playback == control gain playback\n"); + devices[dev_idx++] = UC_OUT_DEV_BT_HEADSET; + } else { + avsys_warning(AVAUDIO, "req gain playback != control gain playback\n"); + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_BTHEADSET; + devices[dev_idx++] = UC_OUT_DEV_BT_HEADSET; + } + break; + + default: + break; + } + + switch (control->path.capture) { + case AVSYS_AUDIO_PATH_EX_FMINPUT: + if (control->reqgain.capture == control->gain.capture) { + avsys_warning(AVAUDIO, "req gain capture == control gain capture\n"); + devices[dev_idx++] = UC_IN_DEV_FMRADIO; + if (control->reqgain.capture == control->pregain.capture) { + avsys_warning(AVAUDIO, "req gain capture == control pregain capture\n"); + } + } + break; + default: + break; + } + + return AVSYS_STATE_SUCCESS; +} + +static int __avsys_audio_path_set_ap_capture(avsys_audio_path_ex_info_t *control) +{ + avsys_info(AVAUDIO, "<< path.capture = %d, option = %x, gain.capture = %d\n", + control->path.capture, control->option, control->gain.capture); + + switch(control->path.capture) { + case AVSYS_AUDIO_PATH_EX_MIC: + if (control->option & AVSYS_AUDIO_PATH_OPTION_BARGEIN) { + devices[dev_idx++] = UC_IN_DEV_VR_SEC_SUB_MIC; + } else if (control->option & AVSYS_AUDIO_PATH_OPTION_USE_SUBMIC) { + devices[dev_idx++] = UC_IN_DEV_SUB_MIC; + } else if (control->option & AVSYS_AUDIO_PATH_OPTION_USE_STEREOMIC) { + devices[dev_idx++] = UC_IN_DEV_STEREO_MIC; + } else if (control->option & AVSYS_AUDIO_PATH_OPTION_USE_STEREOMIC_DIRECTNL_INTV) { + devices[dev_idx++] = UC_IN_DEV_STEREO_MIC_INTERVIEW; + } else if (control->option & AVSYS_AUDIO_PATH_OPTION_USE_STEREOMIC_DIRECTNL_CONVS) { + devices[dev_idx++] = UC_IN_DEV_STEREO_MIC_CONVERSATION; + } else if (control->option & AVSYS_AUDIO_PATH_OPTION_USE_MAINMIC) { + devices[dev_idx++] = UC_IN_DEV_MAIN_MIC; + } else { + devices[dev_idx++] = UC_IN_DEV_VR_MAIN_MIC; + } + break; + + case AVSYS_AUDIO_PATH_EX_HEADSETMIC: + if (control->option & AVSYS_AUDIO_PATH_OPTION_BARGEIN) { + devices[dev_idx++] = UC_IN_DEV_VR_SEC_HEADSET_MIC; + } else { + devices[dev_idx++] = UC_IN_DEV_HEADSET_MIC; + } + break; + + case AVSYS_AUDIO_PATH_EX_BTMIC: + if (control->option & AVSYS_AUDIO_PATH_OPTION_BARGEIN) { + avsys_warning(AVAUDIO, "Unexpected BARGEIN option with BTMIC, use mainmic as alternative\n"); + devices[dev_idx++] = UC_IN_DEV_VR_SEC_MAIN_MIC; + } else if (control->option & AVSYS_AUDIO_PATH_OPTION_VR_NORMAL_CMD) { + devices[dev_idx++] = UC_IN_DEV_VR_BT_MIC; + } else { + if (control->option & AVSYS_AUDIO_PATH_OPTION_BT_NREC) { + if (control->option & AVSYS_AUDIO_PATH_OPTION_BT_WB) { + devices[dev_idx++] = UC_IN_DEV_BT_NREC_MIC_16K; + } else { + devices[dev_idx++] = UC_IN_DEV_BT_NREC_MIC; + } + } else { + if (control->option & AVSYS_AUDIO_PATH_OPTION_BT_WB) { + devices[dev_idx++] = UC_IN_DEV_BT_MIC_16K; + } else { + devices[dev_idx++] = UC_IN_DEV_BT_MIC; + } + } + avsys_audio_alsa_set_mixer_control(MIXER_CTL_AUX_PCM_SAMPLERATE, (control->option & AVSYS_AUDIO_PATH_OPTION_BT_WB)? 1:0); + } + break; + + default: + break; + } + modifiers[mod_idx++] = UC_MODIFIER_CAPTURE_MUSIC; + avsys_info (AVAUDIO, ">> leave"); + + return AVSYS_STATE_SUCCESS; +} + +static int __avsys_audio_path_set_ap_voicerecognition(avsys_audio_path_ex_info_t *control) +{ + avsys_info(AVAUDIO, "<< path.capture = %d, option = %x, gain.capture = %d\n", + control->path.capture, control->option, control->gain.capture); + + if (!(control->option & (AVSYS_AUDIO_PATH_OPTION_VR_NORMAL_CMD | AVSYS_AUDIO_PATH_OPTION_VR_NORMAL_WAKE))) { + avsys_warning (AVAUDIO, "this is unexpected case (VR with no CMD/WAKE)...."); + } + + switch(control->path.capture) { + case AVSYS_AUDIO_PATH_EX_MIC: + if (control->option & AVSYS_AUDIO_PATH_OPTION_VR_NORMAL_CMD) { + devices[dev_idx++] = UC_IN_DEV_VR_MAIN_MIC; + } else if (control->option & AVSYS_AUDIO_PATH_OPTION_VR_NORMAL_WAKE) { + devices[dev_idx++] = UC_IN_DEV_VR_SEC_SUB_MIC; + } + break; + + case AVSYS_AUDIO_PATH_EX_HEADSETMIC: + if (control->option & AVSYS_AUDIO_PATH_OPTION_VR_NORMAL_CMD) { + devices[dev_idx++] = UC_IN_DEV_VR_HEADSET_MIC; + } else if (control->option & AVSYS_AUDIO_PATH_OPTION_VR_NORMAL_WAKE) { + devices[dev_idx++] = UC_IN_DEV_VR_SEC_HEADSET_MIC; + } + break; + + case AVSYS_AUDIO_PATH_EX_BTMIC: + if (control->option & AVSYS_AUDIO_PATH_OPTION_VR_NORMAL_CMD) { + if (control->option & AVSYS_AUDIO_PATH_OPTION_BT_NREC) { + /* FIXME : WB support ? */ + devices[dev_idx++] = UC_IN_DEV_VR_BT_NREC_MIC; + } else { + /* FIXME : WB support ? */ + devices[dev_idx++] = UC_IN_DEV_VR_BT_MIC; + } + } else if (control->option & AVSYS_AUDIO_PATH_OPTION_VR_NORMAL_WAKE) { + avsys_warning (AVAUDIO, "this is unexpected case (BT+WAKE)...."); + devices[dev_idx++] = UC_IN_DEV_VR_BT_MIC; + } + break; + + default: + break; + } + + modifiers[mod_idx++] = UC_MODIFIER_CAPTURE_MUSIC; + avsys_info (AVAUDIO, ">> leave"); + + return AVSYS_STATE_SUCCESS; +} + + +int avsys_audio_path_set_single_ascn(char *str) +{ + if (!str) + return AVSYS_STATE_ERR_INVALID_PARAMETER; + +// FIXME +// RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_single_set(str)) + + return AVSYS_STATE_SUCCESS; +} + diff --git a/avsys-audio-path.c b/avsys-audio-path.c new file mode 100755 index 0000000..ba90d03 --- /dev/null +++ b/avsys-audio-path.c @@ -0,0 +1,1174 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "avsys-audio-shm.h" +#include "avsys-audio-sync.h" +#include "avsys-audio-path.h" +#include "avsys-audio-shm.h" +#include "avsys-debug.h" +#include "avsys-common.h" +#include "avsys-audio-handle.h" +#include "avsys-audio-ascenario.h" + +#include + +#define TIZEN_MICRO + +#define EXPORT_API __attribute__((__visibility__("default"))) + +#define RET_IO_CTL_ERR_IF_FAIL(SECTION) { if(AVSYS_FAIL(SECTION)) { \ + avsys_error_r(AVAUDIO,"%s %d\n",__func__,__LINE__); \ + return AVSYS_STATE_ERR_IO_CONTROL; \ + } } + +static int g_playback_path_select_data[AVSYS_AUDIO_PLAYBACK_GAIN_MAX][AVSYS_AUDIO_PATH_EX_OUTMAX] = { + { /* AVSYS_AUDIO_PLAYBACK_GAIN_AP */ + /* NONE SPK RECV HEADSET BTHEADSET A2DP HANDSFREE HDMI DOCK USBAUDIO */ + 0, 1, 1, 1, 1, 1, 0, 1, 1, 0 + }, + { /* AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO */ + /* NONE SPK RECV HEADSET BTHEADSET A2DP HANDSFREE HDMI */ + 1, 1, 0, 1, 0, 1, 0, 0, 0, 0 + }, + { /* AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL */ + /* NONE SPK RECV HEADSET BTHEADSET A2DP HANDSFREE HDMI */ + 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 + }, + { /* AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL */ + /* NONE SPK RECV HEADSET BTHEADSET A2DP HANDSFREE HDMI */ + 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 + }, + { /* AVSYS_AUDIO_PLAYBACK_GAIN_VOIP */ + /* NONE SPK RECV HEADSET BTHEADSET A2DP HANDSFREE HDMI */ + 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 + }, + { /* AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT */ + /* NONE SPK RECV HEADSET BTHEADSET A2DP HANDSFREE HDMI */ + 0, 1, 1, 1, 1, 0, 0, 0, 0, 0 + }, + { /* AVSYS_AUDIO_PLAYBACK_GAIN_VOICE_RECOGNITION */ + /* NONE SPK RECV HEADSET BTHEADSET A2DP HANDSFREE HDMI */ + 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 + } + +}; + +static int g_capture_path_select_data[AVSYS_AUDIO_CAPTURE_GAIN_MAX][AVSYS_AUDIO_PATH_EX_INMAX] = { + { /* AVSYS_AUDIO_CAPTURE_GAIN_AP */ + /* NONE MIC HMIC BMIC FMIN HFREE */ + 1, 1, 1, 1, 0, 0 + }, + { /* AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO */ + /* NONE MIC HMIC BMIC FMIN HFREE */ + 1, 0, 0, 0, 1, 0 + }, + { /* AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL */ + /* NONE MIC HMIC BMIC FMIN HFREE */ + 1, 1, 1, 1, 0, 0 + }, + { /* AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL */ + /* NONE MIC HMIC BMIC FMIN HFREE */ + 1, 1, 1, 1, 0, 0 + }, + { /* AVSYS_AUDIO_CAPTURE_GAIN_VOIP */ + /* NONE MIC HMIC BMIC FMIN HFREE */ + 1, 1, 1, 1, 0, 0 + }, + { /* AVSYS_AUDIO_CAPTURE_GAIN_VOICE_RECOGNITION */ + /* NONE MIC HMIC BMIC FMIN HFREE */ + 1, 1, 1, 1, 0, 0 + }, +}; + +static int g_playback_gain_select_data[AVSYS_AUDIO_PLAYBACK_GAIN_MAX][AVSYS_AUDIO_PLAYBACK_GAIN_MAX] = { + { /* AVSYS_AUDIO_PLAYBACK_GAIN_AP */ + AVSYS_AUDIO_PLAYBACK_GAIN_AP, /* AVSYS_AUDIO_PLAYBACK_GAIN_AP */ + AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO, /* AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO */ + AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL, /* AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL */ + AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL, /* AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL */ + AVSYS_AUDIO_PLAYBACK_GAIN_VOIP, /* AVSYS_AUDIO_PLAYBACK_GAIN_VOIP */ + AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT, /* AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT */ + }, + { /* AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO */ + AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO, /* AVSYS_AUDIO_PLAYBACK_GAIN_AP */ + AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO, /* AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO */ + AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL, /* AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL */ + AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL, /* AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL */ + AVSYS_AUDIO_PLAYBACK_GAIN_VOIP, /* AVSYS_AUDIO_PLAYBACK_GAIN_VOIP */ + AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO, /* AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT */ + }, + { /* AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL */ + AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL, /* AVSYS_AUDIO_PLAYBACK_GAIN_AP */ + AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL, /* AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO */ + AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL, /* AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL */ + AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL, /* AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL */ + AVSYS_AUDIO_PLAYBACK_GAIN_VOIP, /* AVSYS_AUDIO_PLAYBACK_GAIN_VOIP */ + AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT, /* AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT */ + }, + { /* AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL */ + AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL, /* AVSYS_AUDIO_PLAYBACK_GAIN_AP */ + AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL, /* AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO */ + AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL, /* AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL */ + AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL, /* AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL */ + AVSYS_AUDIO_PLAYBACK_GAIN_VOIP, /* AVSYS_AUDIO_PLAYBACK_GAIN_VOIP */ + AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT, /* AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT */ + }, + { /* AVSYS_AUDIO_PLAYBACK_GAIN_VOIP */ + AVSYS_AUDIO_PLAYBACK_GAIN_VOIP, /* AVSYS_AUDIO_PLAYBACK_GAIN_AP */ + AVSYS_AUDIO_PLAYBACK_GAIN_VOIP, /* AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO */ + AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL, /* AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL */ + AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL, /* AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL */ + AVSYS_AUDIO_PLAYBACK_GAIN_VOIP, /* AVSYS_AUDIO_PLAYBACK_GAIN_VOIP */ + AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT, /* AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT */ + }, + { /* AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT */ + AVSYS_AUDIO_PLAYBACK_GAIN_AP, /* AVSYS_AUDIO_PLAYBACK_GAIN_AP */ + AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO, /* AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO */ + AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL, /* AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL */ + AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL, /* AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL */ + AVSYS_AUDIO_PLAYBACK_GAIN_VOIP, /* AVSYS_AUDIO_PLAYBACK_GAIN_VOIP */ + AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT, /* AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT */ + }, +}; + +static int g_capture_gain_select_data[AVSYS_AUDIO_CAPTURE_GAIN_MAX][AVSYS_AUDIO_CAPTURE_GAIN_MAX] = { + { /* AVSYS_AUDIO_CAPTURE_GAIN_AP */ + AVSYS_AUDIO_CAPTURE_GAIN_AP, /* AVSYS_AUDIO_CAPTURE_GAIN_AP */ + AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO, /* AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO */ + AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL, /* AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL */ + AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL, /* AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL */ + AVSYS_AUDIO_CAPTURE_GAIN_VOIP, /* AVSYS_AUDIO_CAPTURE_GAIN_VOIP */ + }, + { /* AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO */ + AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO, /* AVSYS_AUDIO_CAPTURE_GAIN_AP */ + AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO, /* AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO */ + AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL, /* AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL */ + AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL, /* AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL */ + AVSYS_AUDIO_CAPTURE_GAIN_VOIP, /* AVSYS_AUDIO_CAPTURE_GAIN_VOIP */ + }, + { /* AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL */ + AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL, /* AVSYS_AUDIO_CAPTURE_GAIN_AP */ + AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL, /* AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO */ + AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL, /* AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL */ + AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL, /* AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL */ + AVSYS_AUDIO_CAPTURE_GAIN_VOIP, /* AVSYS_AUDIO_CAPTURE_GAIN_VOIP */ + }, + { /* AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL */ + AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL, /* AVSYS_AUDIO_CAPTURE_GAIN_AP */ + AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL, /* AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO */ + AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL, /* AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL */ + AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL, /* AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL */ + AVSYS_AUDIO_CAPTURE_GAIN_VOIP, /* AVSYS_AUDIO_CAPTURE_GAIN_VOIP */ + }, + { /* AVSYS_AUDIO_CAPTURE_GAIN_VOIP */ + AVSYS_AUDIO_CAPTURE_GAIN_VOIP, /* AVSYS_AUDIO_CAPTURE_GAIN_AP */ + AVSYS_AUDIO_CAPTURE_GAIN_VOIP, /* AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO */ + AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL, /* AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL */ + AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL, /* AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL */ + AVSYS_AUDIO_CAPTURE_GAIN_VOIP, /* AVSYS_AUDIO_CAPTURE_GAIN_VOIP */ + }, +}; + + +static int __avsys_audio_path_set_ascn_ap_playback(avsys_audio_path_ex_info_t *control); +static int __avsys_audio_path_set_ascn_ap_capture(avsys_audio_path_ex_info_t *control); +static int __avsys_audio_path_set_ascn_voicecall(avsys_audio_path_ex_info_t *control); +static int __avsys_audio_path_set_ascn_voip(avsys_audio_path_ex_info_t *control); +static int __avsys_audio_path_set_ap_voicerecognition(avsys_audio_path_ex_info_t *control); +static int __avsys_audio_path_set_ascn_factory_loopback(avsys_audio_path_ex_info_t *control); + +#define AUDIOSYSTEM_CONF "/opt/etc/audio_system.conf" +#define CP_STATUS "/sys/class/audio/caps/cp_caps" +#define CP_WB_STRING "wb" + +#define INFO_CALL_START 0x101 +#define INFO_CALL_END 0x100 + +static bool __is_cp_wb () +{ + bool ret = false; + char str[10] = { 0, }; + FILE* fp = NULL; + + avsys_info(AVAUDIO, "Checking [%s] for WB capability...\n", CP_STATUS); + fp = fopen (CP_STATUS, "r"); + if (fp) { + if (fgets (str, sizeof(str)-1, fp)) { + if (strstr (str, CP_WB_STRING)) { + ret = true; + } + } + fclose(fp); + } else { + avsys_warning (AVAUDIO, "failed to open [%s]...errno=[%d]\n", CP_STATUS, errno); + } + + avsys_info(AVAUDIO, "Result [%d] : [%s] capability!!!\n", ret, (ret)? "WB" : "NB"); + return ret; +} + +EXPORT_API +int avsys_audio_path_ex_init(void) +{ + avsys_audio_path_ex_info_t *control = NULL; + avsys_audio_path_ex_info_t **temp = NULL; + gain_info_t default_gain = { AVSYS_AUDIO_PLAYBACK_GAIN_AP, AVSYS_AUDIO_CAPTURE_GAIN_AP }; + path_info_t default_path = { AVSYS_AUDIO_PATH_EX_SPK, AVSYS_AUDIO_PATH_EX_MIC }; + int default_option = AVSYS_AUDIO_PATH_OPTION_NONE; + int index = 0; + int err = AVSYS_STATE_SUCCESS; + + /* Check root user */ + err = avsys_check_root_privilege(); + if (AVSYS_FAIL(err)) { + return err; + } + + temp = &control; + avsys_assert(AVSYS_SUCCESS(avsys_audio_create_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))); + avsys_assert(AVSYS_SUCCESS(avsys_audio_create_shm(AVSYS_AUDIO_SHM_IDEN_PATH))); + + avsys_assert(AVSYS_SUCCESS(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp))); + if (control == NULL) + return AVSYS_STATE_ERR_NULL_POINTER; + + /* init values */ + control->pregain = default_gain; + control->gain = default_gain; + control->reqgain = default_gain; + control->path = default_path; + control->option = default_option; + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + control->wb_enabled = __is_cp_wb(); + control->mute = AVSYS_AUDIO_UNMUTE; + control->path_fixed = PATH_FIXED_NONE; + + index = 0; + do { + control->pathlock_pid[index] = -1; + index++; + } while (index < AVSYS_AUDIO_LOCK_SLOT_MAX); + + index = 0; + do { + control->path_fixed_pid[index] = -1; + index++; + } while (index < PATH_FIXED_TYPE_MAX); + + /* call path control */ + err = __avsys_audio_path_set_ascn_ap_playback(control); + if (AVSYS_SUCCESS(err)) + err = __avsys_audio_path_set_ascn_ap_capture(control); + + /* snd scenario open */ + err = avsys_audio_ascn_open(); + if (err) + avsys_error_r(AVAUDIO, "avsys_audio_ascn_open() failed\n"); + + return err; +} + +EXPORT_API +int avsys_audio_path_ex_fini(void) +{ + /* snd scenario close */ + avsys_audio_ascn_close(); + + if (AVSYS_FAIL(avsys_audio_remove_shm(AVSYS_AUDIO_SHM_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_remove_shm() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + if (AVSYS_FAIL(avsys_audio_remove_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_remove_sync() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + return AVSYS_STATE_SUCCESS; +} + +EXPORT_API +int avsys_audio_path_ex_reset(int forced) +{ + avsys_audio_path_ex_info_t *control = NULL; + avsys_audio_path_ex_info_t **temp = NULL; + gain_info_t default_gain = { AVSYS_AUDIO_PLAYBACK_GAIN_AP, AVSYS_AUDIO_CAPTURE_GAIN_AP }; + path_info_t default_path = { AVSYS_AUDIO_PATH_EX_SPK, AVSYS_AUDIO_PATH_EX_MIC }; + int default_option = AVSYS_AUDIO_PATH_OPTION_NONE; + int index = 0; + int err = AVSYS_STATE_SUCCESS; + + /* Check root user */ + err = avsys_check_root_privilege(); + if (AVSYS_FAIL(err)) { + return err; + } + + temp = &control; + if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp))) { + avsys_error_r(AVAUDIO, "avsys_audio_get_shm() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + if (control == NULL) + return AVSYS_STATE_ERR_NULL_POINTER; + + if (AVSYS_FAIL(avsys_audio_lock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_lock_sync() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + + /* init values */ + control->pregain = default_gain; + control->gain = default_gain; + control->reqgain = default_gain; + control->path = default_path; + control->option = default_option; + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + control->mute = AVSYS_AUDIO_UNMUTE; + control->path_fixed = PATH_FIXED_NONE; + + index = 0; + do { + control->pathlock_pid[index] = -1; + index++; + } while (index < AVSYS_AUDIO_LOCK_SLOT_MAX); + + index = 0; + do { + control->path_fixed_pid[index] = -1; + index++; + } while (index < PATH_FIXED_TYPE_MAX); + + /* call path control */ + err = __avsys_audio_path_set_ascn_ap_playback(control); + if (AVSYS_SUCCESS(err)) + err = __avsys_audio_path_set_ascn_ap_capture(control); + + if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + + return err; +} + +EXPORT_API +int avsys_audio_path_ex_dump(void) +{ + avsys_audio_path_ex_info_t *control = NULL; + avsys_audio_path_ex_info_t **temp = NULL; + const static char *str_earType[] = { "None", "EarOnly", "EarMic", "TVout" }; + const static char *str_yn[] = { "NO", "YES" }; + const static char *str_ear[] = { "MANUAL", "AUTO_MUTE", "AUTO_NOMUTE" }; + const static char *str_out[AVSYS_AUDIO_PATH_EX_OUTMAX] = { + "NONE", "SPK", "RECV", "HEADSET", "BTHEADSET", "A2DP", "HANSFREE", "HDMI", "DOCK", "USBAUDIO" + }; + const static char *str_in[AVSYS_AUDIO_PATH_EX_INMAX] = { + "NONE", "MIC", "HEADMIC", "BTMIC", "FMINPUT", "HANSFREEMIC" + }; + + const static char *str_playback_gain[AVSYS_AUDIO_PLAYBACK_GAIN_MAX] = { + "AP", "FMRADIO", "VOICECALL", "VIDEOCALL", "VOIP", "CALLALERT", + }; + const static char *str_capture_gain[AVSYS_AUDIO_CAPTURE_GAIN_MAX] = { + "AP", "FMRADIO", "VOICECALL", "VIDEOCALL", "VOIP" + }; + + int index = 0; + + temp = &control; + + if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp))) { + avsys_error_r(AVAUDIO, "avsys_audio_get_shm() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + if (control == NULL) + return AVSYS_STATE_ERR_NULL_POINTER; + + fprintf(stdout, "======================================================================\n"); + fprintf(stdout, " Avsystem Audio Path Control Information \n"); + fprintf(stdout, "======================================================================\n"); +#if defined(_MMFW_I386_ALL_SIMULATOR) + fprintf(stdout, " In simulator, follow informations don`t have means.\n"); +#endif + + fprintf(stdout, " GAIN : P (%-s / %-s) - R (%-s / %-s) - C (%-s / %-s)\n", + str_playback_gain[control->pregain.playback], str_capture_gain[control->pregain.capture], + str_playback_gain[control->reqgain.playback], str_capture_gain[control->reqgain.capture], + str_playback_gain[control->gain.playback], str_capture_gain[control->gain.capture]); + fprintf(stdout, " Current Out / In : %-s / %-s\n", str_out[control->path.playback], str_in[control->path.capture] ); + fprintf(stdout, " Path Fixed State : 0x%-x\n", control->path_fixed); + fprintf(stdout, " Mute status : %d\n", control->mute); + if (control->path_fixed_pid[PATH_FIXED_TYPE_FMRADIO] != -1) + fprintf(stdout, " FM Radio path pid : %d\n", control->path_fixed_pid[PATH_FIXED_TYPE_FMRADIO]); + if (control->path_fixed_pid[PATH_FIXED_TYPE_CALL] != -1) + fprintf(stdout, " Call path pid : %d\n", control->path_fixed_pid[PATH_FIXED_TYPE_CALL]); + + index = 0; + do { + if (control->pathlock_pid[index] != -1) + fprintf(stdout, " Path sync lock required PIDs : %d\n", control->pathlock_pid[index]); + index++; + } while (index < AVSYS_AUDIO_LOCK_SLOT_MAX); + + /* Playback option */ + fprintf(stdout, " Playback Option : [ "); + if (control->option & AVSYS_AUDIO_PATH_OPTION_DUAL_OUT) + fprintf(stdout, "DualOut "); + if (control->option & AVSYS_AUDIO_PATH_OPTION_FORCED) + fprintf(stdout, "Forced "); + fprintf(stdout, "]\n"); + + /* Capture option */ + fprintf(stdout, " Capture Option : [ "); + if (control->option & AVSYS_AUDIO_PATH_OPTION_VOICECALL_REC) + fprintf(stdout, "VoicecallRec "); + if (control->option & AVSYS_AUDIO_PATH_OPTION_USE_SUBMIC) + fprintf(stdout, "SubMic "); + if (control->option & AVSYS_AUDIO_PATH_OPTION_USE_STEREOMIC) + fprintf(stdout, "StereoMic "); + if (control->option & AVSYS_AUDIO_PATH_OPTION_USE_2MIC) + fprintf(stdout, "2MIC "); + if (control->option & AVSYS_AUDIO_PATH_OPTION_CALL_NB) + fprintf(stdout, "CallExtraVolume "); + if (control->option & AVSYS_AUDIO_PATH_OPTION_VR_NORMAL_WAKE) + fprintf(stdout, "VRNormalWake "); + if (control->option & AVSYS_AUDIO_PATH_OPTION_VR_NORMAL_CMD) + fprintf(stdout, "VRNormalCommand "); + if (control->option & AVSYS_AUDIO_PATH_OPTION_VR_DRIVE_WAKE) + fprintf(stdout, "VRDrivingWake "); + if (control->option & AVSYS_AUDIO_PATH_OPTION_VR_DRIVE_CMD) + fprintf(stdout, "VRDrivingCommand "); + fprintf(stdout, "]\n"); + + return AVSYS_STATE_SUCCESS; +} + +#define DO_IF_VALID(c, p) { if(c > -1) p; } +#define DO_IF_INVALID(c, p) { if(c == -1) p; } +#define CHECK_VALID(c) (c>-1 ? 1 : 0) + +enum { + CMD_DEVICE_NONE = 0, + CMD_DEVICE_OPEN, + CMD_DEVICE_CLOSE, /* Not used */ + CMD_DEVICE_MAX +}; + +static int __avsys_audio_release_path (gain_info_t local_gain, avsys_audio_path_ex_info_t *control) +{ + int err = AVSYS_STATE_SUCCESS; + + avsys_warning(AVAUDIO, "Release path for %d %d\n", local_gain.playback, local_gain.capture); + + switch (local_gain.playback) { + case AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL: + case AVSYS_AUDIO_PLAYBACK_GAIN_VOIP: + if (getpid() == control->path_fixed_pid[PATH_FIXED_TYPE_CALL]) { + } else { + if (control->path_fixed_pid[PATH_FIXED_TYPE_CALL] < 0) { + avsys_warning(AVAUDIO, "Sound path for call released already\n"); + } else { + avsys_warning(AVAUDIO, "Try to close call path from other process.. original pid[%d]\n", control->path_fixed_pid[PATH_FIXED_TYPE_CALL]); + avsys_warning(AVAUDIO, "Just mark handle as off\n"); + } + } + + if ((control->path_fixed & PATH_FIXED_WITH_CALL) == 0) { + avsys_error(AVAUDIO, "Call path release without call path request\n"); + } + control->path_fixed &= ~PATH_FIXED_WITH_CALL; + control->path_fixed_pid[PATH_FIXED_TYPE_CALL] = -1; + + break; + + default: + avsys_warning(AVAUDIO, "unexpected path release\n"); + break; + } + + /* RESET path */ + if (AVSYS_FAIL(avsys_audio_ascn_single_set(ASCN_STR_RESET))) { + avsys_error_r(AVAUDIO, "failed to set ASCN_STR_RESET\n"); + } + + /* Inform CALL_END to pulseaudio */ + avsys_audio_pa_ctrl_set_info(INFO_CALL_END); + + return err; +} + +int avsys_audio_path_ex_set_path(int gain, int out, int in, int option) +{ + avsys_audio_path_ex_info_t *control = NULL; + avsys_audio_path_ex_info_t **temp = NULL; + gain_info_t local_gain = { -1, -1 }; + gain_info_t req_gain = { -1, -1 }; + pid_t current_pid; + int err = AVSYS_STATE_SUCCESS; + char req_release_path = 0; + bool skip_playback_setting = false; + bool skip_capture_setting = false; + int is_loopback = 0; + + avsys_warning(AVAUDIO, "=================== [Input Param] gain %d, out %d, in %d, opt 0x%x ====================\n", gain, out, in, option); + + /* Determine REQUESTs */ + switch (gain) { + case AVSYS_AUDIO_GAIN_EX_KEYTONE: + case AVSYS_AUDIO_GAIN_EX_ALARMTONE: + case AVSYS_AUDIO_GAIN_EX_AUDIOPLAYER: + case AVSYS_AUDIO_GAIN_EX_VIDEOPLAYER: + case AVSYS_AUDIO_GAIN_EX_CAMERA: + case AVSYS_AUDIO_GAIN_EX_GAME: +#ifndef TIZEN_MICRO + case AVSYS_AUDIO_GAIN_EX_VOICERECOGNITION: +#endif + case AVSYS_AUDIO_GAIN_EX_STEREO_REC: + case AVSYS_AUDIO_GAIN_EX_VOICEREC: + if(out == AVSYS_AUDIO_PATH_EX_NONE && in != AVSYS_AUDIO_PATH_EX_NONE) { + req_gain.capture = AVSYS_AUDIO_CAPTURE_GAIN_AP; + } else { + req_gain.playback = AVSYS_AUDIO_PLAYBACK_GAIN_AP; + req_gain.capture = AVSYS_AUDIO_CAPTURE_GAIN_AP; + } + break; + + case AVSYS_AUDIO_GAIN_EX_RINGTONE: + case AVSYS_AUDIO_GAIN_EX_CALLTONE: + req_gain.playback = AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT; + break; + +#if 0 + case AVSYS_AUDIO_GAIN_EX_VOICEREC: + req_gain.capture = AVSYS_AUDIO_CAPTURE_GAIN_AP; + break; +#endif + +#ifdef TIZEN_MICRO + case AVSYS_AUDIO_GAIN_EX_VOICERECOGNITION: + req_gain.playback = AVSYS_AUDIO_PLAYBACK_GAIN_VOICERECOGNITION; + req_gain.capture = AVSYS_AUDIO_CAPTURE_GAIN_VOICERECOGNITION; + if (out == AVSYS_AUDIO_PATH_EX_NONE && in == AVSYS_AUDIO_PATH_EX_NONE) + req_release_path = 1; + break; +#endif + + case AVSYS_AUDIO_GAIN_EX_VOICECALL: + req_gain.playback = AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL; + req_gain.capture = AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL; + if (out == AVSYS_AUDIO_PATH_EX_NONE && in == AVSYS_AUDIO_PATH_EX_NONE) + req_release_path = 1; + break; + + case AVSYS_AUDIO_GAIN_EX_VOIP: + req_gain.playback = AVSYS_AUDIO_PLAYBACK_GAIN_VOIP; + req_gain.capture = AVSYS_AUDIO_CAPTURE_GAIN_VOIP; + if (out == AVSYS_AUDIO_PATH_EX_NONE && in == AVSYS_AUDIO_PATH_EX_NONE) + req_release_path = 1; + break; + } + /* Get avsys shared memeory */ + temp = &control; + if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp))) { + avsys_error_r(AVAUDIO, "avsys_audio_get_shm() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + /* LOCK */ + if (AVSYS_FAIL(avsys_audio_lock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_lock_sync() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + + current_pid = getpid(); /* moved from below */ + + /* Check FORCED option */ + if (option & AVSYS_AUDIO_PATH_OPTION_FORCED) { + DO_IF_VALID(req_gain.playback, local_gain.playback = req_gain.playback) + DO_IF_VALID(req_gain.capture, local_gain.capture = req_gain.capture) + } else { + DO_IF_VALID(req_gain.playback, local_gain.playback = g_playback_gain_select_data[control->gain.playback][req_gain.playback]) + DO_IF_VALID(req_gain.capture, local_gain.capture = g_capture_gain_select_data[control->gain.capture][req_gain.capture]) + } + + avsys_info(AVAUDIO, "Gain : req(%d,%d) local(%d,%d)\n", req_gain.playback, req_gain.capture, local_gain.playback, local_gain.capture); + avsys_info(AVAUDIO, "Gain : control gain(playback %d,capture %d) \n", control->gain.playback, control->gain.capture); + + /* Check path fixed process alive. */ + if (control->path_fixed & PATH_FIXED_WITH_CALL) { + if (AVSYS_FAIL(avsys_check_process(control->path_fixed_pid[PATH_FIXED_TYPE_CALL]))) { + control->path_fixed &= ~PATH_FIXED_WITH_CALL; + } + } + if (control->path_fixed == PATH_FIXED_NONE) { + /* forced gain setting when path fixed by dead process */ + if (req_gain.playback != local_gain.playback) { + local_gain.playback = req_gain.playback; + } + if (req_gain.capture != local_gain.capture) { + local_gain.capture = req_gain.capture; + } + } + + if (CHECK_VALID(local_gain.playback)) { + if (g_playback_path_select_data[local_gain.playback][out] == 0) { + avsys_error(AVAUDIO, "[PLAYBACK] Does not support request sound path : conv gain %d, out path %d\n", local_gain.playback, out); + if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + return AVSYS_STATE_ERR_INVALID_STATE; + } + } + if (CHECK_VALID(local_gain.capture)) { + if (g_capture_path_select_data[local_gain.capture][in] == 0) { + avsys_error(AVAUDIO, "[CAPTURE] Does not support request sound path : conv gain %d, in path %d\n", local_gain.capture, in); + if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + return AVSYS_STATE_ERR_INVALID_STATE; + } + } + + /* Check duplicated path */ + /* Check duplicated request for playback */ + if ((control->gain.playback == local_gain.playback) && (control->path.playback == out) && (control->option == option)) { + avsys_warning(AVAUDIO, "skip duplicated playback gain:%d out:%x option:%x", local_gain.playback, out, option); + skip_playback_setting = true; + } + /* Check duplicated request for capture */ + if ((control->gain.capture == local_gain.capture) && (control->path.capture == in) && (control->option == option)) { + avsys_warning(AVAUDIO, "skip duplicated capture gain:%d in:%x option:%x", local_gain.capture, in, option); + skip_capture_setting = true; + } + if (skip_playback_setting && skip_capture_setting) { + goto FINISHED; + } +#if 0 /* This function is moved to libmm-sound */ + if ((control->gain.playback == local_gain.playback) && (control->gain.capture == local_gain.capture) + && (control->path.playback == out) && (control->path.capture == in) && (control->option == option)) { + avsys_warning(AVAUDIO, "skip duplicated path request playback:%d capture:%x in:%x out:%x option:%x", + local_gain.playback, local_gain.capture, in, out, option); + goto FINISHED; + } +#endif + + /* overwrite local_gain with current gain if it is simplex sound path */ + if(!(out == AVSYS_AUDIO_PATH_EX_NONE && !req_release_path)) { + DO_IF_INVALID(local_gain.playback, local_gain.playback = control->gain.playback) + } + DO_IF_INVALID(local_gain.capture, local_gain.capture = control->gain.capture) + control->pregain = control->gain; + control->gain = local_gain; + + DO_IF_VALID(req_gain.playback, control->reqgain.playback = req_gain.playback) + DO_IF_VALID(req_gain.capture, control->reqgain.capture = req_gain.capture) + control->option = option; + + /* Check for Release PATH */ + if (req_release_path && (req_gain.playback == local_gain.playback) && (req_gain.capture == local_gain.capture)) { + avsys_warning(AVAUDIO,"Release path for %d %d\n", local_gain.playback, local_gain.capture); + + /* FIXME: If loopback module exist, do unload */ + if (AVSYS_SUCCESS(avsys_audio_pa_ctrl_unload_loopback_module(false))) { + avsys_info(AVAUDIO, "unloading loopback module success!!!"); + } + + err = __avsys_audio_release_path(local_gain, control); + goto FINISHED; + } + + if (CHECK_VALID(req_gain.playback)) { + if(req_gain.playback != local_gain.playback) { + avsys_warning(AVAUDIO, "Sound Path is protected. use current configuration (playback_gain %d, out %d, opt 0x%x)\n", + local_gain.playback, control->path.playback, control->option); + } else { + control->path.playback = out; + + switch (local_gain.playback) { + case AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT: + break; + + case AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL: + case AVSYS_AUDIO_PLAYBACK_GAIN_VOIP: + /* Voicecall / VOIP Common setting */ + control->path_fixed_pid[PATH_FIXED_TYPE_CALL] = current_pid; + break; + + case AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO: + control->path_fixed_pid[PATH_FIXED_TYPE_FMRADIO] = current_pid; + break; + } + } + } + + if (CHECK_VALID(req_gain.capture)) { + if (req_gain.capture != local_gain.capture) { + avsys_warning(AVAUDIO, "Sound Path is protected. use current configuration (capture_gain %d, in %d, opt 0x%x)\n", + local_gain.capture, control->path.capture, control->option); + } else { + control->path.capture = in; + + switch (local_gain.capture) { + case AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL: + case AVSYS_AUDIO_CAPTURE_GAIN_VOIP: + /* Voicecall / VOIP Common setting */ + control->path_fixed_pid[PATH_FIXED_TYPE_CALL] = current_pid; + break; + + case AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO: + control->path_fixed_pid[PATH_FIXED_TYPE_FMRADIO] = current_pid; + break; + } + } + } + + /* Check loopback */ + avsys_audio_path_ex_get_factory_loopback_test(&is_loopback); + if (is_loopback) { + /* set loopback path */ + avsys_warning(AVAUDIO, "factory_loopback"); + err = __avsys_audio_path_set_ascn_factory_loopback(control); + + /* load module-loopback */ + avsys_audio_pa_ctrl_load_loopback_module(false); + goto FINISHED; + } + + /* Do ALSA scenario control based on gain */ + /* Playback/Capture */ + if (0) { + } else if (local_gain.playback == AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL && + local_gain.capture == AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL) { + avsys_warning(AVAUDIO, "voicecall gain\n"); + err = __avsys_audio_path_set_ascn_voicecall(control); + } else if (local_gain.playback == AVSYS_AUDIO_PLAYBACK_GAIN_VOIP && + local_gain.capture == AVSYS_AUDIO_CAPTURE_GAIN_VOIP) { + avsys_warning(AVAUDIO, "voip gain\n"); + err = __avsys_audio_path_set_ascn_voip(control); +#ifdef TIZEN_MICRO + } else if (local_gain.capture == AVSYS_AUDIO_CAPTURE_GAIN_VOICERECOGNITION) { + avsys_warning(AVAUDIO, "capture gain : voicerecognition\n"); + err = __avsys_audio_path_set_ap_voicerecognition(control); +#endif + } else { + /* Playback only */ + if (!skip_playback_setting) { + if (local_gain.playback == AVSYS_AUDIO_PLAYBACK_GAIN_AP) { + avsys_warning(AVAUDIO, "playback gain : ap\n"); + err = __avsys_audio_path_set_ascn_ap_playback(control); + } else if(local_gain.playback == AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT) { + avsys_warning(AVAUDIO,"playback gain : callalert\n"); + err = __avsys_audio_path_set_ascn_ap_playback(control); + } + } + /* Capture only */ + if (!skip_capture_setting) { + if (local_gain.capture == AVSYS_AUDIO_CAPTURE_GAIN_AP) { + avsys_warning(AVAUDIO, "capture gain : ap\n"); + err = __avsys_audio_path_set_ascn_ap_capture(control); + } + } + } + + +FINISHED: + /* UnLOCK */ + if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + avsys_info(AVAUDIO, "------------------------------------------------\n"); + return err; +} + +int avsys_audio_path_ex_get_path(int *gain, int *out, int *in, int *option) +{ + avsys_audio_path_ex_info_t *control = NULL; + avsys_audio_path_ex_info_t ** temp = NULL; + + if(gain == NULL || out == NULL || in == NULL || option == NULL) { + avsys_error(AVAUDIO,"Invalid parameter\n"); + return AVSYS_STATE_ERR_NULL_POINTER; + } + + temp = &control; + + if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp))) { + avsys_error_r(AVAUDIO, "avsys_audio_get_shm() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + if (AVSYS_FAIL(avsys_audio_lock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_lock_sync() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + + *out = control->path.playback; + *in = control->path.capture; + *option = control->option; + + switch (control->gain.playback) { + case AVSYS_AUDIO_PLAYBACK_GAIN_AP: + *gain = AVSYS_AUDIO_GAIN_EX_KEYTONE; + *in = AVSYS_AUDIO_PATH_EX_NONE; + break; + case AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT: + *gain = AVSYS_AUDIO_GAIN_EX_RINGTONE; + *in = AVSYS_AUDIO_PATH_EX_NONE; + break; + case AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL: + *gain = AVSYS_AUDIO_GAIN_EX_VOICECALL; + break; + case AVSYS_AUDIO_PLAYBACK_GAIN_VOIP: + *gain = AVSYS_AUDIO_GAIN_EX_VOIP; + break; + } + + if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + + return AVSYS_STATE_SUCCESS; +} + +int avsys_audio_path_ex_set_amp(const int onoff) +{ + //not yet implemented. + return AVSYS_STATE_SUCCESS; +} + +int avsys_audio_path_ex_set_mute(const int mute) +{ + avsys_audio_path_ex_info_t *control = NULL; + avsys_audio_path_ex_info_t **temp = NULL; + + temp = &control; + + if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp))) { + avsys_error_r(AVAUDIO, "avsys_audio_get_shm() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + + if (control == NULL) { + return AVSYS_STATE_ERR_NULL_POINTER; + } + + if (mute == AVSYS_AUDIO_UNMUTE || mute == AVSYS_AUDIO_MUTE) { + if (AVSYS_FAIL(avsys_audio_lock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_lock_sync() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + + if (control->mute == mute) { + avsys_info(AVAUDIO, "[Path Mute] skip mute ctrl op: %d\n", mute); + if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() 2 failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + return AVSYS_STATE_SUCCESS; + } else { + control->mute = mute; + avsys_warning(AVAUDIO, "[Path Mute] run mute ctrl op: %d\n", mute); + } + + if (control->mute) { + if (AVSYS_FAIL(avsys_audio_ascn_single_set(ASCN_STR_PLAYBACK_MUTE))) { + if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() 1 failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + avsys_error(AVAUDIO, "Mute fail\n"); + return AVSYS_STATE_ERR_IO_CONTROL; + } + } else { + if (AVSYS_FAIL(avsys_audio_ascn_single_set(ASCN_STR_PLAYBACK_UNMUTE))) { + if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() 1 failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + avsys_error(AVAUDIO, "Unmute fail\n"); + return AVSYS_STATE_ERR_IO_CONTROL; + } + } + + if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() 2 failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + } else { + int mute_nolock; + if (mute == AVSYS_AUDIO_UNMUTE_NOLOCK) /* set nomalize */ + mute_nolock = AVSYS_AUDIO_UNMUTE; + else + mute_nolock = AVSYS_AUDIO_MUTE; + + if (control->mute == mute_nolock) { + avsys_info(AVAUDIO, "[Path Mute] skip mute ctrl op: %d\n", mute); + return AVSYS_STATE_SUCCESS; + } else { + control->mute = mute_nolock; + avsys_warning(AVAUDIO, "[Path Mute] run mute ctrl op: %d\n", mute); + } + + if (control->mute) { + if (AVSYS_FAIL(avsys_audio_ascn_single_set(ASCN_STR_PLAYBACK_MUTE))) { + avsys_error(AVAUDIO, "Mute fail\n"); + return AVSYS_STATE_ERR_IO_CONTROL; + } + } else { + if (AVSYS_FAIL(avsys_audio_ascn_single_set(ASCN_STR_PLAYBACK_UNMUTE))) { + avsys_error(AVAUDIO, "Unmute fail\n"); + return AVSYS_STATE_ERR_IO_CONTROL; + } + } + } + + if (mute == AVSYS_AUDIO_UNMUTE || mute == AVSYS_AUDIO_UNMUTE_NOLOCK) + avsys_info_r(AVAUDIO, "Global Mute Disabled\n"); + else if (mute == AVSYS_AUDIO_MUTE || mute == AVSYS_AUDIO_MUTE_NOLOCK) + avsys_info_r(AVAUDIO, "Global Mute Enabled\n"); + return AVSYS_STATE_SUCCESS; +} + +int avsys_audio_path_ex_get_mute(int *mute) +{ + avsys_audio_path_ex_info_t *control = NULL; + avsys_audio_path_ex_info_t **temp = NULL; + + temp = &control; + + if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp))) { + avsys_error_r(AVAUDIO, "avsys_audio_get_shm() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + + if (control == NULL) { + return AVSYS_STATE_ERR_NULL_POINTER; + } + + if (AVSYS_FAIL(avsys_audio_lock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_lock_sync() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + + *mute = control->mute; + + if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + + return AVSYS_STATE_SUCCESS; +} + +#define VCONF_FACTORY_LOOPBACK "memory/private/sound/factory_loopback" + +int avsys_audio_path_ex_set_factory_loopback_test(int loopback) +{ + return vconf_set_int(VCONF_FACTORY_LOOPBACK, loopback); +} + +int avsys_audio_path_ex_get_factory_loopback_test(int *loopback) +{ + return vconf_get_int(VCONF_FACTORY_LOOPBACK, loopback); +} + +static int __avsys_audio_path_set_ascn_factory_loopback(avsys_audio_path_ex_info_t *control) +{ + char *str_path[6]; + int path_idx = 0; + control->path_fixed = PATH_FIXED_WITH_CALL; + int ret = 0; + int is_loopback = 0; + + avsys_info(AVAUDIO, "<< path.playback = %d, option = %x, gain.playback = %d\n", + control->path.playback, control->option, control->gain.playback); + + str_path[path_idx++] = STR_LOOPBACK_SPEAKER; + str_path[path_idx++] = STR_LOOPBACK_MAINMIC; + + /* Inform CALL_START to pulseaudio */ + avsys_audio_pa_ctrl_set_info(INFO_CALL_START); + + RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_single_set(ASCN_STR_RESET)); + RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_str_route_set(str_path, path_idx, ASCN_RESET_NONE)); + + avsys_info(AVAUDIO, ">> leave"); + return AVSYS_STATE_SUCCESS; +} + +static int __avsys_audio_path_set_ascn_ap_playback(avsys_audio_path_ex_info_t *control) +{ + char *str_path[5]; + int path_idx = 0; + + avsys_info(AVAUDIO, "<< path.playback = %d, option = %x, gain.playback = %d\n", + control->path.playback, control->option, control->gain.playback); + + control->path_fixed = PATH_FIXED_NONE; + + str_path[path_idx++] = STR_MEDIA_SPK; //STR_AP_SPK STR_RT_GAIN; + + avsys_warning(AVAUDIO, "Run Alsa Scenario Script\n"); + + RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_str_route_set_vconf(str_path, path_idx, ASCN_PATH, ASCN_PLAYBACK)); + + avsys_info(AVAUDIO, ">> leave"); + return AVSYS_STATE_SUCCESS; +} + +#define USE_BT_WB +static int __avsys_audio_path_set_ascn_voicecall(avsys_audio_path_ex_info_t *control) +{ + char *str_path[6]; + int path_idx = 0; + control->path_fixed = PATH_FIXED_WITH_CALL; + + avsys_info(AVAUDIO, "<< path.playback = %d, option = %x, gain.playback = %d\n", + control->path.playback, control->option, control->gain.playback); + + if (control->option & AVSYS_AUDIO_PATH_OPTION_BT_WB) { + /* BT WB 16K */ + if (control->option & AVSYS_AUDIO_PATH_OPTION_CALL_NB) { + /* BT WB 16K + NB voice */ + avsys_debug(AVAUDIO, "BT WB 16K + NB voice"); + str_path[path_idx++] = STR_VC_SPK_SCO_16K_NB; + str_path[path_idx++] = STR_SCO_ADDON_SPK; + } else { + /* BT WB 16K + WB voice */ + avsys_debug(AVAUDIO, "BT WB 16K + WB voice"); + str_path[path_idx++] = STR_VC_SPK_SCO_16K; + str_path[path_idx++] = STR_SCO_ADDON_SPK; + } + } else { + /* BT NB 8K */ + avsys_debug(AVAUDIO, "BT NB 8K"); + str_path[path_idx++] = STR_VC_SPK_SCO_8K; + str_path[path_idx++] = STR_SCO_ADDON_SPK; + } + + /* Inform CALL_START to pulseaudio */ + avsys_audio_pa_ctrl_set_info(INFO_CALL_START); + + RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_single_set(ASCN_STR_RESET)); + RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_str_route_set(str_path, path_idx, ASCN_RESET_NONE)); + + avsys_info(AVAUDIO, ">> leave"); + return AVSYS_STATE_SUCCESS; +} + +static int __avsys_audio_path_set_ascn_voip(avsys_audio_path_ex_info_t *control) +{ + char *str_path[4]; + int path_idx = 0; + + avsys_error(AVAUDIO, "Set to Chaton VOIP"); + /* For 16K Svoice setting */ + str_path[path_idx++] = STR_CHATON_SPK_SCO_16K; + str_path[path_idx++] = STR_SCO_ADDON_SPK; + + /* Inform CALL_START to pulseaudio */ + avsys_audio_pa_ctrl_set_info(INFO_CALL_START); + + RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_single_set(ASCN_STR_RESET)); + RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_str_route_set(str_path, path_idx, ASCN_RESET_NONE)); + + return AVSYS_STATE_SUCCESS; +} + +static int __avsys_audio_path_set_ascn_ap_capture(avsys_audio_path_ex_info_t *control) +{ + char *str_path[3]; + int path_idx = 0; + + avsys_info(AVAUDIO, "<< path.capture = %d, option = %x, gain.capture = %d\n", + control->path.capture, control->option, control->gain.capture); + switch(control->path.capture) { + case AVSYS_AUDIO_PATH_EX_MIC: + if (control->option & AVSYS_AUDIO_PATH_OPTION_BARGEIN) { + str_path[path_idx++] = STR_VOICECMD_MIC; + } else if (control->option & AVSYS_AUDIO_PATH_OPTION_USE_MAINMIC) { + /* Note : For camcording in camera app */ + str_path[path_idx++] = STR_CAM_MIC; + } else { + str_path[path_idx++] = STR_VREC_MIC; + } + break; + + default: + avsys_error(AVAUDIO, "Unexpected capture!!!!!\n"); + break; + } + + RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_str_route_set_vconf(str_path, path_idx, ASCN_PATH, ASCN_CAPTURE)); + + avsys_info (AVAUDIO, ">> leave"); + + return AVSYS_STATE_SUCCESS; +} + +#ifdef TIZEN_MICRO +static int __avsys_audio_path_set_ap_voicerecognition(avsys_audio_path_ex_info_t *control) +{ + char *str_path[3]; + int path_idx = 0; + + avsys_info(AVAUDIO, "<< path.capture = %d, option = %x, gain.capture = %d\n", + control->path.capture, control->option, control->gain.capture); + + avsys_error(AVAUDIO, "Set to SVoice\n"); + /* For 16K Svoice setting */ + str_path[path_idx++] = STR_SVOICE_CAP_SCO_16K; + str_path[path_idx++] = STR_SCO_ADDON_SPK; + + /* Inform CALL_START to pulseaudio */ + avsys_audio_pa_ctrl_set_info(INFO_CALL_START); + + RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_single_set(ASCN_STR_RESET)); + RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_str_route_set(str_path, path_idx, ASCN_RESET_NONE)); + + avsys_info(AVAUDIO, ">> leave"); + return AVSYS_STATE_SUCCESS; +} +#endif + +int avsys_audio_path_set_single_ascn(char *str) +{ + if (!str) + return AVSYS_STATE_ERR_INVALID_PARAMETER; + + RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_open()); + RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_single_set(str)); + avsys_audio_ascn_close(); + + return AVSYS_STATE_SUCCESS; +} diff --git a/avsys-audio-shm.c b/avsys-audio-shm.c new file mode 100644 index 0000000..689457c --- /dev/null +++ b/avsys-audio-shm.c @@ -0,0 +1,70 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi + * + * 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 "avsys-audio-shm.h" +#include "avsys-common.h" +#include "avsys-error.h" +#include "avsys-audio-handle.h" +#include "avsys-audio-path.h" + +#define SHM_KEY_PATH "/tmp" + +typedef struct { + avsys_shm_param_t param; + void *pdst; +} _avsys_audio_shm_control_t; + +static _avsys_audio_shm_control_t g_presettings[AVSYS_AUDIO_SHM_IDEN_CNT] = { + {{SHM_KEY_PATH, AVSYS_KEY_PREFIX_GEN(AVSYS_KEY_PREFIX_AUDIO,AVSYS_AUDIO_SHM_IDEN_HANDLE) + 0x10,sizeof(avsys_audio_handle_info_t)}, NULL}, + {{SHM_KEY_PATH, AVSYS_KEY_PREFIX_GEN(AVSYS_KEY_PREFIX_AUDIO,AVSYS_AUDIO_SHM_IDEN_PATH) + 0x10,sizeof(avsys_audio_path_ex_info_t)}, NULL}, +}; + +int avsys_audio_create_shm(const avsys_audio_shm_iden_t iden) +{ + if (iden >= AVSYS_AUDIO_SHM_IDEN_CNT || 0 > iden) + return AVSYS_STATE_ERR_INVALID_PARAMETER; + return avsys_create_shm(&g_presettings[iden].param); +} + +int avsys_audio_remove_shm(const avsys_audio_shm_iden_t iden) +{ + if (iden >= AVSYS_AUDIO_SHM_IDEN_CNT || 0 > iden) + return AVSYS_STATE_ERR_INVALID_PARAMETER; + g_presettings[iden].pdst = NULL; + return avsys_remove_shm(&g_presettings[iden].param); +} + +int avsys_audio_get_shm(const avsys_audio_shm_iden_t iden, void **ptr) +{ + if (iden >= AVSYS_AUDIO_SHM_IDEN_CNT || 0 > iden) + return AVSYS_STATE_ERR_INVALID_PARAMETER; + + if (!ptr) + return AVSYS_STATE_ERR_NULL_POINTER; + + if (!g_presettings[iden].pdst) { + g_presettings[iden].pdst = avsys_get_shm(&g_presettings[iden].param); + if (!g_presettings[iden].pdst) + return AVSYS_STATE_ERR_INTERNAL; + } + *ptr = (void *)g_presettings[iden].pdst; + return AVSYS_STATE_SUCCESS; +} diff --git a/avsys-audio-sync.c b/avsys-audio-sync.c new file mode 100644 index 0000000..240c882 --- /dev/null +++ b/avsys-audio-sync.c @@ -0,0 +1,242 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi + * + * 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 +#include +#include +#include +#include + +#include "avsys-common.h" +#include "avsys-audio-sync.h" +#include "avsys-error.h" +#include "avsys-debug.h" +#include "avsys-audio-shm.h" +#include "avsys-audio-path.h" + +static avsys_sync_param_t g_presettings[AVSYS_AUDIO_SYNC_IDEN_CNT] = { + {"audio_handle_lock", AVSYS_KEY_PREFIX_GEN(AVSYS_KEY_PREFIX_AUDIO, AVSYS_AUDIO_SYNC_IDEN_HANDLE)}, + {"audio_path_lock", AVSYS_KEY_PREFIX_GEN(AVSYS_KEY_PREFIX_AUDIO, AVSYS_AUDIO_SYNC_IDEN_PATH)}, +}; + +int avsys_audio_create_sync(const avsys_audio_sync_iden_t iden) +{ + if (iden >= AVSYS_AUDIO_SYNC_IDEN_CNT || 0 > iden) + return AVSYS_STATE_ERR_INVALID_PARAMETER; + return avsys_create_sync(&g_presettings[iden]); +} + +int avsys_audio_remove_sync(const avsys_audio_sync_iden_t iden) +{ + if (iden >= AVSYS_AUDIO_SYNC_IDEN_CNT || 0 > iden) + return AVSYS_STATE_ERR_INVALID_PARAMETER; + return avsys_remove_sync(&g_presettings[iden]); +} + +int avsys_audio_lock_sync(const avsys_audio_sync_iden_t iden) +{ + pid_t pid = -1; + int index = 0; + int err = AVSYS_STATE_SUCCESS; + + if (iden >= AVSYS_AUDIO_SYNC_IDEN_CNT || 0 > iden) { + return AVSYS_STATE_ERR_INVALID_PARAMETER; + } + //avsys_info(AVAUDIO,"lock[%d]\n",(int)iden); + + err = avsys_lock_sync(&g_presettings[iden]); + + pid = getpid(); + if ((iden == AVSYS_AUDIO_SYNC_IDEN_PATH) && (err == AVSYS_STATE_SUCCESS)) { + avsys_audio_path_ex_info_t *control = NULL; + avsys_audio_path_ex_info_t **temp = NULL; + + temp = &control; + if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp))) { + avsys_error_r(AVAUDIO, "avsys_audio_get_shm() for path failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + + do { + /* Add mark */ + if (control->pathlock_pid[index] < 0) { /* find empty slot */ + control->pathlock_pid[index] = pid; + break; + } + index++; + if (index == AVSYS_AUDIO_LOCK_SLOT_MAX) { + int i; + avsys_warning(AVAUDIO, "path lock pid slot is full. print stored pid before clear all slot\n"); + /* print and cleanup all stored pid */ + for (i = 0; i < AVSYS_AUDIO_LOCK_SLOT_MAX; i++) { + avsys_warning(AVAUDIO, "path lock pid : %d\n", control->pathlock_pid[i]); + control->pathlock_pid[i] = -1; + } + control->pathlock_pid[0] = pid; /* add current pid */ + } + } while (index < AVSYS_AUDIO_LOCK_SLOT_MAX); + } else if ((iden == AVSYS_AUDIO_SYNC_IDEN_HANDLE) && (err == AVSYS_STATE_SUCCESS)) { + avsys_audio_handle_info_t *control = NULL; + avsys_audio_handle_info_t **temp = NULL; + + temp = &control; + if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_HANDLE, (void **)temp))) { + avsys_error(AVAUDIO, "avsys_audio_get_shm() for handle failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + + do { + /* Add mark */ + if (control->handlelock_pid[index] < 0) { /* find empty slot */ + control->handlelock_pid[index] = pid; + break; + } + index++; + if (index == AVSYS_AUDIO_LOCK_SLOT_MAX) { + int i; + avsys_warning(AVAUDIO, "handle lock pid slot is full. print stored pid before clear all slot\n"); + /* print and cleanup all stored pid */ + for (i = 0; i < AVSYS_AUDIO_LOCK_SLOT_MAX; i++) { + avsys_warning(AVAUDIO, "handle lock pid : %d\n", control->handlelock_pid[i]); + control->handlelock_pid[i] = -1; + } + control->handlelock_pid[0] = pid; /*add current pid */ + } + } while (index < AVSYS_AUDIO_LOCK_SLOT_MAX); + } + return err; +} + +int avsys_audio_unlock_sync(const avsys_audio_sync_iden_t iden) +{ + pid_t pid = -1; + int index = 0; + int err = AVSYS_STATE_SUCCESS; + + if (iden >= AVSYS_AUDIO_SYNC_IDEN_CNT || 0 > iden) { + return AVSYS_STATE_ERR_INVALID_PARAMETER; + } + //avsys_info(AVAUDIO,"unlock[%d]\n",(int)iden); + + err = avsys_unlock_sync(&g_presettings[iden]); + + pid = getpid(); + if ((iden == AVSYS_AUDIO_SYNC_IDEN_PATH) && (err == AVSYS_STATE_SUCCESS)) { + avsys_audio_path_ex_info_t *control = NULL; + avsys_audio_path_ex_info_t **temp = NULL; + + temp = &control; + if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp))) { + avsys_error_r(AVAUDIO, "avsys_audio_get_shm() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + + do { + /* Remove mark */ + if (control->pathlock_pid[index] == pid) { /* find empty slot */ + control->pathlock_pid[index] = -1; + break; + } + index++; + if (index == AVSYS_AUDIO_LOCK_SLOT_MAX) + avsys_error(AVAUDIO, "Can not find pid (%d) in path_lock_pid slot\n", pid); + } while (index < AVSYS_AUDIO_LOCK_SLOT_MAX); + } else if ((iden == AVSYS_AUDIO_SYNC_IDEN_HANDLE) && (err == AVSYS_STATE_SUCCESS)) { + avsys_audio_handle_info_t *control = NULL; + avsys_audio_handle_info_t **temp = NULL; + + temp = &control; + if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_HANDLE, (void **)temp))) { + avsys_error(AVAUDIO, "avsys_audio_get_shm() for handle failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + + do { + /* Add mark */ + if (control->handlelock_pid[index] == pid) { /* find empty slot */ + control->handlelock_pid[index] = -1; + break; + } + index++; + if (index == AVSYS_AUDIO_LOCK_SLOT_MAX) + avsys_error(AVAUDIO, "Can not find pid (%d) in handlelock_pid slot\n", pid); + } while (index < AVSYS_AUDIO_LOCK_SLOT_MAX); + } + + return err; +} + +/* find pid information in proc filesystem */ +/* if pid exist, return AVSYS_STATE_SUCCESS */ +/* if pid does not exist, return AVSYS_STATE_ERR_ALLOCATION */ +int avsys_check_process(int check_pid) +{ + DIR *dir = NULL; + char check_path[128] = ""; + int exist = AVSYS_STATE_SUCCESS; + + memset(check_path, '\0', sizeof(check_path)); + snprintf(check_path, sizeof(check_path) - 1, "/proc/%d", check_pid); + + dir = opendir(check_path); + if (dir == NULL) { + switch (errno) { + case ENOENT: + avsys_error(AVAUDIO, "pid %d does not exist anymore\n", check_pid); + exist = AVSYS_STATE_ERR_ALLOCATION; + break; + case EACCES: + avsys_error(AVAUDIO, "Permission denied\n"); + break; + case EMFILE: + avsys_error(AVAUDIO, "Too many file descriptors in use by process\n"); + break; + case ENFILE: + avsys_error(AVAUDIO, "Too many files are currently open in the system\n"); + break; + default: + avsys_error(AVAUDIO, "Other error : %d\n", errno); + break; + } + } else { + avsys_warning(AVAUDIO, "pid : %d still alive\n", check_pid); + if (-1 == closedir(dir)) { + avsys_error(AVAUDIO, "closedir failed with errno : %d\n", errno); + } + } + return exist; +} + +int avsys_audio_dump_sync(void) +{ + pid_t pid = -1; + int index = 0; + int err = AVSYS_STATE_SUCCESS; + int i = 0; + int sem_value = 0; + + fprintf(stdout, "Dump sync : Start\n"); + for (i = 0; i < AVSYS_AUDIO_SYNC_IDEN_CNT; i++) { + err = avsys_dump_sync(&g_presettings[i]); + } + fprintf(stdout, "Dump sync : End\n"); + return err; +} diff --git a/avsys-audio.c b/avsys-audio.c new file mode 100755 index 0000000..7ab37d9 --- /dev/null +++ b/avsys-audio.c @@ -0,0 +1,1240 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef PCM_DUMP_ENABLE +#include +#endif + +#include "avsys-types.h" +#include "avsys-error.h" +#include "avsys-debug.h" +#include "avsys-audio.h" +#include "avsys-common.h" +#include "avsys-audio-sync.h" + +#include "avsys-audio-path.h" +#include "avsys-audio-pasimple.h" +#include "avsys-audio-pactrl.h" +#include "avsys-audio-alsa.h" + +#if 0 /* Disabled, Do enable for local debugging */ +#define AVSYS_STREAM_DEBUG +#endif + +#if 0 /* Disabled, Do enable for local debugging */ +#define AVSYS_STREAM_DEBUG +#endif +#ifdef PCM_DUMP_ENABLE +/* dump flag is defined in module-policy.c */ +#define AVSYS_DUMP_VCONF_KEY "memory/private/sound/pcm_dump" +#define AVSYS_DUMP_WRITE_FLAG 0x00000800 /* PA_DUMP_PLAYBACK_AVSYSTEM_WRITE */ +#define AVSYS_DUMP_READ_FLAG 0x00100000 /* PA_DUMP_CAPTURE_AVSYSTEM_READ */ +#define AVSYS_DUMP_WRITE_PATH_PREFIX "/tmp/dump_avsys_write" +#define AVSYS_DUMP_READ_PATH_PREFIX "/tmp/dump_avsys_read" +#endif + +/** + * Internal functions definition + */ +#define FADE_MULTIPLIER 1 +#define LVOLUME_MAX_SVOICE 7 + +static int __avsys_audio_set_info(avsys_audio_handle_t *p, avsys_audio_param_t *param); +static int __avsys_audio_handle_init(int *handle, + avsys_audio_handle_t **ptr, + avsys_audio_param_t *param); + + +void __init_module(void); +void __fini_module(void); + +#define AVSYS_GET_HANDLE_PTR(MODE) do { \ + err = avsys_audio_handle_get_ptr((int)handle, &p, MODE); \ + if (AVSYS_FAIL(err)) { \ + return err; \ + } \ +} while (0) + +#define AVSYS_RELEASE_HANDLE_PTR(MODE) do { \ + if (AVSYS_FAIL(avsys_audio_handle_release_ptr((int)handle, MODE))) { \ + avsys_error(AVAUDIO, "audio handle release failed\n"); \ + return AVSYS_STATE_ERR_INTERNAL; \ + } \ +} while (0) + +#define AVSYS_STREAM_LOCK() do { \ + pthread_mutex_lock(&gmutex); /* avsys_info(AVAUDIO, "(+) LOCKED\n"); */ \ +} while (0) + +#define AVSYS_STREAM_UNLOCK() do { \ + pthread_mutex_unlock(&gmutex); /* avsys_info(AVAUDIO, "(-) UNLOCKED\n"); */ \ +} while (0) + +/** + * Internal global variable + */ +static pthread_mutex_t gmutex = PTHREAD_MUTEX_INITIALIZER; + + +/**************************************************************************** + * + * Interface + * + ***************************************************************************/ +#ifdef PCM_DUMP_ENABLE +static const char *__avsys_audio_get_mode_string(int mode) +{ + switch (mode) { + case AVSYS_AUDIO_MODE_OUTPUT: return "mid"; + case AVSYS_AUDIO_MODE_OUTPUT_CLOCK: return "high"; + case AVSYS_AUDIO_MODE_OUTPUT_VIDEO: return "video"; + case AVSYS_AUDIO_MODE_OUTPUT_LOW_LATENCY: return "low"; + case AVSYS_AUDIO_MODE_INPUT: return "mid"; + case AVSYS_AUDIO_MODE_INPUT_HIGH_LATENCY: return "high"; + case AVSYS_AUDIO_MODE_INPUT_LOW_LATENCY: return "low"; + case AVSYS_AUDIO_MODE_CALL_OUT: return "call"; + case AVSYS_AUDIO_MODE_CALL_IN: return "call"; + case AVSYS_AUDIO_MODE_OUTPUT_AP_CALL: return "ap_call"; + case AVSYS_AUDIO_MODE_INPUT_AP_CALL: return "ap_call"; + default: return "invalid"; + } +} + +static void __avsys_audio_load_dump_config_n_open_file(avsys_audio_handle_t *p, bool is_playback) +{ + int vconf_dump = 0; + + if (vconf_get_int(AVSYS_DUMP_VCONF_KEY, &vconf_dump)) { + avsys_warning(AVAUDIO, "vconf_get_int %s failed", AVSYS_DUMP_VCONF_KEY); + } + + if ((vconf_dump & AVSYS_DUMP_WRITE_FLAG && is_playback) || + (vconf_dump & AVSYS_DUMP_READ_FLAG && !is_playback)) { + time_t t; + char dump_path[256], datetime[12]; + + time(&t); + memset(&datetime[0], 0x00, sizeof(datetime)); + strftime(&datetime[0], sizeof(datetime), "%m%d_%H%M%S", localtime(&t)); + + sprintf(&dump_path[0], "%s_%s_%dch_%dhz_%s.pcm", + (is_playback) ? AVSYS_DUMP_WRITE_PATH_PREFIX : AVSYS_DUMP_READ_PATH_PREFIX, + __avsys_audio_get_mode_string(p->mode), p->channels, p->samplerate, &datetime[0]); + p->dump_fp = fopen(&dump_path[0], "w+"); + if (!p->dump_fp) { + avsys_warning(AVAUDIO, "open pcm dump file %s failed", &dump_path[0]); + } else { + avsys_info(AVAUDIO, "open pcm dump file %s success", &dump_path[0]); + } + } +} +#endif + +EXPORT_API +int avsys_audio_open(avsys_audio_param_t *param, avsys_handle_t *phandle, int *size) +{ + int handle = -1; + avsys_audio_handle_t *p = NULL; + int err = AVSYS_STATE_ERR_UNKNOWN; +#ifdef PCM_DUMP_ENABLE + bool is_playback = false; +#endif + + avsys_info(AVAUDIO, "enter: priority[%d] mode[%d] format[%d] ch[%d] rate[%d] route[%d] vol_cfg[%x]\n", + param->priority, param->mode, param->format, param->channels, param->samplerate, param->handle_route, param->vol_type); + + if (param == NULL || phandle == NULL) { + avsys_error(AVAUDIO, "param or phandle is null\n"); + return AVSYS_STATE_ERR_NULL_POINTER; + } + + if (param->channels > AVSYS_CHANNEL_MAX || param->channels < AVSYS_CHANNEL_MIN) { + return AVSYS_STATE_ERR_INVALID_CHANNEL; + } + + if (param->mode < AVSYS_AUDIO_MODE_OUTPUT || param->mode >= AVSYS_AUDIO_MODE_NUM) { + return AVSYS_STATE_ERR_INVALID_MODE; + } + + if (param->format < AVSYS_AUDIO_FORMAT_MIN || param->format > AVSYS_AUDIO_FORMAT_MAX) { + return AVSYS_STATE_ERR_INVALID_FORMAT; + } + + AVSYS_STREAM_LOCK(); + + err = avsys_audio_handle_rejuvenation(); + if (AVSYS_FAIL(err)) { + avsys_error(AVAUDIO, "Unused handle cleanup before handle allocation failed\n"); + goto error; + } + + err = __avsys_audio_handle_init(&handle, &p, param); + + if (AVSYS_STATE_ERR_RANGE_OVER == err) { + avsys_error(AVAUDIO, "audio handle is fully allocated..try cleanup\n"); + err = avsys_audio_handle_rejuvenation(); + if (AVSYS_FAIL(err)) { + avsys_error(AVAUDIO, "Unused handle cleanup failed\n"); + goto error; + } + avsys_error(AVAUDIO, "one more try...to allocate audio handle\n"); + err = __avsys_audio_handle_init(&handle, &p, param); + if (AVSYS_FAIL(err)) { + avsys_error(AVAUDIO, "handle alloc failed 1\n"); + goto error; + } + } else if ((AVSYS_FAIL(err)) && (err != AVSYS_STATE_ERR_RANGE_OVER)) { + avsys_error(AVAUDIO, "handle alloc failed 2\n"); + goto error; + } + + if (p->mode == AVSYS_AUDIO_MODE_OUTPUT || p->mode == AVSYS_AUDIO_MODE_OUTPUT_CLOCK || + p->mode == AVSYS_AUDIO_MODE_OUTPUT_LOW_LATENCY || p->mode == AVSYS_AUDIO_MODE_OUTPUT_AP_CALL || p->mode == AVSYS_AUDIO_MODE_OUTPUT_VIDEO) { +#ifdef PCM_DUMP_ENABLE + is_playback = true; +#endif + err = avsys_audio_handle_update_priority(handle, param->priority, param->handle_route, AVSYS_AUDIO_SET_PRIORITY); + if (AVSYS_FAIL(err)) { + goto error; + } + } + /* load AEC & loopback module */ + if(p->source_type == AVSYS_AUDIO_SUPPORT_TYPE_VOICECONTROL) { + avsys_warning(AVAUDIO, "param->source_type=[%d]\n", p->source_type); + err = avsys_audio_pa_ctrl_load_loopback_module(true); + if(AVSYS_FAIL(err)) + avsys_error(AVAUDIO, "load aecloopback module failed\n"); + } + + /* open device */ + err = avsys_audio_pasimple_open_device(p->mode, p->format, p->channels, p->samplerate, p, param->handle_route, param->map); + if ((err == AVSYS_STATE_WAR_UNAVAILABLE_DEVICE) && (p->mode == AVSYS_AUDIO_MODE_OUTPUT_CLOCK)) { + /* Change latency if high latency device is unavailable */ + p->mode = AVSYS_AUDIO_MODE_OUTPUT; + err = avsys_audio_pasimple_open_device(p->mode, p->format, p->channels, p->samplerate, p, param->handle_route, param->map); + if (AVSYS_FAIL(err)) { + goto error; + } + } else if (AVSYS_FAIL(err)) { + goto error; + } + + *phandle = (avsys_handle_t) handle; + /* set recommended buffer size */ + if (size != NULL) + *size = p->period; + else + avsys_warning(AVAUDIO, "Size is null\n"); + +#ifdef PCM_DUMP_ENABLE + __avsys_audio_load_dump_config_n_open_file(p, is_playback); +#endif + + avsys_audio_set_mute(handle, AVSYS_AUDIO_UNMUTE); + + err = avsys_audio_handle_release_ptr(handle, HANDLE_PTR_MODE_NORMAL); + if (AVSYS_FAIL(err)) { + goto error; + } + AVSYS_STREAM_UNLOCK(); + + avsys_info(AVAUDIO, "leave: handle[%d] stream_idx[%d] size[%d]\n", handle, p->stream_index, *size); + + return AVSYS_STATE_SUCCESS; + +error: + if (p) { + if (p->device) + free(p->device); + avsys_audio_handle_release_ptr(handle, HANDLE_PTR_MODE_NORMAL); + } + + if (handle != -1) { + if (AVSYS_FAIL(avsys_audio_handle_free(handle))) { + avsys_error(AVAUDIO, "Can not free handle %d\n", handle); + } + } + + avsys_error(AVAUDIO, "failed to open : REASON %x\n", err); + + *phandle = (avsys_handle_t)-1; + AVSYS_STREAM_UNLOCK(); + return err; +} + +EXPORT_API +int avsys_audio_close(avsys_handle_t handle) +{ + avsys_audio_handle_t *p = NULL; + int err = AVSYS_STATE_ERR_UNKNOWN; + int handle_before, stream_index, priority; + + avsys_info(AVAUDIO, "enter: handle[%d]\n", (int)handle); + + AVSYS_STREAM_LOCK(); + + err = avsys_audio_handle_get_ptr((int)handle, &p, HANDLE_PTR_MODE_NORMAL); + if (AVSYS_FAIL(err)) { + AVSYS_STREAM_UNLOCK(); + return err; + } + + handle_before = (int)handle; + stream_index = p->stream_index; + priority = p->priority; + + if (p->mode == AVSYS_AUDIO_MODE_OUTPUT || p->mode == AVSYS_AUDIO_MODE_OUTPUT_CLOCK || + p->mode == AVSYS_AUDIO_MODE_OUTPUT_LOW_LATENCY || p->mode == AVSYS_AUDIO_MODE_OUTPUT_AP_CALL || p->mode == AVSYS_AUDIO_MODE_OUTPUT_VIDEO) { + if (AVSYS_FAIL(avsys_audio_handle_update_priority((int)handle, p->priority, AVSYS_AUDIO_HANDLE_ROUTE_FOLLOWING_POLICY, AVSYS_AUDIO_UNSET_PRIORITY))) { + avsys_error(AVAUDIO, "unset priority of handle %d error: %x\n", handle, err); + } + } + + if(p->source_type == AVSYS_AUDIO_SUPPORT_TYPE_VOICECONTROL) { + avsys_info(AVAUDIO, "param->source_type=[%d]\n", p->source_type); + err = avsys_audio_pa_ctrl_unload_loopback_module(true); + if(AVSYS_FAIL(err)) + avsys_error(AVAUDIO, "unload aecloopback module failed\n"); + } + + err = avsys_audio_pasimple_close_device(p); + if (AVSYS_FAIL(err)) { + avsys_error_r(AVAUDIO, "audio device close error : %x\n", err); + } + +#ifdef PCM_DUMP_ENABLE + if (p->dump_fp) { + fclose(p->dump_fp); + p->dump_fp = NULL; + } +#endif + + if (AVSYS_FAIL(avsys_audio_handle_release_ptr((int)handle, HANDLE_PTR_MODE_NORMAL))) { + avsys_error(AVAUDIO, "audio handle release failed\n"); + AVSYS_STREAM_UNLOCK(); + return AVSYS_STATE_ERR_INTERNAL; + } + + avsys_audio_handle_free((int)handle); + + avsys_info(AVAUDIO, "leave: handle[%d->%d] stream_index[%d] priority[%d]\n", handle_before, (int)handle, stream_index, priority); + AVSYS_STREAM_UNLOCK(); + + return err; +} + +EXPORT_API +int avsys_audio_update_volume_config(avsys_handle_t handle, int volume_config) +{ + return AVSYS_STATE_SUCCESS; +} + +EXPORT_API +int avsys_audio_ampon(void) +{ + return avsys_audio_path_ex_set_amp(AVSYS_AUDIO_AMP_ON); +} + +EXPORT_API +int avsys_audio_ampoff(void) +{ + return avsys_audio_path_ex_set_amp(AVSYS_AUDIO_AMP_OFF); +} + + +EXPORT_API +int avsys_audio_ext_device_ampon(avsysaudio_ext_device_t device_type) +{ + return avsys_audio_handle_ext_dev_set_mute(device_type, AVSYS_AUDIO_UNMUTE); +} + +EXPORT_API +int avsys_audio_ext_device_ampoff(avsysaudio_ext_device_t device_type) +{ + return avsys_audio_handle_ext_dev_set_mute(device_type, AVSYS_AUDIO_MUTE); +} + +EXPORT_API +int avsys_audio_set_ext_device_status(avsysaudio_ext_device_t device_type, int onoff) +{ + return avsys_audio_handle_ext_dev_status_update(device_type, onoff); +} + +EXPORT_API +int avsys_audio_get_ext_device_status(avsysaudio_ext_device_t device_type, int *onoff) +{ + return avsys_audio_handle_ext_dev_status(device_type, onoff); +} + +EXPORT_API +int avsys_audio_flush(avsys_handle_t handle) +{ + int err = AVSYS_STATE_SUCCESS; + avsys_audio_handle_t *p = NULL; + avsys_info(AVAUDIO, "\n"); + + AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + err = avsys_audio_pasimple_reset(p); + + AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + return err; +} + +EXPORT_API +int avsys_audio_drain(avsys_handle_t handle) +{ + int err = AVSYS_STATE_SUCCESS; + avsys_audio_handle_t *p = NULL; + avsys_info(AVAUDIO, "idx=[%d]\n", (int)handle); + + AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + err = avsys_audio_pasimple_drain(p); + + AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + return err; +} + +EXPORT_API +int avsys_audio_read(avsys_handle_t handle, void *buf, int size) +{ + int err = AVSYS_STATE_SUCCESS; + avsys_audio_handle_t *p = NULL; + +#ifdef AVSYS_STREAM_DEBUG + avsys_debug(AVAUDIO, "idx=[%d], buf=[%p], size=[%d]\n", (int)handle, buf, size); +#endif + + if (buf == NULL) { + avsys_error(AVAUDIO, "input buffer pointer is null\n"); + return AVSYS_STATE_ERR_NULL_POINTER; + } + + AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_FAST); + + if (p->mode != AVSYS_AUDIO_MODE_INPUT && p->mode != AVSYS_AUDIO_MODE_INPUT_LOW_LATENCY && + p->mode != AVSYS_AUDIO_MODE_INPUT_HIGH_LATENCY && p->mode != AVSYS_AUDIO_MODE_INPUT_AP_CALL) { + avsys_error(AVAUDIO, "opened output mode\n"); + return AVSYS_STATE_ERR_INVALID_MODE; + } + + err = avsys_audio_pasimple_read(p, buf, size); + +#ifdef PCM_DUMP_ENABLE + if (p->dump_fp) { + fwrite(buf, 1, size, p->dump_fp); + } +#endif + + AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_FAST); + + return err; +} + +EXPORT_API +int avsys_audio_write(avsys_handle_t handle, void *buf, int size) +{ + int err = AVSYS_STATE_SUCCESS; + avsys_audio_handle_t *p = NULL; + +#ifdef AVSYS_STREAM_DEBUG + avsys_debug(AVAUDIO, "idx=[%d], buf=[%p], size=[%d]\n", (int)handle, buf, size); +#endif + + if (buf == NULL) { + avsys_error(AVAUDIO, "buf is null\n"); + return AVSYS_STATE_ERR_NULL_POINTER; + } + + AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_FAST); + + if (p->mode != AVSYS_AUDIO_MODE_OUTPUT && p->mode != AVSYS_AUDIO_MODE_OUTPUT_CLOCK && + p->mode != AVSYS_AUDIO_MODE_OUTPUT_LOW_LATENCY && p->mode != AVSYS_AUDIO_MODE_OUTPUT_AP_CALL && p->mode != AVSYS_AUDIO_MODE_OUTPUT_VIDEO) { + avsys_error(AVAUDIO, "opened input mode\n"); + avsys_audio_handle_release_ptr((int)handle, HANDLE_PTR_MODE_FAST); + return AVSYS_STATE_ERR_INVALID_MODE; + } + + if (p->fadeup_vol > -1) { + if (p->fadeup_multiplier == 0) { + avsys_audio_pa_ctrl_set_volume_level(p->stream_index, (-1), p->fadeup_vol_current); + if (p->fadeup_vol > p->fadeup_vol_current) { + p->fadeup_vol_current++; + } else if (p->fadeup_vol < p->fadeup_vol_current) { + p->fadeup_vol_current--; + } else { + p->fadeup_vol = -1; + } + if (p->msec_per_period > 50) + p->fadeup_multiplier = 0; + else + p->fadeup_multiplier = FADE_MULTIPLIER; + } else { + p->fadeup_multiplier--; + } + } + err = avsys_audio_pasimple_write(p, buf, size); + +#ifdef PCM_DUMP_ENABLE + if (p->dump_fp) { + fwrite(buf, 1, size, p->dump_fp); + } +#endif + + AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_FAST); + + return err; +} + +EXPORT_API +int avsys_audio_set_volume_fadeup(avsys_handle_t handle) +{ + int err = AVSYS_STATE_SUCCESS; + avsys_audio_handle_t *p = NULL; + + avsys_warning(AVAUDIO, "\n"); + + AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + avsys_audio_pa_ctrl_get_volume_level(p->stream_index, (-1), &p->fadeup_vol); + p->fadeup_vol_current = 0; + p->fadeup_multiplier = 0; + + AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + return err; +} + +EXPORT_API +int avsys_audio_set_mute_fadedown(avsys_handle_t handle) +{ + int err = AVSYS_STATE_SUCCESS; + avsys_audio_handle_t *p = NULL; + + avsys_warning(AVAUDIO, "\n"); + + AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + avsys_audio_pa_ctrl_get_volume_level(p->stream_index, (-1), &p->fadeup_vol_current); + p->fadeup_vol = 0; + p->fadeup_multiplier = 0; + + AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + return err; +} + +EXPORT_API +int avsys_audio_is_available_high_latency(int *available) +{ + return avsys_audio_pa_ctrl_is_available_high_latency(available); +} + +EXPORT_API +int avsys_audio_set_vsp_speed(avsys_handle_t handle, int speed) +{ + int err = AVSYS_STATE_SUCCESS; + avsys_audio_handle_t *p = NULL; + + avsys_warning(AVAUDIO, "\n"); + + AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + err = avsys_audio_pa_ctrl_set_vsp_speed(p->stream_index, speed); + + AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + return err; +} + +EXPORT_API +int avsys_audio_set_soundalive_filter_action(avsys_handle_t handle, int filter_action) +{ + int err = AVSYS_STATE_SUCCESS; + avsys_audio_handle_t *p = NULL; + + avsys_warning(AVAUDIO, "\n"); + + AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + err = avsys_audio_pa_ctrl_set_soundalive_filter_action(p->stream_index, filter_action); + + AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + return err; +} + +EXPORT_API +int avsys_audio_set_soundalive_preset_mode(avsys_handle_t handle, int preset_mode) +{ + int err = AVSYS_STATE_SUCCESS; + avsys_audio_handle_t *p = NULL; + + avsys_warning(AVAUDIO, "\n"); + + AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + err = avsys_audio_pa_ctrl_set_soundalive_preset_mode(p->stream_index, preset_mode); + + AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + return err; +} + +EXPORT_API +int avsys_audio_set_soundalive_eq(avsys_handle_t handle, int eq[]) +{ + int err = AVSYS_STATE_SUCCESS; + avsys_audio_handle_t *p = NULL; + + avsys_warning(AVAUDIO, "\n"); + + AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + err = avsys_audio_pa_ctrl_set_soundalive_eq(p->stream_index, eq); + + AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + return err; +} + +EXPORT_API +int avsys_audio_set_soundalive_ext(avsys_handle_t handle, int ext[]) +{ + int err = AVSYS_STATE_SUCCESS; + avsys_audio_handle_t *p = NULL; + + avsys_warning(AVAUDIO, "\n"); + + AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + err = avsys_audio_pa_ctrl_set_soundalive_ext(p->stream_index, ext); + + AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + return err; +} + +EXPORT_API +int avsys_audio_set_soundalive_device(avsys_handle_t handle, int device) +{ + int err = AVSYS_STATE_SUCCESS; + avsys_audio_handle_t *p = NULL; + + avsys_warning(AVAUDIO, "\n"); + + AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + err = avsys_audio_pa_ctrl_set_soundalive_device(p->stream_index, device); + + AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + return err; +} + +EXPORT_API +int avsys_audio_set_dha(avsys_handle_t handle, int onoff, int gain[]) +{ + int err = AVSYS_STATE_SUCCESS; + avsys_audio_handle_t *p = NULL; + + avsys_warning(AVAUDIO, "\n"); + + AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + err = avsys_audio_pa_ctrl_set_dha(p->stream_index, onoff, gain); + + AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + return err; +} + +/* Tuning part */ +EXPORT_API +int avsys_audio_set_volume_table(int volume_type, int dev_type, int step, int lv, int rv) +{ + return AVSYS_STATE_SUCCESS; +} + +EXPORT_API +int avsys_audio_get_volume_table(int volume_type, int dev_type, int step, int *lv, int *rv) +{ + /* workaround for playing camera shutter sound */ + *lv = 65535; + *rv = 65535; + return AVSYS_STATE_SUCCESS; +} + +EXPORT_API +int avsys_audio_get_volume_max_ex(int volume_type, int *max_step) +{ + if (max_step == NULL) { + return AVSYS_STATE_ERR_NULL_POINTER; + } + + return avsys_audio_pa_ctrl_get_volume_level_max(volume_type, max_step); +} + +EXPORT_API +int avsys_audio_set_volume_gain_table(int volume_gain_idx, int dev_type, float lv, float rv) +{ + return AVSYS_STATE_SUCCESS; +} + +EXPORT_API +int avsys_audio_get_volume_gain_table(int volume_gain_idx, int dev_type, float *lv, float *rv) +{ + /* workaround for playing camera shutter sound */ + *lv = 1.0f; + *rv = 1.0f; + return AVSYS_STATE_SUCCESS; +} + +EXPORT_API +int avsys_audio_set_mute(avsys_handle_t handle, int mute) +{ + if (mute > AVSYS_AUDIO_MUTE || mute < AVSYS_AUDIO_UNMUTE) { + return AVSYS_STATE_ERR_INVALID_PARAMETER; + } + + if (AVSYS_FAIL(avsys_audio_handle_set_mute((int)handle, mute))) { + avsys_error(AVAUDIO, "failed to set handle mute\n"); + } + + return AVSYS_STATE_SUCCESS; +} + +EXPORT_API +int avsys_audio_get_mute(avsys_handle_t handle, int *pmute) +{ + int err = AVSYS_STATE_SUCCESS; + avsys_audio_handle_t *p = NULL; + + avsys_info(AVAUDIO, "\n"); + + if (pmute == NULL) { + avsys_error(AVAUDIO, "pvolume is null\n"); + return AVSYS_STATE_ERR_NULL_POINTER; + } + + AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + *pmute = p->mute; + + AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + return AVSYS_STATE_SUCCESS; +} + +/* + * Option : AVSYS_AUDIO_PATH_OPTION_LEGACY_MODE support NowPlus style sound path function + * Option : AVSYS_AUDIO_PATH_OPTION_DUAL_OUT will effect only when out is speaker. + * Option : AVSYS_AUDIO_PATH_OPTION_JACK_AUTO will effect only when out is speaker or receiver. + * Option : AVSYS_AUDIO_PATH_OPTION_FORCED is avail only for shutdown animation + * + * Limitation : Only FORCED option can be used same time with other options (exclude LEGACY_MODE) + */ +EXPORT_API +int avsys_audio_set_path_ex(int gain, int out, int in, int option) +{ + if (AVSYS_AUDIO_GAIN_EX_KEYTONE > gain || AVSYS_AUDIO_GAIN_EX_MAX <= gain || + AVSYS_AUDIO_PATH_EX_NONE > out || AVSYS_AUDIO_PATH_EX_OUTMAX <= out || + AVSYS_AUDIO_PATH_EX_NONE > in || AVSYS_AUDIO_PATH_EX_INMAX <= in) { + avsys_error(AVAUDIO, "Your input parameter is invalid. Please check\n"); + avsys_error(AVAUDIO, " gain %d, out %d, in %d\n", gain, out, in); + return AVSYS_STATE_ERR_INVALID_PARAMETER; + } + + return avsys_audio_path_ex_set_path(gain, out, in, option); +} +EXPORT_API +int avsys_audio_get_path_ex(int *gain, int *out, int *in, int *option) +{ + if (!gain || !out || !in || !option) { + avsys_warning(AVAUDIO, "Your input parameter is NULL pointer. Please check.\n"); + avsys_warning(AVAUDIO, " gain %p, out %p, in %p, option %p\n", gain, out, in, option); + return AVSYS_STATE_ERR_INVALID_PARAMETER; + } + return avsys_audio_path_ex_get_path(gain, out, in, option); +} + +EXPORT_API +int avsys_audio_set_global_mute(int mute) +{ + int err = AVSYS_STATE_SUCCESS; + + avsys_info(AVAUDIO, "mute=%d\n", mute); + + if (mute < AVSYS_AUDIO_UNMUTE && mute > AVSYS_AUDIO_MUTE_NOLOCK) { + err = AVSYS_STATE_ERR_INVALID_PARAMETER; + } else { + err = avsys_audio_path_ex_set_mute(mute); + } + return err; +} + +EXPORT_API +int avsys_audio_get_global_mute(int *pmute) +{ + int err = AVSYS_STATE_SUCCESS; + + avsys_info(AVAUDIO, "\n"); + if (pmute == NULL) { + err = AVSYS_STATE_ERR_NULL_POINTER; + } else { + err = avsys_audio_path_ex_get_mute(pmute); + } + return err; +} + +/** + * Internal functions implementation + */ + +static int __avsys_audio_set_info(avsys_audio_handle_t *p, avsys_audio_param_t *param) +{ + int vol_conf_type = AVSYS_AUDIO_VOLUME_CONFIG_TYPE(param->vol_type); + int vol_conf_gain = AVSYS_AUDIO_VOLUME_CONFIG_GAIN(param->vol_type); + + p->mode = param->mode; + p->channels = param->channels; + p->samplerate = param->samplerate; + p->format = param->format; + p->priority = param->priority; + p->source_type = param->source_type; + p->corked = false; + + if ((vol_conf_type < 0) || (vol_conf_type >= AVSYS_AUDIO_VOLUME_TYPE_MAX)) { + avsys_error(AVAUDIO, "Invalid volume type %d. use default system type\n", vol_conf_type); + p->gain_setting.volume_config = AVSYS_AUDIO_VOLUME_TYPE_SYSTEM; + } else { + p->gain_setting.volume_config = param->vol_type; + } + + p->fadeup_vol = -1; + + return AVSYS_STATE_SUCCESS; +} + +static int __avsys_audio_handle_init(int *handle, + avsys_audio_handle_t **ptr, + avsys_audio_param_t *param) +{ + int err = AVSYS_STATE_ERR_UNKNOWN; + + if (AVSYS_FAIL(avsys_audio_lock_sync(AVSYS_AUDIO_SYNC_IDEN_HANDLE))) { + avsys_error(AVAUDIO,"avsys_audio_lock_sync() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + + err = avsys_audio_handle_alloc_unlocked(handle); + + if (AVSYS_STATE_SUCCESS == err) { + + err = avsys_audio_handle_get_ptr_unlocked(*handle, ptr, HANDLE_PTR_MODE_NORMAL); + if(AVSYS_STATE_SUCCESS == err) { + + /* set information to handle */ + err = __avsys_audio_set_info(*ptr, param); + } + } + + if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_HANDLE))) { + avsys_error(AVAUDIO,"avsys_audio_unlock_sync() failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + + return err; +} + +EXPORT_API +int avsys_audio_get_current_playing_volume_type(int *volume_type) +{ + if (volume_type == NULL) + return AVSYS_STATE_ERR_NULL_POINTER; + return avsys_audio_handle_current_playing_volume_type(volume_type); +} + +static inline int __avsys_audio_validate_volume(const int type, const int value) +{ + if (value < 0) + return -1; + switch (type) { + case AVSYS_AUDIO_VOLUME_TYPE_CALL: + case AVSYS_AUDIO_VOLUME_TYPE_VOIP: + if (value >= AVSYS_AUDIO_VOLUME_MAX_BASIC) { + return -1; + } + break; + case AVSYS_AUDIO_VOLUME_TYPE_ALARM: + case AVSYS_AUDIO_VOLUME_TYPE_RINGTONE: + case AVSYS_AUDIO_VOLUME_TYPE_NOTIFICATION: + case AVSYS_AUDIO_VOLUME_TYPE_SYSTEM: + case AVSYS_AUDIO_VOLUME_TYPE_MEDIA: + case AVSYS_AUDIO_VOLUME_TYPE_EXT_SYSTEM_JAVA: + if (value >= AVSYS_AUDIO_VOLUME_MAX_MULTIMEDIA) { + return -1; + } + break; + case AVSYS_AUDIO_VOLUME_TYPE_SVOICE: + if (value >= LVOLUME_MAX_SVOICE) { + return -1; + } + break; + case AVSYS_AUDIO_VOLUME_TYPE_EXT_SYSTEM_ANDROID: + if (value >= AVSYS_AUDIO_VOLUME_MAX_SINGLE) { + return -1; + } + break; + default: + return -1; + break; + } + return 0; +} + +EXPORT_API +int avsys_audio_set_volume_by_type(const int type, const int value) +{ + avsys_error(AVAUDIO,"type %d value %d\n", type, value); + if (type < 0 || type >= AVSYS_AUDIO_VOLUME_TYPE_MAX) + return AVSYS_STATE_ERR_INVALID_PARAMETER; + if (0 > __avsys_audio_validate_volume(type, value)) + return AVSYS_STATE_ERR_INVALID_PARAMETER; + + return avsys_audio_pa_ctrl_set_volume_level((-1), type, value); +} + +int avsys_audio_get_volume_by_type(const int type, const int *value) +{ + avsys_error(AVAUDIO, "get_volume type:%d", type); + + if (type < 0 || type >= AVSYS_AUDIO_VOLUME_TYPE_MAX) + return AVSYS_STATE_ERR_INVALID_PARAMETER; + return avsys_audio_pa_ctrl_get_volume_level((-1), type, value); +} + +EXPORT_API +int avsys_audio_set_mute_all(int mute_all) +{ + return avsys_audio_handle_update_mute_all(mute_all); +} + + +EXPORT_API +int avsys_audio_set_call_mute(avsys_audio_volume_type_t type, int mute) +{ + return avsys_audio_pa_ctrl_set_mute((-1), type, AVSYS_AUDIO_DIRECTION_IN, mute); +} + +EXPORT_API +int avsys_audio_get_call_mute(avsys_audio_volume_type_t type, int *mute) +{ + return avsys_audio_pa_ctrl_get_mute((-1), type, AVSYS_AUDIO_DIRECTION_IN, mute); +} + +EXPORT_API +int avsys_audio_set_factory_loopback_test(int loopback) +{ + return avsys_audio_path_ex_set_factory_loopback_test(loopback); +} + +EXPORT_API +int avsys_audio_get_factory_loopback_test(int *loopback) +{ + return avsys_audio_path_ex_get_factory_loopback_test(loopback); +} + + +EXPORT_API +int avsys_audio_set_primary_volume(const int pid, const int type) +{ + return avsys_audio_handle_set_primary_volume_type(pid, type, AVSYS_AUDIO_PRIMARY_VOLUME_SET); +} + +EXPORT_API +int avsys_audio_clear_primary_volume(const int pid) +{ + return avsys_audio_handle_set_primary_volume_type(pid, 0, AVSYS_AUDIO_PRIMARY_VOLUME_CLEAR); +} + +EXPORT_API +int avsys_audio_hibernation_reset(int *vol) +{ + int err = AVSYS_STATE_SUCCESS; + + err = avsys_audio_path_ex_reset(1); + if (AVSYS_FAIL(err)) { + avsys_error(AVAUDIO, "avsys_audio_path_ex_reset(forced) failed 0x%x\n", err); + return err; + } + + err = avsys_audio_handle_reset(vol); + if (AVSYS_FAIL(err)) { + avsys_error(AVAUDIO, "avsys_audio_handle_reset() failed 0x%x\n", err); + return err; + } + + return err; +} + +EXPORT_API +int avsys_audio_delay(avsys_handle_t handle, int *delay) +{ + int err = AVSYS_STATE_SUCCESS; + int frame_delay = 0; + avsys_audio_handle_t *p = NULL; + + AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + err = avsys_audio_pasimple_delay(p, &frame_delay); + if (AVSYS_SUCCESS(err)) { + *delay = frame_delay; + } + + AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + return err; +} + +EXPORT_API +int avsys_audio_get_latency(avsys_handle_t handle, int *latency) +{ + int err = AVSYS_STATE_SUCCESS; + int mlatency = 0; + avsys_audio_handle_t *p = NULL; + + AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + err = avsys_audio_pasimple_latency(p, &mlatency); + if (AVSYS_SUCCESS(err)) { + *latency = mlatency; + } + avsys_info(AVAUDIO, "avsys_audio_get_latency handle:%d latency = %d\n", handle, mlatency); + + AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + return err; +} + +EXPORT_API +int avsys_audio_reset(avsys_handle_t handle) +{ + int err = AVSYS_STATE_SUCCESS; + avsys_audio_handle_t *p = NULL; + + AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + err = avsys_audio_pasimple_reset(p); + if (AVSYS_FAIL(err)) { + avsys_error(AVAUDIO, "avsys_audio_reset() failed, 0x%X\n", err); + } + + AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + return err; +} + +#define HIGH_LATENCY_SINK "alsa_output.4.analog-stereo" +#define TRUE 1 +#define FALSE 0 + +EXPORT_API +int avsys_audio_pause(avsys_handle_t handle) +{ + int err = AVSYS_STATE_SUCCESS; + avsys_audio_handle_t *p = NULL; + const char *sink_name = HIGH_LATENCY_SINK; + + AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + avsys_info(AVAUDIO, "p->mode: %d, p->gain_setting.volume_config: %d",p->mode, p->gain_setting.volume_config); + if(AVSYS_AUDIO_MODE_OUTPUT_CLOCK == p->mode && + AVSYS_AUDIO_VOLUME_TYPE_MEDIA == p->gain_setting.volume_config) { + sink_name = HIGH_LATENCY_SINK; + } + else { + err = AVSYS_STATE_ERR_DEVICE_NOT_SUPPORT; + goto __exit; + } + + err = avsys_audio_pa_ctrl_suspend_sink(sink_name, TRUE); + if (AVSYS_FAIL(err)) { + avsys_error(AVAUDIO, "avsys_audio_pause() failed, 0x%X\n", err); + } + +__exit: + AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + return err; +} + + +EXPORT_API +int avsys_audio_resume(avsys_handle_t handle) +{ + int err = AVSYS_STATE_SUCCESS; + avsys_audio_handle_t *p = NULL; + const char *sink_name = HIGH_LATENCY_SINK; + + AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + avsys_info(AVAUDIO, "p->mode: %d, p->gain_setting.volume_config: %d",p->mode, p->gain_setting.volume_config); + + if(AVSYS_AUDIO_MODE_OUTPUT_CLOCK == p->mode && + AVSYS_AUDIO_VOLUME_TYPE_MEDIA == p->gain_setting.volume_config) { + sink_name = HIGH_LATENCY_SINK; + } + else { + err = AVSYS_STATE_ERR_DEVICE_NOT_SUPPORT; + goto __exit; + } + + err = avsys_audio_pa_ctrl_suspend_sink(sink_name, FALSE); + if (AVSYS_FAIL(err)) { + avsys_error(AVAUDIO, "avsys_audio_resume() failed, 0x%X\n", err); + } + +__exit: + AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + return err; +} + + +EXPORT_API +int avsys_audio_get_period_buffer_time(avsys_handle_t handle, unsigned int *period_time, unsigned int *buffer_time) +{ + int err = AVSYS_STATE_SUCCESS; + avsys_audio_handle_t *p = NULL; + unsigned int p_time = 0, b_time=0; + + AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + err = avsys_audio_pasimple_get_period_buffer_time(p, &p_time, &b_time); + if(AVSYS_FAIL(err)) { + avsys_error(AVAUDIO, "avsys_audio_get_period_buffer_time() failed, 0x%X\n",err); + } + else + { + *period_time = p_time; + *buffer_time = b_time; + avsys_info(AVAUDIO,"period time : %u, buffer_time : %u\n", p_time, b_time); + } + + AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + return err; +} + +EXPORT_API +int avsys_audio_cork (avsys_handle_t handle, int cork) +{ + int err = AVSYS_STATE_SUCCESS; + avsys_audio_handle_t *p = NULL; + + AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + err = avsys_audio_pasimple_cork(p, cork); + if(AVSYS_FAIL(err)) { + avsys_error(AVAUDIO, "avsys_audio_pasimple_cork() failed, 0x%X\n",err); + } else { + p->corked = cork; + } + + AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + return err; +} + +EXPORT_API +int avsys_audio_is_corked (avsys_handle_t handle, int *is_corked) +{ + int err = AVSYS_STATE_SUCCESS; + avsys_audio_handle_t *p = NULL; + + if (is_corked == NULL) { + AVSYS_STREAM_UNLOCK(); + return AVSYS_STATE_ERR_NULL_POINTER; + } + + AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + *is_corked = p->corked; + AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + return err; +} + +EXPORT_API +int avsys_audio_get_capture_status(int *on_capture) +{ + return avsys_audio_handle_current_capture_status(on_capture); +} + +EXPORT_API +int avsys_audio_update_scn(void) +{ + return avsys_audio_pa_ctrl_update_scn(); +} + +EXPORT_API +int avsys_audio_load_loopback_module(bool is_aec) +{ + return avsys_audio_pa_ctrl_load_loopback_module(is_aec); +} + +EXPORT_API +int avsys_audio_unload_loopback_module(bool is_aec) +{ + return avsys_audio_pa_ctrl_unload_loopback_module(is_aec); +} + +EXPORT_API +int avsys_audio_set_DHA_control(unsigned short* param) +{ + return AVSYS_STATE_SUCCESS; +} + +__attribute__ ((constructor)) +void __init_module(void) +{ +} + +__attribute__ ((destructor)) +void __fini_module(void) +{ +} diff --git a/avsys-common.c b/avsys-common.c new file mode 100644 index 0000000..eb7e50f --- /dev/null +++ b/avsys-common.c @@ -0,0 +1,370 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi + * + * 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 "avsys-common.h" +#include "avsys-debug.h" +#include "avsys-error.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define RETRY_EINTR +#include +#include + +void * avsys_malloc(size_t size) +{ + char *allocated; + allocated = (char*) malloc(size + 12); + + if(!allocated) { + return NULL; + } + memset(allocated, 0, size+8); + memcpy(allocated, AVSYS_MAGIC_START, 4); + (*(int*)(allocated+4)) = size; + memcpy(allocated+size+8, AVSYS_MAGIC_END, 4); + + return (void*)(allocated + 8); +} + +void avsys_free(void *ptr) +{ + char *allocated = (char*)ptr; + if(allocated) { + if(avsys_mem_check(allocated)) { + free(allocated-8); + } + } +} + +int avsys_create_shm(const avsys_shm_param_t* param) +{ + int shmid = -1; + int *segptr = NULL; + key_t key; + + if (!param) { + return AVSYS_STATE_ERR_NULL_POINTER; + } + if (param->size < 1 || param->key_path == NULL || access(param->key_path, R_OK) != 0) { + return AVSYS_STATE_ERR_INVALID_VALUE; + } + + key = ftok(param->key_path, param->key_prefix); + + if ((shmid = shmget(key, param->size, IPC_CREAT|IPC_EXCL|0666)) == -1) { + if (errno == EEXIST) { + avsys_error(AVAUDIO,"Already initialized.\n"); + if ((shmid = shmget(key, param->size, 0)) == -1) { + avsys_error(AVAUDIO, "Initialization fail.\n"); + } else { + segptr = shmat(shmid, 0, 0); + avsys_assert_r(segptr != NULL); + } + } else { + if(errno == EACCES) + avsys_error_r(AVAUDIO, "Require ROOT permission.\n"); + else if(errno == ENOMEM) + avsys_critical_r(AVAUDIO, "System memory is empty.\n"); + else if(errno == ENOSPC) + avsys_critical_r(AVAUDIO, "Resource is empty.\n"); + } + } else { + shmctl(shmid, SHM_LOCK, 0); + segptr = shmat(shmid, 0, 0); + avsys_assert_r(segptr != NULL); + memset((void*)segptr, 0, param->size); + } + + if (shmid != -1) { + return AVSYS_STATE_SUCCESS; + } else { + return AVSYS_STATE_ERR_INTERNAL; + } +} + +int avsys_remove_shm(const avsys_shm_param_t* param) +{ + int shmid = -1; + key_t key; + + if (!param) { + return AVSYS_STATE_ERR_NULL_POINTER; + } + if (param->size < 1 || param->key_path == NULL || access(param->key_path, R_OK) != 0) { + return AVSYS_STATE_ERR_INVALID_VALUE; + } + + key = ftok(param->key_path, param->key_prefix); + + if ((shmid = shmget(key, param->size, 0)) == -1) { + if(errno == ENOENT) + avsys_error_r(AVAUDIO, "Not initialized.\n"); + else if(errno == EACCES) + avsys_error_r(AVAUDIO, "Require ROOT permission.\n"); + else if(errno == ENOSPC) + avsys_critical_r(AVAUDIO, "Resource is empty.\n"); + } else { + avsys_assert_r(shmctl(shmid, IPC_RMID, 0) == 0); + } + + if (shmid != -1) { + return AVSYS_STATE_SUCCESS; + } else { + return AVSYS_STATE_ERR_INTERNAL; + } +} + +void* avsys_get_shm(const avsys_shm_param_t* param) +{ + int shmid = -1; + void *ptr = NULL; + key_t key; + + if (!param) { + return NULL; + } + if (param->size < 1 || param->key_path == NULL || access(param->key_path, R_OK) != 0) { + return NULL; + } + + key = ftok(param->key_path, param->key_prefix); + + if ((shmid = shmget(key, param->size, 0)) == -1) { + if(errno == ENOENT) + avsys_error_r(AVAUDIO, "Not initialized.\n"); + else if(errno == EACCES) + avsys_error_r(AVAUDIO, "Require ROOT permission.\n"); + else if(errno == ENOSPC) + avsys_critical_r(AVAUDIO, "Resource is empty.\n"); + return NULL; + } + + ptr = shmat(shmid, 0, 0); + if(ptr == (void*)-1) { + if(errno == EACCES) + avsys_error_r(AVAUDIO,"no permission\n"); + else if(errno == EINVAL) + avsys_error_r(AVAUDIO,"invalid shmid\n"); + else if(errno == ENOMEM) + avsys_error_r(AVAUDIO,"can not allocate memory\n"); + else + avsys_error_r(AVAUDIO,"shmat() failed %d\n", errno); + ptr = NULL; + } + return ptr; +} + +int avsys_create_sync(const avsys_sync_param_t *param) +{ + sem_t *sem = NULL; + sem = sem_open(param->key_path, O_CREAT, 0666, 1); + if (sem == SEM_FAILED) { + switch(errno) + { + case EACCES: + avsys_error(AVAUDIO, + "The semaphore already exist, but caller does not have permission %s\n",param->key_path); + break; + case ENOMEM: + avsys_error(AVAUDIO,"Insufficient memory\n"); + break; + case ENFILE: + avsys_error(AVAUDIO,"Too many open files in system\n"); + break; + default: + avsys_critical(AVAUDIO, "Semaphore create fail! (name:%s, errno %d)\n", param->key_path, errno); + break; + } + return AVSYS_STATE_ERR_INTERNAL; + } + return AVSYS_STATE_SUCCESS; +} + +int avsys_remove_sync(const avsys_sync_param_t *param) +{ + int err = 0; + + err = sem_unlink(param->key_path); + if (err == -1) { + avsys_critical(AVAUDIO, "Semaphore destroy Fail! (name:%s, errno %d)\n", param->key_path, errno); + return AVSYS_STATE_ERR_INTERNAL; + } + + return AVSYS_STATE_SUCCESS; +} + +int avsys_lock_sync(const avsys_sync_param_t *param) +{ + sem_t *sem = NULL; + int ret; + int err = AVSYS_STATE_SUCCESS; + struct timespec wait_time; + struct timeval tv; + + sem = sem_open(param->key_path, O_CREAT, 0666, 1); + if (sem == SEM_FAILED) { + avsys_critical(AVAUDIO, "Semaphore open Fail! (name:%s, errno %d)\n", param->key_path, errno); + return AVSYS_STATE_ERR_INTERNAL; + } +retry_lock: + gettimeofday(&tv,NULL); + wait_time.tv_sec = tv.tv_sec + LOCK_TIMEOUT_SEC; + wait_time.tv_nsec = tv.tv_usec * 1000; + ret = sem_timedwait(sem, &wait_time); + if(ret == -1) { + switch(errno) + { + case EINTR: + avsys_error(AVAUDIO, "Lock RETRY LOCK\n"); + goto retry_lock; + break; + case EINVAL: + avsys_error(AVAUDIO, "Invalid semaphore\n"); + err = AVSYS_STATE_ERR_INTERNAL; + break; + case EAGAIN: + avsys_error(AVAUDIO, "EAGAIN\n"); + err = AVSYS_STATE_ERR_INTERNAL; + break; + case ETIMEDOUT: + avsys_error(AVAUDIO, "sem_wait leached %d seconds timeout.\n", LOCK_TIMEOUT_SEC); + { + /* Recovery of sem_wait lock....in abnormal condition */ + int sem_value = -1; + if (0 == sem_getvalue(sem, &sem_value)) { + avsys_error(AVAUDIO,"%s sem value is %d\n",param->key_path, sem_value); + if (sem_value == 0) { + ret = sem_post(sem); + if (ret == -1) { + avsys_error(AVAUDIO,"sem_post error %s : %d\n", param->key_path, sem_value); + } else { + avsys_warning(AVAUDIO,"lock recovery success...try lock again\n"); + goto retry_lock; + } + } else { + avsys_error(AVAUDIO,"sem value is not 0. but failed sem_timedwait so retry.. : %s\n",param->key_path); + usleep(5); + goto retry_lock; + } + } else { + avsys_error(AVAUDIO,"sem_getvalue failed : %s\n",param->key_path); + } + } + err = AVSYS_STATE_ERR_INTERNAL; + break; + } + } + sem_close(sem); + return err; +} + +int avsys_unlock_sync(const avsys_sync_param_t *param) +{ + sem_t *sem = NULL; + int ret; + int err = AVSYS_STATE_SUCCESS; + + sem = sem_open(param->key_path, O_CREAT, 0666, 1); + if (sem == SEM_FAILED) { + avsys_critical(AVAUDIO, "Semaphore open Fail! (name:%s, errno %d)\n", param->key_path, errno); + return AVSYS_STATE_ERR_INTERNAL; + } + + ret = sem_post(sem); + if (ret == -1) { + avsys_error(AVAUDIO, "UNLOCK FAIL\n"); + err = AVSYS_STATE_ERR_INTERNAL; + } + + sem_close(sem); + return err; +} + +int avsys_check_root_privilege() +{ + uid_t uid; + uid = getuid(); + if(0 != uid) { + /* code from man page */ + struct passwd pwd; + struct passwd *result; + char *buf; + size_t bufsize; + int s = 0; + + bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); + if (bufsize == -1) /* Value was indeterminate */ + bufsize = 16384; /* Should be more than enough */ + + buf = malloc(bufsize); + if (buf == NULL) { + perror("malloc"); + } else { + s= getpwuid_r (uid, &pwd, buf, bufsize, &result); + if (result == NULL) { + if (s == 0) + printf("Not found\n"); + else { + errno = s; + perror("getpwnam_r"); + } + } else { + avsys_error_r(AVAUDIO,"super user privilege check failed (%s)\n", pwd.pw_name); + } + free (buf); + } + return AVSYS_STATE_ERR_PRIVILEGE; + } + return AVSYS_STATE_SUCCESS; +} + +int avsys_dump_sync (const avsys_sync_param_t *param) +{ + int err = AVSYS_STATE_SUCCESS; + + sem_t *sem = NULL; + int ret; + int sem_value = -1; + + sem = sem_open(param->key_path, O_CREAT, 0666, 1); + if (sem == SEM_FAILED) { + avsys_critical(AVAUDIO, "Semaphore open Fail! (name:%s, errno %d)\n", param->key_path, errno); + return AVSYS_STATE_ERR_INTERNAL; + } + + if(0 == sem_getvalue(sem, &sem_value)) { + fprintf (stdout, " * [%d] sem value for [%s]\n", sem_value, param->key_path); + } else { + avsys_error(AVAUDIO,"sem_getvalue failed : %s\n",param->key_path); + } + + sem_close(sem); + return err; +} diff --git a/avsystem-ymu831.manifest b/avsystem-ymu831.manifest new file mode 100755 index 0000000..da414ee --- /dev/null +++ b/avsystem-ymu831.manifest @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..f659142 --- /dev/null +++ b/configure.ac @@ -0,0 +1,154 @@ +AC_PREREQ(2.52) + +AC_INIT([avsystem], [1.0]) +AM_INIT_AUTOMAKE([-Wall -Werror foreign]) +AC_CONFIG_HEADERS([config.h:config.hin]) + +AC_CONFIG_MACRO_DIR([m4]) + +# Checks for programs. +AC_PROG_CC +AC_C_CONST +dnl AC_FUNC_MALLOC +AC_FUNC_MMAP +AC_FUNC_REALLOC +AC_FUNC_SELECT_ARGTYPES +AC_FUNC_STAT +AC_FUNC_VPRINTF +AC_HEADER_STDBOOL +AC_HEADER_STDC +AC_HEADER_TIME +AC_PROG_GCC_TRADITIONAL +AC_PROG_LIBTOOL + +AC_ARG_ENABLE(sdk, AC_HELP_STRING([--enable-sdk], [sdk build]), + [ + case "${enableval}" in + yes) IS_SDK=yes ;; + no) IS_SDK=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-sdk) ;; + esac + ], + [IS_SDK=no]) +AM_CONDITIONAL([IS_SDK], [test "x$IS_SDK" = "xyes"]) + +AC_ARG_ENABLE(audiotest, AC_HELP_STRING([--enable-audiotest], [build audio test program]), + [ + case "${enableval}" in + yes) WITH_AUDIOTEST=yes ;; + no) WITH_AUDIOTEST=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-audiotest) ;; + esac + ], + [WITH_AUDIOTEST=no]) +AM_CONDITIONAL([WITH_AUDIOTEST], [test "x$WITH_AUDIOTEST" = "xyes"]) + +AC_ARG_ENABLE(ucm, AC_HELP_STRING([--enable-ucm], [build avsystem with alsaucm]), + [ + case "${enableval}" in + yes) ALSA_UCM=yes ;; + no) ALSA_UCM=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-ucm) ;; + esac + ], + [ALSA_UCM=no]) +AM_CONDITIONAL([ALSA_UCM], [test "x$ALSA_UCM" = "xyes"]) + +AC_ARG_ENABLE(ymu831, AC_HELP_STRING([--enable-ymu831], [use ymu831]), +[ + case "${enableval}" in + yes) USE_YMU831=yes ;; + no) USE_YMU831=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-ymu831) ;; + esac +], +[USE_YMU831=no]) +AM_CONDITIONAL([USE_YMU831], [test "x$USE_YMU831" = "xyes"]) + +AC_ARG_ENABLE(tizen-mobile, AC_HELP_STRING([--enable-tizen-mobile], [use tizen-mobile]), +[ + case "${enableval}" in + yes) TIZEN_MOBILE=yes ;; + no) TIZEN_MOBILE=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-tizen-mobile) ;; + esac +], +[TIZEN_MOBILE=no]) +AM_CONDITIONAL([TIZEN_MOBILE], [test "x$TIZEN_MOBILE" = "xyes"]) + +AC_ARG_ENABLE(pcmdump, AC_HELP_STRING([--enable-pcmdump], [pcm dump]), + [ + case "${enableval}" in + yes) PCM_DUMP_ENABLE=yes ;; + no) PCM_DUMP_ENABLE=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-pcmdump) ;; + esac + ], + [PCM_DUMP_ENABLE=no]) +AM_CONDITIONAL([PCM_DUMP_ENABLE], [test "x$PCM_DUMP_ENABLE" = "xyes"]) + + +# Checks for libraries. +PKG_CHECK_MODULES(ALSA, alsa >= 1.0.15) +AC_SUBST(ALSA_CFLAGS) +AC_SUBST(ALSA_LIBS) + +PKG_CHECK_MODULES(EXIF, libexif) +AC_SUBST(EXIF_CFLAGS) +AC_SUBST(EXIF_LIBS) + +PKG_CHECK_MODULES(MMTA, mm-ta) +AC_SUBST(MMTA_CFLAGS) +AC_SUBST(MMTA_LIBS) + +PKG_CHECK_MODULES(MMLOG, mm-log) +AC_SUBST(MMLOG_CFLAGS) +AC_SUBST(MMLOG_LIBS) + +PKG_CHECK_MODULES(PASIMPLE, libpulse-simple) +AC_SUBST(PASIMPLE_CFLAGS) +AC_SUBST(PASIMPLE_LIBS) +PKG_CHECK_MODULES(PA, libpulse) +AC_SUBST(PA_CFLAGS) +AC_SUBST(PA_LIBS) + +PKG_CHECK_MODULES(ASCN, libascenario) +AC_SUBST(ASCN_CFLAGS) +AC_SUBST(ASCN_LIBS) + +PKG_CHECK_MODULES(INIPARSER, iniparser) +AC_SUBST(INIPARSER_CFLAGS) +AC_SUBST(INIPARSER_LIBS) + +PKG_CHECK_MODULES(VCONF, vconf) +AC_SUBST(VCONF_CFLAGS) +AC_SUBST(VCONF_LIBS) + +# Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS([fcntl.h memory.h stdlib.h string.h sys/time.h unistd.h errno.h sys/types.h sys/stat.h]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_TYPE_PID_T +AC_TYPE_SIZE_T + +# Checks for library functions. +AC_FUNC_ALLOCA +AC_FUNC_FORK +AC_FUNC_MALLOC +AC_FUNC_MEMCMP +AC_FUNC_SELECT_ARGTYPES +AC_TYPE_SIGNAL +AC_CHECK_FUNCS([memset select]) + +AC_CONFIG_FILES([ +Makefile +pkgconfig-arm/Makefile +pkgconfig-arm/avsystem.pc +pkgconfig-arm/avsysaudio.pc +pkgconfig-i386/Makefile +pkgconfig-i386/avsystem.pc +pkgconfig-i386/avsysaudio.pc +]) +AC_OUTPUT diff --git a/depcomp b/depcomp new file mode 100755 index 0000000..e5f9736 --- /dev/null +++ b/depcomp @@ -0,0 +1,589 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2007-03-29.01 + +# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007 Free Software +# Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by `PROGRAMS ARGS'. + object Object file output by `PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputing dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> $depfile + echo >> $depfile + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> $depfile + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts `$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler understands `-MD -MF file'. However on + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using \ : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" + # Add `dependent.h:' lines. + sed -ne '2,${; s/^ *//; s/ \\*$//; s/$/:/; p;}' "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # With Tru64 cc, shared objects can also be used to make a + # static library. This mechanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # generates 2 separate objects for the 2 libraries. These two + # compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for `:' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + "$@" $dashmflag | + sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no + for arg in "$@"; do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix="`echo $object | sed 's/^.*\././'`" + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o, + # because we must use -o when running libtool. + "$@" || exit $? + IFS=" " + for arg + do + case "$arg" in + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/include/alsa-ucm-constants.h b/include/alsa-ucm-constants.h new file mode 100755 index 0000000..1d246cf --- /dev/null +++ b/include/alsa-ucm-constants.h @@ -0,0 +1,164 @@ +/* + * avsystem + * + * Copyright (c) 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * + * 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. + * + */ + +#ifndef __AVSYS_AUDIO_ALSA_UCM_H__ +#define __AVSYS_AUDIO_ALSA_UCM_H__ + +/* Verbs */ +#define UC_VERB_INACTIVE "Inactive" +#define UC_VERB_HIFI "HiFi" +#define UC_VERB_VOICE_CALL "Voice Call" +#define UC_VERB_VIDEO_CALL "Video Call" +#define UC_VERB_VOIP "VoIP" +#define UC_VERB_LOOPBACK "Loopback" +#define UC_VERB_VOLTE "VoLTE" +#define UC_VERB_FMRADIO "FmRadio" +#define UC_VERB_MULTI_CHANNEL "Multi Channel" + +/* Devices : Normal */ +#define UC_OUT_DEV_SPEAKER "Speaker" +#define UC_OUT_DEV_SPEAKER_EXTRA_VOL "Speaker Extra Vol" +#define UC_OUT_DEV_HANDSET "Handset" +#define UC_OUT_DEV_HANDSET_EXTRA_VOL "Handset Extra Vol" +#define UC_OUT_DEV_HEADSET "Headset" +#define UC_OUT_DEV_SPEAKER_HEADSET "Speaker Headset" +#define UC_OUT_DEV_BT_HEADSET "BT Headset" +#define UC_OUT_DEV_BT_NREC_HEADSET "BT Nrec Headset" +#define UC_OUT_DEV_BT_HEADSET_16K "BT Headset 16K" +#define UC_OUT_DEV_BT_NREC_HEADSET_16K "BT Nrec Headset 16K" +#define UC_OUT_DEV_DOCK "Dock" +#define UC_OUT_DEV_USB_AUDIO "Usb Audio" +#define UC_OUT_DEV_LINEOUT "Line Out" +#define UC_OUT_DEV_HDMI "Hdmi" +#define UC_OUT_DEV_WIFI_DISPLAY "WiFi Display" + +#define UC_IN_DEV_MAIN_MIC "Main Mic" +#define UC_IN_DEV_SUB_MIC "Sub Mic" +#define UC_IN_DEV_HEADSET_MIC "Headset Mic" +#define UC_IN_DEV_STEREO_MIC "Stereo Mic" +#define UC_IN_DEV_STEREO_MIC_INTERVIEW "Voicenote Interview Dual Mic" +#define UC_IN_DEV_STEREO_MIC_CONVERSATION "Voicenote Conversation Dual Mic" +#define UC_IN_DEV_BT_MIC "BT Mic" +#define UC_IN_DEV_BT_NREC_MIC "BT Nrec Mic" +#define UC_IN_DEV_BT_MIC_16K "BT Mic 16K" +#define UC_IN_DEV_BT_NREC_MIC_16K "BT Nrec Mic 16K" +#define UC_IN_DEV_FMRADIO "FmRadio" + +/* Devices : Samsung */ +#define UC_IN_DEV_DUAL_MIC_RCV "Samsung Dualmic RCV" +#define UC_IN_DEV_DUAL_MIC_SPK "Samsung Dualmic SPK" +#define UC_IN_DEV_CALL_DUAL_MIC_RCV "Call Samsung Dualmic RCV" +#define UC_IN_DEV_CALL_DUAL_MIC_SPK "Call Samsung Dualmic SPK" +#define UC_IN_DEV_CALL_DUAL_MIC_RCV_WB "Call Samsung Dualmic RCV WB" +#define UC_IN_DEV_CALL_DUAL_MIC_SPK_WB "Call Samsung Dualmic SPK WB" + +/* Devices : VR */ +#define UC_IN_DEV_VR_MAIN_MIC "VR Main Mic" +#define UC_IN_DEV_VR_HEADSET_MIC "VR Headset Mic" +#define UC_IN_DEV_VR_BT_MIC "VR BT Mic" +#define UC_IN_DEV_VR_BT_NREC_MIC "VR BT Nrec Mic" + + +/* Devices : VR Sec */ +#define UC_IN_DEV_VR_SEC_MAIN_MIC "VR Sec Main Mic" +#define UC_IN_DEV_VR_SEC_SUB_MIC "VR Sec Sub Mic" +#define UC_IN_DEV_VR_SEC_HEADSET_MIC "VR Sec Headset Mic" +#define UC_IN_DEV_VR_SEC_HEADPHONE_MIC "VR Sec Headphone Mic" + +/* Devices : Loopback */ +#define UC_OUT_DEV_LOOPBACK_SPEAKER "LoopbackSpeaker" +#define UC_OUT_DEV_LOOPBACK_HANDSET "LoopbackHandset" +#define UC_OUT_DEV_LOOPBACK_HEADSET "LoopbackHeadset" + +#define UC_IN_DEV_LOOPBACK_MAIN_MIC "LoopbackMain Mic" +#define UC_IN_DEV_LOOPBACK_SUB_MIC "LoopbackSub Mic" +#define UC_IN_DEV_LOOPBACK_HEADSET_MIC "LoopbackHeadset Mic" + + +/* Devices : VoIP */ + +#define UC_OUT_DEV_VOIP_SPEAKER "VoIP Comm Speaker" +#define UC_OUT_DEV_VOIP_HANDSET "VoIP Comm Handset" +#define UC_OUT_DEV_VOIP_HEADSET "VoIP Comm Headset" + +#define UC_IN_DEV_VOIP_MAIN_MIC "VoIP Comm Main Mic" +#define UC_IN_DEV_VOIP_SUB_MIC "VoIP Comm Sub Mic" +#define UC_IN_DEV_VOIP_HEADSET_MIC "VoIP Comm Headset Mic" +#define UC_IN_DEV_VOIP_HEADPHONE_MIC "VoIP Comm Headphone Mic" +#define UC_IN_DEV_VOIP_BT_MIC "VoIP Comm BT Mic" +#define UC_IN_DEV_VOIP_BT_NREC_MIC "VoIP Comm BT Nrec Mic" + +#define UC_OUT_DEV_VOIP_SEC_SPEAKER "VoIP Sec Comm Speaker" +#define UC_OUT_DEV_VOIP_SEC_HANDSET "VoIP Sec Comm Handset" +#define UC_OUT_DEV_VOIP_SEC_HEADSET "VoIP Sec Comm Headset" +#define UC_OUT_DEV_VOIP_SEC_BT_HEADSET "VoIP Sec Comm BT Headset" +#define UC_OUT_DEV_VOIP_SEC_BT_NREC_HEADSET "VoIP Sec Comm BT Nrec Headset" + +#define UC_IN_DEV_VOIP_SEC_MAIN_MIC "VoIP Sec Comm Main Mic" +#define UC_IN_DEV_VOIP_SEC_SUB_MIC "VoIP Sec Comm Sub Mic" +#define UC_IN_DEV_VOIP_SEC_HEADSET_MIC "VoIP Sec Comm Headset Mic" +#define UC_IN_DEV_VOIP_SEC_HEADPHONE_MIC "VoIP Sec Comm Headphone Mic" +#define UC_IN_DEV_VOIP_SEC_BT_MIC "VoIP Sec Comm BT Mic" +#define UC_IN_DEV_VOIP_SEC_BT_MIC_16K "VoIP Sec Comm BT Mic 16K" +#define UC_IN_DEV_VOIP_SEC_BT_NREC_MIC "VoIP Sec Comm BT Nrec Mic" +#define UC_IN_DEV_VOIP_SEC_BT_NREC_MIC_16K "VoIP Sec Comm BT Nrec Mic 16K" + + +/* Devices : Call */ +#define UC_OUT_DEV_CALL_SPEAKER "Call Speaker" +#define UC_OUT_DEV_CALL_SPEAKER_EXTRA_VOL "Call Speaker Extra Vol" +#define UC_OUT_DEV_CALL_HANDSET "Call Handset" +#define UC_OUT_DEV_CALL_HANDSET_EXTRA_VOL "Call Handset Extra Vol" +#define UC_OUT_DEV_CALL_HEADSET "Call Headset" + +#define UC_IN_DEV_CALL_MAIN_MIC "Call Main Mic" +#define UC_IN_DEV_CALL_SUB_MIC "Call Sub Mic" +#define UC_IN_DEV_CALL_HEADSET_MIC "Call Headset Mic" +#define UC_IN_DEV_CALL_HEADPHONE_MIC "Call Headphone Mic" +#define UC_IN_DEV_CALL_BT_MIC "Call BT Mic" +#define UC_IN_DEV_CALL_BT_MIC_16K "Call BT Mic 16K" +#define UC_IN_DEV_CALL_BT_NREC_MIC "Call BT Nrec Mic" +#define UC_IN_DEV_CALL_BT_NREC_MIC_16K "Call BT Nrec Mic 16K" +#define UC_IN_DEV_CALL_HANDSET_AM "Call Handset AM" +#define UC_IN_DEV_CALL_MAN_MIC_AM "Call Main Mic AM" + +/* Devices : TTY */ +#define UC_OUT_DEV_TTY_FULL "TTY Full" +#define UC_OUT_DEV_TTY_HEADSET "TTY Headset" + +#define UC_IN_DEV_TTY_HEADSET_MIC "TTY Headset Mic" +#define UC_IN_DEV_TTY_FULL_MIC "TTY Full Mic" + + +/* Modifiers */ +#define UC_MODIFIER_NONE "" +#define UC_MODIFIER_VOICE_CALL "Play Voice Call" +#define UC_MODIFIER_VOIP "Play VoIP" +#define UC_MODIFIER_CAPTURE_MUSIC "Capture Music" +#define UC_MODIFIER_PLAY_MUSIC "Play Music" +#define UC_MODIFIER_PLAY_LPA "Play LPA" +#define UC_MODIFIER_PLAY_MULTICH_HDMI "Play Multi ChHdmi" +#define UC_MODIFIER_PLAY_VOICE_CALL_MUSIC "Play Voice Call Music" +#define UC_MODIFIER_CAPTURE_CALL_DOWNLINK "Capture Call Downlink" +#define UC_MODIFIER_CAPTURE_CALL_UPLINK_DOWNLINK "Capture Call Uplink Downlink" +#define UC_MODIFIER_PLAY_WIFI_DISPLAY "Play WiFi Display" + +#endif /* __AVSYS_AUDIO_ALSA_UCM_H__ */ diff --git a/include/avsys-audio-alsa.h b/include/avsys-audio-alsa.h new file mode 100644 index 0000000..14e1be4 --- /dev/null +++ b/include/avsys-audio-alsa.h @@ -0,0 +1,63 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi + * + * 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. + * + */ + +#ifndef __AVSYS_AUDIO_ALSA_H__ +#define __AVSYS_AUDIO_ALSA_H__ + +#ifdef __cplusplus + extern "C" { +#endif +#include + +typedef enum { + AIF_CP_CAPTURE, + AIF_CP_PLAYBACK, + AIF_BT_CAPTURE, + AIF_BT_PLAYBACK, + AIF_RADIO_PLAYBACK, + AIF_DEVICE_MAX, +} aif_device_type_t; + +typedef enum { + AIF_CONF_RATE = 0, + AIF_NB_RATE = 8000, + AIF_WB_RATE = 16000, +} aif_rate_t; + +typedef struct { + void *alsa_handle; + int type; + int rate; +} avsys_audio_alsa_aif_handle_t; + +int avsys_audio_alsa_open_AIF_device(aif_device_type_t aif_type, avsys_audio_alsa_aif_handle_t *handle); +int avsys_audio_alsa_close_AIF_device(avsys_audio_alsa_aif_handle_t* handle); +int avsys_audio_alsa_set_AIF_params(avsys_audio_alsa_aif_handle_t *handle, aif_rate_t rate); +int avsys_audio_alsa_set_mixer_control(const char *ctl_name, int val); +int avsys_audio_alsa_get_mixer_control(const char *ctl_name, int *val); +int avsys_audio_alsa_multi_set_mixer_control(const char *ctl_name, void *val); + + +#ifdef __cplusplus + } +#endif + +#endif /* __AVSYS_AUDIO_H__ */ diff --git a/include/avsys-audio-ascenario.h b/include/avsys-audio-ascenario.h new file mode 100755 index 0000000..5dd5b63 --- /dev/null +++ b/include/avsys-audio-ascenario.h @@ -0,0 +1,179 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi + * + * 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. + * + */ + +#ifndef __AVSYS_AUDIO_ASCENARIO_H__ +#define __AVSYS_AUDIO_ASCENARIO_H__ + +typedef enum { + ASCN_RESET_NONE = 0, + ASCN_RESET_ALL, + ASCN_RESET_PLAYBACK, + ASCN_RESET_CAPTURE, + ASCN_RESET_MODEM, +}AscnResetType; + +#define ASCN_STR_RESET "reset" +#define ASCN_STR_RESET_PLAYBACK "reset_playback" +#define ASCN_STR_RESET_CAPTURE "reset_capture" +#define ASCN_STR_PLAYBACK_MUTE "mute_playback" +#define ASCN_STR_PLAYBACK_UNMUTE "unmute_playback" +#define ASCN_CODEC_DISABLE_ON_SUSPEND "codec_disable_on_suspend" + +typedef enum { + ASCN_GAIN = 0, + ASCN_PATH, +} ASCN_MODE_T; + +typedef enum { + ASCN_PLAYBACK = 0, + ASCN_CAPTURE, +} ASCN_TYPE_T; + + +#define STR_GAIN "_gain" +#define STR_VC_GAIN "_voicecall_gain" +#define STR_RT_GAIN "_ringtone_gain" +#define STR_VT_GAIN "_videocall_gain" +#define STR_VOIP_GAIN "_voip_gain" +/* AP PLAYBACK */ +#define STR_AP_SPK "ap_to_speaker" +#define STR_AP_HEADSET "ap_to_headset" +#define STR_AP_RECV "ap_to_receiver" +#define STR_AP_BT "ap_to_bt" +#define STR_AP_HDMI "ap_to_hdmi" +#define STR_AP_DOCK "ap_to_dock" +#define STR_AP_SP_HS "ap_to_sp_hs" +/* AP CAPTURE */ +#define STR_MIC1_AP "mainmic_to_ap" +#define STR_MIC2_AP "submic_to_ap" +#define STR_STEREO_MIC_AP "stereomic_to_ap" +#define STR_EARMIC_AP "earmic_to_ap" +#define STR_STEREO_REC "capture_ap_camcorder_stereo" +#define STR_BT_AP "bt_to_ap" +#define STR_CP_AP "cp_to_ap" +/* CP PLAYBACK */ +#define STR_CP_SPK "cp_to_speaker" +#define STR_CP_HEADSET "cp_to_headset" +#define STR_CP_HEADPHONE "cp_to_headphone" +#define STR_CP_RECV_2MIC "cp_to_receiver_2mic" +#define STR_CP_RECV "cp_to_receiver" +#define STR_CP_BT "cp_to_bt" +/* CP CAPTURE */ +#define STR_MIC1_CP "mainmic_to_cp" +#define STR_MIC2_CP "submic_to_cp" +#define STR_EARMIC_CP "earmic_to_cp" +#define STR_BT_CP "bt_to_cp" +/* FMRADIO */ +#define STR_FM_AP "fmradio_to_ap" +#define STR_FM_SPEAKER "fmradio_to_speaker" +#define STR_FM_HEADSET "fmradio_to_headset" +/* VOICECALL */ +#define STR_VOICECALL_SPK "voicecall_speaker" +#define STR_VOICECALL_SPK_8K "voicecall_speaker_8khz" +#define STR_VOICECALL_SPK_EXTVOL "voicecall_speaker_extvol" +#define STR_VOICECALL_SPK_NB "voicecall_speaker_upsampling" +#define STR_VOICECALL_SPK_NB_EXTVOL "voicecall_speaker_upsampling_extvol" +#define STR_VOICECALL_SPK_2MIC "voicecall_speaker_2mic" +#define STR_VOICECALL_SPK_2MIC_EXTVOL "voicecall_speaker_2mic_extvol" +#define STR_VOICECALL_SPK_2MIC_NB "voicecall_speaker_2mic_upsampling" +#define STR_VOICECALL_SPK_2MIC_NB_EXTVOL "voicecall_speaker_2mic_upsampling_extvol" +#define STR_VOICECALL_RCV "voicecall_receiver" +#define STR_VOICECALL_RCV_EXTVOL "voicecall_receiver_extvol" +#define STR_VOICECALL_RCV_NB "voicecall_receiver_upsampling" +#define STR_VOICECALL_RCV_NB_EXTVOL "voicecall_receiver_upsampling_extvol" +#define STR_VOICECALL_RCV_2MIC "voicecall_receiver_2mic" +#define STR_VOICECALL_RCV_2MIC_EXTVOL "voicecall_receiver_2mic_extvol" +#define STR_VOICECALL_RCV_2MIC_NB "voicecall_receiver_2mic_upsampling" +#define STR_VOICECALL_RCV_2MIC_NB_EXTVOL "voicecall_receiver_2mic_upsampling_extvol" +#define STR_VOICECALL_HEADPHONE "voicecall_headphone" +#define STR_VOICECALL_HEADPHONE_NB "voicecall_headphone_upsampling" +#define STR_VOICECALL_HEADSET "voicecall_headset" +#define STR_VOICECALL_HEADSET_NB "voicecall_headset_upsampling" +#define STR_VOICECALL_BLUETOOTH "voicecall_bt_wb" +#define STR_VOICECALL_BLUETOOTH_NREC "voicecall_bt_wb_nrec" +/* VIDEOCALL */ +#define STR_VIDEOCALL_SPK_2MIC "videocall_speaker_2mic" +#define STR_VIDEOCALL_SPK_2MIC_NB "videocall_speaker_2mic_upsampling" +#define STR_VIDEOCALL_RCV_2MIC "videocall_receiver_2mic" +#define STR_VIDEOCALL_RCV_2MIC_NB "videocall_receiver_2mic_upsampling" +#define STR_VIDEOCALL_HEADPHONE "videocall_headphone" +#define STR_VIDEOCALL_HEADPHONE_NB "videocall_headphone_upsampling" +#define STR_VIDEOCALL_HEADSET "videocall_headset" +#define STR_VIDEOCALL_HEADSET_NB "videocall_headset_upsampling" +#define STR_VIDEOCALL_BLUETOOTH "videocall_bt_wb" +#define STR_VIDEOCALL_BLUETOOTH_NREC "videocall_bt_wb_nrec" +/* INCALL ADDON */ +#define STR_INCALL_ADDON "ap_playback_incall_addon" +#define STR_INCALL_1MIC_ADDON "ap_playback_incall_1mic_addon" +#define STR_INCALL_BT_ADDON "ap_playback_incall_bt_addon" +/* VOIP */ +#define STR_CHATON_SPK "voip_chaton_speaker" +#define STR_CHATON_RCV "voip_chaton_receiver" +#define STR_CHATON_HEADPHONE "voip_chaton_headphone" +#define STR_CHATON_HEADSET "voip_chaton_headset" +#define STR_CHATON_BLUETOOTH "voip_chaton_bt" +/* S-VOICE */ +#define STR_WAKEUP_NORMAL "capture_ap_wakeup_normal" +#define STR_WAKEUP_EARMIC_NORMAL "capture_ap_wakeup_earmic_normal" +#define STR_WAKEUP_BTMIC_NORMAL "capture_ap_wakeup_btmic_normal" +#define STR_WAKEUP_DRIVING "capture_ap_wakeup_driving" +#define STR_SVOICE_NORMAL "capture_ap_svoice_normal" +#define STR_SVOICE_EARMIC_NORMAL "capture_ap_svoice_earmic_normal" +#define STR_SVOICE_BTMIC_NORMAL "capture_ap_svoice_btmic_normal" +#define STR_SVOICE_DRIVING "capture_ap_svoice_driving" +/* BARGEIN */ +#define STR_BARGEIN_EARMIC_NORMAL "capture_ap_bargein_earmic_normal" +#define STR_BARGEIN_BTMIC_NORMAL "capture_ap_bargein_btmic_normal" + +/* New String */ +#define STR_MEDIA_SPK "media-speaker" +#define STR_VREC_MIC "voicerec-mic" +#define STR_CAM_MIC "camcording-mic" +#define STR_SVOICE_CAP_SCO_16K "svoice-with-capture-sco-16k" +#define STR_VC_SPK_SCO_16K "voicecall-speaker-sco-16k" +#define STR_VC_SPK_SCO_16K_NB "voicecall-speaker-sco-16k-nb" +#define STR_VC_SPK_SCO_8K "voicecall-speaker-sco-8k" +#define STR_SVOICE_CAP_SCO_16K "svoice-with-capture-sco-16k" +#define STR_LOOPBACK_SPK "loopback-speaker" +#define STR_LOOPBACK_MIC "loopback-mainmic" +#define STR_CHATON_SPK_SCO_16K "chaton-speaker-sco-16k" +#define STR_CHATON_SPK_SCO_8K "chaton-speaker-sco-8k" +#define STR_VOICESEARCH_MIC "voicesearch-mic" +#define STR_SCO_ADDON_SPK "media-playback-incall-addon" +/* BARGEIN */ +#define STR_VOICECMD_MIC "voicecommand-mic" + +/* LOOPBACK */ +#define STR_LOOPBACK_SPEAKER "loopback-speaker" +#define STR_LOOPBACK_MAINMIC "loopback-mainmic" + +/* function prototype */ +#if 0 +int avsys_audio_ascn_bulk_set(int * bulk, int bulk_cnt, AscnResetType clear); +int avsys_audio_ascn_bulk_set_vconf (int * bulk, int bulk_cnt, ASCN_MODE_T mode, ASCN_TYPE_T type); +#endif +int avsys_audio_ascn_single_set(char * str); +int avsys_audio_ascn_str_route_set(int *str_route[], int route_cnt, AscnResetType clear); +int avsys_audio_ascn_str_route_set_vconf (char *str_route[], int route_cnt, ASCN_MODE_T mode, ASCN_TYPE_T type); +int avsys_audio_ascn_open(void); +void avsys_audio_ascn_close(void); + +#endif /* __AVSYS_AUDIO_ASCENARIO_H__ */ diff --git a/include/avsys-audio-handle.h b/include/avsys-audio-handle.h new file mode 100644 index 0000000..73d6232 --- /dev/null +++ b/include/avsys-audio-handle.h @@ -0,0 +1,132 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi + * + * 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. + * + */ + +#ifndef __AVSYS_AUDIO_HANDLE_H__ +#define __AVSYS_AUDIO_HANDLE_H__ + +#include +#ifdef PCM_DUMP_ENABLE +#include +#endif + +#include "avsys-audio.h" + +#define AVSYS_AUDIO_HANDLE_MAX 64 /* this is related with allocated bit size in avsys_audio_handle_info_t*/ +#define AVSYS_AUDIO_LOCK_SLOT_MAX 4 + +enum { + AVSYS_AUDIO_PRIMARY_VOLUME_CLEAR = 0, + AVSYS_AUDIO_PRIMARY_VOLUME_SET +}; + +enum { + AVSYS_AUDIO_HANDLE_PRIORITY_TYPE_0 = 0, /**< normal */ + AVSYS_AUDIO_HANDLE_PRIORITY_TYPE_1, /**< solo */ + AVSYS_AUDIO_HANDLE_PRIORITY_TYPE_2, /**< solo with transition effect */ + AVSYS_AUDIO_HANDLE_PRIORITY_TYPE_3, /**< regardless of priority, mix with others */ + AVSYS_AUDIO_HANDLE_PRIORITY_TYPE_MAX, +}; + +enum { + AVSYS_AUDIO_HANDLE_EXT_DEV_NONE = 0x00000000, + AVSYS_AUDIO_HANDLE_EXT_DEV_FMRADIO = 0x00000001, +}; + +typedef struct { + int volume_config; + int dev_type; + int max_level; +} avsys_audio_volume_setting_t; + +typedef struct { + /* common base */ + int mode; + int channels; + int mute; + int format; + int samplerate; + int period; + int msec_per_period; + int pid; + int tid; + int priority; + + /* logical volume */ + avsys_audio_volume_setting_t gain_setting; + int fadeup_vol_current; + int fadeup_vol; + int fadeup_multiplier; + char dirty_volume; + + /* routing information */ + char path_off; + int stream_index; + int handle_route; + int source_type; + /* backend specific */ + void *device; + int corked; +#ifdef PCM_DUMP_ENABLE + FILE *dump_fp; +#endif +} avsys_audio_handle_t; + +typedef struct { + long long int allocated; + int handle_amp; /* 1 for unmute, 0 for mute per each handle*/ + int ext_device_amp; + int ext_device_status; + int primary_volume_type; + int mute_all; + pid_t primary_volume_pid; + char handle_priority[AVSYS_AUDIO_HANDLE_MAX]; + pid_t handlelock_pid[AVSYS_AUDIO_LOCK_SLOT_MAX]; + avsys_audio_handle_t handles[AVSYS_AUDIO_HANDLE_MAX]; +} avsys_audio_handle_info_t; + +enum { + HANDLE_PTR_MODE_NORMAL, + HANDLE_PTR_MODE_FAST, + HANDLE_PTR_MODE_NUM, +}; + +int avsys_audio_handle_init(void); +int avsys_audio_handle_fini(void); +int avsys_audio_handle_reset(int *volume_value); +int avsys_audio_handle_dump(void); +int avsys_audio_handle_rejuvenation(void); +int avsys_audio_handle_alloc(int *handle); +int avsys_audio_handle_alloc_unlocked(int *handle); +int avsys_audio_handle_free(int handle); +int avsys_audio_handle_get_ptr(int handle, avsys_audio_handle_t **ptr, const int mode); +int avsys_audio_handle_get_ptr_unlocked(int handle, avsys_audio_handle_t **ptr, const int mode); +int avsys_audio_handle_release_ptr(int handle, const int mode); +int avsys_audio_handle_set_mute(int handle, int mute); +int avsys_audio_handle_ext_dev_set_mute(avsysaudio_ext_device_t device_type, int mute); +int avsys_audio_handle_ext_dev_status(avsysaudio_ext_device_t device_type, int *onoff); +int avsys_audio_handle_ext_dev_status_update(avsysaudio_ext_device_t device_type, int onoff); +int avsys_audio_handle_current_playing_volume_type(int *type); +int avsys_audio_handle_get_mute_all_status(avsys_audio_handle_t *p); +int avsys_audio_handle_update_mute_all(int onoff); +int avsys_audio_handle_set_primary_volume_type(const int pid, const int type, const int command); +int avsys_audio_handle_update_priority(int handle, int priority, int handle_route, int cmd); +int avsys_audio_handle_current_capture_status(int *on_capture); +#endif /* __AVSYS_AUDIO_HANDLE_H__ */ diff --git a/include/avsys-audio-pactrl.h b/include/avsys-audio-pactrl.h new file mode 100644 index 0000000..972fc80 --- /dev/null +++ b/include/avsys-audio-pactrl.h @@ -0,0 +1,86 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi + * + * 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. + * + */ + +#ifndef __AVSYS_AUDIO_PACTRL_H__ +#define __AVSYS_AUDIO_PACTRL_H__ + +#ifdef __cplusplus + extern "C" { +#endif +#include +#include +#include +#include +#include +#include + +/* + * Enums + */ +enum { + AVSYS_AUDIO_PA_CTL_SINK_UNKNOWN = 0x0000, + AVSYS_AUDIO_PA_CTL_SINK_ALSA = 0x0001, + AVSYS_AUDIO_PA_CTL_SINK_BLUEZ = 0x0002, +}; +/* + * Defines + */ +#define ALSA_SINK 0 +#define BLUEZ_SINK 16 + +#define _EXIST 1 +#define _DEACTIVE 2 +#define _ACTIVE 3 + +#define ALSA_SINK_EXIST ((1 << (_EXIST + ALSA_SINK))) +#define ALSA_SINK_DEACTIVE ((1 << (_DEACTIVE + ALSA_SINK))) +#define ALSA_SINK_ACTIVE ((1 << (_ACTIVE + ALSA_SINK))) + +#define BULEZ_SINK_EXIST ((1 << (_EXIST + BLUEZ_SINK))) +#define BULEZ_SINK_DEACTIVE ((1 << (_DEACTIVE + BLUEZ_SINK))) +#define BULEZ_SINK_ACTIVE ((1 << (_ACTIVE + BLUEZ_SINK))) + +/* + * Function Prototypes + */ +int avsys_audio_pa_ctrl_get_volume_level_max(int volume_type, int *level); +int avsys_audio_pa_ctrl_get_volume_level(int idx, int volume_type, int *level); +int avsys_audio_pa_ctrl_set_volume_level(int idx, int volume_type, int level); +int avsys_audio_pa_ctrl_get_mute(int idx, int volume_type, int direction, int *mute); +int avsys_audio_pa_ctrl_set_mute(int idx, int volume_type, int direction, int mute); +int avsys_audio_pa_ctrl_get_default_sink(int *sink); +int avsys_audio_pa_ctrl_suspend_sink(const char *sink_name, int suspend); +int avsys_audio_pa_ctrl_set_use_case(const char *verb, const char *devices[], const int num_devices, const char *modifiers[], const int num_modifiers); +int avsys_audio_pa_ctrl_is_available_high_latency(int *available); +int avsys_audio_pa_ctrl_set_soundalive_filter_action(int idx, int filter_action); +int avsys_audio_pa_ctrl_set_soundalive_preset_mode(int idx, int preset_mode); +int avsys_audio_pa_ctrl_set_soundalive_eq(int idx, int eq[]); +int avsys_audio_pa_ctrl_set_soundalive_ext(int idx, int ext[]); +int avsys_audio_pa_ctrl_set_soundalive_device(int idx, int device); +int avsys_audio_pa_ctrl_set_dha(int idx, int onoff, int gain[]); +int avsys_audio_pa_ctrl_update_scn(); +int avsys_audio_pa_ctrl_load_loopback_module(bool is_aec); +int avsys_audio_pa_ctrl_unload_loopback_module(bool is_aec); +#ifdef __cplusplus + } +#endif + +#endif /* __AVSYS_AUDIO_PACTRL_H__ */ diff --git a/include/avsys-audio-pasimple.h b/include/avsys-audio-pasimple.h new file mode 100644 index 0000000..6fa9b69 --- /dev/null +++ b/include/avsys-audio-pasimple.h @@ -0,0 +1,61 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi + * + * 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. + * + */ + +#ifndef __AVSYS_AUDIO_PASIMPLE_H__ +#define __AVSYS_AUDIO_PASIMPLE_H__ + +#ifdef __cplusplus + extern "C" { +#endif +#include +#include +#include +#include +#include +#include + +typedef struct { + void *pasimple_handle; + unsigned int samplesize; + unsigned int period_frames; + unsigned int buffer_frames; + unsigned int mode; + unsigned int periods_per_buffer; +} avsys_audio_pasimple_handle_t; + +int avsys_audio_pasimple_open_device(const int mode, const unsigned int format, const unsigned int channel, const unsigned int samplerate, avsys_audio_handle_t *handle,int policy, avsys_audio_channel_pos_t *map); +int avsys_audio_pasimple_close_device(avsys_audio_handle_t *handle); +int avsys_audio_pasimple_write(avsys_audio_handle_t *handle, const void *buf, int size); +int avsys_audio_pasimple_read(avsys_audio_handle_t *handle, void *buf, int size); +int avsys_audio_pasimple_reset(avsys_audio_handle_t *handle); +int avsys_audio_pasimple_drain(avsys_audio_handle_t *handle); +int avsys_audio_pasimple_delay(avsys_audio_handle_t *handle, int *delay_frames); +int avsys_audio_pasimple_latency(avsys_audio_handle_t *handle, int *latency); +int avsys_audio_pasimple_set_volume(avsys_audio_handle_t *handle, int volume); +int avsys_audio_pasimple_get_period_buffer_time(avsys_audio_handle_t *handle, unsigned int *period_time, unsigned int *buffer_time); +int avsys_audio_pasimple_cork(avsys_audio_handle_t *handle, int cork); +int avsys_audio_pasimple_is_corked(avsys_audio_handle_t *handle, int *is_corked); + +#ifdef __cplusplus + } +#endif + +#endif /* __AVSYS_AUDIO_PASIMPLE_H__ */ diff --git a/include/avsys-audio-path.h b/include/avsys-audio-path.h new file mode 100755 index 0000000..d8ced00 --- /dev/null +++ b/include/avsys-audio-path.h @@ -0,0 +1,135 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi + * + * 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. + * + */ + +#ifndef __AVSYS_AUDIO_PATH_H__ +#define __AVSYS_AUDIO_PATH_H__ + +#include +#include + +#include "avsys-audio.h" +#include "avsys-audio-handle.h" + +enum avsys_audio_playback_gain{ + AVSYS_AUDIO_PLAYBACK_GAIN_AP = 0, + AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO, + AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL, + AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL, + AVSYS_AUDIO_PLAYBACK_GAIN_VOIP, + AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT, + AVSYS_AUDIO_PLAYBACK_GAIN_VOICERECOGNITION, + AVSYS_AUDIO_PLAYBACK_GAIN_MAX +}; + +enum avsys_audio_capture_gain{ + AVSYS_AUDIO_CAPTURE_GAIN_AP = 0, + AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO, + AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL, + AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL, + AVSYS_AUDIO_CAPTURE_GAIN_VOIP, + AVSYS_AUDIO_CAPTURE_GAIN_VOICERECOGNITION, + AVSYS_AUDIO_CAPTURE_GAIN_MAX +}; + +enum avsys_audio_ear_ctrl { + AVSYS_AUDIO_EAR_SWITCH_AUTO_WITH_MUTE = 1, + AVSYS_AUDIO_EAR_SWITCH_AUTO_WITHOUT_MUTE, +}; + +enum +{ + AVSYS_AUDIO_LVOL_DEV_TYPE_SPK, + AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET, + AVSYS_AUDIO_LVOL_DEV_TYPE_BTHEADSET, + AVSYS_AUDIO_LVOL_DEV_TYPE_HDMI, + AVSYS_AUDIO_LVOL_DEV_TYPE_MAX, +}; + +#define TYPE_EVENT_SWITCH 0x05 +#define CODE_HEADPHONE_INSERT 0x02 +#define CODE_MICROPHONE_INSERT 0x04 +#define CODE_LINEOUT_INSERT 0x06 +#define CODE_JACK_PHYSICAL_INSERT 0x07 + +#define PATH_FIXED_NONE (0x00000000) +#define PATH_FIXED_WITH_CALL (1 << PATH_FIXED_TYPE_CALL) /* 0x00000002 */ + +enum avsys_audio_amp_t { + AVSYS_AUDIO_AMP_OFF = 0, /**< AMP OFF in pda out */ + AVSYS_AUDIO_AMP_ON, /**< AMP ON in pda out */ + AVSYS_AUDIO_AMP_OFF_ALL, +}; + +enum path_fixed_type_t { + PATH_FIXED_TYPE_FMRADIO = 0, + PATH_FIXED_TYPE_CALL, + PATH_FIXED_TYPE_MAX, +}; + +struct audio_route_info_t { + int playback; + int capture; +}; + +typedef struct audio_route_info_t gain_info_t; +typedef struct audio_route_info_t path_info_t; +typedef struct audio_route_info_t gain_status_t; +typedef struct audio_route_info_t path_status_t; + +typedef struct { + gain_info_t gain; + path_info_t path; + gain_info_t pregain; + gain_info_t reqgain; + + int option; + + /* path fixed information */ + int path_fixed; + pid_t path_fixed_pid[PATH_FIXED_TYPE_MAX]; + + /* hw mute */ + int mute; + + int lvol_dev_type; + bool control_aif_before_path_set; + bool wb_enabled; + + /* For Lock debugging */ + pid_t pathlock_pid[AVSYS_AUDIO_LOCK_SLOT_MAX]; +} avsys_audio_path_ex_info_t; + +int avsys_audio_path_ex_init(void); +int avsys_audio_path_ex_fini(void); +int avsys_audio_path_ex_reset(int forced); +int avsys_audio_path_ex_dump(void); +int avsys_audio_path_ex_set_path(int gain, int out, int in, int option); +int avsys_audio_path_ex_get_path(int *gain, int *out, int *in, int *option); +int avsys_audio_path_ex_set_amp(const int onoff); +int avsys_audio_path_ex_set_mute(const int mute); +int avsys_audio_path_ex_get_mute(int *mute); +int avsys_audio_path_set_single_ascn(char *str); + +int avsys_audio_path_ex_set_factory_loopback_test(int loopback); +int avsys_audio_path_ex_get_factory_loopback_test(int *loopback); + + +#endif /* __AVSYS_AUDIO_PATH_H__ */ diff --git a/include/avsys-audio-shm.h b/include/avsys-audio-shm.h new file mode 100644 index 0000000..9edde57 --- /dev/null +++ b/include/avsys-audio-shm.h @@ -0,0 +1,44 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi + * + * 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. + * + */ + +#ifndef __AVSYS_AUDIO_SHM_H__ +#define __AVSYS_AUDIO_SHM_H__ + +#ifdef __cplusplus + extern "C" { +#endif + +typedef enum { + AVSYS_AUDIO_SHM_IDEN_HANDLE, + AVSYS_AUDIO_SHM_IDEN_PATH, + AVSYS_AUDIO_SHM_IDEN_LVOLUME, + AVSYS_AUDIO_SHM_IDEN_CNT +} avsys_audio_shm_iden_t; + +int avsys_audio_create_shm(const avsys_audio_shm_iden_t iden); +int avsys_audio_remove_shm(const avsys_audio_shm_iden_t iden); +int avsys_audio_get_shm(const avsys_audio_shm_iden_t iden, void **ptr); + +#ifdef __cplusplus + } +#endif + +#endif /* __AVSYS_AUDIO_SHM_H__ */ diff --git a/include/avsys-audio-sync.h b/include/avsys-audio-sync.h new file mode 100644 index 0000000..cab7221 --- /dev/null +++ b/include/avsys-audio-sync.h @@ -0,0 +1,45 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi + * + * 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. + * + */ + +#ifndef __AVSYS_AUDIO_SYNC_H__ +#define __AVSYS_AUDIO_SYNC_H__ + +#ifdef __cplusplus + extern "C" { +#endif + +typedef enum { + AVSYS_AUDIO_SYNC_IDEN_HANDLE, + AVSYS_AUDIO_SYNC_IDEN_PATH, + AVSYS_AUDIO_SYNC_IDEN_CNT +} avsys_audio_sync_iden_t; + +int avsys_audio_create_sync(const avsys_audio_sync_iden_t iden); +int avsys_audio_remove_sync(const avsys_audio_sync_iden_t iden); +int avsys_audio_lock_sync(const avsys_audio_sync_iden_t iden); +int avsys_audio_unlock_sync(const avsys_audio_sync_iden_t iden); +int avsys_check_process(int check_pid); + +#ifdef __cplusplus + } +#endif + +#endif /* __AVSYS_AUDIO_SYNC_H__ */ diff --git a/include/avsys-audio.h b/include/avsys-audio.h new file mode 100755 index 0000000..8ec022b --- /dev/null +++ b/include/avsys-audio.h @@ -0,0 +1,760 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi + * + * 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. + * + */ + +#ifndef __AVSYS_AUDIO_H__ +#define __AVSYS_AUDIO_H__ + +#include + +#include "avsys-types.h" +#include "avsys-error.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/** + @addtogroup AVSYSTEM + @{ + + @par + This part describes the interface with audio input/output. + */ + +#define AVSYS_AUDIO_VOLUME_MAX_MULTIMEDIA 16 +#define AVSYS_AUDIO_VOLUME_MAX_BASIC 8 +#define AVSYS_AUDIO_VOLUME_MAX_SVOICE 7 +#define AVSYS_AUDIO_VOLUME_MAX_SINGLE 1 + +#define AVSYS_AUDIO_VOLUME_CONFIG_TYPE(vol) (vol & 0x00FF) +#define AVSYS_AUDIO_VOLUME_CONFIG_GAIN(vol) (vol & 0xFF00) +#define AVSYS_AUDIO_VOLUME_GAIN_IDX(gain) ((gain >> 8) - 1) + +#define AVSYS_CHANNEL_MIN 1 +#define AVSYS_CHANNEL_MAX 6 + +/** + * Enumerations for audio support type + */ +enum avsys_audio_support_type_t { + AVSYS_AUDIO_SUPPORT_TYPE_DEFAULT, + AVSYS_AUDIO_SUPPORT_TYPE_MIRRORING, + AVSYS_AUDIO_SUPPORT_TYPE_VOICECONTROL, + AVSYS_AUDIO_SUPPORT_TYPE_SVR, + AVSYS_AUDIO_SUPPORT_TYPE_VIDEOCALL, + AVSYS_AUDIO_SUPPORT_TYPE_VOICERECORDING, + AVSYS_AUDIO_SUPPORT_TYPE_VOIP, +}; + +/** + * Enumerations for audio mode + */ +enum avsys_audio_mode_t { + AVSYS_AUDIO_MODE_OUTPUT, /**< Output mode of handle */ + AVSYS_AUDIO_MODE_OUTPUT_CLOCK, /**< Output mode of gst audio only mode */ + AVSYS_AUDIO_MODE_OUTPUT_VIDEO, /**< Output mode of gst video mode */ + AVSYS_AUDIO_MODE_OUTPUT_LOW_LATENCY, /**< Output mode for low latency play mode. typically for game */ + AVSYS_AUDIO_MODE_INPUT, /**< Input mode of handle */ + AVSYS_AUDIO_MODE_INPUT_HIGH_LATENCY, /**< Input mode for high latency capture mode. */ + AVSYS_AUDIO_MODE_INPUT_LOW_LATENCY, /**< Input mode for low latency capture mode. typically for VoIP */ + AVSYS_AUDIO_MODE_CALL_OUT, /**< for voice call establish */ + AVSYS_AUDIO_MODE_CALL_IN, /**< for voice call establish */ + AVSYS_AUDIO_MODE_OUTPUT_AP_CALL, /**< for VT call on thin modem */ + AVSYS_AUDIO_MODE_INPUT_AP_CALL, /**< for VT call on thin modem */ + AVSYS_AUDIO_MODE_NUM, /**< Number of mode */ +}; + +/** + * Enumerations for audio direction + */ +enum avsys_audio_direction_t { + AVSYS_AUDIO_DIRECTION_NONE, + AVSYS_AUDIO_DIRECTION_IN, + AVSYS_AUDIO_DIRECTION_OUT, +}; + +/** + * Enumerations for audio format + */ +enum avsys_audio_format_t { + AVSYS_AUDIO_FORMAT_UNKNOWN = -1, /**< Invalid audio format */ + AVSYS_AUDIO_FORMAT_8BIT, /**< Unsigned 8Bit */ + AVSYS_AUDIO_FORMAT_16BIT, /**< Signed 16bit Little Endian */ + AVSYS_AUDIO_FORMAT_MIN = AVSYS_AUDIO_FORMAT_8BIT, /**< Minimum value 8-bit integer per sample */ + AVSYS_AUDIO_FORMAT_MAX = AVSYS_AUDIO_FORMAT_16BIT, /**< Maximum value 16-bit integer per sample */ +}; + +/** + * Enumerations for channel position + */ +typedef enum { + AVSYS_AUDIO_CHANNEL_POSITION_INVALID, + AVSYS_AUDIO_CHANNEL_POSITION_MONO, + AVSYS_AUDIO_CHANNEL_POSITION_FRONT_LEFT, + AVSYS_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, + AVSYS_AUDIO_CHANNEL_POSITION_REAR_CENTER, + AVSYS_AUDIO_CHANNEL_POSITION_REAR_LEFT, + AVSYS_AUDIO_CHANNEL_POSITION_REAR_RIGHT, + AVSYS_AUDIO_CHANNEL_POSITION_LFE, + AVSYS_AUDIO_CHANNEL_POSITION_FRONT_CENTER, + AVSYS_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, + AVSYS_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, + AVSYS_AUDIO_CHANNEL_POSITION_SIDE_LEFT, + AVSYS_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, + AVSYS_AUDIO_CHANNEL_POSITION_NUM +} avsys_audio_channel_pos_t; + +/* + * Enums for volume types + */ +typedef enum { + AVSYS_AUDIO_VOLUME_TYPE_SYSTEM, + AVSYS_AUDIO_VOLUME_TYPE_NOTIFICATION, + AVSYS_AUDIO_VOLUME_TYPE_ALARM, + AVSYS_AUDIO_VOLUME_TYPE_RINGTONE, + AVSYS_AUDIO_VOLUME_TYPE_MEDIA, + AVSYS_AUDIO_VOLUME_TYPE_CALL, + AVSYS_AUDIO_VOLUME_TYPE_VOIP, + AVSYS_AUDIO_VOLUME_TYPE_SVOICE, + AVSYS_AUDIO_VOLUME_TYPE_FIXED, + AVSYS_AUDIO_VOLUME_TYPE_EXT_SYSTEM_JAVA, + AVSYS_AUDIO_VOLUME_TYPE_NUM, + AVSYS_AUDIO_VOLUME_TYPE_MAX = AVSYS_AUDIO_VOLUME_TYPE_NUM, + AVSYS_AUDIO_VOLUME_TYPE_EXT_SYSTEM_ANDROID = AVSYS_AUDIO_VOLUME_TYPE_FIXED, +}avsys_audio_volume_type_t; + +enum avsys_audio_volume_gain_t { + AVSYS_AUDIO_VOLUME_GAIN_DIALER = 1<<8, + AVSYS_AUDIO_VOLUME_GAIN_TOUCH = 2<<8, + AVSYS_AUDIO_VOLUME_GAIN_AF = 3<<8, + AVSYS_AUDIO_VOLUME_GAIN_SHUTTER1 = 4<<8, + AVSYS_AUDIO_VOLUME_GAIN_SHUTTER2 = 5<<8, + AVSYS_AUDIO_VOLUME_GAIN_CAMCORDING = 6<<8, + AVSYS_AUDIO_VOLUME_GAIN_MIDI = 7<<8, + AVSYS_AUDIO_VOLUME_GAIN_BOOTING = 8<<8, + AVSYS_AUDIO_VOLUME_GAIN_VIDEO = 9<<8, + AVSYS_AUDIO_VOLUME_GAIN_TTS = 10<<8, + AVSYS_AUDIO_VOLUME_GAIN_TYPE_MAX, +}; + +enum avsys_audio_priority_t { + AVSYS_AUDIO_PRIORITY_0 = 0, /*< deprecated. use AVSYS_AUDIO_PRIORITY_NORMAL or AVSYS_AUDIO_PRIORITY_SOLO instead */ + AVSYS_AUDIO_PRIORITY_NORMAL = AVSYS_AUDIO_PRIORITY_0, + AVSYS_AUDIO_PRIORITY_SOLO, + AVSYS_AUDIO_PRIORITY_SOLO_WITH_TRANSITION_EFFECT, + AVSYS_AUDIO_PRIORITY_ALWAYS_MIX_NO_EFFECT, + AVSYS_AUDIO_PRIORITY_MAX, +}; + +enum avsys_audio_device_t { + AVSYS_AUDIO_DEVICE_TYPE_SPK = 0, + AVSYS_AUDIO_DEVICE_TYPE_RECV, + AVSYS_AUDIO_DEVICE_TYPE_HEADSET, + AVSYS_AUDIO_DEVICE_TYPE_HANDSFREE, + AVSYS_AUDIO_DEVICE_TYPE_BT, + AVSYS_AUDIO_DEVICE_TYPE_NUM, + AVSYS_AUDIO_DEVICE_TYPE_MAX = AVSYS_AUDIO_DEVICE_TYPE_NUM, +}; + +/** + * Enumerations for audio channel + */ +enum avsys_audio_channel_t { + AVSYS_AUDIO_CHANNEL_LEFT, /**< front-left channel */ + AVSYS_AUDIO_CHANNEL_RIGHT, /**< front-righth channel */ + AVSYS_AUDIO_CHANNEL_NUM, /**< Number of channels */ +}; + +/** + * Enumerations for audio mute condition + */ +enum avsys_audio_mute_t { + AVSYS_AUDIO_UNMUTE = 0, /**< Unmute state */ + AVSYS_AUDIO_MUTE, /**< Mute state */ + AVSYS_AUDIO_UNMUTE_NOLOCK, /** < Unmute without lock */ + AVSYS_AUDIO_MUTE_NOLOCK, /** < Mute without lock */ + AVSYS_AUDIO_PRIORITY_MUTE, + AVSYS_AUDIO_PRIORITY_UNMUTE, +}; + +/** + * Enumerations for priority command + */ +enum avsys_audio_priority_cmd_t { + AVSYS_AUDIO_SET_PRIORITY = 0, /**< Command set priority */ + AVSYS_AUDIO_UNSET_PRIORITY, /**< Command unset priority */ +}; + +/** + * Structure for sound device parameters. + */ +typedef struct { + int mode; /**< Open mode (In/Out) */ + int priority; /**< Priority of sound handle */ + int channels; /**< Number of channels */ + int samplerate; /**< Sampling rate */ + int format; /**< Sampling format */ + int handle_route; /**< Handle route information. refer. avsys_audio_handle_route_t */ + int vol_type; /**< volume type */ + int allow_mix; + int source_type; + avsys_audio_channel_pos_t map[AVSYS_CHANNEL_MAX]; /**< Channel map */ +} avsys_audio_param_t; + + +/** + * Structure for volume information. + */ +typedef struct { + int level[AVSYS_AUDIO_CHANNEL_NUM]; /**< Array of volume level for each channel */ +} avsys_audio_volume_t; + +/* NEW PATH DEFINE */ + /** + * + */ +enum avsys_audio_path_ex { + AVSYS_AUDIO_PATH_EX_NONE = 0, + AVSYS_AUDIO_PATH_EX_SPK, + AVSYS_AUDIO_PATH_EX_RECV, + AVSYS_AUDIO_PATH_EX_HEADSET, + AVSYS_AUDIO_PATH_EX_BTHEADSET, + AVSYS_AUDIO_PATH_EX_A2DP, + AVSYS_AUDIO_PATH_EX_HANDSFREE, /* Not used : will be deprecated */ + AVSYS_AUDIO_PATH_EX_HDMI, + AVSYS_AUDIO_PATH_EX_DOCK, + AVSYS_AUDIO_PATH_EX_USBAUDIO, + AVSYS_AUDIO_PATH_EX_WFD, + AVSYS_AUDIO_PATH_EX_OUTMAX, + AVSYS_AUDIO_PATH_EX_MIC = 1, + AVSYS_AUDIO_PATH_EX_HEADSETMIC, + AVSYS_AUDIO_PATH_EX_BTMIC, + AVSYS_AUDIO_PATH_EX_FMINPUT, + AVSYS_AUDIO_PATH_EX_HANDSFREEMIC, /* Not used : will be deprecated */ + AVSYS_AUDIO_PATH_EX_INMAX, +}; + +enum avsys_audio_gain_ex { + AVSYS_AUDIO_GAIN_EX_KEYTONE = 0, + AVSYS_AUDIO_GAIN_EX_RINGTONE, + AVSYS_AUDIO_GAIN_EX_ALARMTONE, + AVSYS_AUDIO_GAIN_EX_CALLTONE, + AVSYS_AUDIO_GAIN_EX_AUDIOPLAYER, + AVSYS_AUDIO_GAIN_EX_VIDEOPLAYER, + AVSYS_AUDIO_GAIN_EX_VOICECALL, + AVSYS_AUDIO_GAIN_EX_VIDEOCALL, + AVSYS_AUDIO_GAIN_EX_VOIP, + AVSYS_AUDIO_GAIN_EX_FMRADIO, + AVSYS_AUDIO_GAIN_EX_VOICEREC, + AVSYS_AUDIO_GAIN_EX_STEREO_REC, + AVSYS_AUDIO_GAIN_EX_CAMERA, + AVSYS_AUDIO_GAIN_EX_GAME, + AVSYS_AUDIO_GAIN_EX_VOICERECOGNITION, + AVSYS_AUDIO_GAIN_EX_MAX, + AVSYS_AUDIO_GAIN_EX_PDA_PLAYBACK = AVSYS_AUDIO_GAIN_EX_KEYTONE, +}; + +typedef enum { + AVSYS_AUDIO_EXT_DEVICE_FMRADIO = 0, + AVSYS_AUDIO_EXT_DEVICE_NUM +}avsysaudio_ext_device_t; + +enum avsys_audio_handle_route_t{ + AVSYS_AUDIO_HANDLE_ROUTE_FOLLOWING_POLICY, + AVSYS_AUDIO_HANDLE_ROUTE_HANDSET_ONLY, + AVSYS_AUDIO_HANDLE_ROUTE_ALL, +}; /* custom routing per handle */ + +typedef enum { + AVSYS_AUDIO_ROUTE_DEVICE_UNKNOWN = -1, + AVSYS_AUDIO_ROUTE_DEVICE_HANDSET, + AVSYS_AUDIO_ROUTE_DEVICE_BLUETOOTH, + AVSYS_AUDIO_ROUTE_DEVICE_EARPHONE, + AVSYS_AUDIO_ROUTE_DEVICE_NUM, +}avsys_audio_playing_devcie_t;/* routing device */ + +/* path option */ +#define AVSYS_AUDIO_PATH_OPTION_NONE 0x00000000 /*!< Sound path option none */ +#define AVSYS_AUDIO_PATH_OPTION_DUAL_OUT 0x00000002 /*!< SPK or Recv with headset sound path. used for Ringtone or Alarm */ +#define AVSYS_AUDIO_PATH_OPTION_VOICECALL_REC 0x00000010 /*!< Voice call recording path option */ +#define AVSYS_AUDIO_PATH_OPTION_USE_SUBMIC 0x00000020 /*!< Use sub-mic when call or recording */ +#define AVSYS_AUDIO_PATH_OPTION_USE_STEREOMIC 0x00000040 /*!< Use stereo mic when recording */ +#define AVSYS_AUDIO_PATH_OPTION_USE_2MIC 0x00000080 /*!< Use stereo mic when recording */ +#define AVSYS_AUDIO_PATH_OPTION_CALL_EXTRA_VOL 0x00000100 /*!< Call extra volume option */ +#define AVSYS_AUDIO_PATH_OPTION_CALL_NB 0x00000200 /*!< Call upscaling option */ +#define AVSYS_AUDIO_PATH_OPTION_VR_NORMAL_WAKE 0x00000400 /*!< Voice Recognition Normal */ +#define AVSYS_AUDIO_PATH_OPTION_VR_NORMAL_CMD 0x00000800 /*!< Voice Recognition Drive */ +#define AVSYS_AUDIO_PATH_OPTION_VR_DRIVE_WAKE 0x00001000 /*!< Voice Recognition Normal */ +#define AVSYS_AUDIO_PATH_OPTION_VR_DRIVE_CMD 0x00002000 /*!< Voice Recognition Drive */ +#define AVSYS_AUDIO_PATH_OPTION_BT_NREC 0x00004000 /*!< Bluetooth NREC */ +#define AVSYS_AUDIO_PATH_OPTION_BARGEIN 0x00008000 /*!< Bargein */ +#define AVSYS_AUDIO_PATH_OPTION_FORCED 0x01000000 /*!< Forced sound path setting. only for booting animation */ +#define AVSYS_AUDIO_PATH_OPTION_VOICECALL_PLAY_AM 0x00010000 /*!< play audio over voice call(for answer memo) */ +#define AVSYS_AUDIO_PATH_OPTION_VOICECALL_REC_AM 0x00020000 /*!< rec audio over voice call(for answer memo) */ +#define AVSYS_AUDIO_PATH_OPTION_USE_STEREOMIC_DIRECTNL_INTV 0x00040000 /*!< Use directional stereo mic when recording for interview */ +#define AVSYS_AUDIO_PATH_OPTION_USE_STEREOMIC_DIRECTNL_CONVS 0x00080000 /*!< Use directional stereo mic when recording for conversation */ +#define AVSYS_AUDIO_PATH_OPTION_MIRRORING 0x00040000 /*!< Mirroring option */ +#define AVSYS_AUDIO_PATH_OPTION_USE_MAINMIC 0x00100000 /*!< Use stereo mic when recording */ +#define AVSYS_AUDIO_PATH_OPTION_BT_WB 0x00200000 /*!< Bluetooth WB */ + +/** + * This function make instance for audio system, and retreives handle. + * + * @param param [in] Parameters of audio system. + * @param phandle [out] Handle of audio system. + * @param size [out] Recomended buffer size. + * + * @return This function returns AVSYS_STATE_SUCCESS on success, or negative + * value with error code. + * on failure. + * @remark + * @see + */ +int avsys_audio_open(avsys_audio_param_t *param, avsys_handle_t *phandle, int *size); + +/** + * This function is to close sound handle and release allocated resources. + * + * @param handle [in] Handle of audio system + * + * @return This function returns AVSYS_STATE_SUCCESS on success, or negative + * value with error code. + * @remark + * @see + */ +int avsys_audio_close(avsys_handle_t handle); + +/** + * This function is to update volume type & volume gain. + * + * @param handle [in] Handle of audio system + * + * @return This function returns AVSYS_STATE_SUCCESS on success, or negative + * value with error code. + * @remark + * @see + */ +int avsys_audio_update_volume_config(avsys_handle_t handle, int volume_config); + +/** + * This function is to stop playback stream immediately. this drops all buffer remaining data. + * + * @param handle [in] Playback handle of audio system + * + * @return This function returns AVSYS_STATE_SUCCESS on success, or negative + * value with error code. + * @remark + * @see + */ +int avsys_audio_flush(avsys_handle_t handle); + +/** + * This function is to stop playback stream after all remaining buffer data played. + * + * @param handle [in] Playback handle of audio system + * + * @return This function returns AVSYS_STATE_SUCCESS on success, or negative + * value with error code. + * @remark + * @see + */ +int avsys_audio_drain(avsys_handle_t handle); + +/** + * This function is turn on speaker amp. + * + * + * @return This function returns AVSYS_STATE_SUCCESS on success, or negative + * value with error code. + * @remark + * @see + */ +int avsys_audio_ampon(void) __attribute__((deprecated)); + +/** + * This function is turn off speaker amp. + * + * @return This function returns AVSYS_STATE_SUCCESS on success, or negative + * value with error code. + * @remark + * @see + */ +int avsys_audio_ampoff(void) __attribute__((deprecated)); + +/** + * This function is to read pcm data from sound handle. + * + * @param handle [in] Handle of audio system + * @param buf [in] Buffer of audio data to read + * @param size [in] Size of buffer + * + * @return This function returns number of bytes read, or negative value with + * error code on failure. + * @remark + * @see + */ +int avsys_audio_read(avsys_handle_t handle, void *buf, int size); + +/** + * This function is to write audio data to sound handle. + * + * @param handle [in] Handle of audio system + * @param buf [in] Buffer of audio data to write + * @param size [in] Size of buffer + * + * @return This function returns number of bytes written, or negative value + * with error code on failure. + * @remark + * @see + */ +int avsys_audio_write(avsys_handle_t handle, void *buf, int size); + +int avsys_audio_set_volume_table(int volume_type, int dev_type, int step, int lv, int rv); +int avsys_audio_get_volume_table(int volume_type, int dev_type, int step, int *lv, int *rv); +int avsys_audio_set_volume_gain_table(int volume_gain_idx, int dev_type, float lv, float rv); +int avsys_audio_get_volume_gain_table(int volume_gain_idx, int dev_type, float *lv, float *rv); + +int avsys_audio_set_volume_fadeup(avsys_handle_t handle); + +/** + * This function is to get volume max. + * + * @param vol_type [in] Type of volume table + * @param max [out] number of volume steps + * + * @return This function returns AVSYS_STATE_SUCCESS on success, or negative + * value with error code. + * @remark + * @see + */ +int avsys_audio_get_volume_max_ex(int volume_table, int *max_step); + +/** + * This function is to set relative mute of sound handle. + * + * @param handle [in] Handle of audio system + * @param mute [in] Mute information to set + * + * @return This function returns AVSYS_STATE_SUCCESS on success, or negative + * value with error code. + * @remark + * mute is AVSYS_AUDIO_MUTE : mute + * mute is AVSYS_AUDIO_UNMUTE : unmute + * @see + */ +int avsys_audio_set_mute(avsys_handle_t handle, int mute); + + +/** + * This function is to set mute of sound handle with fade out effect. + * + * @param handle [in] Handle of audio system + * + * @return This function returns AVSYS_STATE_SUCCESS on success, or negative + * value with error code. + * @remark + * @see + */ +int avsys_audio_set_mute_fadedown(avsys_handle_t handle); + +/** + * This function is to get relative mute of sound handle. + * + * @param handle [in] Handle of audio system + * @param pmute [out] Pointer to mute information to retrieve + * + * @return This function returns AVSYS_STATE_SUCCESS on success, or negative + * value with error code. + * @remark + * pmute is AVSYS_AUDIO_MUTE : mute + * pmute is AVSYS_AUDIO_UNMUTE : unmute + * @see avsys_audio_mute_t + */ +int avsys_audio_get_mute(avsys_handle_t handle, int* pmute); + + +/** + * This function is to set amp on external device + * + * @param device [in] External audio device type + * + * @return This function returns AVSYS_STATE_SUCCESS on success, or negative + * value with error code. + * @remark + * mute is AVSYS_AUDIO_MUTE : mute + * mute is AVSYS_AUDIO_UNMUTE : unmute + * @see avsysaudio_ext_device_t + */ +int avsys_audio_ext_device_ampon(avsysaudio_ext_device_t device); + +/** + * This function is to set amp off external device + * + * @param device [in] External audio device type + * + * @return This function returns AVSYS_STATE_SUCCESS on success, or negative + * value with error code. + * @remark + * pmute is AVSYS_AUDIO_MUTE : mute + * pmute is AVSYS_AUDIO_UNMUTE : unmute + * @see avsysaudio_ext_device_t + */ +int avsys_audio_ext_device_ampoff(avsysaudio_ext_device_t device); + +/** + * This function is to set status of external device + * + * @param device [in] External audio device type + * @param onoff [in] 1 for on , 0 for off + * + * @return This function returns AVSYS_STATE_SUCCESS on success, or negative + * value with error code. + * @remark + * @see avsysaudio_ext_device_t + */ +int avsys_audio_set_ext_device_status(avsysaudio_ext_device_t device_type, int onoff); + +/** + * This function is to get status of external device + * + * @param device [in] External audio device type + * @param onoff [out] 1 for on , 0 for off + * + * @return This function returns AVSYS_STATE_SUCCESS on success, or negative + * value with error code. + * @remark + * @see avsys_audio_set_ext_device_status + */ +int avsys_audio_get_ext_device_status(avsysaudio_ext_device_t device_type, int *onoff); +/** + * This function is to set sound path of sound device. + * + * @param path [in] value of sound gain + * @param output [in] value of output device + * @param input [in] value of input device + * @param option [in] value of sound path option + * + * @return This function returns AVSYS_STATE_SUCCESS on success, or negative + * value with error code. + * AVSYS_STATE_ERR_RANGE_OVER : input path value is invalid range + * AVSYS_STATE_ERR_INTERNAL : internal device error + * @remark + * @see + */ +int avsys_audio_set_path_ex(int gain, int out, int in, int option); + +/** + * This function is to get sound path of sound device. + * + * @param path [out] value of sound gain + * @param output [out] value of output device + * @param input [out] value of input device + * @param option [out] value of sound path option + * + * @return This function returns AVSYS_STATE_SUCCESS on success, or negative + * value with error code. + * AVSYS_STATE_ERR_INTERNAL : internal device error + * @remark + * @see + */ +int avsys_audio_get_path_ex(int *gain, int *out, int *in, int *option); + +/** + * This function is to set relative global mute of sound device. + * + * @param mute [in] Global mute information to retreive + * + * @return This function returns AVSYS_STATE_SUCCESS on success, or negative + * value with error code. + * @remark + * mute is avsys_audio_mute_disable : unmute + * mute is avsys_audio_mute_enable : mute + * others : ignore + * @see avsys_audio_mute_t + */ +int avsys_audio_set_global_mute(int mute); + +/** + * This function is to get relative global mute of sound device. + * + * @param pmute [out] Pointer to global mute information to retreive + * + * @return This function returns AVSYS_STATE_SUCCESS on success, or negative + * value with error code. + * @remark + * *pbmute is avsys_audio_mute_disable or avsys_audio_mute_enable + * @see + */ +int avsys_audio_get_global_mute(int* pmute); + +/** + * This function is to get number of remaining audio frames in hw buffer. + * + * @param handle [in] handle to get delay frames + * @param frame_delay [out] value of number of remaining audio frames + * + * @return This function returns AVSYS_STATE_SUCCESS on success, or negative + * value with error code. + * @remark + * @see + */ +int avsys_audio_delay(avsys_handle_t handle, int *frame_delay); + +/** + * This function is to get latency of the specified handle stream. + * + * @param handle [in] handle to get latency + * @param latency [out] value of latency of the specified handle stream in millisecond + * + * @return This function returns AVSYS_STATE_SUCCESS on success, or negative + * value with error code. + * @remark + * @see + */ +int avsys_audio_get_latency(avsys_handle_t handle, int *latency); + +/** + * This function is to reset audio stream. (drops all remaining audio frames in device buffer) + * + * @param handle [in] handle to reset + * + * @return This function returns AVSYS_STATE_SUCCESS on success, or negative + * value with error code. + * @remark + * @see + */ +int avsys_audio_reset(avsys_handle_t handle); + +/** + * This function is to pause audio stream. (drops all remaining audio frames in hw buffer) + * + * @param handle [in] handle to pause + * + * @return This function returns AVSYS_STATE_SUCCESS on success, or negative + * value with error code. + * @remark + * @see + */ + +int avsys_audio_pause(avsys_handle_t handle); + +/** + * This function is to resume audio stream + * + * @param handle [in] handle to resume + * + * @return This function returns AVSYS_STATE_SUCCESS on success, or negative + * value with error code. + * @remark + * @see + */ + +int avsys_audio_resume(avsys_handle_t handle); + + +/** + * This function is to get period time and buffer time of audio stream. + * + * @param handle [in] handle to get period & buffer time + * @param period_time [out] value of period time in microsecond. + * @param buffer_time [out] value of buffer time in microsecond. + * + * @return This function returns AVSYS_STATE_SUCCESS on success, or negative + * value with error code. + * @remark + * @see + */ +int avsys_audio_get_period_buffer_time(avsys_handle_t handle, unsigned int *period_time, unsigned int *buffer_time); + +/** + * This function is to cork stream. + * + * @param handle [in] handle to cork + * @param cork [in] cork=1, uncork=0 + * + * @return This function returns AVSYS_STATE_SUCCESS on success, or negative + * value with error code. + * @remark + * @see + */ +int avsys_audio_cork (avsys_handle_t handle, int cork); + +/** + * This function is to check whether stream is corked or not. + * + * @param handle [in] handle to cork + * @param is_corked [out] corked is 1, otherwise 0 + * + * @return This function returns AVSYS_STATE_SUCCESS on success, or negative + * value with error code. + * @remark + * @see + */ +int avsys_audio_is_corked (avsys_handle_t handle, int *is_corked); + +/** + * This function is to get audio capturing status of system. + * + * @param on_capture [out] capture status. + * zero if there is no capture instance. + * positive value if there is capture instance + * + * @return This function returns AVSYS_STATE_SUCCESS on success, or negative + * value with error code. + * @remark + * @see + */ +int avsys_audio_get_capture_status(int *on_capture); +int avsys_audio_update_scn(void); +int avsys_audio_get_current_playing_volume_type(int *volume_type); +int avsys_audio_set_volume_by_type(const int volume_type, const int volume_value); +int avsys_audio_get_volume_by_type(const int type, const int *value); +int avsys_audio_set_mute_all(int mute_all); +int avsys_audio_set_primary_volume(const int pid, const int type); +int avsys_audio_clear_primary_volume(const int pid); +int avsys_audio_hibernation_reset(int *vol); +int avsys_audio_set_call_mute(avsys_audio_volume_type_t type, int mute); +int avsys_audio_get_call_mute(avsys_audio_volume_type_t type, int *mute); +int avsys_audio_set_factory_loopback_test(int loopback); +int avsys_audio_get_factory_loopback_test(int *loopback); +int avsys_audio_load_loopback_module(bool is_aec); +int avsys_audio_unload_loopback_module(bool is_aec); +int avsys_audio_set_DHA_control(unsigned short* param); +int avsys_audio_cork_all(bool cork); + +int avsys_audio_is_available_high_latency(int *available); +int avsys_audio_set_vsp_speed(avsys_handle_t handle, int speed); +int avsys_audio_set_soundalive_filter_action(avsys_handle_t handle, int filter_action); +int avsys_audio_set_soundalive_preset_mode(avsys_handle_t handle, int preset_mode); +int avsys_audio_set_soundalive_eq(avsys_handle_t handle, int eq[]); +int avsys_audio_set_soundalive_ext(avsys_handle_t handle, int ext[]); +int avsys_audio_set_soundalive_device(avsys_handle_t handle, int device); +int avsys_audio_set_dha(avsys_handle_t handle, int onoff, int gain[]); + +/** + @} + */ + +#ifdef __cplusplus + } +#endif + +#endif /* __AVSYS_AUDIO_H__ */ diff --git a/include/avsys-common.h b/include/avsys-common.h new file mode 100644 index 0000000..b7ad027 --- /dev/null +++ b/include/avsys-common.h @@ -0,0 +1,80 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi + * + * 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. + * + */ + +#ifndef __AVSYS_COMMON_H__ +#define __AVSYS_COMMON_H__ + +#include +#include + +#ifdef __cplusplus + extern "C" { +#endif +#define EXPORT_API __attribute__((__visibility__("default"))) + +#define AVSYS_MAGIC_START "TSVA" +#define AVSYS_MAGIC_END "NEVA" + +#define AVSYS_KEY_PREFIX_AUDIO 0x10 +#define AVSYS_KEY_PREFIX_GEN(X,Y) ((X) + (Y)) + +typedef struct { + char *key_path; + int key_prefix; + int size; +} avsys_shm_param_t; + +typedef struct { + char *key_path; + int key_prefix; +} avsys_sync_param_t; + + +#define LOCK_TIMEOUT_SEC 6 + +/* get thread id : Not implemented 'gettid' at system libs. */ +#define avsys_gettid() (long int)syscall(__NR_gettid) + +/* memory */ +void * avsys_malloc(size_t size); +void avsys_free(void *ptr); +#define avsys_mem_check(ptr) ( (memcmp(AVSYS_MAGIC_START, ((char*)(ptr))-8, 4) == 0) && \ + (memcmp(AVSYS_MAGIC_END, ((char*)(ptr))+(*((int*)((ptr)-4))), 4) == 0) ) + +/* shared memory */ +int avsys_create_shm(const avsys_shm_param_t* param); +int avsys_remove_shm(const avsys_shm_param_t* param); +void* avsys_get_shm(const avsys_shm_param_t* param); + +/* Sync object */ +int avsys_create_sync(const avsys_sync_param_t *param); +int avsys_remove_sync(const avsys_sync_param_t *param); +int avsys_lock_sync(const avsys_sync_param_t *param); +int avsys_unlock_sync(const avsys_sync_param_t *param); + +/* Privilege */ +int avsys_check_root_privilege(void); + +#ifdef __cplusplus + } +#endif + +#endif /* __AVSYS_COMMON_H__ */ diff --git a/include/avsys-debug.h b/include/avsys-debug.h new file mode 100644 index 0000000..95a91b3 --- /dev/null +++ b/include/avsys-debug.h @@ -0,0 +1,93 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi + * + * 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. + * + */ + +/** + * This file defines the debug function of AV System. + * + * @file avsys_debug.h + * @version 0.1 + */ + +#ifndef __AVSYS_DEBUG_H__ +#define __AVSYS_DEBUG_H__ + +#ifdef __USE_LOGMANAGER__ +#include +#include +#define AVAUDIO LOG_AVSYSTEM +#else +#define AVAUDIO +#endif + +#ifdef __DEBUG_MODE__ +#ifdef __USE_LOGMANAGER__ + +#define avsys_debug_r(owner, msg, args...) log_print_rel( owner, LOG_CLASS_DEBUG, msg, ##args ) +#define avsys_info_r(owner, msg, args...) log_print_rel( owner, LOG_CLASS_INFO, msg, ##args ) +#define avsys_warning_r(owner, msg, args...) log_print_rel( owner, LOG_CLASS_WARNING, msg, ##args ) +#define avsys_error_r(owner, msg, args...) log_print_rel( owner, LOG_CLASS_ERR, msg, ##args ) +#define avsys_critical_r(owner, msg, args...) log_print_rel( owner, LOG_CLASS_CRITICAL, msg, ##args ) +#define avsys_assert_r(condition) log_assert_rel(( condition )) + +#define avsys_debug(owner, msg, args...) log_print_dbg( owner, LOG_CLASS_DEBUG, msg, ##args ) +#define avsys_info(owner, msg, args...) log_print_dbg( owner, LOG_CLASS_INFO, msg, ##args ) +#define avsys_warning(owner, msg, args...) log_print_dbg( owner, LOG_CLASS_WARNING, msg, ##args ) +#define avsys_error(owner, msg, args...) log_print_dbg( owner, LOG_CLASS_ERR, msg, ##args ) +#define avsys_critical(owner, msg, args...) log_print_dbg( owner, LOG_CLASS_CRITICAL, msg, ##args ) +#define avsys_assert(condition) log_assert_dbg( (condition) ) + +#else /* __USE_LOGMANAGER__ */ + +#define avsys_debug_r(owner, msg, args...) fprintf(stderr, msg, ##args) +#define avsys_info_r(owner, msg, args...) fprintf(stderr, msg, ##args) +#define avsys_warning_r(owner, msg, args...) fprintf(stderr, msg, ##args) +#define avsys_error_r(owner, msg, args...) fprintf(stderr, msg, ##args) +#define avsys_critical_r(owner, msg, args...) fprintf(stderr, msg, ##args) +#define avsys_assert_r(condition) (condition) + +#define avsys_debug(owner, msg, args...) fprintf(stderr, msg, ##args) +#define avsys_info(owner, msg, args...) fprintf(stderr, msg, ##args) +#define avsys_warning(owner, msg, args...) fprintf(stderr, msg, ##args) +#define avsys_error(owner, msg, args...) fprintf(stderr, msg, ##args) +#define avsys_critical(owner, msg, args...) fprintf(stderr, msg, ##args) +#define avsys_assert(condition) (condition) + +#endif /* __USE_LOGMANAGER__ */ + +#else /* __DEBUG_MODE__ */ + +#define avsys_debug_r(owner, msg, args...) +#define avsys_info_r(owner, msg, args...) +#define avsys_warning_r(owner, msg, args...) +#define avsys_error_r(owner, msg, args...) +#define avsys_critical_r(owner, msg, args...) +#define avsys_assert_r(condition) (condition) + +#define avsys_debug(owner, msg, args...) +#define avsys_info(owner, msg, args...) +#define avsys_warning(owner, msg, args...) +#define avsys_error(owner, msg, args...) +#define avsys_critical(owner, msg, args...) +#define avsys_assert(condition) (condition) + +#endif /* __DEBUG_MODE__ */ + +#endif /* __AVSYS_DEBUG_H__ */ diff --git a/include/avsys-error.h b/include/avsys-error.h new file mode 100644 index 0000000..3142647 --- /dev/null +++ b/include/avsys-error.h @@ -0,0 +1,130 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi + * + * 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. + * + */ + +#ifndef __AVSYS_ERROR_H__ +#define __AVSYS_ERROR_H__ + +#ifdef __cplusplus + extern "C" { +#endif + +/** + * AVSYS CLASS + */ +#define AVSYS_STATE_SUCCESS (0x00000000) /**< No Error */ +#define AVSYS_STATE_ERROR (0x80000000) /**< Error Class */ +#define AVSYS_STATE_WARNING (0x70000000) /**< Warning Class */ + +/* + * Detail enumeration + */ +enum { + AVSYS_IN_UNKNOWN = 0, + AVSYS_IN_PARAMETER, + AVSYS_IN_HANDLE, + AVSYS_IN_POINTER, + AVSYS_IN_VALUE, + AVSYS_IN_OVERRUN, + AVSYS_IN_UNDERRUN, + AVSYS_IN_RANGE_OVER, + AVSYS_IN_RANGE_UNDER, + AVSYS_IN_MODE, + AVSYS_IN_FORMAT, + AVSYS_IN_CHANNEL, + AVSYS_IN_SAMPLERATE, + AVSYS_IN_LAYER, + AVSYS_IN_ROTATE, + AVSYS_IN_ALLOC, + AVSYS_IN_INTERNAL, + /*Extra state for camera*/ + AVSYS_IN_IO_CONTROL, + AVSYS_IN_DEVICE, + AVSYS_IN_WAIT_RES, + AVSYS_IN_SUPPORT, + AVSYS_IN_STATE, + AVSYS_IN_PRIVILEGE, +}; + +/* + * AVSYS_WARING + */ +#define AVSYS_STATE_WAR_INVALID_PARAMETER (AVSYS_STATE_WARNING | AVSYS_IN_PARAMETER) +#define AVSYS_STATE_WAR_INVALID_HANDLE (AVSYS_STATE_WARNING | AVSYS_IN_HANDLE) +#define AVSYS_STATE_WAR_INVALID_VALUE (AVSYS_STATE_WARNING | AVSYS_IN_VALUE) +#define AVSYS_STATE_WAR_INVALID_MODE (AVSYS_STATE_WARNING | AVSYS_IN_MODE) +#define AVSYS_STATE_WAR_INVALID_FORMAT (AVSYS_STATE_WARNING | AVSYS_IN_FORMAT) +#define AVSYS_STATE_WAR_INVALID_CHANNEL (AVSYS_STATE_WARNING | AVSYS_IN_CHANNEL) +#define AVSYS_STATE_WAR_INVALID_SAMPLERATE (AVSYS_STATE_WARNING | AVSYS_IN_SAMPLERATE) +#define AVSYS_STATE_WAR_INVALID_LAYER (AVSYS_STATE_WARNING | AVSYS_IN_LAYER) +#define AVSYS_STATE_WAR_INVALID_ROTATE (AVSYS_STATE_WARNING | AVSYS_IN_ROTATE) +#define AVSYS_STATE_WAR_NULL_POINTER (AVSYS_STATE_WARNING | AVSYS_IN_POINTER) +#define AVSYS_STATE_WAR_UNDERRUN (AVSYS_STATE_WARNING | AVSYS_IN_UNDERRUN) +#define AVSYS_STATE_WAR_OVERRUN (AVSYS_STATE_WARNING | AVSYS_IN_OVERRUN) +#define AVSYS_STATE_WAR_RANGE_OVER (AVSYS_STATE_WARNING | AVSYS_IN_RANGE_OVER) +#define AVSYS_STATE_WAR_RANGE_UNDER (AVSYS_STATE_WARNING | AVSYS_IN_RANGE_UNDER) +#define AVSYS_STATE_WAR_ALLOCATION (AVSYS_STATE_WARNING | AVSYS_IN_ALLOC) +#define AVSYS_STATE_WAR_INTERNAL (AVSYS_STATE_WARNING | AVSYS_IN_INTERNAL) +/*Extra warning for camera*/ +#define AVSYS_STATE_WAR_IO_CONTROL (AVSYS_STATE_WARNING | AVSYS_IN_IO_CONTROL) +#define AVSYS_STATE_WAR_UNAVAILABLE_DEVICE (AVSYS_STATE_WARNING | AVSYS_IN_DEVICE) +#define AVSYS_STATE_WAR_DEVICE_WAIT_TIMEOUT (AVSYS_STATE_WARNING | AVSYS_IN_WAIT_RES) +#define AVSYS_STATE_WAR_DEVICE_NOT_SUPPORT (AVSYS_STATE_WARNING | AVSYS_IN_SUPPORT) +#define AVSYS_STATE_WAR_INVALID_STATE_TRANSITION (AVSYS_STATE_WARNING | AVSYS_IN_STATE) + +/** + * AVSYS_ERROR + */ +#define AVSYS_STATE_ERR_INVALID_PARAMETER (AVSYS_STATE_ERROR | AVSYS_IN_PARAMETER) +#define AVSYS_STATE_ERR_INVALID_HANDLE (AVSYS_STATE_ERROR | AVSYS_IN_HANDLE) +#define AVSYS_STATE_ERR_INVALID_VALUE (AVSYS_STATE_ERROR | AVSYS_IN_VALUE) +#define AVSYS_STATE_ERR_INVALID_MODE (AVSYS_STATE_ERROR | AVSYS_IN_MODE) +#define AVSYS_STATE_ERR_INVALID_FORMAT (AVSYS_STATE_ERROR | AVSYS_IN_FORMAT) +#define AVSYS_STATE_ERR_INVALID_CHANNEL (AVSYS_STATE_ERROR | AVSYS_IN_CHANNEL) +#define AVSYS_STATE_ERR_INVALID_SAMPLERATE (AVSYS_STATE_ERROR | AVSYS_IN_SAMPLERATE) +#define AVSYS_STATE_ERR_INVALID_LAYER (AVSYS_STATE_ERROR | AVSYS_IN_LAYER) +#define AVSYS_STATE_ERR_INVALID_ROTATE (AVSYS_STATE_ERROR | AVSYS_IN_ROTATE) +#define AVSYS_STATE_ERR_NULL_POINTER (AVSYS_STATE_ERROR | AVSYS_IN_POINTER) +#define AVSYS_STATE_ERR_UNDERRUN (AVSYS_STATE_ERROR | AVSYS_IN_UNDERRUN) +#define AVSYS_STATE_ERR_OVERRUN (AVSYS_STATE_ERROR | AVSYS_IN_OVERRUN) +#define AVSYS_STATE_ERR_RANGE_OVER (AVSYS_STATE_ERROR | AVSYS_IN_RANGE_OVER) +#define AVSYS_STATE_ERR_RANGE_UNDER (AVSYS_STATE_ERROR | AVSYS_IN_RANGE_UNDER) +#define AVSYS_STATE_ERR_ALLOCATION (AVSYS_STATE_ERROR | AVSYS_IN_ALLOC) +#define AVSYS_STATE_ERR_INTERNAL (AVSYS_STATE_ERROR | AVSYS_IN_INTERNAL) +#define AVSYS_STATE_ERR_UNKNOWN (AVSYS_STATE_ERROR | AVSYS_IN_UNKNOWN) /**< unknown error */ +/*Extra warning for camera*/ +#define AVSYS_STATE_ERR_IO_CONTROL (AVSYS_STATE_ERROR | AVSYS_IN_IO_CONTROL) +#define AVSYS_STATE_ERR_UNAVAILABLE_DEVICE (AVSYS_STATE_ERROR | AVSYS_IN_DEVICE) +#define AVSYS_STATE_ERR_DEVICE_WAIT_TIMEOUT (AVSYS_STATE_ERROR | AVSYS_IN_WAIT_RES) +#define AVSYS_STATE_ERR_DEVICE_NOT_SUPPORT (AVSYS_STATE_ERROR | AVSYS_IN_SUPPORT) +#define AVSYS_STATE_ERR_INVALID_STATE (AVSYS_STATE_ERROR | AVSYS_IN_STATE) +#define AVSYS_STATE_ERR_PRIVILEGE (AVSYS_STATE_ERROR | AVSYS_IN_PRIVILEGE) + + +#define AVSYS_FAIL(_A_) (AVSYS_STATE_ERROR & (_A_)) +#define AVSYS_SUCCESS(_A_) (!AVSYS_FAIL(_A_)) +#define AVSYS_WARNING(_A_) (AVSYS_STATE_WARNING & (_A_)) +#define AVSYS_ERROR(_A_) (AVSYS_STATE_ERROR & (_A_)) + +#ifdef __cplusplus + } +#endif + +#endif /* __AVSYS_ERROR_H__ */ diff --git a/include/avsys-types.h b/include/avsys-types.h new file mode 100644 index 0000000..7e0066d --- /dev/null +++ b/include/avsys-types.h @@ -0,0 +1,41 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi + * + * 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. + * + */ + +#ifndef __AVSYS_TYPES_H__ +#define __AVSYS_TYPES_H__ + +#ifdef __cplusplus + extern "C" { +#endif + +/** + * Type definition of av system handle. + */ +typedef void *avsys_handle_t; + +#define AVSYS_INVALID_HANDLE NULL +#define AVSYS_AUDIO_INVALID_HANDLE (-1) + +#ifdef __cplusplus + } +#endif + +#endif /* __AVSYS_TYPES_H__ */ diff --git a/include/avsystem.h b/include/avsystem.h new file mode 100644 index 0000000..ca1195a --- /dev/null +++ b/include/avsystem.h @@ -0,0 +1,37 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi + * + * 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. + * + */ + +#ifndef __AVSYSTEM_H__ +#define __AVSYSTEM_H__ + +#include +#include +#include + +/** + @mainpage AV System + + @par + This document provides necessary information for developers who are going + to use audio/video functionality. +*/ + +#endif /* __AVSYSTEM_H__ */ diff --git a/install-sh b/install-sh new file mode 100755 index 0000000..a5897de --- /dev/null +++ b/install-sh @@ -0,0 +1,519 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2006-12-25.00 + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + trap '(exit $?); exit' 1 2 13 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dst_arg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + -*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test -z "$d" && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/missing b/missing new file mode 100755 index 0000000..1c8ff70 --- /dev/null +++ b/missing @@ -0,0 +1,367 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2006-05-10.23 + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006 +# Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: +sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' +sed_minuso='s/.* -o \([^ ]*\).*/\1/p' + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case $1 in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + autom4te touch the output file, or create a stub one + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch] + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + +esac + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). +case $1 in + lex|yacc) + # Not GNU programs, they don't have --version. + ;; + + tar) + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + exit 1 + fi + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case $1 in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case $f in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if test $# -ne 1; then + eval LASTARG="\${$#}" + case $LASTARG in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if test ! -f y.tab.h; then + echo >y.tab.h + fi + if test ! -f y.tab.c; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if test $# -ne 1; then + eval LASTARG="\${$#}" + case $LASTARG in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if test ! -f lex.yy.c; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit 1 + fi + ;; + + makeinfo) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n ' + /^@setfilename/{ + s/.* \([^ ]*\) *$/\1/ + p + q + }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + tar) + shift + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case $firstarg in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case $firstarg in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/packaging/avsystem-ymu831.spec b/packaging/avsystem-ymu831.spec new file mode 100644 index 0000000..96597b7 --- /dev/null +++ b/packaging/avsystem-ymu831.spec @@ -0,0 +1,87 @@ + +Name: avsystem-ymu831 +Summary: Audio Video System for ymu831 +Version: 0.6.70 +Release: 0 +VCS: magnolia/adaptation/devices/avsystem-ymu831#avsystem-ymu831-0.6.24_0-36-gc44f352675a385aa57e55a3baa0106c5c20ebe6d +Group: System/Libraries +License: Apache-2.0 +Source0: %{name}-%{version}.tar.gz +Requires(post): /usr/bin/vconftool +BuildRequires: pkgconfig(alsa) +BuildRequires: pkgconfig(iniparser) +BuildRequires: pkgconfig(vconf) +BuildRequires: pkgconfig(mm-ta) +BuildRequires: pkgconfig(mm-log) +BuildRequires: pkgconfig(libexif) +BuildRequires: pkgconfig(libpulse) +BuildRequires: pkgconfig(libascenario) +BuildRequires: pkgconfig(vconf) + +%description +Audio Video System + + +%package devel +Summary: Audio Video System Development headers and libraries +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} + +%description devel +Audio Video System Development headers and libraries. + + +%prep +%setup -q -n %{name}-%{version} + + +%build +%autogen +%configure \ +%if 0%{?tizen_build_binary_release_type_eng} + --enable-pcmdump \ +%endif +%ifarch %{ix86} + --enable-audiotest --enable-sdk +%else + --enable-audiotest --enable-ymu831 +%endif + +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/usr/share/license +mkdir -p %{buildroot}/opt/usr/devel/usr/bin +cp LICENSE.APLv2 %{buildroot}/usr/share/license/%{name} +%make_install +mkdir -p %{buildroot}%{_libdir}/systemd/system/multi-user.target.wants +mv %{buildroot}/usr/bin/avsys_audio_test %{buildroot}/opt/usr/devel/usr/bin + +%post +/sbin/ldconfig + +/usr/bin/vconftool set -t string memory/private/sound/path/gain_playback "" -g 29 -f -i -s system::vconf_multimedia +/usr/bin/vconftool set -t string memory/private/sound/path/path_playback "" -g 29 -f -i -s system::vconf_multimedia +/usr/bin/vconftool set -t string memory/private/sound/path/gain_capture "" -g 29 -f -i -s system::vconf_multimedia +/usr/bin/vconftool set -t string memory/private/sound/path/path_capture "" -g 29 -f -i -s system::vconf_multimedia +/usr/bin/vconftool set -t int memory/private/sound/factory_loopback 0 -g 29 -f -i -s system::vconf_multimedia + +%postun +/sbin/ldconfig + +%files +%manifest avsystem-ymu831.manifest +%defattr(-,root,root,-) +/opt/usr/devel/usr/bin/avsys_audio_test +/usr/lib/libavsysaudio.so.0 +/usr/lib/libavsysaudio.so.0.0.1 +%{_datadir}/license/%{name} + +%files devel +/usr/lib/libavsysaudio.so +/usr/lib/pkgconfig/*.pc +/usr/include/avsystem/avsys-audio.h +/usr/include/avsystem/avsys-error.h +/usr/include/avsystem/avsys-types.h +/usr/include/avsystem/avsystem.h diff --git a/pkgconfig-arm/Makefile.am b/pkgconfig-arm/Makefile.am new file mode 100644 index 0000000..e86350a --- /dev/null +++ b/pkgconfig-arm/Makefile.am @@ -0,0 +1,16 @@ +pcfiles = avsystem.pc avsysaudio.pc + +all-local: $(pcfiles) + +%.pc: %.pc + cp $< $@ + +pkgconfigdir= $(libdir)/pkgconfig +pkgconfig_DATA= $(pcfiles) + +CLEANFILES= $(pcfiles) + +pcinfiles= avsystem.pc.in avsysaudio.pc.in + +EXTRA_DIST= $(pcinfiles) + diff --git a/pkgconfig-arm/avsysaudio.pc.in b/pkgconfig-arm/avsysaudio.pc.in new file mode 100644 index 0000000..286d6e7 --- /dev/null +++ b/pkgconfig-arm/avsysaudio.pc.in @@ -0,0 +1,11 @@ +prefix = @prefix@ +exec_prefix= @exec_prefix@ +libdir = @libdir@ +includedir = @includedir@ + +Name : avsysaudio +Description : Multimedia Framework AV system Audio Library +Requires : alsa libascenario mm-log libpulse-simple +Version : @VERSION@ +Libs : -L${libdir} -lavsysaudio -lrt -lpthread +Cflags : -I${includedir}/avsystem diff --git a/pkgconfig-arm/avsystem.pc.in b/pkgconfig-arm/avsystem.pc.in new file mode 100755 index 0000000..d92c42c --- /dev/null +++ b/pkgconfig-arm/avsystem.pc.in @@ -0,0 +1,11 @@ +prefix = @prefix@ +exec_prefix= @exec_prefix@ +libdir = @libdir@ +includedir = @includedir@ + +Name : avsystem +Description : Multimedia Framework AV system Library +Requires : avsysaudio +Version : @VERSION@ +Libs : +Cflags : diff --git a/pkgconfig-arm/avsystem.pc.in.all b/pkgconfig-arm/avsystem.pc.in.all new file mode 100644 index 0000000..56de5e1 --- /dev/null +++ b/pkgconfig-arm/avsystem.pc.in.all @@ -0,0 +1,11 @@ +prefix = @prefix@ +exec_prefix= @exec_prefix@ +libdir = @libdir@ +includedir = @includedir@ + +Name : avsystem +Description : Multimedia Framework AV system Library +Requires : alsa libascenario +Version : @VERSION@ +Libs : -L${libdir} -lavsysaudio -lrt -lpthread -lexif -liniparser -ldl +Cflags : -I${includedir}/avsystem diff --git a/pkgconfig-i386/Makefile.am b/pkgconfig-i386/Makefile.am new file mode 100644 index 0000000..858fb48 --- /dev/null +++ b/pkgconfig-i386/Makefile.am @@ -0,0 +1,15 @@ +pcfiles = avsystem.pc avsysaudio.pc + +all-local: $(pcfiles) + +%.pc: %.pc + cp $< $@ + +pkgconfigdir= $(libdir)/pkgconfig +pkgconfig_DATA= $(pcfiles) + +CLEANFILES= $(pcfiles) + +pcinfiles= avsystem.pc.in avsysaudio.pc.in +EXTRA_DIST= $(pcinfiles) + diff --git a/pkgconfig-i386/avsysaudio.pc.in b/pkgconfig-i386/avsysaudio.pc.in new file mode 100644 index 0000000..7a5fc6b --- /dev/null +++ b/pkgconfig-i386/avsysaudio.pc.in @@ -0,0 +1,11 @@ +prefix = @prefix@ +exec_prefix= @exec_prefix@ +libdir = @libdir@ +includedir = @includedir@ + +Name : avsysaudio +Description : Multimedia Framework AV system Audio Library +Requires : alsa libpulse-simple +Version : @VERSION@ +Libs : -L${libdir} -lavsysaudio -lrt -lpthread +Cflags : -I${includedir}/avsystem diff --git a/pkgconfig-i386/avsystem.pc.in b/pkgconfig-i386/avsystem.pc.in new file mode 100755 index 0000000..d92c42c --- /dev/null +++ b/pkgconfig-i386/avsystem.pc.in @@ -0,0 +1,11 @@ +prefix = @prefix@ +exec_prefix= @exec_prefix@ +libdir = @libdir@ +includedir = @includedir@ + +Name : avsystem +Description : Multimedia Framework AV system Library +Requires : avsysaudio +Version : @VERSION@ +Libs : +Cflags : diff --git a/pkgconfig-i386/avsystem.pc.in.all b/pkgconfig-i386/avsystem.pc.in.all new file mode 100644 index 0000000..56de5e1 --- /dev/null +++ b/pkgconfig-i386/avsystem.pc.in.all @@ -0,0 +1,11 @@ +prefix = @prefix@ +exec_prefix= @exec_prefix@ +libdir = @libdir@ +includedir = @includedir@ + +Name : avsystem +Description : Multimedia Framework AV system Library +Requires : alsa libascenario +Version : @VERSION@ +Libs : -L${libdir} -lavsysaudio -lrt -lpthread -lexif -liniparser -ldl +Cflags : -I${includedir}/avsystem -- 2.7.4