diff options
57 files changed, 11475 insertions, 0 deletions
@@ -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..1fba2b0 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,74 @@ +if IS_SDK +SUBDIRS = pkgconfig-i386 +else +SUBDIRS = pkgconfig-arm +endif +SUBDIRS += init + +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-logical-volume.c \ + avsys-audio-handle.c \ + avsys-audio-shm.c \ + avsys-audio-sync.c \ + avsys-audio-alsa.c \ + avsys-audio.c \ + avsys-audio-ascenario.c \ + avsys-audio-path.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) + + +if IS_SDK +libavsysaudio_la_CFLAGS += -DAUDIO_SDK_BUILD \ + -D_MMFW_I386_ALL_SIMULATOR +endif + +libavsysaudio_la_CFLAGS += $(MMLOG_CFLAGS) \ + -D__DEBUG_MODE__ \ + -D__USE_LOGMANAGER__ \ + -DMM_DEBUG_FLAG + +libavsysaudio_la_LIBADD += $(MMLOG_LIBS) + + +bin_PROGRAMS = sound_initializer +sound_initializer_SOURCES = avsys-audio-initializer.c +sound_initializer_CFLAGS = -I$(srcdir)/include + +sound_initializer_CFLAGS += $(MMLOG_CFLAGS) +sound_initializer_LDADD = libavsysaudio.la +sound_initializer_DEPENDENCIES = libavsysaudio.la + +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 + +bin_PROGRAMS += avsys_volume_dump +avsys_volume_dump_SOURCES = audiotest/avsys-audio-volume-dump.c +avsys_volume_dump_LDADD = libavsysaudio.la +avsys_volume_dump_DEPENDENCIES = libavsysaudio.la +endif diff --git a/audiotest/avsys-audio-test.c b/audiotest/avsys-audio-test.c new file mode 100644 index 0000000..c6a53d5 --- /dev/null +++ b/audiotest/avsys-audio-test.c @@ -0,0 +1,308 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi <jhchoi.choi@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include <stdio.h> +#include <unistd.h> +#include <alloca.h> +#include <memory.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <signal.h> +#include <avsys-audio.h> + +#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->bluetooth = 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, sizeof(avsys_audio_param_t), '\0'); + + 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); + + if (fd != -1) + close(fd); + + 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, sizeof(avsys_audio_param_t), '\0'); + + 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); + 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/audiotest/avsys-audio-volume-dump.c b/audiotest/avsys-audio-volume-dump.c new file mode 100644 index 0000000..76a97a5 --- /dev/null +++ b/audiotest/avsys-audio-volume-dump.c @@ -0,0 +1,104 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi <jhchoi.choi@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include <stdio.h> +#include <alloca.h> +#include <string.h> +#include "../include/avsys-audio.h" +#include "../include/avsys-audio-logical-volume.h" + +#define VERSION_NUM 0001 + + +void usage(char *name) +{ + printf("Usage: %s [FILE]...\n\n", name); + printf("Version %04d\n", VERSION_NUM); + printf("\n"); + return; +} + +int main(int argc, char* argv[]) +{ + int i = 0; + int j = 0; + int k = 0; + int err = 0; + char filepath[256]={0,}; + FILE *fp = NULL; + + if(argc > 2) + { + usage(argv[0]); + return 0; + } + else if(argc == 2) + { + strncpy(filepath, argv[1], sizeof(filepath)-1); + } + else if(argc == 1) + { + strncpy(filepath, VOLUME_FILE_PATH, sizeof(filepath)-1); + fprintf(stderr,"Use default file path %s\n", filepath); + } + + fp = fopen(filepath, "w"); + if(!fp) + { + fprintf(stderr,"Can not open file %s\n",filepath); + return -1; + } + + for(i=AVSYS_AUDIO_LVOL_GAIN_TYPE_0; i<AVSYS_AUDIO_LVOL_GAIN_TYPE_MAX; i++) + { + for(j=AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; j<=AVSYS_AUDIO_LVOL_DEV_TYPE_BTHEADSET;j++) + { + int lv = 0; + int rv = 0; + char *str_dev[] = { "SPK", "HEADSET", "BTHEADSET" }; + + for(k=0;k<LVOLUME_MAX_MULTIMEDIA;k++) + { + err = avsys_audio_get_volume_table(i, AVSYS_AUDIO_LVOL_DEV_TYPE_SPK, k, &lv, &rv); + if(err) + goto FAIL; + + fprintf(fp,"%1d:%s:%d:%d:%d\n",i,str_dev[j],k,lv,rv); + } + } + } + + if(fp != NULL) + { + fclose(fp); + } + printf("Success\n"); + return 0; + +FAIL: + if(fp != NULL) + { + fclose(fp); + } + unlink(filepath); + fprintf(stderr,"Can not dump volume table\n"); + return -1; +} 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..7e7916a --- /dev/null +++ b/avsys-audio-alsa.c @@ -0,0 +1,175 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi <jhchoi.choi@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include <alsa/asoundlib.h> + +#include "avsys-audio-alsa.h" +#include "avsys-types.h" +#include "avsys-error.h" +#include "avsys-debug.h" + +#if defined(_MMFW_I386_ALL_SIMULATOR) +#define AIF2_DEVICE_NAME "default" +#define AIF3_DEVICE_NAME "default" +#else +#define AIF2_DEVICE_NAME "AIF2" +#define AIF3_DEVICE_NAME "AIF3" +#endif + +int avsys_audio_alsa_open_AIF_device(const int 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, "%s\n", __func__); + if (!handle) + return AVSYS_STATE_ERR_NULL_POINTER; + + memset(dev_name, '\0', sizeof(dev_name)); + switch (AIF_type) { + case AIF2_CAPTURE: + strncpy(dev_name, AIF2_DEVICE_NAME, sizeof(dev_name) - 1); + stream = SND_PCM_STREAM_CAPTURE; + break; + case AIF2_PLAYBACK: + strncpy(dev_name, AIF2_DEVICE_NAME, sizeof(dev_name) - 1); + stream = SND_PCM_STREAM_PLAYBACK; + break; + case AIF3_CAPTURE: + strncpy(dev_name, AIF3_DEVICE_NAME, sizeof(dev_name) - 1); + stream = SND_PCM_STREAM_CAPTURE; + break; + case AIF3_PLAYBACK: + strncpy(dev_name, AIF3_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); +#else + avsys_warning_r(AVAUDIO, "Skip real device open in SDK\n"); + err = 0; /* set fake return value */ +#endif + + if (err < 0) { + avsys_error_r(AVAUDIO, "unable to open AIF device: %s\n", snd_strerror(err)); + return AVSYS_STATE_ERR_INTERNAL; + } + + 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, "%s\n", __func__); +#if defined(_MMFW_I386_ALL_SIMULATOR) + avsys_warning(AVAUDIO, "Skip close call device in SDK"); + return AVSYS_STATE_SUCCESS; +#endif + if (!handle) + return AVSYS_STATE_ERR_NULL_POINTER; + + ahandle = (snd_pcm_t *)handle->alsa_handle; + if (!ahandle) { + avsys_error_r(AVAUDIO, "[%s] alsa handle is null\n", __func__); + 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; +} + +int avsys_audio_alsa_set_AIF_params(avsys_audio_alsa_aif_handle_t *handle) +{ +#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; + int dir; + + avsys_info(AVAUDIO, "%s\n", __func__); + if (!handle) + return AVSYS_STATE_ERR_NULL_POINTER; + + ahandle = (snd_pcm_t *)handle->alsa_handle; + if (!ahandle) + return AVSYS_STATE_ERR_NULL_POINTER; + + /* Allocate a hardware parameters object. */ + snd_pcm_hw_params_alloca(¶ms); + /* Fill it in with default values. */ + snd_pcm_hw_params_any(ahandle, params); + + /* Set the desired hardware parameters. */ + /* Interleaved mode */ + snd_pcm_hw_params_set_access(ahandle, params, SND_PCM_ACCESS_RW_INTERLEAVED); + + 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 bps\n", val); + + return AVSYS_STATE_SUCCESS; +#endif +} diff --git a/avsys-audio-ascenario.c b/avsys-audio-ascenario.c new file mode 100644 index 0000000..c78f155 --- /dev/null +++ b/avsys-audio-ascenario.c @@ -0,0 +1,273 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi <jhchoi.choi@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#if !defined(_MMFW_I386_ALL_SIMULATOR) +#include <alsa/ascenario.h> +#endif +#include <string.h> + +#include "avsys-audio-ascenario.h" +#include "avsys-types.h" +#include "avsys-error.h" +#include "avsys-debug.h" +#if defined(TIME_CHECK) +#include <sys/time.h> +#include <time.h> +#endif + +#define STR_BUFF_MAX 128 +#define P_STR_MAX 42 +#define O_STR_MAX 44 +static int __avsys_audio_ascn_make_scenario_str(int input, char *buf, int buf_len) +{ + char fromStr[P_STR_MAX] = { 0, }; + char toStr[P_STR_MAX] = { 0, }; + char optStr[O_STR_MAX] = { 0, }; + + if (buf == NULL) { + avsys_error(AVAUDIO, "Input Buf is null\n"); + return AVSYS_STATE_ERR_NULL_POINTER; + } + + if (input & INPUT_MAIN_MIC) { + strncpy(fromStr, "mainmic", sizeof(fromStr) - 1); + } + if (input & INPUT_SUB_MIC) { + strncpy(fromStr, "submic", sizeof(fromStr) - 1); + } + if (input & INPUT_STEREO_MIC) { + strncpy(fromStr, "stereomic", sizeof(fromStr) - 1); + } + if (input & INPUT_EAR_MIC) { + strncpy(fromStr, "earmic", sizeof(fromStr) - 1); + } + if (input & INPUT_BT_MIC) { + strncpy(fromStr, "bt", sizeof(fromStr) - 1); + } + if (input & INPUT_AP) { + strncpy(fromStr, "ap", sizeof(fromStr) - 1); + } + if (input & INPUT_CP) { + strncpy(fromStr, "cp", sizeof(fromStr) - 1); + } + if (input & INPUT_FMRADIO) { + strncpy(fromStr, "fmradio", sizeof(fromStr) - 1); + } + + if (input & OUTPUT_HEADSET) { + strncpy(toStr, "headset", sizeof(toStr) - 1); + } + if (input & OUTPUT_LEFT_SPK) { + strncpy(toStr, "speaker_left", sizeof(toStr) - 1); + } + if (input & OUTPUT_RIGHT_SPK) { + strncpy(toStr, "speaker_right", sizeof(toStr) - 1); + } + if (input & OUTPUT_STEREO_SPK) { + strncpy(toStr, "speaker", sizeof(toStr) - 1); + } + if (input & OUTPUT_RECV) { + strncpy(toStr, "receiver", sizeof(toStr) - 1); + } + if (input & OUTPUT_BT_HEADSET) { + strncpy(toStr, "bt", sizeof(toStr) - 1); + } + if (input & OUTPUT_CP) { + strncpy(toStr, "cp", sizeof(toStr) - 1); + } + if (input & OUTPUT_AP) { + strncpy(toStr, "ap", sizeof(toStr) - 1); + } + + if (input & GAIN_MODE) { + strncpy(optStr, "_gain", sizeof(optStr) - 1); + } + if (input & GAIN_VIDEO_CALL) { + strncpy(optStr, "_videocall_gain", sizeof(optStr) - 1); + } + if (input & GAIN_VOICE_CALL) { + strncpy(optStr, "_voicecall_gain", sizeof(optStr) - 1); + } + if (input & GAIN_CALLALERT) { + strncpy(optStr, "_ringtone_gain", sizeof(optStr) - 1); + } + + snprintf(buf, buf_len - 1, "%s_to_%s%s", fromStr, toStr, optStr); + //avsys_info(AVAUDIO, "rslt str : %s\n", buf); + return AVSYS_STATE_SUCCESS; +} + +int avsys_audio_ascn_bulk_set(int * bulk, int bulk_cnt, AscnResetType clear) +{ + struct snd_scenario *scn = NULL; + char card_name[STR_BUFF_MAX] = { 0, }; + char str_buf[STR_BUFF_MAX] = { 0, }; + 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, "<< %s, clear = %d\n", __func__, 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 (bulk == NULL) { + avsys_error_r(AVAUDIO, "input bulk is null\n"); + return AVSYS_STATE_ERR_NULL_POINTER; + } + if (bulk_cnt < 0) { + avsys_error_r(AVAUDIO, "bulk_cnt is negative\n"); + return AVSYS_STATE_ERR_RANGE_OVER; + } + + snprintf(card_name, sizeof(card_name) - 1, "default"); +#if defined(TIME_CHECK) + gettimeofday(&t_start, NULL); +#endif + //avsys_info(AVAUDIO, "snd_scenario_open() with [%s]\n", card_name); + scn = snd_scenario_open(card_name); +#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 + if (scn == NULL) { + avsys_error_r(AVAUDIO, "alsa scenario open failed %s\n", card_name); + return AVSYS_STATE_ERR_INTERNAL; + } + //avsys_info(AVAUDIO, "snd_scenario_open() success\n"); + + 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 < bulk_cnt; i++) { + if (bulk[i] == 0) + continue; + memset(str_buf, '\0', sizeof(str_buf)); + //avsys_info(AVAUDIO, "make string for 0x%X\n", bulk[i]); + __avsys_audio_ascn_make_scenario_str(bulk[i], str_buf, sizeof(str_buf)); + //avsys_info(AVAUDIO, "result string [%s]\n", str_buf); +#if defined(TIME_CHECK) + gettimeofday(&t_start, NULL); +#endif + err = snd_scenario_set_scn(scn, str_buf); +#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_buf, check); +#endif + if (err < 0) { + avsys_error_r(AVAUDIO, "snd_scenario_set_scn(%s) failed with %d\n", str_buf, err); + goto bulk_error; + } + avsys_warning(AVAUDIO, "* [0x%010X] Set [%s] success\n", bulk[i], str_buf); + } + +bulk_error: +#if defined(TIME_CHECK) + gettimeofday(&t_start, NULL); +#endif + snd_scenario_close(scn); +#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) +{ + struct snd_scenario *scn = NULL; + char card_name[STR_BUFF_MAX] = { 0, }; + char cmd_str[STR_BUFF_MAX] = { 0, }; + int err = AVSYS_STATE_SUCCESS; + + if (str == NULL) { + avsys_error_r(AVAUDIO, "input str is null\n"); + return AVSYS_STATE_ERR_NULL_POINTER; + } + + snprintf(card_name, sizeof(card_name) - 1, "default"); +// avsys_info(AVAUDIO, "snd_scenario_open() with [%s]\n", card_name); + scn = snd_scenario_open(card_name); + if (scn == NULL) { + avsys_error_r(AVAUDIO, "alsa scenario open failed %s\n", card_name); + return AVSYS_STATE_ERR_INTERNAL; + } +// avsys_info(AVAUDIO, "snd_scenario_open() success\n"); + + 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_r(AVAUDIO, "snd_scenario_set(%s) failed\n", str); + } + + snd_scenario_close(scn); + + return err; +} diff --git a/avsys-audio-handle.c b/avsys-audio-handle.c new file mode 100644 index 0000000..fbfa441 --- /dev/null +++ b/avsys-audio-handle.c @@ -0,0 +1,1160 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi <jhchoi.choi@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <unistd.h> + +#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-logical-volume.h" +#include "avsys-audio-pactrl.h" + +#define DEFAULT_VOLUME_SYSTEM 2 +#define DEFAULT_VOLUME_RINGTONE 6 +#define DEFAULT_VOLUME_MEDIA 11 +#define DEFAULT_VOLUME_NOTIFICATION 6 +#define DEFAULT_VOLUME_ALARM 6 +#define DEFAULT_VOLUME_CALL 6 +#define DEFAULT_VOLUME_FIXED 0 +#define DEFAULT_VOLUME_JAVA 11 + +#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 in %s\n", __func__); \ + 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 in %s\n", __func__); \ + 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 in %s\n", __func__); \ + 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 in %s\n", __func__); + 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 in %s\n", __func__); + return AVSYS_STATE_ERR_INTERNAL; + } + + temp = &control; + AVSYS_GET_SHM(temp,AVSYS_STATE_ERR_INTERNAL); + if (control == NULL) { + avsys_error(AVAUDIO, "control is null in %s\n", __func__); + return AVSYS_STATE_ERR_NULL_POINTER; + } + + /* init allocted bits */ + control->allocated = 0; + control->handle_amp = 0; + control->volume_value[AVSYS_AUDIO_LVOL_GAIN_TYPE_0] = DEFAULT_VOLUME_SYSTEM; + control->volume_value[AVSYS_AUDIO_LVOL_GAIN_TYPE_1] = DEFAULT_VOLUME_NOTIFICATION; + control->volume_value[AVSYS_AUDIO_LVOL_GAIN_TYPE_2] = DEFAULT_VOLUME_ALARM; + control->volume_value[AVSYS_AUDIO_LVOL_GAIN_TYPE_3] = DEFAULT_VOLUME_RINGTONE; + control->volume_value[AVSYS_AUDIO_LVOL_GAIN_TYPE_4] = DEFAULT_VOLUME_MEDIA; + control->volume_value[AVSYS_AUDIO_LVOL_GAIN_TYPE_5] = DEFAULT_VOLUME_CALL; + control->volume_value[AVSYS_AUDIO_LVOL_GAIN_TYPE_6] = DEFAULT_VOLUME_FIXED; + control->volume_value[AVSYS_AUDIO_LVOL_GAIN_TYPE_7] = DEFAULT_VOLUME_JAVA; + control->volume_value[AVSYS_AUDIO_LVOL_GAIN_TYPE_8] = DEFAULT_VOLUME_MEDIA; + 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 in %s\n", __func__); + 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 in %s\n", __func__); + 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; + int *lvolume = NULL; + int default_volume[] = { DEFAULT_VOLUME_SYSTEM, DEFAULT_VOLUME_NOTIFICATION, + DEFAULT_VOLUME_ALARM, DEFAULT_VOLUME_RINGTONE, + DEFAULT_VOLUME_MEDIA, DEFAULT_VOLUME_CALL, + DEFAULT_VOLUME_FIXED, DEFAULT_VOLUME_JAVA}; + 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 in %s\n", __func__); + return AVSYS_STATE_ERR_NULL_POINTER; + } + + if (volume_value == NULL) { + lvolume = default_volume; + } else { + lvolume = volume_value; + } + + 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); + } + } + } + } + + 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); + } + + AVSYS_LOCK_SYNC(); + if (volume_value == NULL) { + control->allocated = 0; + control->handle_amp = 0; + } + control->volume_value[AVSYS_AUDIO_LVOL_GAIN_TYPE_0] = lvolume[0]; /* DEFAULT_VOLUME_SYSTEM */ + control->volume_value[AVSYS_AUDIO_LVOL_GAIN_TYPE_1] = lvolume[1]; /* DEFAULT_VOLUME_NOTIFICATION */ + control->volume_value[AVSYS_AUDIO_LVOL_GAIN_TYPE_2] = lvolume[2]; /* DEFAULT_VOLUME_ALARM */ + control->volume_value[AVSYS_AUDIO_LVOL_GAIN_TYPE_3] = lvolume[3]; /* DEFAULT_VOLUME_RINGTONE */ + control->volume_value[AVSYS_AUDIO_LVOL_GAIN_TYPE_4] = lvolume[4]; /* DEFAULT_VOLUME_MEDIA */ + control->volume_value[AVSYS_AUDIO_LVOL_GAIN_TYPE_5] = lvolume[5]; /* DEFAULT_VOLUME_CALL */ + control->volume_value[AVSYS_AUDIO_LVOL_GAIN_TYPE_6] = lvolume[6]; /* DEFAULT_VOLUME_FIXED */ + control->volume_value[AVSYS_AUDIO_LVOL_GAIN_TYPE_7] = lvolume[7]; /* DEFAULT_VOLUME_JAVA */ + control->volume_value[AVSYS_AUDIO_LVOL_GAIN_TYPE_8] = lvolume[4]; /* DEFAULT_VOLUME_MEDIA */ + 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; + int dead_handle = 0x00; + + avsys_audio_handle_info_t *control = NULL; + avsys_audio_handle_info_t **temp = NULL; + int dead_pids[AVSYS_AUDIO_HANDLE_MAX]; + + temp = &control; + + AVSYS_GET_SHM(temp,AVSYS_STATE_ERR_INTERNAL); + if (control == NULL) { + avsys_error(AVAUDIO, "control is null in %s\n", __func__); + return AVSYS_STATE_ERR_NULL_POINTER; + } + + AVSYS_LOCK_SYNC(); + + /* Clear semaphore condition */ + + for (i = 0; i < AVSYS_AUDIO_HANDLE_MAX; i++) { + dead_pids[i] = -1; + 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\n", i); + dead_handle |= (flag << i); + dead_pids[i] = control->handles[i].pid; + } + } + } + + AVSYS_UNLOCK_SYNC(); + + avsys_warning(AVAUDIO, "dead_handle : 0x%0X\n", dead_handle); + /* Cleanup dead handle... */ + for (i = 0; i < AVSYS_AUDIO_HANDLE_MAX; i++) { + if (dead_handle & (flag << i)) { + /* set priority of dead handle as lowest */ + control->handle_priority[i] = AVSYS_AUDIO_HANDLE_PRIORITY_TYPE_0; + /* free this handle */ + avsys_error(AVAUDIO, "Cleanup handle %d...\n", i); + if (AVSYS_FAIL(avsys_audio_handle_free(i))) + avsys_error(AVAUDIO, "Cleanup handle %d failed\n", i); + } + } + if (dead_handle) { + char high_priority_exist = 0; + AVSYS_LOCK_SYNC(); + for (i = 0; i < AVSYS_AUDIO_HANDLE_MAX; i++) { + if (control->handle_priority[i] > AVSYS_AUDIO_HANDLE_PRIORITY_TYPE_0) { + high_priority_exist = 1; + break; + } + } + + for (i = 0; i < AVSYS_AUDIO_HANDLE_MAX; i++) { + if (control->handle_priority[i] == AVSYS_AUDIO_HANDLE_PRIORITY_TYPE_0) { + if (high_priority_exist) { + /* sink input mute immediately */ + if (control->handles[i].mute == AVSYS_AUDIO_UNMUTE) { + if (AVSYS_FAIL(avsys_audio_pa_ctrl_mute_by_index(control->handles[i].stream_index, AVSYS_AUDIO_MUTE))) { + avsys_error(AVAUDIO, "set sink input mute for %d failed\n", control->handles[i].stream_index); + } else { + avsys_warning(AVAUDIO, "set sink input mute for %d success\n", control->handles[i].stream_index); + } + control->handles[i].mute = AVSYS_AUDIO_MUTE; + } + } else { + /* sink input unmute immediately */ + if (control->handles[i].mute == AVSYS_AUDIO_MUTE) { + if (AVSYS_FAIL(avsys_audio_pa_ctrl_mute_by_index(control->handles[i].stream_index, AVSYS_AUDIO_UNMUTE))) { + avsys_error(AVAUDIO, "set sink input unmute for %d failed\n", control->handles[i].stream_index); + } else { + avsys_warning(AVAUDIO, "set sink input unmute for %d success\n", control->handles[i].stream_index); + } + control->handles[i].mute = AVSYS_AUDIO_UNMUTE; + } + } + + } else { /* this is high priority case */ + /* sink input unmute immediately */ + if (control->handles[i].mute == AVSYS_AUDIO_MUTE) { + if (AVSYS_FAIL(avsys_audio_pa_ctrl_mute_by_index(control->handles[i].stream_index, AVSYS_AUDIO_UNMUTE))) { + avsys_error(AVAUDIO, "set sink input unmute for %d failed\n", control->handles[i].stream_index); + } else { + avsys_warning(AVAUDIO, "set sink input unmute for %d success\n", control->handles[i].stream_index); + } + control->handles[i].mute = AVSYS_AUDIO_UNMUTE; + } + } + } + + 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 in %s\n", __func__); + 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) { + if (control->handles[i].dirty_volume) { + fprintf(stdout, " Dirty volume : %s\n", vol_str[control->handles[i].gain_setting.vol_type]); + } else { + fprintf(stdout, " Volume Type : %s\n", vol_str[control->handles[i].gain_setting.vol_type]); + } + fprintf(stdout, " Target device : %s\n", dev_str[control->handles[i].gain_setting.dev_type]); + fprintf(stdout, " Maximum Len : %2d\n", control->handles[i].gain_setting.max_len); + fprintf(stdout, " UI setted volume : L:%3d R:%3d\n", control->handles[i].setting_vol.level[0], control->handles[i].setting_vol.level[1]); + fprintf(stdout, " Real working volume : L:%3d R:%3d\n", control->handles[i].working_vol.level[0], control->handles[i].working_vol.level[1]); + } + 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, " Volume [System] : %2d ", control->volume_value[AVSYS_AUDIO_VOLUME_TYPE_SYSTEM]); + for (i = 0; i < control->volume_value[AVSYS_AUDIO_VOLUME_TYPE_SYSTEM]; i++) + fprintf(stdout, "+"); + fprintf(stdout, "\n"); + fprintf(stdout, " Volume [Notification] : %2d ", control->volume_value[AVSYS_AUDIO_VOLUME_TYPE_NOTIFICATION]); + for (i = 0; i < control->volume_value[AVSYS_AUDIO_VOLUME_TYPE_NOTIFICATION]; i++) + fprintf(stdout, "+"); + fprintf(stdout, "\n"); + fprintf(stdout, " Volume [Alarm] : %2d ", control->volume_value[AVSYS_AUDIO_VOLUME_TYPE_ALARM]); + for (i = 0; i < control->volume_value[AVSYS_AUDIO_VOLUME_TYPE_ALARM]; i++) + fprintf(stdout, "+"); + fprintf(stdout, "\n"); + fprintf(stdout, " Volume [Ringtone] : %2d ", control->volume_value[AVSYS_AUDIO_VOLUME_TYPE_RINGTONE]); + for (i = 0; i < control->volume_value[AVSYS_AUDIO_VOLUME_TYPE_RINGTONE]; i++) + fprintf(stdout, "+"); + fprintf(stdout, "\n"); + fprintf(stdout, " Volume [Media] : %2d ", control->volume_value[AVSYS_AUDIO_VOLUME_TYPE_MEDIA]); + for (i = 0; i < control->volume_value[AVSYS_AUDIO_VOLUME_TYPE_MEDIA]; i++) + fprintf(stdout, "+"); + fprintf(stdout, "\n"); + fprintf(stdout, " Volume [MediaHL] : %2d ", control->volume_value[AVSYS_AUDIO_VOLUME_TYPE_MEDIA_HL]); + for (i = 0; i < control->volume_value[AVSYS_AUDIO_VOLUME_TYPE_MEDIA_HL]; i++) + fprintf(stdout, "+"); + fprintf(stdout, "\n"); + fprintf(stdout, " Volume [Call] : %2d ", control->volume_value[AVSYS_AUDIO_VOLUME_TYPE_CALL]); + for (i = 0; i < control->volume_value[AVSYS_AUDIO_VOLUME_TYPE_CALL]; i++) + fprintf(stdout, "+"); + fprintf(stdout, "\n"); + fprintf(stdout, " Volume [Android] : %2d ", control->volume_value[AVSYS_AUDIO_VOLUME_TYPE_EXT_SYSTEM_ANDROID]); + for (i = 0; i < control->volume_value[AVSYS_AUDIO_VOLUME_TYPE_EXT_SYSTEM_ANDROID]; i++) + fprintf(stdout, "+"); + fprintf(stdout, "\n"); + fprintf(stdout, " Volume [Java] : %2d ", control->volume_value[AVSYS_AUDIO_VOLUME_TYPE_EXT_SYSTEM_JAVA]); + for (i = 0; i < control->volume_value[AVSYS_AUDIO_VOLUME_TYPE_EXT_SYSTEM_JAVA]; i++) + fprintf(stdout, "+"); + fprintf(stdout, "\n"); + 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, "%s\n", __func__); + 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_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, "%s, handle=[%d]\n", __func__, 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, "%s handle %d\n", __func__, 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 in %s\n", __func__); + *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 in %s\n", __func__); + *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 in %s\n", __func__); + *ptr = NULL; + return AVSYS_STATE_ERR_INTERNAL; + } + } + + 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, "%s handle %d\n", __func__, 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, "%s_%d_%d\n", __func__, 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_mute_by_index(ptr->stream_index, 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; + + /* reset fadedown mute */ + ptr->fadeup_vol = 0; +#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 + } + + result = AVSYS_STATE_SUCCESS; + } else { + avsys_warning(AVAUDIO, "[%s] handle %d does not allocated\n", __func__, handle); + if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_HANDLE))) { + avsys_error(AVAUDIO, "avsys_audio_unlock_sync() failed in %s\n", __func__); + 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. %s_%d\n", __func__, 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, "%s_%d_%d\n", __func__, (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. %s_%d\n", __func__, 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, "%s\n", __func__); + + 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, "%s_%d_%d\n", __func__, (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, "[%s] Unknown parameter %d. To nothing\n", __func__, 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 }; + char capture_used = 0; + 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(); + + 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_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 ) { + used_table[control->handles[i].gain_setting.vol_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] Ringtone[%d] Media[%d] MediaHL[%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_RINGTONE], + used_table[AVSYS_AUDIO_VOLUME_TYPE_MEDIA], + used_table[AVSYS_AUDIO_VOLUME_TYPE_MEDIA_HL], + 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_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_MEDIA_HL]) { + *type = AVSYS_AUDIO_VOLUME_TYPE_MEDIA; + } 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_update_volume(avsys_audio_handle_t *p, const int vol_type) +{ + int result = AVSYS_STATE_SUCCESS; + avsys_audio_handle_info_t *control = NULL; + avsys_audio_handle_info_t **temp = NULL; + temp = &control; + + avsys_audio_volume_t *set_volume = NULL; + int volume_type = vol_type; + + AVSYS_GET_SHM(temp,AVSYS_STATE_ERR_INTERNAL); + + AVSYS_LOCK_SYNC(); + + set_volume = &(p->setting_vol); + set_volume->level[AVSYS_AUDIO_CHANNEL_LEFT] = control->volume_value[volume_type]; + set_volume->level[AVSYS_AUDIO_CHANNEL_RIGHT] = control->volume_value[volume_type]; + result = avsys_audio_logical_volume_convert(set_volume, &(p->working_vol), &(p->gain_setting)); + + AVSYS_UNLOCK_SYNC(); + + return result; +} + +int avsys_audio_handle_update_volume_by_type(const int volume_type, const int volume_value) +{ + int i; + int result = AVSYS_STATE_SUCCESS; + avsys_audio_handle_info_t *control = NULL; + avsys_audio_handle_info_t **temp = NULL; + temp = &control; + + avsys_info(AVAUDIO, "%s\n", __func__); + AVSYS_GET_SHM(temp,AVSYS_STATE_ERR_INTERNAL); + + AVSYS_LOCK_SYNC(); + + control->volume_value[volume_type] = volume_value; + + for (i = 0; i < AVSYS_AUDIO_HANDLE_MAX; i++) { + int mode; + avsys_audio_volume_t *set_volume = NULL; + long long int flag = 0x01; + flag <<= i; + + if ((control->allocated & flag) == 0) { + continue; + } + mode = control->handles[i].mode; + if (mode != AVSYS_AUDIO_MODE_OUTPUT && mode != AVSYS_AUDIO_MODE_OUTPUT_CLOCK + && mode != AVSYS_AUDIO_MODE_OUTPUT_VIDEO && mode != AVSYS_AUDIO_MODE_OUTPUT_LOW_LATENCY + && mode != AVSYS_AUDIO_MODE_OUTPUT_AP_CALL) { + continue; + } + + if (control->handles[i].gain_setting.vol_type != volume_type) { + continue; + } + + if (control->handles[i].dirty_volume) { + /* This is volatile volume per handle */ + continue; + } + + set_volume = &(control->handles[i].setting_vol); + set_volume->level[AVSYS_AUDIO_CHANNEL_LEFT] = control->volume_value[volume_type]; + set_volume->level[AVSYS_AUDIO_CHANNEL_RIGHT] = control->volume_value[volume_type]; + result = avsys_audio_logical_volume_convert(set_volume, &(control->handles[i].working_vol), &(control->handles[i].gain_setting)); + if (AVSYS_FAIL(result)) { + avsys_error(AVAUDIO, "Can not set volume for handle %d. Error 0x%x\n", i, result); + break; + } + avsys_warning(AVAUDIO, "stream index %d\n", control->handles[i].stream_index); + if (AVSYS_FAIL(avsys_audio_pa_ctrl_volume_by_index(control->handles[i].stream_index, control->handles[i].working_vol.level[AVSYS_AUDIO_CHANNEL_LEFT], control->handles[i].channels))) { + avsys_error(AVAUDIO, "avsys_audio_pa_ctrl_volume_by_index() failed\n"); + } + } + + AVSYS_UNLOCK_SYNC(); + + 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, "%s\n", __func__); + 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; +} + +int avsys_audio_handle_update_priority(int handle, int priority, int handle_route, int cmd) +{ + long long int flag = 0x01; + int path_mute = 0, 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; + int sink_info = 0; + + temp = &control; + + if (cmd < AVSYS_AUDIO_SET_PRIORITY || cmd > AVSYS_AUDIO_UNSET_PRIORITY) { + avsys_error_r(AVAUDIO, "Invalid command %s\n", __func__); + 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 = 1; + } + } + } else { + avsys_warning(AVAUDIO, "[%s] handle %d does not allocated\n", __func__, 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 = 1; + } + } + + 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_warning(AVAUDIO, "handle[%d] has stream index 0, skip....(only mono sink-input use 0)\n", i); + continue; + } + + if (control->handle_priority[i] == AVSYS_AUDIO_HANDLE_PRIORITY_TYPE_0) { + + if (high_priority_exist) { /* mute */ + if (transition_effect) { + /* set fade out */ + if (control->handles[i].setting_vol.level[AVSYS_AUDIO_CHANNEL_LEFT] >= control->handles[i].setting_vol.level[AVSYS_AUDIO_CHANNEL_RIGHT]) { + control->handles[i].fadeup_vol = (-1) * control->handles[i].setting_vol.level[AVSYS_AUDIO_CHANNEL_LEFT]; + } else { + control->handles[i].fadeup_vol = (-1) * control->handles[i].setting_vol.level[AVSYS_AUDIO_CHANNEL_RIGHT]; + } + control->handles[i].fadeup_multiplier = 0; + } else { + /* mute immediately */ + if (AVSYS_FAIL(avsys_audio_pa_ctrl_mute_by_index(control->handles[i].stream_index, AVSYS_AUDIO_MUTE))) { + avsys_error(AVAUDIO, "set sink input mute for %d failed\n", control->handles[i].stream_index); + } else { + avsys_warning(AVAUDIO, "set sink input mute for %d success\n", control->handles[i].stream_index); + } + control->handles[i].mute = AVSYS_AUDIO_MUTE; + } + } else { /* unmute */ + if (transition_effect) { + /* set fade in */ + if (control->handles[i].setting_vol.level[AVSYS_AUDIO_CHANNEL_LEFT] >= control->handles[i].setting_vol.level[AVSYS_AUDIO_CHANNEL_RIGHT]) { + control->handles[i].fadeup_vol = control->handles[i].setting_vol.level[AVSYS_AUDIO_CHANNEL_LEFT]; + } else { + control->handles[i].fadeup_vol = control->handles[i].setting_vol.level[AVSYS_AUDIO_CHANNEL_RIGHT]; + } + control->handles[i].fadeup_multiplier = 0; + } else { + /* unmute immediately */ + if (control->handles[i].mute != AVSYS_AUDIO_UNMUTE) { + if (AVSYS_FAIL(avsys_audio_pa_ctrl_mute_by_index(control->handles[i].stream_index, AVSYS_AUDIO_UNMUTE))) { + avsys_error(AVAUDIO, "set sink input unmute for %d failed\n", control->handles[i].stream_index); + } else { + avsys_warning(AVAUDIO, "set sink input unmute for %d success\n", control->handles[i].stream_index); + } + control->handles[i].mute = AVSYS_AUDIO_UNMUTE; + } + } + } + } + } + + 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-initializer.c b/avsys-audio-initializer.c new file mode 100644 index 0000000..31b92cc --- /dev/null +++ b/avsys-audio-initializer.c @@ -0,0 +1,242 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi <jhchoi.choi@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <signal.h> + +#include "include/avsys-error.h" +#include "include/avsys-debug.h" + +#include "include/avsys-audio-handle.h" +#include "include/avsys-audio-path.h" +#include "include/avsys-audio-logical-volume.h" + +#define OP_NONE -1 +#define OP_USAGE 0 +#define OP_INIT 1 +#define OP_UNINIT 2 +#define OP_RESET 3 +#define OP_DUMP 4 +#define OP_DAEMON 5 +#define OP_AMP 6 +#define OP_SHUTDOWN 8 +#define OP_REJUVE 9 + +static int usage(int argc, char *argv[]); +static int get_options(int argc, char *argv[]); + +int main(int argc, char *argv[]) +{ + int operation = OP_NONE; + int result = 0; + int mute = 1; + pid_t pid; + mode_t old_umask = 0; + + static char *str_errormsg[] = { + "Operation is success.", + "Handle Init Fail", + "Path Init Fail", + "Handle Fini Fail", + "Path Fini Fail", + "Handle Reset Fail", + "Path Reset Fail", + "Handle Dump Fail", + "Path Dump Fail", + "Global Mute Fail", + "Handle Rejuvenation Fail", + "Vconf Get Value Fail", + "Sync Dump Fail", + }; + + operation = get_options(argc, argv); + + switch (operation) { + case OP_INIT: + old_umask = umask(0); + fprintf(stderr, "old umask was [%o]\n", old_umask); + result = avsys_audio_handle_init(); + if (AVSYS_FAIL(result)) { + result = 1; + umask(old_umask); + fprintf(stderr, "set umask to old value\n"); + break; + } + result = avsys_audio_path_ex_init(); + if (AVSYS_FAIL(result)) { + result = 2; + umask(old_umask); + fprintf(stderr, "set umask to old value\n"); + break; + } + result = avsys_audio_logical_volume_init(); + if (AVSYS_FAIL(result)) { + result = 2; + umask(old_umask); + fprintf(stderr, "set umask to old value\n"); + break; + } + umask(old_umask); + fprintf(stderr, "set umask to old value\n"); + break; + + case OP_UNINIT: + result = avsys_audio_handle_fini(); + if (AVSYS_FAIL(result)) { + result = 3; + break; + } + + result = avsys_audio_path_ex_fini(); + if (AVSYS_FAIL(result)) { + result = 4; + break; + } + break; + case OP_RESET: + result = avsys_audio_handle_reset(NULL); + if (AVSYS_FAIL(result)) { + result = 5; + break; + } + + result = avsys_audio_path_ex_reset(0); + if (AVSYS_FAIL(result)) { + result = 6; + break; + } + break; + case OP_DUMP: + result = avsys_audio_handle_dump(); + if (AVSYS_FAIL(result)) { + result = 7; + break; + } + result = avsys_audio_path_ex_dump(); + if (AVSYS_FAIL(result)) { + result = 8; + break; + } + + result = avsys_audio_dump_sync(); + if (AVSYS_FAIL(result)) { + result = 12; + break; + } + break; + case OP_DAEMON: + result = 0; + break; + case OP_USAGE: + break; + case OP_SHUTDOWN: + result = avsys_audio_path_ex_set_mute(mute); + if (AVSYS_FAIL(result)) { + result = 9; + } + break; + case OP_REJUVE: + result = avsys_audio_handle_rejuvenation(); + if (AVSYS_FAIL(result)) { + result = 10; + } + break; + default: + fprintf(stderr, "Unknown operation\n"); + break; + } + + if (result != 0) { + fprintf(stderr, "%s\n", str_errormsg[result]); + return 1; + } else + return 0; +} + +static int get_options(int argc, char *argv[]) +{ + int ch = 0; + int operation = OP_NONE; + + if (argc != 2) + return usage(argc, argv); + + while ((ch = getopt(argc, argv, "iurtdmjhap")) != EOF) { + switch (ch) { + case 'i': + if (operation != OP_NONE) + return usage(argc, argv); + operation = OP_INIT; + break; + case 'u': + if (operation != OP_NONE) + return usage(argc, argv); + operation = OP_UNINIT; + break; + case 'r': + if (operation != OP_NONE) + return usage(argc, argv); + operation = OP_RESET; + break; + case 'd': + if (operation != OP_NONE) + return usage(argc, argv); + operation = OP_DUMP; + break; + case 'h': + if (operation != OP_NONE) + return usage(argc, argv); + operation = OP_DAEMON; + break; + case 'm': + if (operation != OP_NONE) + return usage(argc, argv); + operation = OP_SHUTDOWN; + break; + case 'j': + if (operation != OP_NONE) + return usage(argc, argv); + operation = OP_REJUVE; + break; + default: + return usage(argc, argv); + } + if (optind != argc) + return usage(argc, argv); + } + return operation; +} + +static int usage(int argc, char *argv[]) +{ + fprintf(stderr, "Usage : %s option\n", argv[0]); + fprintf(stderr, "[OPTIONS]\n"); + fprintf(stderr, " -i : Initialize audio system\n"); + fprintf(stderr, " -u : Uninitialize audio system\n"); + fprintf(stderr, " -r : Reset audio system\n"); + fprintf(stderr, " -d : Dump audio system\n"); + fprintf(stderr, " -m : Global mute\n"); + fprintf(stderr, " -j : Handle rejuvenation\n"); + return OP_USAGE; +} + diff --git a/avsys-audio-logical-volume.c b/avsys-audio-logical-volume.c new file mode 100644 index 0000000..c9bf544 --- /dev/null +++ b/avsys-audio-logical-volume.c @@ -0,0 +1,365 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi <jhchoi.choi@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "avsys-audio-logical-volume.h" +#include "avsys-audio-shm.h" +#include "avsys-error.h" +#include "avsys-debug.h" + +/* {TYPE, {MAXLEN, {MAXLEN, SPK{L,R}...}, {MAXLEN, RECV {L,R}...}, {MAXLEN, HEADSET{L,R}...}, {MAXLEN, BT{L,R}...}}} */ +static const avsys_logical_gain_t g_volume_table[AVSYS_AUDIO_LVOL_GAIN_TYPE_MAX] = { + { AVSYS_AUDIO_LVOL_GAIN_TYPE_0, /* system : 0~15, default : 5 */ + { /* FNT DEFAULT */ + {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{19000,19000}}, {{22323,22323}}, {{25647,25647}}, {{28971,28971}}, {{32295,32295}}, {{35619,35619}}, {{38943,38943}}, {{42267,42267}}, {{45591,45591}}, {{48915,48915}}, {{52239,52239}}, {{55563,55563}}, {{58887,58887}}, {{62211,62211}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_SPK */ + {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{20480,20480}}, {{23698,23698}}, {{26916,26916}}, {{30135,30135}}, {{33353,33353}}, {{36571,36571}}, {{39789,39789}}, {{43008,43008}}, {{46226,46226}}, {{49444,49444}}, {{52662,52662}}, {{55880,55880}}, {{59099,59099}}, {{62317,62317}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET0 */ + {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{20480,20480}}, {{23698,23698}}, {{26916,26916}}, {{30135,30135}}, {{33353,33353}}, {{36571,36571}}, {{39789,39789}}, {{43008,43008}}, {{46226,46226}}, {{49444,49444}}, {{52662,52662}}, {{55880,55880}}, {{59099,59099}}, {{62317,62317}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_BTHEADSET */ + }, + }, + { AVSYS_AUDIO_LVOL_GAIN_TYPE_1, /* notification : 0~15, default : 7 */ + { /* FNT DEFAULT */ + {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{19000,19000}}, {{22323,22323}}, {{25647,25647}}, {{28971,28971}}, {{32295,32295}}, {{35619,35619}}, {{38943,38943}}, {{42267,42267}}, {{45591,45591}}, {{48915,48915}}, {{52239,52239}}, {{55563,55563}}, {{58887,58887}}, {{62211,62211}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_SPK */ + {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{20480,20480}}, {{23698,23698}}, {{26916,26916}}, {{30135,30135}}, {{33353,33353}}, {{36571,36571}}, {{39789,39789}}, {{43008,43008}}, {{46226,46226}}, {{49444,49444}}, {{52662,52662}}, {{55880,55880}}, {{59099,59099}}, {{62317,62317}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET0 */ + {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{20480,20480}}, {{23698,23698}}, {{26916,26916}}, {{30135,30135}}, {{33353,33353}}, {{36571,36571}}, {{39789,39789}}, {{43008,43008}}, {{46226,46226}}, {{49444,49444}}, {{52662,52662}}, {{55880,55880}}, {{59099,59099}}, {{62317,62317}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_BTHEADSET */ + }, + }, + { AVSYS_AUDIO_LVOL_GAIN_TYPE_2, /* alarm */ + { /* FNT DEFAULT */ + {LVOLUME_MAX_BASIC, {{{0,0}}, {{19000,19000}}, {{25991,25991}}, {{32982,32982}}, {{39973,39973}}, {{46964,46964}}, {{53955,53955}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_SPK */ + {LVOLUME_MAX_BASIC, {{{0,0}}, {{20480,20480}}, {{27225,27225}}, {{33969,33969}}, {{40714,40714}}, {{47458,47458}}, {{54203,54203}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET0 */ + {LVOLUME_MAX_BASIC, {{{0,0}}, {{20480,20480}}, {{27225,27225}}, {{33969,33969}}, {{40714,40714}}, {{47458,47458}}, {{54203,54203}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_BTHEADSET */ + }, + }, + { AVSYS_AUDIO_LVOL_GAIN_TYPE_3, /* ringtone : 0~15, default : 13 */ + { /* FNT DEFAULT */ + {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{19000,19000}}, {{22323,22323}}, {{25647,25647}}, {{28971,28971}}, {{32295,32295}}, {{35619,35619}}, {{38943,38943}}, {{42267,42267}}, {{45591,45591}}, {{48915,48915}}, {{52239,52239}}, {{55563,55563}}, {{58887,58887}}, {{62211,62211}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_SPK */ + {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{20480,20480}}, {{23698,23698}}, {{26916,26916}}, {{30135,30135}}, {{33353,33353}}, {{36571,36571}}, {{39789,39789}}, {{43008,43008}}, {{46226,46226}}, {{49444,49444}}, {{52662,52662}}, {{55880,55880}}, {{59099,59099}}, {{62317,62317}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET0 */ + {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{20480,20480}}, {{23698,23698}}, {{26916,26916}}, {{30135,30135}}, {{33353,33353}}, {{36571,36571}}, {{39789,39789}}, {{43008,43008}}, {{46226,46226}}, {{49444,49444}}, {{52662,52662}}, {{55880,55880}}, {{59099,59099}}, {{62317,62317}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_BTHEADSET */ + }, + }, + { AVSYS_AUDIO_LVOL_GAIN_TYPE_4, /* media */ + { /* FNT DEFAULT */ + {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{19000,19000}}, {{22323,22323}}, {{25647,25647}}, {{28971,28971}}, {{32295,32295}}, {{35619,35619}}, {{38943,38943}}, {{42267,42267}}, {{45591,45591}}, {{48915,48915}}, {{52239,52239}}, {{55563,55563}}, {{58887,58887}}, {{62211,62211}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_SPK */ + {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{20480,20480}}, {{23698,23698}}, {{26916,26916}}, {{30135,30135}}, {{33353,33353}}, {{36571,36571}}, {{39789,39789}}, {{43008,43008}}, {{46226,46226}}, {{49444,49444}}, {{52662,52662}}, {{55880,55880}}, {{59099,59099}}, {{62317,62317}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET0 */ + {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{20480,20480}}, {{23698,23698}}, {{26916,26916}}, {{30135,30135}}, {{33353,33353}}, {{36571,36571}}, {{39789,39789}}, {{43008,43008}}, {{46226,46226}}, {{49444,49444}}, {{52662,52662}}, {{55880,55880}}, {{59099,59099}}, {{62317,62317}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_BTHEADSET */ + }, + }, + { AVSYS_AUDIO_LVOL_GAIN_TYPE_5, /* call */ + { /* FNT DEFAULT */ + {LVOLUME_MAX_BASIC, {{{0,0}}, {{19000,19000}}, {{25991,25991}}, {{32982,32982}}, {{39973,39973}}, {{46964,46964}}, {{53955,53955}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_SPK */ + {LVOLUME_MAX_BASIC, {{{0,0}}, {{20480,20480}}, {{27225,27225}}, {{33969,33969}}, {{40714,40714}}, {{47458,47458}}, {{54203,54203}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET0 */ + {LVOLUME_MAX_BASIC, {{{0,0}}, {{20480,20480}}, {{27225,27225}}, {{33969,33969}}, {{40714,40714}}, {{47458,47458}}, {{54203,54203}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}, {{60947,60947}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_BTHEADSET */ + }, + }, + { AVSYS_AUDIO_LVOL_GAIN_TYPE_6, /* fixed */ + { /* FNT DEFAULT */ + {LVOLUME_MAX_SINGLE, {{{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_SPK */ + {LVOLUME_MAX_SINGLE, {{{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET0 */ + {LVOLUME_MAX_SINGLE, {{{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_BTHEADSET */ + }, + }, + { AVSYS_AUDIO_LVOL_GAIN_TYPE_7, /* java */ + { /* FNT DEFAULT */ + {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{19000,19000}}, {{22323,22323}}, {{25647,25647}}, {{28971,28971}}, {{32295,32295}}, {{35619,35619}}, {{38943,38943}}, {{42267,42267}}, {{45591,45591}}, {{48915,48915}}, {{52239,52239}}, {{55563,55563}}, {{58887,58887}}, {{62211,62211}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_SPK */ + {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{20480,20480}}, {{23698,23698}}, {{26916,26916}}, {{30135,30135}}, {{33353,33353}}, {{36571,36571}}, {{39789,39789}}, {{43008,43008}}, {{46226,46226}}, {{49444,49444}}, {{52662,52662}}, {{55880,55880}}, {{59099,59099}}, {{62317,62317}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET0 */ + {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{20480,20480}}, {{23698,23698}}, {{26916,26916}}, {{30135,30135}}, {{33353,33353}}, {{36571,36571}}, {{39789,39789}}, {{43008,43008}}, {{46226,46226}}, {{49444,49444}}, {{52662,52662}}, {{55880,55880}}, {{59099,59099}}, {{62317,62317}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_BTHEADSET */ + }, + }, + { AVSYS_AUDIO_LVOL_GAIN_TYPE_8, /* music only (max level) */ + { /* FNT DEFAULT */ + {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{19000,19000}}, {{22323,22323}}, {{25647,25647}}, {{28971,28971}}, {{32295,32295}}, {{35619,35619}}, {{38943,38943}}, {{42267,42267}}, {{45591,45591}}, {{48915,48915}}, {{52239,52239}}, {{55563,55563}}, {{58887,58887}}, {{62211,62211}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_SPK */ + {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{20480,20480}}, {{23698,23698}}, {{26916,26916}}, {{30135,30135}}, {{33353,33353}}, {{36571,36571}}, {{39789,39789}}, {{43008,43008}}, {{46226,46226}}, {{49444,49444}}, {{52662,52662}}, {{55880,55880}}, {{59099,59099}}, {{62317,62317}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET0 */ + {LVOLUME_MAX_MULTIMEDIA, {{{0,0}}, {{20480,20480}}, {{23698,23698}}, {{26916,26916}}, {{30135,30135}}, {{33353,33353}}, {{36571,36571}}, {{39789,39789}}, {{43008,43008}}, {{46226,46226}}, {{49444,49444}}, {{52662,52662}}, {{55880,55880}}, {{59099,59099}}, {{62317,62317}}, {{65535,65535}}}}, /* AVSYS_AUDIO_LVOL_DEV_TYPE_BTHEADSET */ + }, + }, +}; + +int avsys_audio_logical_volume_get_max(int vol_type, int dev_type, int *max) +{ + void **data = NULL; + avsys_logical_gain_t *table = NULL; + data = (void **)&table; + if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_LVOLUME, data))) { + avsys_error(AVAUDIO, "attach shared memory failed\n"); + return AVSYS_STATE_ERR_ALLOCATION; + } + + if (vol_type < 0 || vol_type >= AVSYS_AUDIO_LVOL_GAIN_TYPE_MAX || + dev_type < 0 || dev_type >= AVSYS_AUDIO_LVOL_DEV_TYPE_MAX || + max == NULL) { + avsys_error(AVAUDIO, "Input param wrong. Please check params\n\t type %d\n\tdevicetype %d\n", + vol_type, dev_type); + return AVSYS_STATE_ERR_INVALID_PARAMETER; + } + + *max = table[vol_type].devices[dev_type].max_len; + return AVSYS_STATE_SUCCESS; +} + +int avsys_audio_logical_volume_set_table(int vol_type, int dev_type, avsys_audio_volume_setting_t *setting) +{ + void **data = NULL; + avsys_logical_gain_t *table = NULL; + data = (void**)&table; + if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_LVOLUME, data))) { + avsys_error(AVAUDIO, "attach shared memory failed\n"); + return AVSYS_STATE_ERR_ALLOCATION; + } + + avsys_info(AVAUDIO, "Set Logical gain table\n"); + avsys_info(AVAUDIO, "\t vol_type %d dev_type %d\n", vol_type, dev_type); + + if (setting == NULL) { + avsys_error(AVAUDIO, "setting is null in %s\n", __func__); + return AVSYS_STATE_ERR_NULL_POINTER; + } + + /* Change ">" -> ">=" for CRASH LOGGER */ + if ((vol_type < 0 || vol_type >= AVSYS_AUDIO_LVOL_GAIN_TYPE_MAX) || + (dev_type < 0 || dev_type >= AVSYS_AUDIO_LVOL_DEV_TYPE_MAX)) { + avsys_error(AVAUDIO, "Input param wrong. Please check params\n\ttype %d\n\tdevicetype %d\n", + vol_type, dev_type); + return AVSYS_STATE_ERR_INVALID_PARAMETER; + } + + if (table[vol_type].type != vol_type) { + avsys_error(AVAUDIO, "volume type does not match (%d, %d)in %s\n", table[vol_type].type, vol_type, __func__); + return AVSYS_STATE_ERR_INVALID_PARAMETER; + } + + setting->vol_type = vol_type; + setting->dev_type = dev_type; + setting->max_len = table[vol_type].devices[dev_type].max_len; + setting->table = (avsys_audio_volume_t *)(((int)table[vol_type].devices[dev_type].gain) - (int)table); + + avsys_info(AVAUDIO, "vol %d, dev%d table setted.\n", vol_type, dev_type); + return AVSYS_STATE_SUCCESS; +} + +int avsys_audio_logical_volume_update_table(int dev_type, avsys_audio_volume_setting_t *setting) +{ + void **data = NULL; + avsys_logical_gain_t *table = NULL; + data = (void **)&table; + if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_LVOLUME, data))) { + avsys_error(AVAUDIO, "attach shared memory failed\n"); + return AVSYS_STATE_ERR_ALLOCATION; + } + + avsys_info(AVAUDIO, "Update Logical gain table\n"); + avsys_info(AVAUDIO, "\t dev_type %d\n", dev_type); + + if (setting == NULL) { + avsys_error(AVAUDIO, "setting is null in %s\n", __func__); + return AVSYS_STATE_ERR_NULL_POINTER; + } + if (table[setting->vol_type].type != setting->vol_type) { + avsys_error(AVAUDIO, "volume type does not match in %s\n", __func__); + return AVSYS_STATE_ERR_INVALID_PARAMETER; + } + + if (dev_type < 0 || dev_type >= AVSYS_AUDIO_LVOL_DEV_TYPE_MAX) { + avsys_error(AVAUDIO, "Input param wrong. Please check params\tdevicetype %d\n", dev_type); + return AVSYS_STATE_ERR_INVALID_PARAMETER; + } + setting->dev_type = dev_type; + setting->max_len = table[setting->vol_type].devices[dev_type].max_len; + setting->table = (avsys_audio_volume_t *)(((int)table[setting->vol_type].devices[dev_type].gain) - (int)table); + return AVSYS_STATE_SUCCESS; +} + +int avsys_audio_logical_volume_convert(avsys_audio_volume_t *level, avsys_audio_volume_t *converted, avsys_audio_volume_setting_t *setting) +{ + void **data = NULL; + avsys_logical_gain_t *table = NULL; + data = (void **)&table; + if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_LVOLUME, data))) { + avsys_error(AVAUDIO, "attach shared memory failed\n"); + return AVSYS_STATE_ERR_ALLOCATION; + } + + if (level == NULL) { + avsys_error(AVAUDIO, "level is null in %s\n", __func__); + return AVSYS_STATE_ERR_NULL_POINTER; + } + if (level->level[AVSYS_AUDIO_CHANNEL_LEFT] < 0) { + avsys_error(AVAUDIO, "negative volume level (left) in %s : %d\n", __func__, level->level[AVSYS_AUDIO_CHANNEL_LEFT]); + return AVSYS_STATE_ERR_INVALID_PARAMETER; + } + if (level->level[AVSYS_AUDIO_CHANNEL_RIGHT] < 0) { + avsys_error(AVAUDIO, "negative volume level (right) in %s : %d\n", __func__, level->level[AVSYS_AUDIO_CHANNEL_RIGHT]); + return AVSYS_STATE_ERR_INVALID_PARAMETER; + } + + if (setting->max_len <= level->level[AVSYS_AUDIO_CHANNEL_LEFT] || + setting->max_len <= level->level[AVSYS_AUDIO_CHANNEL_RIGHT] || + 0 > level->level[AVSYS_AUDIO_CHANNEL_LEFT] || + 0 > level->level[AVSYS_AUDIO_CHANNEL_RIGHT]) + { + avsys_error(AVAUDIO, "Input param wrong. Please check params\n\t level %d %d\n", level->level[AVSYS_AUDIO_CHANNEL_LEFT], level->level[AVSYS_AUDIO_CHANNEL_RIGHT]); + + return AVSYS_STATE_ERR_INVALID_VALUE; + } + + converted->level[AVSYS_AUDIO_CHANNEL_LEFT] = ((avsys_audio_volume_t *)((int)table + (int)setting->table))[level->level[AVSYS_AUDIO_CHANNEL_LEFT]].level[AVSYS_AUDIO_CHANNEL_LEFT]; + converted->level[AVSYS_AUDIO_CHANNEL_RIGHT] = ((avsys_audio_volume_t *)((int)table + (int)setting->table))[level->level[AVSYS_AUDIO_CHANNEL_RIGHT]].level[AVSYS_AUDIO_CHANNEL_RIGHT]; + + avsys_warning(AVAUDIO, "Volume converted vol_type %d dev_type %d\n", setting->vol_type, setting->dev_type); + avsys_warning(AVAUDIO, "\tL: %d to %d\n", level->level[AVSYS_AUDIO_CHANNEL_LEFT], converted->level[AVSYS_AUDIO_CHANNEL_LEFT]); + avsys_warning(AVAUDIO, "\tR: %d to %d\n", level->level[AVSYS_AUDIO_CHANNEL_RIGHT], converted->level[AVSYS_AUDIO_CHANNEL_RIGHT]); + + return AVSYS_STATE_SUCCESS; +} + +int avsys_audio_logical_volume_init(void) +{ + void *data = NULL; + avsys_audio_create_shm(AVSYS_AUDIO_SHM_IDEN_LVOLUME); + if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_LVOLUME, &data))) { + avsys_error(AVAUDIO, "attach shared memory failed\n"); + return AVSYS_STATE_ERR_ALLOCATION; + } + memcpy(data, g_volume_table, sizeof(avsys_logical_gain_t) * AVSYS_AUDIO_LVOL_GAIN_TYPE_MAX); + if (AVSYS_FAIL(avsys_audio_load_volume_from_file())) { + avsys_error(AVAUDIO, "Loading volume table from file failed. use default table\n"); + } + return AVSYS_STATE_SUCCESS; +} + +int avsys_audio_logical_volume_set_to_table(int gain_type, int dev_type, int step, int lv, int rv) +{ + void **data = NULL; + avsys_logical_gain_t *table = NULL; + data = (void **)&table; + if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_LVOLUME, data))) { + avsys_error(AVAUDIO, "attach shared memory failed\n"); + return AVSYS_STATE_ERR_ALLOCATION; + } + + table[gain_type].devices[dev_type].gain[step].level[0] = lv; + table[gain_type].devices[dev_type].gain[step].level[1] = rv; + return AVSYS_STATE_SUCCESS; +} + +int avsys_audio_logical_volume_get_from_table(int gain_type, int dev_type, int step, int *lv, int *rv) +{ + void **data = NULL; + avsys_logical_gain_t *table = NULL; + data = (void **)&table; + if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_LVOLUME, data))) { + avsys_error(AVAUDIO, "attach shared memory failed\n"); + return AVSYS_STATE_ERR_ALLOCATION; + } + + *lv = table[gain_type].devices[dev_type].gain[step].level[0]; + *rv = table[gain_type].devices[dev_type].gain[step].level[1]; + return AVSYS_STATE_SUCCESS; +} + +int avsys_audio_load_volume_from_file() +{ + FILE *fp = NULL; + int result = AVSYS_STATE_SUCCESS; + char strBuffer[128]; + + fp = fopen(VOLUME_FILE_PATH, "r"); + if (fp == NULL) { + printf("Loading volume table from file failed\n"); + return AVSYS_STATE_ERR_INTERNAL; + } + + memset(strBuffer, '\0', sizeof(strBuffer)); + while (fgets(strBuffer, sizeof(strBuffer), fp) != NULL) { + char *pEnd = NULL; + char *pStart = NULL; + int volumetable = 0; + int device = 0; + int level = 0; + int lvalue = 0, rvalue = 0; + char parseBuf[10] = ""; + + /* remove newline */ + if (strBuffer[strlen(strBuffer) - 1] == '\n') + strBuffer[strlen(strBuffer) - 1] = '\0'; + if (strBuffer[strlen(strBuffer) - 1] == '\r') + strBuffer[strlen(strBuffer) - 1] = '\0'; + if (strBuffer[0] == '#') + continue; + + pStart = strBuffer; + pEnd = strstr(pStart, ":"); + if (pEnd) { + memset(parseBuf, '\0', sizeof(parseBuf)); + memcpy(parseBuf, pStart, pEnd - pStart); + volumetable = atoi(parseBuf); + } else { + result = AVSYS_STATE_ERR_INTERNAL; + break; + } + + pStart = ++pEnd; + pEnd = strstr(pStart, ":"); + if (pEnd) { + memset(parseBuf, '\0', sizeof(parseBuf)); + memcpy(parseBuf, pStart, pEnd - pStart); + if (strcmp(parseBuf, "SPK") == 0) + device = 0; + else if (strcmp(parseBuf, "HEADSET") == 0) + device = 1; + else if (strcmp(parseBuf, "BTHEADSET") == 0) + device = 2; + } else { + result = AVSYS_STATE_ERR_INTERNAL; + break; + } + + pStart = ++pEnd; + pEnd = strstr(pStart, ":"); + if (pEnd) { + memset(parseBuf, '\0', sizeof(parseBuf)); + memcpy(parseBuf, pStart, pEnd - pStart); + level = atoi(parseBuf); + } else { + result = AVSYS_STATE_ERR_INTERNAL; + break; + } + + pStart = ++pEnd; + if (pEnd) { + pEnd = strstr(pStart, ":"); + memset(parseBuf, '\0', sizeof(parseBuf)); + memcpy(parseBuf, pStart, pEnd - pStart); + lvalue = atoi(parseBuf); + } else { + result = AVSYS_STATE_ERR_INTERNAL; + break; + } + + pStart = ++pEnd; + rvalue = atoi(pStart); + avsys_audio_set_volume_table(volumetable, device, level, lvalue, rvalue); + } + fclose(fp); + //avsys_info(AVAUDIO,"Load volume table from file success\n"); + return result; +} diff --git a/avsys-audio-pactrl.c b/avsys-audio-pactrl.c new file mode 100644 index 0000000..eff8d89 --- /dev/null +++ b/avsys-audio-pactrl.c @@ -0,0 +1,426 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi <jhchoi.choi@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include <string.h> +#include <stdio.h> + +#include "avsys-audio-pactrl.h" +#include "avsys-debug.h" + +enum { + AVSYS_PA_CTL_CMD_VOLUME, + AVSYS_PA_CTL_CMD_MUTE, + AVSYS_PA_CTL_CMD_GET_SINK_INFO, + AVSYS_PA_CTL_CMD_GET_DEFAULT_SINK, + AVSYS_PA_CTL_CMD_MAX, +}; + +typedef struct avsys_pa_ctrl_info { + pa_threaded_mainloop *m; + int cmd; + int mute; + int idx; + int vol; + int ch; + int res; +} avsys_pa_ctrl_info_t; + +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\n"); + } else { + avsys_info(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_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_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_VOLUME) { + pa_cvolume_set(&cv, info->ch, info->vol); + pa_operation_unref(pa_context_set_sink_input_volume(c, info->idx, &cv, __avsys_audio_pa_ctrl_success_cb, (void *)info->m)); + } else if (info->cmd == AVSYS_PA_CTL_CMD_MUTE) { + pa_operation_unref(pa_context_set_sink_input_mute(c, info->idx, info->mute, __avsys_audio_pa_ctrl_success_cb, (void *)info->m)); + } else if (info->cmd == AVSYS_PA_CTL_CMD_GET_SINK_INFO) { + pa_operation_unref(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) { + pa_operation_unref(pa_context_get_server_info(c, __avsys_audio_pa_ctrl_get_server_info_cb, (void *)info)); + } + 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_volume_by_index(unsigned int idx, int volume, int ch) +{ + pa_threaded_mainloop *mainloop = NULL; + pa_context *context = NULL; + int error = PA_ERR_INTERNAL; + avsys_pa_ctrl_info_t *info = NULL; + + if (volume < 0 || volume > 65535) { + avsys_error(AVAUDIO, "invalid volume value %d\n", volume); + return AVSYS_STATE_ERR_INVALID_PARAMETER; + } + if (ch < 0) { + avsys_error(AVAUDIO, "invalid channel value\n", ch); + 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_VOLUME; + info->idx = idx; + info->vol = volume; + info->ch = ch; + 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); + } + + 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_mute_by_index(unsigned int idx, int mute) +{ + pa_threaded_mainloop *mainloop = NULL; + pa_context *context = NULL; + int error = PA_ERR_INTERNAL; + avsys_pa_ctrl_info_t *info = NULL; + + if (mute != AVSYS_AUDIO_MUTE && mute != AVSYS_AUDIO_UNMUTE) { + avsys_error(AVAUDIO, "invalid mute value %d\n", mute); + 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_MUTE; + info->idx = idx; + info->mute = mute; + + 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); + } + + 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; + + 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; + + 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 100644 index 0000000..29c4593 --- /dev/null +++ b/avsys-audio-pasimple.c @@ -0,0 +1,475 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi <jhchoi.choi@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include <stdlib.h> +#include <string.h> + +#include "avsys-audio-pasimple.h" +#include "avsys-types.h" +#include "avsys-error.h" +#include "avsys-debug.h" + +#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_PLAYBACK 8 +#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 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) + +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) +{ + 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; + + avsys_info(AVAUDIO, ">>>[%s] mode=%d, format=%d, channel=%d, samplerate=%d\n", __func__, mode, format, channel, samplerate); + avsys_assert(handle != NULL); + + if (channel < 1 || channel > 2) + 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; + + 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 policy property */ + avsys_info(AVAUDIO, ">>>[%s] policy=[%d], vol_type=[%d]\n", __func__, policy, handle->gain_setting.vol_type); + if (policy == AVSYS_AUDIO_HANDLE_ROUTE_HANDSET_ONLY) { + avsys_info(AVAUDIO, ": set media plicy to PHONE\n"); + pa_proplist_sets(proplist, PA_PROP_MEDIA_POLICY, "phone"); + } else { + /* AVSYS_AUDIO_HANDLE_ROUTE_FOLLOWING_POLICY */ + /* check stream type (vol type) */ + if (handle->gain_setting.vol_type == AVSYS_AUDIO_VOLUME_TYPE_NOTIFICATION || + handle->gain_setting.vol_type == AVSYS_AUDIO_VOLUME_TYPE_ALARM) { + avsys_info(AVAUDIO, ": set media plicy to ALL\n"); + pa_proplist_sets(proplist, PA_PROP_MEDIA_POLICY, "all"); + } else { + avsys_info(AVAUDIO, ": set media plicy to AUTO\n"); + pa_proplist_sets(proplist, PA_PROP_MEDIA_POLICY, "auto"); + } + } + + handle->handle_route = policy; + + memset(&attr, '\0', sizeof(attr)); + + switch (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, NULL, &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, NULL, &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, NULL, &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, periods_per_buffer * samples_per_period * device->samplesize, attr.tlength, 0); + + s = pa_simple_new_proplist(NULL, "AVSYSTEM", PA_STREAM_PLAYBACK, NULL, "PLAYBACK", &ss, NULL, &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, + samples_per_period * device->samplesize, -1, samples_per_period * device->samplesize + 3430, (uint32_t)-1, 0); + + s = pa_simple_new_proplist(NULL,"AVSYSTEM", PA_STREAM_PLAYBACK, NULL, "LOW LATENCY PLAYBACK", &ss, NULL, &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_PLAYBACK, + (uint32_t) -1, (uint32_t) -1, periods_per_buffer * samples_per_period * device->samplesize, (uint32_t)-1, 0); + + s = pa_simple_new_proplist(NULL, "AVSYSTEM", PA_STREAM_PLAYBACK, NULL, "HIGH LATENCY PLAYBACK", &ss, NULL, &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, NULL, &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_LOW_LATENCY_MSEC, + MSEC_TO_SAMPLE(samplerate,period_time), + PA_SIMPLE_PERIODS_PER_BUFFER_DEFAULT, + (uint32_t) -1, (uint32_t) -1, periods_per_buffer * samples_per_period * device->samplesize, attr.tlength, 0); + + + s = pa_simple_new_proplist(NULL, "AVSYSTEM", PA_STREAM_PLAYBACK, NULL, "VoIP PLAYBACK", &ss, NULL, &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_LOW_LATENCY_MSEC, + MSEC_TO_SAMPLE(samplerate,period_time), + PA_SIMPLE_PERIODS_PER_BUFFER_DEFAULT, + 0, (uint32_t) -1, (uint32_t) -1, (uint32_t) -1, samples_per_period * device->samplesize); + + s = pa_simple_new_proplist(NULL, "AVSYSTEM", PA_STREAM_RECORD, NULL, "VoIP CAPTURE", &ss, NULL, &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", 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; + } + + avsys_info(AVAUDIO, "Samples(per period) : %d\t Periods(per buffer) : %d\n", samples_per_period, periods_per_buffer); + + device->pasimple_handle = (void *)s; + device->mode = 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; + } + +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_info(AVAUDIO, "%s\n", __func__); + + 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); + + switch (handle->mode) { + case AVSYS_AUDIO_MODE_OUTPUT: + case AVSYS_AUDIO_MODE_OUTPUT_CLOCK: + case AVSYS_AUDIO_MODE_OUTPUT_LOW_LATENCY: + 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 (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_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_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, "[%s][%d] period = %d, buffer = %d\n", __func__, __LINE__, *period_time, *buffer_time); + + return AVSYS_STATE_SUCCESS; +} + diff --git a/avsys-audio-path.c b/avsys-audio-path.c new file mode 100644 index 0000000..7967842 --- /dev/null +++ b/avsys-audio-path.c @@ -0,0 +1,2318 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi <jhchoi.choi@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> +#include <stdlib.h> + +#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-logical-volume.h" +#include "avsys-audio-alsa.h" +#include "avsys-audio-ascenario.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 OPEN_AIF_BEFORE_SCENARIO_SET + +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 */ + 0, 1, 0, 1, 0, 0, 0, 0 + }, + { /* AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO */ + /* NONE SPK RECV HEADSET BTHEADSET A2DP HANDSFREE HDMI */ + 1, 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 + }, + { /* AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL */ + /* NONE SPK RECV HEADSET BTHEADSET A2DP HANDSFREE HDMI */ + 1, 1, 1, 1, 1, 0, 0, 0 + }, + { /* AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT */ + /* NONE SPK RECV HEADSET BTHEADSET A2DP HANDSFREE HDMI */ + 0, 1, 1, 1, 1, 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 + }, +}; + +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_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_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_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_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_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_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_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_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 */ + }, +}; + + +static int __avsys_audio_path_set_ascn_ap_playback(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_videocall(avsys_audio_path_ex_info_t *control); +static int __avsys_audio_path_set_ascn_fmradio(avsys_audio_path_ex_info_t *control); +static int __avsys_audio_path_set_ascn_ap_capture(avsys_audio_path_ex_info_t *control); + + +typedef int (*_internal_gain_func)(avsys_audio_path_ex_info_t *control); +static _internal_gain_func playback_gain_func_table[AVSYS_AUDIO_PLAYBACK_GAIN_MAX] = +{ + __avsys_audio_path_set_ascn_ap_playback, + __avsys_audio_path_set_ascn_fmradio, + __avsys_audio_path_set_ascn_voicecall, + __avsys_audio_path_set_ascn_videocall, + __avsys_audio_path_set_ascn_ap_playback, +}; + +static _internal_gain_func capture_gain_func_table[AVSYS_AUDIO_CAPTURE_GAIN_MAX] = +{ + __avsys_audio_path_set_ascn_ap_capture, + __avsys_audio_path_set_ascn_fmradio, + __avsys_audio_path_set_ascn_voicecall, + __avsys_audio_path_set_ascn_videocall, +}; + +static int __avsys_audio_path_set_hw_controls(avsys_audio_path_ex_info_t *control); +static int __avsys_audio_path_get_earjack_type(void); + +#define AUDIOSYSTEM_CONF "/opt/etc/audio_system.conf" +#define CONF_ITEM_COUNT 2 +#define INPUT_DEV_MAX 20 +static char *conf_string[] = { + "headset_detection", + "headset_node", +}; + +typedef struct { + char headset_detection; + char headset_node_number; +} AudioSystemConf; + +static int __load_conf(AudioSystemConf *data) +{ +#if defined(_MMFW_I386_ALL_SIMULATOR) + if (data == NULL) + return AVSYS_STATE_ERR_NULL_POINTER; + + data->headset_detection = 1; + data->headset_node_number = 4; +#else + FILE *fp = NULL; + int i = 0; + char buffer[64] = { 0, }; + char conf_data[CONF_ITEM_COUNT] = { 1, 0 }; + + if (data == NULL) + return AVSYS_STATE_ERR_NULL_POINTER; + + fp = fopen(AUDIOSYSTEM_CONF, "r"); + if (fp == NULL) { + char filename[128] = { 0, }; + char readBuffer[32] = { 0, }; + char headset_find = 0; + int num = 0, headset_num = -1; + + for (num = 0; num < INPUT_DEV_MAX; num++) { + FILE *sfp = NULL; + memset(filename, '\0', sizeof(filename)); + snprintf(filename, sizeof(filename), "/sys/class/input/input%01d/name", num); + if (NULL == (sfp = fopen(filename, "r"))) + continue; + memset(readBuffer, '\0', sizeof(readBuffer)); + if (NULL == fgets(readBuffer, sizeof(readBuffer) - 1, sfp)) { + fclose(sfp); + continue; + } + if (strstr(readBuffer, "Headset")) { + headset_find = 1; + headset_num = num; + } + + fclose(sfp); + if (headset_num != -1) { + break; + } + } + if (headset_num == -1) + return AVSYS_STATE_ERR_INTERNAL; + + if (NULL == (fp = fopen(AUDIOSYSTEM_CONF, "w"))) { + return AVSYS_STATE_ERR_INTERNAL; + } + + fprintf(fp, "%s:1\n", conf_string[0]); + fprintf(fp, "%s:%d\n", conf_string[1], headset_num); + fflush(fp); + fclose(fp); + fp = NULL; + sync(); + data->headset_detection = 1; + data->headset_node_number = headset_num; + return AVSYS_STATE_SUCCESS; + } + + while (fgets(buffer, sizeof(buffer) - 1, fp) != NULL) { + if ((strlen(buffer) < 3) || (buffer[0] == '#') || (buffer[0] == '!')) + continue; + if (buffer[strlen(buffer) - 1] == '\n') + buffer[strlen(buffer) - 1] = '\0'; + for (i = 0; i < CONF_ITEM_COUNT; i++) { + if (0 == strncmp(buffer, conf_string[i], strlen(conf_string[i]))) { + char *ptr = NULL; + if (NULL == (ptr = strstr(buffer, ":"))) + break; + conf_data[i] = atoi(ptr + 1); + avsys_warning(AVAUDIO, "%s[%d]\n", buffer, conf_data[i]); + } + } + } + fclose(fp); + data->headset_detection = conf_data[0]; + data->headset_node_number = conf_data[1]; +#endif + return AVSYS_STATE_SUCCESS; +} + +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 }; + gain_status_t clean_gain_status = { GS_GAIN_NONE, GS_GAIN_NONE }; + path_status_t clean_path_status = { PS_PATH_NONE, PS_PATH_NONE }; + option_info_t default_option = { AVSYS_AUDIO_PATH_OPTION_JACK_AUTO, AVSYS_AUDIO_PATH_OPTION_JACK_AUTO }; + int index = 0; + int err = AVSYS_STATE_SUCCESS; + AudioSystemConf conf = { 1, 4 }; + + /* 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_sync(AVSYS_AUDIO_SYNC_IDEN_SOUNDPATH))); /* for audio route policy */ + 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->backup_gain = default_gain; + control->backup_path = default_path; + control->option = default_option; + control->gain_status = clean_gain_status; + control->path_status = clean_path_status; + control->p_gain_status = clean_gain_status; + control->p_path_status = clean_path_status; + + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + control->inserted = AVSYS_AUDIO_INSERTED_NONE; + control->route_policy = AVSYS_AUDIO_ROUTE_POLICY_DEFAULT; + if (AVSYS_FAIL(__load_conf(&conf))) + avsys_error_r(AVAUDIO, "Can not load audio system configuration file\n"); + + if (conf.headset_detection) { + control->inserted = __avsys_audio_path_get_earjack_type(); + if (control->inserted == AVSYS_AUDIO_INSERTED_NONE) + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + else + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET; + } else { + avsys_warning(AVAUDIO, "Ignore headset detection. Use speaker device\n"); + control->inserted = AVSYS_AUDIO_INSERTED_NONE; + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + } + + avsys_error_r(AVAUDIO, "Earjack init value is %d\n", control->inserted); + + { + /* Gain tunning Debug mode */ + FILE *gainTunningFp = NULL; + if (NULL != (gainTunningFp = fopen("/opt/etc/gain_tuner.ini", "r"))) { + char buffer[32] = ""; + avsys_warning(AVAUDIO, "GAIN TUNNING DEBUG MODE...This degrade sound path performance\n"); + memset(buffer, '\0', sizeof(buffer)); + if (NULL == fgets(buffer, sizeof(buffer) - 1, gainTunningFp)) { + fclose(gainTunningFp); + control->gain_debug_mode = 0; + } else { + fclose(gainTunningFp); + if (0 == strncmp("debug=1", buffer, 7)) { + control->gain_debug_mode = 1; + } else { + control->gain_debug_mode = 0; + } + } + } else { + control->gain_debug_mode = 0; + } + } + control->ear_auto = AVSYS_AUDIO_EAR_SWITCH_MANUAL; + 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_hw_controls(control); + + if (AVSYS_SUCCESS(err)) + err = __avsys_audio_path_set_ascn_ap_capture(control); + + 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 in %s\n", __func__); + 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 in %s\n", __func__); + 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 }; + gain_status_t clean_gain_status = { GS_GAIN_NONE, GS_GAIN_NONE }; + path_status_t clean_path_status = { PS_PATH_NONE, PS_PATH_NONE }; + option_info_t default_option = { AVSYS_AUDIO_PATH_OPTION_JACK_AUTO, AVSYS_AUDIO_PATH_OPTION_JACK_AUTO }; + int index = 0; + int err = AVSYS_STATE_SUCCESS; + int backup_debug = 0; + AudioSystemConf conf = { 1, 4 }; + + /* 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 in %s\n", __func__); + 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 in %s\n", __func__); + return AVSYS_STATE_ERR_INTERNAL; + } + + /* init values */ + control->pregain = default_gain; + control->gain = default_gain; + control->reqgain = default_gain; + control->path = default_path; + control->backup_gain = default_gain; + control->backup_path = default_path; + control->option = default_option; + control->gain_status = clean_gain_status; + control->path_status = clean_path_status; + control->p_gain_status = clean_gain_status; + control->p_path_status = clean_path_status; + + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + control->inserted = AVSYS_AUDIO_INSERTED_NONE; + control->route_policy = AVSYS_AUDIO_ROUTE_POLICY_DEFAULT; + if (AVSYS_FAIL(__load_conf(&conf))) + avsys_error_r(AVAUDIO, "Can not load audio system configuration file\n"); + + if (conf.headset_detection) { + control->inserted = __avsys_audio_path_get_earjack_type(); + if (control->inserted == AVSYS_AUDIO_INSERTED_NONE) + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + else + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET; + } else { + avsys_warning(AVAUDIO, "Ignore headset detection. Use speaker device\n"); + control->inserted = AVSYS_AUDIO_INSERTED_NONE; + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + } + + avsys_error_r(AVAUDIO, "Earjack init value is %d\n", control->inserted); + + { + /* Gain tunning Debug mode */ + FILE *gainTunningFp = NULL; + if (NULL != (gainTunningFp = fopen("/opt/etc/gain_tuner.ini", "r"))) { + char buffer[32] = ""; + avsys_warning(AVAUDIO, "GAIN TUNNING DEBUG MODE...This degrade sound path performance\n"); + memset(buffer, '\0', sizeof(buffer)); + if (NULL == fgets(buffer, sizeof(buffer) - 1, gainTunningFp)) { + fclose(gainTunningFp); + control->gain_debug_mode = 0; + } else { + fclose(gainTunningFp); + if (0 == strncmp("debug=1", buffer, 7)) { + control->gain_debug_mode = 1; + } else { + control->gain_debug_mode = 0; + } + } + } else { + control->gain_debug_mode = 0; + } + } + control->ear_auto = AVSYS_AUDIO_EAR_SWITCH_MANUAL; + 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); + + if (forced) { + backup_debug = control->gain_debug_mode; + control->gain_debug_mode = 1; + } + /* call path control */ + err = __avsys_audio_path_set_ascn_ap_playback(control); + if (AVSYS_SUCCESS(err)) + err = __avsys_audio_path_set_hw_controls(control); + + if (AVSYS_SUCCESS(err)) + err = __avsys_audio_path_set_ascn_ap_capture(control); + + if (forced) { + control->gain_debug_mode = backup_debug; + } + + if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() failed in %s\n", __func__); + 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" + }; + const static char *str_in[AVSYS_AUDIO_PATH_EX_INMAX] = { + "NONE", "MIC", "HEADMIC", "BTMIC", "FMINPUT", "HANSFREEMIC" + }; + const static char *str_route[AVSYS_AUDIO_ROUTE_POLICY_MAX] = { + "DEFAULT", "IGN_A2DP", "HANDSET" + }; + /* + const static char *str_gain[AVSYS_AUDIO_GAIN_EX_MAX] = { + "KEYTONE", "RINGTONE", "ALARMTONE", "CALLTONE", "AUDIOPLAYER", "VIDEOPLAYER", + "VOICECALL", "VIDEOCALL", "FMRADIO", "VOICEREC", "CAMCORDER", "CAMERA", "GAME"}; + */ + const static char *str_playback_gain[AVSYS_AUDIO_PLAYBACK_GAIN_MAX] = { + "AP", "FMRADIO", "VOICECALL", "VIDEOCALL", "CALLALERT", + }; + const static char *str_capture_gain[AVSYS_AUDIO_CAPTURE_GAIN_MAX] = { + "AP", "FMRADIO", "VOICECALL", "VIDEOCALL", + }; + + 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 in %s\n", __func__); + 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, " Gain debug mode : 0x%-x\n", control->gain_debug_mode); + fprintf(stdout, " Gain status : 0x%x 0x%x\n", control->gain_status.playback, control->gain_status.capture); + fprintf(stdout, " Path status : 0x%x 0x%x\n", control->path_status.playback, control->path_status.capture); + fprintf(stdout, " Auto EarJack Control : %-s\n", str_ear[control->ear_auto]); + fprintf(stdout, " Audio Route Policy : %-s\n", str_route[control->route_policy]); + fprintf(stdout, " Physical Earjack? [type] : %-s [%-s]\n", str_yn[control->inserted != AVSYS_AUDIO_INSERTED_NONE], str_earType[control->inserted]); + 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 Lagacy : %-s\n", str_yn[(control->option.playback & AVSYS_AUDIO_PATH_OPTION_LEGACY_MODE) ? 1 : 0]); + fprintf(stdout, " Option Jack Playback : %-s\n", str_yn[(control->option.playback & AVSYS_AUDIO_PATH_OPTION_JACK_AUTO) ? 1 : 0]); + fprintf(stdout, " Option Jack Capture : %-s\n", str_yn[(control->option.capture & AVSYS_AUDIO_PATH_OPTION_JACK_AUTO) ? 1 : 0]); + fprintf(stdout, " Option Dual out : %-s\n", str_yn[(control->option.playback & AVSYS_AUDIO_PATH_OPTION_DUAL_OUT) ? 1 : 0]); + fprintf(stdout, " Option Forced : %-s\n", str_yn[(control->option.playback & AVSYS_AUDIO_PATH_OPTION_FORCED) ? 1 : 0]); + + return AVSYS_STATE_SUCCESS; +} + +static int __avsys_audio_path_get_earjack_type (void) +{ + int fd = 0; + char readval = AVSYS_AUDIO_INSERTED_NONE; + fd = open("/sys/devices/platform/jack/earjack_online", O_RDONLY); + + if (fd == -1) { + avsys_error_r(AVAUDIO, "Can not get initial jack type\n"); + return AVSYS_AUDIO_INSERTED_NONE; + } + read(fd, &readval, sizeof(readval)); + switch (readval) { + case '0': + readval = AVSYS_AUDIO_INSERTED_NONE; + break; + case '1': + readval = AVSYS_AUDIO_INSERTED_3; + break; + case '3': + readval = AVSYS_AUDIO_INSERTED_4; + break; + case '8': + readval = AVSYS_AUDIO_INSERTED_AV; + break; + case '2': + if (1 == read(fd, &readval, sizeof(readval))) { + if (readval == '0') { + readval = AVSYS_AUDIO_INSERTED_AV; + } else { + avsys_error(AVAUDIO, "Unknown jack type value...2%d\n", readval); + readval = AVSYS_AUDIO_INSERTED_NONE; + } + } else { + avsys_error(AVAUDIO, "jack type read error...\n"); + readval = AVSYS_AUDIO_INSERTED_NONE; + } + break; + default: + avsys_error(AVAUDIO, "jack type unknown value...%c\n", readval); + readval = AVSYS_AUDIO_INSERTED_NONE; + break; + } + + close(fd); + return readval; +} + +int avsys_audio_path_earjack_init(int *init_type, int *outfd) +{ +#if !defined(_MMFW_I386_ALL_SIMULATOR) + char eventnode_filename[32] = { 0, }; + int fd = 0; + AudioSystemConf conf = { 1, 4 }; + + if (outfd == NULL || init_type == NULL) { + avsys_error(AVAUDIO, "input parameter is null\n"); + return AVSYS_STATE_ERR_NULL_POINTER; + } + + if (AVSYS_FAIL(__load_conf(&conf))) { + avsys_error_r(AVAUDIO, "Can not load audio system configuration file\n"); + } + + if (!conf.headset_detection) { + avsys_error(AVAUDIO, "Earjack control daemon will be closed by user option...\n"); + return AVSYS_STATE_SUCCESS; + } + + snprintf(eventnode_filename, sizeof(eventnode_filename), "/dev/event%01d", conf.headset_node_number); + + fd = open(eventnode_filename, O_RDONLY); + if (fd == -1) { + avsys_error_r(AVAUDIO, "Device file open error\n"); + return AVSYS_STATE_ERR_INTERNAL; + } else { + avsys_audio_path_ex_info_t *control = NULL; + avsys_audio_path_ex_info_t **temp = NULL; + void *vol_data = NULL; + void *handle_data = NULL; + temp = &control; + + if(AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_LVOLUME, &vol_data))) { + avsys_error(AVAUDIO,"attach logical volume shared memory failed\n"); + return AVSYS_STATE_ERR_ALLOCATION; + } + if(AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_HANDLE, &handle_data))) { + avsys_error(AVAUDIO,"attach handle shared memory failed\n"); + return AVSYS_STATE_ERR_ALLOCATION; + } + if(AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void**)temp))) { + avsys_error_r(AVAUDIO,"avsys_audio_get_shm() failed in %s\n", __func__); + return AVSYS_STATE_ERR_INTERNAL; + } + + *init_type = control->inserted; + *outfd = fd; + return AVSYS_STATE_SUCCESS; + } +#else + return AVSYS_STATE_ERR_DEVICE_NOT_SUPPORT; +#endif +} + +int avsys_audio_path_earjack_wait(int fd, int *current_type, int *new_type, int *is_auto_mute) +{ +#if !defined(_MMFW_I386_ALL_SIMULATOR) + fd_set set; + int readtemp; + int select_ret = 0; + struct avsys_audio_jack_event jevent; + int res = AVSYS_STATE_SUCCESS; + int set_flag = 0; + int cur_type = -1; + + if (new_type == NULL || is_auto_mute == NULL) + return AVSYS_STATE_ERR_NULL_POINTER; + + FD_ZERO(&set); + FD_SET(fd, &set); + + cur_type = *current_type; + + select_ret = select(fd + 1, &set, NULL, NULL, NULL); + avsys_info(AVAUDIO, "SELECT returns......\n"); + + if (select_ret != 1) { + if (select_ret == 0) { + avsys_error_r(AVAUDIO, "Earjack timeout in autocontrol\n"); + } else if (select_ret == -1) { + avsys_error_r(AVAUDIO, "Earjack detect unknown error: %d\n", errno); + } + return AVSYS_STATE_WAR_INVALID_VALUE; + } +#ifdef EARJACK_LOCK /* currently this is disabled to avoid semapore value increase */ + if (AVSYS_FAIL(avsys_audio_lock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_lock_sync() failed in %s\n", __func__); + return AVSYS_STATE_ERR_INTERNAL; + } +#endif + if (read(fd, &jevent, sizeof(jevent)) < 0) { + avsys_error(AVAUDIO, "read fd failed with 0x%x\n", errno); + return AVSYS_STATE_WAR_INVALID_MODE; + } + avsys_info(AVAUDIO, "*** JEVENT : code=%d, value=%d\n", jevent.code, jevent.value); + if (jevent.type != TYPE_EVENT_SWITCH) { + avsys_info(AVAUDIO, "Not a switch event\n"); + return AVSYS_STATE_WAR_INVALID_MODE; + } + + switch (jevent.code) { + case CODE_HEADPHONE_INSERT: + case CODE_LINEOUT_INSERT: + case CODE_JACK_PHYSICAL_INSERT: + if (jevent.value == 1) { + readtemp = __avsys_audio_path_get_earjack_type(); + } else { + readtemp = 0; + } + + set_flag = 1; /* need change earphone status */ + break; + default: + readtemp = cur_type; /* same value */ + break; + } + + *new_type = readtemp; + + 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 in %s\n", __func__); + return AVSYS_STATE_ERR_INTERNAL; + } + + avsys_info(AVAUDIO, "control->ear_auto = %d\n", control->ear_auto); + if (control->ear_auto == AVSYS_AUDIO_EAR_SWITCH_AUTO_WITH_MUTE) { + *current_type = control->inserted; + *is_auto_mute = 1; + res = AVSYS_STATE_SUCCESS; + } else if (control->ear_auto == AVSYS_AUDIO_EAR_SWITCH_AUTO_WITHOUT_MUTE) { + *current_type = control->inserted; + *is_auto_mute = 0; + res = AVSYS_STATE_SUCCESS; + } else if (control->ear_auto == AVSYS_AUDIO_EAR_SWITCH_MANUAL) { + *is_auto_mute = 0; + /* return warning */ + if (set_flag) { + control->inserted = *new_type; + set_flag = 0; + } + res = AVSYS_STATE_WAR_INTERNAL; + } + + return res; +#else + return AVSYS_STATE_ERR_DEVICE_NOT_SUPPORT; +#endif +} + +int avsys_audio_path_earjack_process(int new_type) +{ +#if !defined(_MMFW_I386_ALL_SIMULATOR) + avsys_audio_path_ex_info_t *control = NULL; + avsys_audio_path_ex_info_t **temp = NULL; + int err = AVSYS_STATE_SUCCESS; + temp = &control; + + avsys_info(AVAUDIO, "new_type = %d\n", new_type); + if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp))) { + avsys_error_r(AVAUDIO, "avsys_audio_get_shm() failed in %s\n", __func__); + return AVSYS_STATE_ERR_INTERNAL; + } + + control->inserted = new_type; + + if (control->ear_auto == AVSYS_AUDIO_EAR_SWITCH_MANUAL) { + return AVSYS_STATE_SUCCESS; + } + + /* Capture/Playback Gain Control */ + avsys_warning(AVAUDIO, "Gain C(%d), P(%d)\n", control->gain.capture, control->gain.playback); + err = capture_gain_func_table[control->gain.capture] (control); + if (AVSYS_FAIL(err)) { + avsys_error_r(AVAUDIO, "earjack change failed for %d gain : error 0x%x\n", control->gain.capture, err); + } + + err = playback_gain_func_table[control->gain.playback] (control); + if (AVSYS_SUCCESS(err)) { + /* H/W Control */ + err = __avsys_audio_path_set_hw_controls(control); + if (AVSYS_FAIL(err)) { + avsys_error_r(AVAUDIO, "__avsys_audio_path_set_hw_controls() failed in %s\n", __func__); + } + } else + avsys_error_r(AVAUDIO, "earjack change failed for %d gain : error 0x%x\n", control->gain.playback, err); + + return err; +#else + return AVSYS_STATE_ERR_DEVICE_NOT_SUPPORT; +#endif +} + +int avsys_audio_path_earjack_deinit(int fd) +{ +#if !defined(_MMFW_I386_ALL_SIMULATOR) + close(fd); + return AVSYS_STATE_SUCCESS; +#else + return AVSYS_STATE_ERR_DEVICE_NOT_SUPPORT; +#endif +} + +int avsys_audio_path_earjack_unlock() +{ +#ifdef EARJACK_LOCK /* currently this is disabled to avoid semapore value increase */ + if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() failed in %s\n", __func__); + return AVSYS_STATE_ERR_INTERNAL; + } +#endif + 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, + CMD_DEVICE_MAX +}; + +avsys_audio_alsa_aif_handle_t *g_hAIF[AIF_DEVICE_MAX] = { NULL, NULL, NULL, NULL }; +char *strAIF[AIF_DEVICE_MAX] = { "AIF2 Capture", "AIF2 Playback", "AIF3 Capture", "AIF3 Playback" }; + +#define SET_AIF(index) \ +do { \ + if(g_hAIF[index]) { \ + avsys_warning(AVAUDIO,#index" device already opened\n"); \ + AIF_control[index] = CMD_DEVICE_NONE; \ + } else { \ + AIF_control[index] = CMD_DEVICE_OPEN; \ + } \ +} while (0) + +static int __avsys_open_aif(char AIF_control[]) +{ + int iAIF = 0; + int err = AVSYS_STATE_SUCCESS; + + for (iAIF = 0; iAIF < AIF_DEVICE_MAX; iAIF++) { + /* check command */ + if (AIF_control[iAIF] != CMD_DEVICE_OPEN) + continue; + + /* check handle allocation */ + if (g_hAIF[iAIF]) { + avsys_warning(AVAUDIO, "Oops! Free %s device handle first", strAIF[iAIF]); + free(g_hAIF[iAIF]); + g_hAIF[iAIF] = NULL; + } + /* memory allocation for handle */ + avsys_warning(AVAUDIO, "%s handle alloc", strAIF[iAIF]); + g_hAIF[iAIF] = calloc(sizeof(avsys_audio_handle_t), 1); + if (!g_hAIF[iAIF]) { + avsys_error_r(AVAUDIO, "Can not alloc memory for %s device handle", strAIF[iAIF]); + err = AVSYS_STATE_ERR_ALLOCATION; + continue; + } + + if (AVSYS_FAIL(avsys_audio_alsa_open_AIF_device(iAIF, g_hAIF[iAIF]))) { + avsys_error_r(AVAUDIO, "open %s device failed\n", strAIF[iAIF]); + err = AVSYS_STATE_ERR_INVALID_HANDLE; + } else { + avsys_warning(AVAUDIO, "open %s device success\n", strAIF[iAIF]); + if (AVSYS_FAIL(avsys_audio_alsa_set_AIF_params(g_hAIF[iAIF]))) { + avsys_error_r(AVAUDIO, "%s device set parameter failed\n", strAIF[iAIF]); + err = AVSYS_STATE_ERR_INVALID_PARAMETER; + } else { + avsys_warning(AVAUDIO, "%s device set parameter success\n", strAIF[iAIF]); + } + } + } + return err; +} + +static void __avsys_close_aif () +{ + int iAIF = 0; + + for (iAIF = 0; iAIF < AIF_DEVICE_MAX; iAIF++) { + if (g_hAIF[iAIF]) { + avsys_info(AVAUDIO, "close device :: %s\n", strAIF[iAIF]); + if (AVSYS_FAIL(avsys_audio_alsa_close_AIF_device(g_hAIF[iAIF]))) { + avsys_error_r(AVAUDIO, "close %s device failed\n", strAIF[iAIF]); + } + free(g_hAIF[iAIF]); + g_hAIF[iAIF] = NULL; + avsys_warning(AVAUDIO, "%s device handle free\n", strAIF[iAIF]); + } else { + avsys_info(AVAUDIO, "skip closing device :: %s\n", strAIF[iAIF]); + } + } +} + +static int __avsys_audio_release_path (gain_info_t local_gain, avsys_audio_path_ex_info_t *control) +{ + int err = AVSYS_STATE_SUCCESS; + int iAIF = 0; + + 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: + if (getpid() == control->path_fixed_pid[PATH_FIXED_TYPE_CALL]) { +#ifndef OPEN_AIF_BEFORE_SCENARIO_SET /* FIXME : disable here, close after scenario set */ + __avsys_close_aif(); +#endif + + if (AVSYS_FAIL(avsys_audio_ascn_single_set(ASCN_CODEC_DISABLE_ON_SUSPEND))) { + avsys_error_r(AVAUDIO, "[%s] failed to set codec_disable_on_suspend\n", __func__); + } + control->p_path_status.playback |= PS_CODEC_DISABLE_ON_SUSPEND; + } 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; + + case AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO: + /* TODO: Reset & Codec disable on suspend script */ + if (AVSYS_FAIL(avsys_audio_ascn_single_set(ASCN_CODEC_DISABLE_ON_SUSPEND))) { + avsys_error_r(AVAUDIO, "[%s] failed to set codec_disable_on_suspend\n", __func__); + } + control->p_path_status.playback |= PS_CODEC_DISABLE_ON_SUSPEND; + + if (AVSYS_FAIL(avsys_audio_ascn_single_set(ASCN_STR_RESET))) { + avsys_error_r(AVAUDIO, "[%s] failed to set reset\n", __func__); + } else { + control->p_path_status.playback = PS_PATH_NONE; + } + + /* TODO: Path fixed clear (path_fixed, path_fixed_pid) */ + if ((control->path_fixed & PATH_FIXED_WITH_FMRADIO) == 0) { + avsys_error(AVAUDIO, "FM-Radio path release without radio path request\n"); + } + control->path_fixed &= ~PATH_FIXED_WITH_FMRADIO; + control->path_fixed_pid[PATH_FIXED_TYPE_FMRADIO] = -1; + 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; + + switch(control->route_policy) + { + case AVSYS_AUDIO_ROUTE_POLICY_DEFAULT: + case AVSYS_AUDIO_ROUTE_POLICY_IGNORE_A2DP: + control->ear_auto = AVSYS_AUDIO_EAR_SWITCH_AUTO_WITH_MUTE; + control->option.playback = AVSYS_AUDIO_PATH_OPTION_JACK_AUTO; + control->option.capture = AVSYS_AUDIO_PATH_OPTION_JACK_AUTO; + break; + + case AVSYS_AUDIO_ROUTE_POLICY_HANDSET_ONLY: + control->ear_auto = AVSYS_AUDIO_EAR_SWITCH_AUTO_WITHOUT_MUTE; + control->option.playback = AVSYS_AUDIO_PATH_OPTION_NONE; + control->option.capture = AVSYS_AUDIO_PATH_OPTION_NONE; + break; + + default: + break; + } + + control->p_path_status.playback = PS_PATH_NONE; + control->p_path_status.capture = PS_PATH_NONE; + control->p_gain_status.playback = GS_GAIN_NONE; + control->p_gain_status.capture = GS_GAIN_NONE; + + /* Playback */ + err = __avsys_audio_path_set_ascn_ap_playback(control); + if (AVSYS_SUCCESS(err)) { + err = __avsys_audio_path_set_hw_controls(control); + if (AVSYS_FAIL(err)) { + avsys_error(AVAUDIO, "Update logical volume failure\n"); + } + } else { + avsys_error(AVAUDIO, "Set ap playback failure\n"); + } + + /* Capture */ + err = __avsys_audio_path_set_ascn_ap_capture(control); + if (AVSYS_FAIL(err)) { + avsys_error(AVAUDIO, "Set ap capture failure\n"); + } + } + + /* FIXME : Close AIF, this will be moved before scneario set */ +#ifdef OPEN_AIF_BEFORE_SCENARIO_SET + if ((local_gain.playback == AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL || local_gain.playback == AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL) && + getpid() == control->path_fixed_pid[PATH_FIXED_TYPE_CALL]) { + __avsys_close_aif(); + } +#endif + + 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; + char AIF_control[AIF_DEVICE_MAX] = { CMD_DEVICE_NONE, CMD_DEVICE_NONE, CMD_DEVICE_NONE, CMD_DEVICE_NONE }; + int iAIF = 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: + req_gain.playback = AVSYS_AUDIO_PLAYBACK_GAIN_AP; + break; + + case AVSYS_AUDIO_GAIN_EX_RINGTONE: + case AVSYS_AUDIO_GAIN_EX_CALLTONE: + req_gain.playback = AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT; + break; + + case AVSYS_AUDIO_GAIN_EX_VOICEREC: + case AVSYS_AUDIO_GAIN_EX_CAMCORDER: + req_gain.capture = AVSYS_AUDIO_CAPTURE_GAIN_AP; + 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_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 in %s\n", __func__); + 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 in %s\n", __func__); + 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_WITH_FMRADIO) { + if (AVSYS_FAIL(avsys_check_process(control->path_fixed_pid[PATH_FIXED_TYPE_FMRADIO]))) { + control->path_fixed &= ~PATH_FIXED_WITH_FMRADIO; + } + } + 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 in %s\n", __func__); + 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 in %s\n", __func__); + return AVSYS_STATE_ERR_INTERNAL; + } + return AVSYS_STATE_ERR_INVALID_STATE; + } + } + /* overwrite local_gain with current gain if it is simplex sound 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) + DO_IF_VALID(local_gain.playback, control->option.playback = option) + DO_IF_VALID(local_gain.capture, control->option.capture = 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.playback); + if (req_gain.playback == AVSYS_AUDIO_PLAYBACK_GAIN_AP) { + control->backup_gain.playback = control->reqgain.playback; + control->backup_path.playback = out; + } + } else { + control->path.playback = out; + control->backup_gain.playback = local_gain.playback; + control->backup_path.playback = out; + + switch (local_gain.playback) { + case AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL: + control->path_fixed_pid[PATH_FIXED_TYPE_CALL] = current_pid; + case AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT: + if (control->path.playback == AVSYS_AUDIO_PATH_EX_BTHEADSET) { + SET_AIF(AIF3_PLAYBACK); + SET_AIF(AIF3_CAPTURE); + } + break; + + case AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL: + control->path_fixed_pid[PATH_FIXED_TYPE_CALL] = current_pid; + SET_AIF(AIF2_PLAYBACK); + + if (control->path.playback == AVSYS_AUDIO_PATH_EX_BTHEADSET) { + SET_AIF(AIF3_PLAYBACK); + } + 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.capture); + if (req_gain.capture == AVSYS_AUDIO_CAPTURE_GAIN_AP) { + control->backup_gain.capture = control->reqgain.capture; + control->backup_path.capture = in; + } + } else { + control->path.capture = in; + control->backup_gain.capture = local_gain.capture; + control->backup_path.capture = in; + + switch (local_gain.capture) { + case AVSYS_AUDIO_CAPTURE_GAIN_VIDEOCALL: + control->path_fixed_pid[PATH_FIXED_TYPE_CALL] = current_pid; + if (control->path.capture == AVSYS_AUDIO_PATH_EX_BTMIC) { + SET_AIF(AIF3_CAPTURE); + } + break; + + case AVSYS_AUDIO_CAPTURE_GAIN_VOICECALL: + control->path_fixed_pid[PATH_FIXED_TYPE_CALL] = current_pid; + SET_AIF(AIF2_CAPTURE); + + if (control->path.capture == AVSYS_AUDIO_PATH_EX_BTMIC) { + SET_AIF(AIF3_CAPTURE); + } + break; + + case AVSYS_AUDIO_CAPTURE_GAIN_FMRADIO: + control->path_fixed_pid[PATH_FIXED_TYPE_FMRADIO] = current_pid; + break; + } + } + } + + /* Open AIFs */ + /* FIXME: this will be moved to after alsa scenraio set */ +#ifdef OPEN_AIF_BEFORE_SCENARIO_SET + err = __avsys_open_aif(AIF_control); +#endif + + /* Do ALSA scenario 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_ascn_ap_playback(control); + if (AVSYS_SUCCESS(err)) { + err = __avsys_audio_path_set_hw_controls(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); + if (AVSYS_SUCCESS(err)) { + err = __avsys_audio_path_set_hw_controls(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_ascn_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_ascn_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"); + err = __avsys_audio_path_set_ascn_videocall(control); + } + /* Capture */ + 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); + } +#ifndef OPEN_AIF_BEFORE_SCENARIO_SET + err = __avsys_open_aif(AIF_control); +#endif + +FINISHED: + /* UnLOCK */ + if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() failed in %s\n", __func__); + 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 in %s\n", __func__); + 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 in %s\n", __func__); + return AVSYS_STATE_ERR_INTERNAL; + } + + switch (control->gain.playback) { + case AVSYS_AUDIO_PLAYBACK_GAIN_AP: + *gain = AVSYS_AUDIO_GAIN_EX_KEYTONE; + *out = control->path.playback; + *in = AVSYS_AUDIO_PATH_EX_NONE; + *option = control->option.playback; + break; + case AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT: + *gain = AVSYS_AUDIO_GAIN_EX_RINGTONE; + *out = control->path.playback; + *in = AVSYS_AUDIO_PATH_EX_NONE; + *option = control->option.playback; + break; + case AVSYS_AUDIO_PLAYBACK_GAIN_VOICECALL: + *gain = AVSYS_AUDIO_GAIN_EX_VOICECALL; + *out = control->path.playback; + *in = control->path.capture; + *option = control->option.playback; + break; + case AVSYS_AUDIO_PLAYBACK_GAIN_VIDEOCALL: + *gain = AVSYS_AUDIO_GAIN_EX_VIDEOCALL; + *out = control->path.playback; + *in = control->path.capture; + *option = control->option.playback; + break; + case AVSYS_AUDIO_PLAYBACK_GAIN_FMRADIO: + *gain = AVSYS_AUDIO_GAIN_EX_FMRADIO; + *out = control->path.playback; + *in = control->path.capture; + *option = control->option.playback; + break; + } + + if (AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))) { + avsys_error_r(AVAUDIO, "avsys_audio_unlock_sync() failed in %s\n", __func__); + 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 in %s\n", __func__); + 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 in %s\n", __func__); + 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 in %s\n", __func__); + 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 in %s\n", __func__); + return AVSYS_STATE_ERR_INTERNAL; + } + avsys_error(AVAUDIO, "Mute fail %s\n", __func__); + 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 in %s\n", __func__); + return AVSYS_STATE_ERR_INTERNAL; + } + avsys_error(AVAUDIO, "Unmute fail %s\n", __func__); + 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 in %s\n", __func__); + 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 %s\n", __func__); + return AVSYS_STATE_ERR_IO_CONTROL; + } + } else { + if (AVSYS_FAIL(avsys_audio_ascn_single_set(ASCN_STR_PLAYBACK_UNMUTE))) { + avsys_error(AVAUDIO, "Unmute fail %s\n", __func__); + 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 in %s\n", __func__); + 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 in %s\n", __func__); + 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 in %s\n", __func__); + return AVSYS_STATE_ERR_INTERNAL; + } + + return AVSYS_STATE_SUCCESS; +} + +static int __avsys_audio_path_set_ascn_ap_playback(avsys_audio_path_ex_info_t *control) +{ + int cmd_gain[2] = { 0, 0 }; + int cmd_path[3] = { 0, 0, 0 }; + char callalert_mode = 0; + + avsys_info(AVAUDIO, "<< path.playback = %d, option = %x, gain.playback = %d, inserted = %d\n", + control->path.playback, control->option.playback, control->gain.playback, control->inserted); + + callalert_mode = (control->gain.playback == AVSYS_AUDIO_PLAYBACK_GAIN_CALLALERT) ? 1 : 0; + control->path_fixed = PATH_FIXED_NONE; + + switch (control->path.playback) { + case AVSYS_AUDIO_PATH_EX_SPK: + if (control->option.playback & AVSYS_AUDIO_PATH_OPTION_LEGACY_MODE) { + avsys_warning(AVAUDIO, "Does not support legacy mode anymore\n"); + } + + if (control->option.playback & AVSYS_AUDIO_PATH_OPTION_DUAL_OUT) { + if (callalert_mode) { + control->gain_status.playback = GS_AP_TO_SPK_CALLALERT; + cmd_gain[0] = INPUT_AP | OUTPUT_STEREO_SPK | GAIN_CALLALERT; + } else { + control->gain_status.playback = GS_AP_TO_SPK; + cmd_gain[0] = INPUT_AP | OUTPUT_STEREO_SPK | GAIN_MODE; + } + + if (control->inserted == AVSYS_AUDIO_INSERTED_NONE) { + control->path_status.playback = PS_AP_TO_SPK; + cmd_path[0] = INPUT_AP | OUTPUT_STEREO_SPK; + } else { + control->path_status.playback = PS_AP_TO_SPK | PS_AP_TO_HEADSET; + cmd_path[0] = INPUT_AP | OUTPUT_STEREO_SPK; + cmd_path[1] = INPUT_AP | OUTPUT_HEADSET; + } + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + } else { + if (control->option.playback & AVSYS_AUDIO_PATH_OPTION_JACK_AUTO) { + control->ear_auto = AVSYS_AUDIO_EAR_SWITCH_AUTO_WITH_MUTE; + if (control->inserted == AVSYS_AUDIO_INSERTED_NONE) { + if (callalert_mode) { + control->gain_status.playback = GS_AP_TO_SPK_CALLALERT; + cmd_gain[0] = INPUT_AP | OUTPUT_STEREO_SPK | GAIN_CALLALERT; + } else { + control->gain_status.playback = GS_AP_TO_SPK; + cmd_gain[0] = INPUT_AP | OUTPUT_STEREO_SPK | GAIN_MODE; + } + control->path_status.playback = PS_AP_TO_SPK; + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + cmd_path[0] = INPUT_AP | OUTPUT_STEREO_SPK; + } else { + if (callalert_mode) { + control->gain_status.playback = GS_AP_TO_HEADSET_CALLALERT; + cmd_gain[0] = INPUT_AP | OUTPUT_HEADSET | GAIN_CALLALERT; + } else { + control->gain_status.playback = GS_AP_TO_HEADSET; + cmd_gain[0] = INPUT_AP | OUTPUT_HEADSET | GAIN_MODE; + } + control->path_status.playback = PS_AP_TO_HEADSET; + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET; + cmd_path[0] = INPUT_AP | OUTPUT_HEADSET; + } + } else { + if (callalert_mode) { + control->gain_status.playback = GS_AP_TO_SPK_CALLALERT; + cmd_gain[0] = INPUT_AP | OUTPUT_STEREO_SPK | GAIN_CALLALERT; + } else { + control->gain_status.playback = GS_AP_TO_SPK; + cmd_gain[0] = INPUT_AP | OUTPUT_STEREO_SPK | GAIN_MODE; + } + control->ear_auto = AVSYS_AUDIO_EAR_SWITCH_AUTO_WITHOUT_MUTE; + control->path_status.playback = PS_AP_TO_SPK; + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + + cmd_path[0] = INPUT_AP | OUTPUT_STEREO_SPK; + } + } + break; + + case AVSYS_AUDIO_PATH_EX_RECV: + if (control->option.playback & AVSYS_AUDIO_PATH_OPTION_LEGACY_MODE) { + avsys_warning(AVAUDIO, "Does not support legacy mode anymore\n"); + } + + if (control->option.playback & AVSYS_AUDIO_PATH_OPTION_JACK_AUTO) { + control->ear_auto = AVSYS_AUDIO_EAR_SWITCH_AUTO_WITH_MUTE; + if (control->inserted == AVSYS_AUDIO_INSERTED_NONE) { + control->gain_status.playback = GS_AP_TO_RECV; + control->path_status.playback = PS_AP_TO_RECV; + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + cmd_gain[0] = INPUT_AP | OUTPUT_RECV | GAIN_MODE; + cmd_path[0] = INPUT_AP | OUTPUT_RECV; + } else { + if (callalert_mode) { + control->gain_status.playback = GS_AP_TO_HEADSET_CALLALERT; + cmd_gain[0] = INPUT_AP | OUTPUT_HEADSET | GAIN_CALLALERT; + } else { + control->gain_status.playback = GS_AP_TO_HEADSET; + cmd_gain[0] = INPUT_AP | OUTPUT_HEADSET | GAIN_MODE; + } + control->path_status.playback = PS_AP_TO_HEADSET; + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET; + cmd_path[0] = INPUT_AP | OUTPUT_HEADSET; + } + } else { + control->ear_auto = AVSYS_AUDIO_EAR_SWITCH_MANUAL; + control->gain_status.playback = GS_AP_TO_RECV; + control->path_status.playback = PS_AP_TO_RECV; + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + cmd_gain[0] = INPUT_AP | OUTPUT_RECV | GAIN_MODE; + cmd_path[0] = INPUT_AP | OUTPUT_RECV; + } + break; + + case AVSYS_AUDIO_PATH_EX_HEADSET: + control->ear_auto = AVSYS_AUDIO_EAR_SWITCH_MANUAL; + if (callalert_mode) { + control->gain_status.playback = GS_AP_TO_HEADSET_CALLALERT; + cmd_gain[0] = INPUT_AP | OUTPUT_HEADSET | GAIN_CALLALERT; + } else { + control->gain_status.playback = GS_AP_TO_HEADSET; + cmd_gain[0] = INPUT_AP | OUTPUT_HEADSET | GAIN_MODE; + } + control->path_status.playback = PS_AP_TO_HEADSET; + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET; + cmd_path[0] = INPUT_AP | OUTPUT_HEADSET; + break; + + case AVSYS_AUDIO_PATH_EX_HDMI: + avsys_warning(AVAUDIO, "Does not support dedicated HDMI sound path\n"); + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + break; + + case AVSYS_AUDIO_PATH_EX_BTHEADSET: + control->ear_auto = AVSYS_AUDIO_EAR_SWITCH_MANUAL; + control->gain_status.playback = GS_AP_TO_BT; + control->path_status.playback = PS_AP_TO_BT; + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_BTHEADSET; + cmd_gain[0] = INPUT_AP | OUTPUT_BT_HEADSET | GAIN_MODE; + cmd_path[0] = INPUT_AP | OUTPUT_BT_HEADSET; + break; + case AVSYS_AUDIO_PATH_EX_HANDSFREE: + default: /* DEFAULT PATH CONTROL TO NONE */ + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + break; + } + + //avsys_warning(AVAUDIO,"pg(0x%X), g(0x%X), pp(0x%X), p(0x%X)\n", control->p_gain_status, control->gain_status, control->p_path_status, control->path_status); + if ((control->p_path_status.playback != control->path_status.playback) || control->gain_debug_mode == 1) { + avsys_warning(AVAUDIO, "Run Alsa Scenario Script\n"); + RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_bulk_set(cmd_gain, 1, ASCN_RESET_PLAYBACK)) + control->p_gain_status.playback = control->gain_status.playback; + RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_bulk_set(cmd_path, 2, ASCN_RESET_NONE)) + control->p_path_status.playback = control->path_status.playback; + } + + avsys_info(AVAUDIO, ">> leave"); + return AVSYS_STATE_SUCCESS; +} + +static int __avsys_audio_path_set_ascn_voicecall(avsys_audio_path_ex_info_t *control) +{ + return AVSYS_STATE_SUCCESS; +} + +static int __avsys_audio_path_set_ascn_videocall(avsys_audio_path_ex_info_t *control) +{ + int cmd_gain[2] = { 0, 0 }; + int cmd_path[3] = { 0, 0, 0 }; + int skip_clear = 0; + control->path_fixed = PATH_FIXED_WITH_CALL; + switch (control->path.playback) { + case AVSYS_AUDIO_PATH_EX_NONE: + if (control->option.playback & AVSYS_AUDIO_PATH_OPTION_LEGACY_MODE) { + /* Legacy mode does not effect here... */ + avsys_warning(AVAUDIO, "legacy mode option %s\n", __func__); + } + control->ear_auto = AVSYS_AUDIO_EAR_SWITCH_MANUAL; + if (control->reqgain.playback == control->gain.playback) { + avsys_warning(AVAUDIO, "Output block on videocall"); + } else { + avsys_warning(AVAUDIO, "Ignore another path setting request during voicecall"); + } + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + break; + + case AVSYS_AUDIO_PATH_EX_SPK: + if (control->reqgain.playback == control->gain.playback) { + if (control->option.playback & AVSYS_AUDIO_PATH_OPTION_JACK_AUTO) { + control->ear_auto = AVSYS_AUDIO_EAR_SWITCH_AUTO_WITH_MUTE; + if (control->inserted != AVSYS_AUDIO_INSERTED_NONE) { + control->gain_status.playback = GS_AP_TO_HEADSET; + control->path_status.playback = PS_AP_TO_HEADSET; + cmd_gain[0] = INPUT_AP | OUTPUT_HEADSET | GAIN_MODE; + cmd_path[0] = INPUT_AP | OUTPUT_HEADSET; + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET; + } else { + control->gain_status.playback = GS_AP_TO_SPK; + control->path_status.playback = PS_AP_TO_SPK; + cmd_gain[0] = INPUT_AP | OUTPUT_STEREO_SPK | GAIN_MODE; + cmd_path[0] = INPUT_AP | OUTPUT_STEREO_SPK; + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + } + } else { /* ear jack manual */ + control->ear_auto = AVSYS_AUDIO_EAR_SWITCH_MANUAL; + control->gain_status.playback = GS_AP_TO_SPK; + control->path_status.playback = PS_AP_TO_SPK; + cmd_gain[0] = INPUT_AP | OUTPUT_STEREO_SPK | GAIN_MODE; + cmd_path[0] = INPUT_AP | OUTPUT_STEREO_SPK; + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + } + } else { /* changed by priority */ + avsys_warning(AVAUDIO, "Sound Path request during VT call ignored."); + } + break; + + case AVSYS_AUDIO_PATH_EX_RECV: + if (control->gain.playback == control->reqgain.playback) { + if (control->option.playback & AVSYS_AUDIO_PATH_OPTION_JACK_AUTO) { + control->ear_auto = AVSYS_AUDIO_EAR_SWITCH_AUTO_WITH_MUTE; + if (control->inserted != AVSYS_AUDIO_INSERTED_NONE) { + control->gain_status.playback = GS_AP_TO_HEADSET; + control->path_status.playback = PS_AP_TO_HEADSET; + cmd_gain[0] = INPUT_AP | OUTPUT_HEADSET | GAIN_MODE; + cmd_path[0] = INPUT_AP | OUTPUT_HEADSET; + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET; + } else { + control->gain_status.playback = GS_AP_TO_RECV; + control->path_status.playback = PS_AP_TO_RECV; + cmd_gain[0] = INPUT_AP | OUTPUT_RECV | GAIN_MODE; + cmd_path[0] = INPUT_AP | OUTPUT_RECV; + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + } + } else { /* ear jack manual */ + control->ear_auto = AVSYS_AUDIO_EAR_SWITCH_MANUAL; + control->gain_status.playback = GS_AP_TO_RECV; + control->path_status.playback = PS_AP_TO_RECV; + cmd_gain[0] = INPUT_AP | OUTPUT_RECV | GAIN_MODE; + cmd_path[0] = INPUT_AP | OUTPUT_RECV; + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + } + } else { /* changed by priority */ + avsys_warning(AVAUDIO, "Sound Path request during VT call ignored."); + } /* reqgain, gain */ + break; + + case AVSYS_AUDIO_PATH_EX_HEADSET: + if (control->reqgain.playback == control->gain.playback) { + control->ear_auto = AVSYS_AUDIO_EAR_SWITCH_MANUAL; + control->gain_status.playback = GS_AP_TO_HEADSET; + control->path_status.playback = PS_AP_TO_HEADSET; + cmd_gain[0] = INPUT_AP | OUTPUT_HEADSET | GAIN_MODE; + cmd_path[0] = INPUT_AP | OUTPUT_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) { + control->ear_auto = AVSYS_AUDIO_EAR_SWITCH_MANUAL; + control->gain_status.playback = GS_AP_TO_BT; + control->path_status.playback = PS_AP_TO_BT; + cmd_gain[0] = INPUT_AP | OUTPUT_BT_HEADSET | GAIN_MODE; + cmd_path[0] = INPUT_AP | OUTPUT_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: + if (control->reqgain.capture == control->gain.capture) { + /* Clear modem input */ + control->path_status.capture &= ~(PS_MAINMIC_TO_AP | PS_SUBMIC_TO_AP | PS_EARMIC_TO_AP | PS_BTMIC_TO_AP); + } else { + avsys_warning(AVAUDIO, "Ignore another path setting request during VT call (input)\n"); + } + break; + + case AVSYS_AUDIO_PATH_EX_MIC: + if (control->option.capture & AVSYS_AUDIO_PATH_OPTION_JACK_AUTO) { + if ((control->inserted == AVSYS_AUDIO_INSERTED_4) && (control->path_status.playback & PS_AP_TO_HEADSET)) { + control->gain_status.capture |= GS_EARMIC_TO_AP; + control->path_status.capture |= PS_EARMIC_TO_AP; + cmd_gain[1] = INPUT_EAR_MIC | OUTPUT_AP | GAIN_MODE; + cmd_path[1] = INPUT_EAR_MIC | OUTPUT_AP; + } else { + if (control->option.capture & AVSYS_AUDIO_PATH_OPTION_USE_SUBMIC) { + control->gain_status.capture |= GS_SUBMIC_TO_AP; + control->path_status.capture |= PS_SUBMIC_TO_AP; + cmd_gain[1] = INPUT_SUB_MIC | OUTPUT_AP | GAIN_MODE; + cmd_path[1] = INPUT_SUB_MIC | OUTPUT_AP; + } else { + control->gain_status.capture |= GS_MAINMIC_TO_AP; + control->path_status.capture |= PS_MAINMIC_TO_AP; + cmd_gain[1] = INPUT_MAIN_MIC | OUTPUT_AP | GAIN_MODE; + cmd_path[1] = INPUT_MAIN_MIC | OUTPUT_AP; + } + } + } else { + if (control->option.capture & AVSYS_AUDIO_PATH_OPTION_USE_SUBMIC) { + control->gain_status.capture |= GS_SUBMIC_TO_AP; + control->path_status.capture |= PS_SUBMIC_TO_AP; + cmd_gain[1] = INPUT_SUB_MIC | OUTPUT_AP | GAIN_MODE; + cmd_path[1] = INPUT_SUB_MIC | OUTPUT_AP; + } else { + control->gain_status.capture |= GS_MAINMIC_TO_AP; + control->path_status.capture |= PS_MAINMIC_TO_AP; + cmd_gain[1] = INPUT_MAIN_MIC | OUTPUT_AP | GAIN_MODE; + cmd_path[1] = INPUT_MAIN_MIC | OUTPUT_AP; + } + } + break; + + case AVSYS_AUDIO_PATH_EX_HEADSETMIC: + control->gain_status.capture |= GS_EARMIC_TO_AP; + control->path_status.capture |= PS_EARMIC_TO_AP; + cmd_gain[1] = INPUT_EAR_MIC | OUTPUT_AP | GAIN_MODE; + cmd_path[1] = INPUT_EAR_MIC | OUTPUT_AP; + break; + + case AVSYS_AUDIO_PATH_EX_BTMIC: + control->gain_status.capture |= GS_BTMIC_TO_AP; + control->path_status.capture |= PS_BTMIC_TO_AP; + cmd_gain[1] = INPUT_BT_MIC | OUTPUT_AP | GAIN_MODE; + cmd_path[1] = INPUT_BT_MIC | OUTPUT_AP; + + break; + case AVSYS_AUDIO_PATH_EX_HANDSFREE: + default: + break; + } + + if((control->p_path_status.playback != control->path_status.playback) + || ((control->p_path_status.capture != control->path_status.capture)) || control->gain_debug_mode == 1) { + if(!skip_clear) { + RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_single_set(ASCN_STR_RESET)) + } + RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_bulk_set(cmd_gain, 2, ASCN_RESET_NONE)) + control->p_gain_status = control->gain_status; /* both playback and capture */ + RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_bulk_set(cmd_path, 2, ASCN_RESET_NONE)) + control->p_path_status = control->path_status; /* both playback and capture */ + } + + return AVSYS_STATE_SUCCESS; +} + + +static int __avsys_audio_path_set_ascn_fmradio(avsys_audio_path_ex_info_t *control) +{ + int cmd_gain[2] = { 0, 0 }; + int cmd_path[3] = { 0, 0, 0 }; + int skip_clear = 0; + int skip_clear_record = 0; + int gain_idx = 0; + int path_idx = 0; + control->path_fixed = PATH_FIXED_WITH_FMRADIO; + switch (control->path.playback) { + case AVSYS_AUDIO_PATH_EX_NONE: + control->ear_auto = AVSYS_AUDIO_EAR_SWITCH_MANUAL; + control->gain_status.playback = GS_FMRADIO_TO_SPK; + control->path_status.playback = PS_PATH_NONE; + cmd_gain[gain_idx++] = INPUT_FMRADIO | OUTPUT_STEREO_SPK | GAIN_MODE; + break; + + case AVSYS_AUDIO_PATH_EX_SPK: + if (control->option.playback & AVSYS_AUDIO_PATH_OPTION_JACK_AUTO) { + control->ear_auto = AVSYS_AUDIO_EAR_SWITCH_AUTO_WITHOUT_MUTE; + if (control->reqgain.playback == control->gain.playback) { + if (control->inserted != AVSYS_AUDIO_INSERTED_NONE) { + control->gain_status.playback = GS_FMRADIO_TO_HEADSET; + control->path_status.playback = PS_FMRADIO_TO_HEADSET; + cmd_gain[gain_idx++] = INPUT_FMRADIO | OUTPUT_HEADSET | GAIN_MODE; + cmd_path[path_idx++] = INPUT_FMRADIO | OUTPUT_HEADSET; + cmd_path[path_idx++] = INPUT_AP | OUTPUT_HEADSET; + } else { + control->gain_status.playback = GS_FMRADIO_TO_SPK; + control->path_status.playback = PS_FMRADIO_TO_SPK; + cmd_gain[gain_idx++] = INPUT_FMRADIO | OUTPUT_STEREO_SPK | GAIN_MODE; + cmd_path[path_idx++] = INPUT_FMRADIO | OUTPUT_STEREO_SPK; + cmd_path[path_idx++] = INPUT_AP | OUTPUT_STEREO_SPK; + } + } else { + /* append ap playback sound path */ + control->path_status.playback = control->p_path_status.playback; + if (control->inserted != AVSYS_AUDIO_INSERTED_NONE) { + control->path_status.playback |= PS_AP_TO_HEADSET; + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET; + cmd_path[path_idx++] = INPUT_AP | OUTPUT_HEADSET; + } else { + control->path_status.playback |= PS_AP_TO_SPK; + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + cmd_path[path_idx++] = INPUT_AP | OUTPUT_STEREO_SPK; + } + skip_clear = 1; + } + } else { /* ear jack manual */ + control->ear_auto = AVSYS_AUDIO_EAR_SWITCH_MANUAL; + if (control->reqgain.playback == control->gain.playback) { + control->gain_status.playback = GS_FMRADIO_TO_SPK; + control->path_status.playback = PS_FMRADIO_TO_SPK; + cmd_gain[gain_idx++] = INPUT_FMRADIO | OUTPUT_STEREO_SPK | GAIN_MODE; + cmd_path[path_idx++] = INPUT_FMRADIO | OUTPUT_STEREO_SPK; + cmd_path[path_idx++] = INPUT_AP | OUTPUT_STEREO_SPK; + } else { + /* append ap playback sound path */ + control->path_status.playback = control->p_path_status.playback; + control->path_status.playback |= PS_AP_TO_SPK; + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + cmd_path[path_idx++] = INPUT_AP | OUTPUT_STEREO_SPK; + skip_clear = 1; + } + } + break; + + case AVSYS_AUDIO_PATH_EX_HEADSET: + control->ear_auto = AVSYS_AUDIO_EAR_SWITCH_MANUAL; + if (control->reqgain.playback == control->gain.playback) { + control->gain_status.playback = GS_FMRADIO_TO_HEADSET; + control->path_status.playback = PS_FMRADIO_TO_HEADSET; + cmd_gain[gain_idx++] = INPUT_FMRADIO | OUTPUT_HEADSET | GAIN_MODE; + cmd_path[path_idx++] = INPUT_FMRADIO | OUTPUT_HEADSET; + cmd_path[path_idx++] = INPUT_AP | OUTPUT_HEADSET; + } else { + /* append ap playback */ + control->path_status.playback = control->p_path_status.playback; + control->path_status.playback |= PS_AP_TO_HEADSET; + control->lvol_dev_type = AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET; + cmd_path[path_idx++] = INPUT_AP | OUTPUT_HEADSET; + skip_clear = 1; + } + break; + default: + break; + } + + switch (control->path.capture) { + case AVSYS_AUDIO_PATH_EX_FMINPUT: + if (control->reqgain.capture == control->gain.capture) { + control->path_status.capture |= PS_FMRADIO_TO_AP; + cmd_path[path_idx++] = INPUT_FMRADIO | OUTPUT_AP; + if (control->reqgain.capture == control->pregain.capture) { + skip_clear_record = 1; + } + } + break; + default: + break; + } + + if((control->p_path_status.playback != control->path_status.playback) + || (control->p_path_status.capture != control->path_status.capture) || control->gain_debug_mode == 1) { + if (skip_clear_record) { + RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_single_set(ASCN_STR_RESET_PLAYBACK)) + } else if (!skip_clear) { + RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_single_set(ASCN_STR_RESET)) + } + RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_bulk_set(cmd_gain, gain_idx, ASCN_RESET_NONE)) + control->p_gain_status = control->gain_status; /* both playback & capture */ + RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_bulk_set(cmd_path, path_idx, ASCN_RESET_NONE)) + control->p_path_status = control->path_status; /* both playback & capture */ + } + + return AVSYS_STATE_SUCCESS; +} + +static int __avsys_audio_path_set_ascn_ap_capture(avsys_audio_path_ex_info_t *control) +{ + int cmd_gain[2] = { 0, 0 }; + int cmd_path[3] = { 0, 0, 0 }; + + avsys_info(AVAUDIO, "<< path.capture = %d, option = %x, gain.capture = %d, inserted = %d\n", + control->path.capture, control->option.capture, control->gain.capture, control->inserted); + switch(control->path.capture) { + case AVSYS_AUDIO_PATH_EX_MIC: + if (control->option.capture & AVSYS_AUDIO_PATH_OPTION_JACK_AUTO) { + control->ear_auto = AVSYS_AUDIO_EAR_SWITCH_AUTO_WITH_MUTE; + if (control->inserted == AVSYS_AUDIO_INSERTED_4) { + control->gain_status.capture = GS_EARMIC_TO_AP; + control->path_status.capture = PS_EARMIC_TO_AP; + cmd_gain[0] = INPUT_EAR_MIC | OUTPUT_AP | GAIN_MODE; + cmd_path[0] = INPUT_EAR_MIC | OUTPUT_AP; + } else { + if (control->option.capture & AVSYS_AUDIO_PATH_OPTION_USE_SUBMIC) { + control->gain_status.capture = GS_SUBMIC_TO_AP; + control->path_status.capture = PS_SUBMIC_TO_AP; + cmd_gain[0] = INPUT_SUB_MIC | OUTPUT_AP | GAIN_MODE; + cmd_path[0] = INPUT_SUB_MIC | OUTPUT_AP; + } else if (control->option.capture & AVSYS_AUDIO_PATH_OPTION_USE_STEREOMIC) { + control->gain_status.capture = GS_STEREOMIC_TO_AP; + control->path_status.capture = PS_STEREOMIC_TO_AP; + cmd_gain[0] = INPUT_STEREO_MIC | OUTPUT_AP | GAIN_MODE; + cmd_path[0] = INPUT_STEREO_MIC | OUTPUT_AP; + } else { + control->gain_status.capture = GS_MAINMIC_TO_AP; + control->path_status.capture = PS_MAINMIC_TO_AP; + cmd_gain[0] = INPUT_MAIN_MIC | OUTPUT_AP | GAIN_MODE; + cmd_path[0] = INPUT_MAIN_MIC | OUTPUT_AP; + } + } + } else { + control->ear_auto = AVSYS_AUDIO_EAR_SWITCH_AUTO_WITHOUT_MUTE; + if (control->option.capture & AVSYS_AUDIO_PATH_OPTION_USE_SUBMIC) { + control->gain_status.capture = GS_SUBMIC_TO_AP; + control->path_status.capture = PS_SUBMIC_TO_AP; + cmd_gain[0] = INPUT_SUB_MIC | OUTPUT_AP | GAIN_MODE; + cmd_path[0] = INPUT_SUB_MIC | OUTPUT_AP; + } else if (control->option.capture & AVSYS_AUDIO_PATH_OPTION_USE_STEREOMIC) { + control->gain_status.capture = GS_STEREOMIC_TO_AP; + control->path_status.capture = PS_STEREOMIC_TO_AP; + cmd_gain[0] = INPUT_STEREO_MIC | OUTPUT_AP | GAIN_MODE; + cmd_path[0] = INPUT_STEREO_MIC | OUTPUT_AP; + } else { + control->gain_status.capture = GS_MAINMIC_TO_AP; + control->path_status.capture = PS_MAINMIC_TO_AP; + cmd_gain[0] = INPUT_MAIN_MIC | OUTPUT_AP | GAIN_MODE; + cmd_path[0] = INPUT_MAIN_MIC | OUTPUT_AP; + } + } + break; + + case AVSYS_AUDIO_PATH_EX_HEADSETMIC: + control->ear_auto = AVSYS_AUDIO_EAR_SWITCH_MANUAL; + control->gain_status.capture = GS_EARMIC_TO_AP; + control->path_status.capture = PS_EARMIC_TO_AP; + cmd_gain[0] = INPUT_EAR_MIC | OUTPUT_AP | GAIN_MODE; + cmd_path[0] = INPUT_EAR_MIC | OUTPUT_AP; + break; + + default: + break; + } + + if ((control->p_path_status.capture != control->path_status.capture) || control->gain_debug_mode == 1) { + RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_bulk_set(cmd_gain, 2, ASCN_RESET_CAPTURE)) + control->p_gain_status.capture = control->gain_status.capture; + RET_IO_CTL_ERR_IF_FAIL(avsys_audio_ascn_bulk_set(cmd_path, 2, ASCN_RESET_NONE)) + control->p_path_status.capture = control->path_status.capture; + } + + avsys_info (AVAUDIO, ">> leave"); + + return AVSYS_STATE_SUCCESS; +} + + +static int __avsys_audio_path_set_hw_controls(avsys_audio_path_ex_info_t *control) +{ + avsys_audio_handle_info_t *handle_control = NULL; + avsys_audio_handle_info_t **temp = NULL; + int ret = AVSYS_STATE_SUCCESS; + avsys_info(AVAUDIO, "global mute %d\n", control->mute); + avsys_info(AVAUDIO, "path_fixed mute %d\n", control->path_fixed); + + /* update logical volume table - about output device - information for open handles */ + avsys_info(AVAUDIO, "Control handle informations\n"); + { + avsys_audio_handle_t *ptr = NULL; + int handle = -1; + int out_device = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + + temp = &handle_control; + if (AVSYS_FAIL(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_HANDLE, (void**)temp))) { + avsys_error(AVAUDIO, "avsys_audio_get_shm() failed in %s\n",__func__); + return AVSYS_STATE_ERR_INTERNAL; + } + + if (AVSYS_FAIL(avsys_audio_lock_sync(AVSYS_AUDIO_SYNC_IDEN_HANDLE))) { + avsys_error(AVAUDIO, "avsys_audio_lock_sync() failed in %s\n",__func__); + return AVSYS_STATE_ERR_INTERNAL; + } + + while (++handle < AVSYS_AUDIO_HANDLE_MAX) { + long long int flag = 0x01; + flag <<= handle; + + if (handle_control->allocated & flag) + { + ptr = &(handle_control->handles[handle]); + + if (ptr->mode != AVSYS_AUDIO_MODE_OUTPUT && ptr->mode != AVSYS_AUDIO_MODE_OUTPUT_CLOCK + && ptr->mode != AVSYS_AUDIO_MODE_OUTPUT_LOW_LATENCY && ptr->mode != AVSYS_AUDIO_MODE_OUTPUT_AP_CALL) { + continue; + } + ptr->path_off = 0; + out_device = control->lvol_dev_type; + if (control->path_status.playback == PS_PATH_NONE) { + ptr->path_off = 1; + avsys_warning(AVAUDIO, "Path off status...set logical volume device type to speaker\n"); + out_device = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + } + avsys_audio_logical_volume_update_table(out_device, &ptr->gain_setting); + avsys_audio_logical_volume_convert(&ptr->setting_vol, &ptr->working_vol, &ptr->gain_setting); + } + } + + if(AVSYS_FAIL(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_HANDLE))) { + avsys_error(AVAUDIO,"avsys_audio_unlock_sync() failed in %s\n",__func__); + return AVSYS_STATE_ERR_INTERNAL; + } + } + return AVSYS_STATE_SUCCESS; +} + +static bool __avsys_audio_path_check_cp_audio(int gain) +{ + /*If video call uses CP audio, add AVSYS_AUDIO_GAIN_EX_VIDEOCALL to following code. */ + if (gain == AVSYS_AUDIO_GAIN_EX_VOICECALL) + return true; + else + return false; +} + +int avsys_audio_path_set_volume(int handle) +{ + avsys_audio_path_ex_info_t *control = NULL; + avsys_audio_path_ex_info_t **temp = NULL; + avsys_audio_handle_t *ptr = NULL; + int err; + int gain_type; + int out_device = AVSYS_AUDIO_DEVICE_TYPE_SPK; + + err = avsys_audio_handle_get_ptr(handle, &ptr, HANDLE_PTR_MODE_NORMAL); + if (AVSYS_FAIL(err)) { + avsys_error(AVAUDIO, "Handle is not allocated\n"); + avsys_audio_handle_release_ptr(handle, HANDLE_PTR_MODE_NORMAL); + return AVSYS_STATE_ERR_INVALID_PARAMETER; + } + + temp = &control; + avsys_assert(AVSYS_SUCCESS(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp))); + avsys_assert(control != NULL); + avsys_assert(AVSYS_SUCCESS(avsys_audio_lock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))); + + if (__avsys_audio_path_check_cp_audio(control->gain.playback)) + ptr->during_cp_audio = 1; + else + ptr->during_cp_audio = 0; + + gain_type = ptr->gain_setting.vol_type; + out_device = control->lvol_dev_type; + if (control->path_status.playback == PS_PATH_NONE) { + ptr->path_off = 1; + avsys_warning(AVAUDIO, "Path off status...set logical volume device type to speaker\n"); + out_device = AVSYS_AUDIO_LVOL_DEV_TYPE_SPK; + } + avsys_assert(AVSYS_SUCCESS(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))); + avsys_warning(AVAUDIO, "set path volume : gain(%d), out_dev(%d)\n", gain_type, out_device); + err = avsys_audio_logical_volume_set_table(gain_type, out_device, &ptr->gain_setting); + avsys_audio_handle_release_ptr(handle, HANDLE_PTR_MODE_NORMAL); + return err; +} + +int avsys_audio_path_set_route_policy(avsys_audio_route_policy_t route) +{ + avsys_audio_path_ex_info_t *control = NULL; + avsys_audio_path_ex_info_t **temp = NULL; + int err = AVSYS_STATE_SUCCESS; + + temp = &control; + avsys_assert(AVSYS_SUCCESS(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp))); + avsys_assert(control != NULL); + avsys_assert(AVSYS_SUCCESS(avsys_audio_lock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))); + + control->route_policy = route; + + avsys_assert(AVSYS_SUCCESS(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))); + return err; +} + +int avsys_audio_path_get_route_policy(avsys_audio_route_policy_t *route) +{ + avsys_audio_path_ex_info_t *control = NULL; + avsys_audio_path_ex_info_t **temp = NULL; + int err = AVSYS_STATE_SUCCESS; + + if (!route) + return AVSYS_STATE_ERR_INVALID_PARAMETER; + + temp = &control; + avsys_assert(AVSYS_SUCCESS(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp))); + avsys_assert(control != NULL); + avsys_assert(AVSYS_SUCCESS(avsys_audio_lock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))); + + *route = control->route_policy; + + avsys_assert(AVSYS_SUCCESS(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))); + return err; +} + +int avsys_audio_path_check_loud(bool *loud) +{ + avsys_audio_path_ex_info_t *control = NULL; + avsys_audio_path_ex_info_t **temp = NULL; + int err = AVSYS_STATE_SUCCESS; + + if (!loud) + return AVSYS_STATE_ERR_INVALID_PARAMETER; + + temp = &control; + avsys_assert(AVSYS_SUCCESS(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp))); + avsys_assert(control != NULL); + avsys_assert(AVSYS_SUCCESS(avsys_audio_lock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))); + + if ((control->path_status.playback & PS_AP_TO_SPK) || + (control->path_status.playback & PS_AP_TO_RECV) || + (control->path_status.playback & PS_FMRADIO_TO_SPK)) { + *loud = true; + } else { + avsys_info(AVAUDIO, "playback path status 0x%x\n", control->path_status.playback); + *loud = false; + } + + avsys_assert(AVSYS_SUCCESS(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))); + return err; +} + +int avsys_audio_path_check_cp_audio(bool *cpaudio, bool *btpath) +{ + avsys_audio_path_ex_info_t *control = NULL; + avsys_audio_path_ex_info_t **temp = NULL; + + if (!cpaudio || !btpath) + return AVSYS_STATE_ERR_INVALID_PARAMETER; + + temp = &control; + avsys_assert(AVSYS_SUCCESS(avsys_audio_get_shm(AVSYS_AUDIO_SHM_IDEN_PATH, (void **)temp))); + avsys_assert(control != NULL); + avsys_assert(AVSYS_SUCCESS(avsys_audio_lock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))); + + if (__avsys_audio_path_check_cp_audio(control->gain.playback)) + *cpaudio = true; + else + *cpaudio = false; + + if (control->path.playback == AVSYS_AUDIO_PATH_EX_BTHEADSET) + *btpath = true; + else + *btpath = false; + + avsys_assert(AVSYS_SUCCESS(avsys_audio_unlock_sync(AVSYS_AUDIO_SYNC_IDEN_PATH))); + return AVSYS_STATE_SUCCESS; +} + +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_single_set(str)) + + return AVSYS_STATE_SUCCESS; +} diff --git a/avsys-audio-shm.c b/avsys-audio-shm.c new file mode 100644 index 0000000..850f59f --- /dev/null +++ b/avsys-audio-shm.c @@ -0,0 +1,72 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi <jhchoi.choi@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "avsys-audio-shm.h" +#include "avsys-common.h" +#include "avsys-error.h" +#include "avsys-audio-handle.h" +#include "avsys-audio-path.h" +#include "avsys-audio-logical-volume.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}, + {{SHM_KEY_PATH, AVSYS_KEY_PREFIX_GEN(AVSYS_KEY_PREFIX_AUDIO,AVSYS_AUDIO_SHM_IDEN_LVOLUME) + 0x10,sizeof(avsys_logical_gain_t) * AVSYS_AUDIO_LVOL_GAIN_TYPE_MAX}, 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..dac16db --- /dev/null +++ b/avsys-audio-sync.c @@ -0,0 +1,244 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi <jhchoi.choi@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include <string.h> +#include <dirent.h> +#include <errno.h> +#include <sys/types.h> +#include <unistd.h> + +#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)}, + {"audio_route_policy_lock", AVSYS_KEY_PREFIX_GEN(AVSYS_KEY_PREFIX_AUDIO, AVSYS_AUDIO_SYNC_IDEN_SOUNDPATH)}, + {"av_volume_sem", AVSYS_KEY_PREFIX_GEN(AVSYS_KEY_PREFIX_AUDIO, AVSYS_AUDIO_SYNC_IDEN_VOLUME)}, +}; + +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 in %s\n", __func__); + 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_critical(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_critical(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 in %s\n", __func__); + 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_critical(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_critical(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 in %s\n", __func__); + 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 in %s\n", __func__); + 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, "[%s] closedir failed with errno : %d\n", __func__, 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 100644 index 0000000..8ce7538 --- /dev/null +++ b/avsys-audio.c @@ -0,0 +1,908 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi <jhchoi.choi@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <pthread.h> +#include <time.h> +#include <sys/types.h> +#include <sys/time.h> +#include <unistd.h> +#include <sys/syscall.h> +#include <signal.h> +#include <string.h> +#include <fcntl.h> + +#include "avsys-types.h" +#include "avsys-error.h" +#include "avsys-debug.h" +#include "avsys-audio.h" +#include "avsys-audio-logical-volume.h" +#include "avsys-common.h" + +#include "avsys-audio-path.h" +#include "avsys-audio-alsa.h" + +#include "avsys-audio-pasimple.h" +#include "avsys-audio-pactrl.h" + +/** + * Internal functions definition + */ +#define FADEUP_CALC_BIAS (1) + +static int __avsys_audio_set_info(avsys_audio_handle_t *p, 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) + +/** + * Internal global variable + */ + +/**************************************************************************** + * + * Interface + * + ***************************************************************************/ +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; + + avsys_info(AVAUDIO, "%s\n", __func__); + + if (param == NULL || phandle == NULL) { + avsys_error(AVAUDIO, "param or phandle is null\n"); + return AVSYS_STATE_ERR_NULL_POINTER; + } + + if (param->channels > 2 || param->channels < 1) { + 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; + } + + err = avsys_audio_handle_rejuvenation(); + if (AVSYS_FAIL(err)) { + avsys_error(AVAUDIO, "Unused handle cleanup before handle allocation failed in %s\n", __func__); + goto error; + } + err = avsys_audio_handle_alloc(&handle); + 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 in %s\n", __func__); + goto error; + } + avsys_error(AVAUDIO, "one more try...to allocate audio handle\n"); + err = avsys_audio_handle_alloc(&handle); + if (AVSYS_FAIL(err)) { + avsys_error(AVAUDIO, "handle alloc failed 1 in %s\n", __func__); + goto error; + } + } else if ((AVSYS_FAIL(err)) && (err != AVSYS_STATE_ERR_RANGE_OVER)) { + avsys_error(AVAUDIO, "handle alloc failed 2 in %s\n", __func__); + goto error; + } + + err = avsys_audio_handle_get_ptr(handle, &p, HANDLE_PTR_MODE_NORMAL); + if (AVSYS_FAIL(err)) { + goto error; + } + + /* set information to handle */ + err = __avsys_audio_set_info(p, param); + if (AVSYS_FAIL(err)) { + 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) { + /* set volume table */ + err = avsys_audio_path_set_volume(handle); + if (AVSYS_FAIL(err)) { + goto error; + } + + /* update volume by type */ + err = avsys_audio_handle_update_volume(p, p->gain_setting.vol_type); + if (AVSYS_FAIL(err)) { + goto error; + } + err = avsys_audio_handle_update_priority(handle, param->priority, param->bluetooth, AVSYS_AUDIO_SET_PRIORITY); + if (AVSYS_FAIL(err)) { + goto error; + } + } + + /* open device */ + err = avsys_audio_pasimple_open_device(p->mode, p->format, p->channels, p->samplerate, p, param->bluetooth); + if (AVSYS_FAIL(err)) { + goto error; + } + switch (p->mode) { + case AVSYS_AUDIO_MODE_OUTPUT: + case AVSYS_AUDIO_MODE_OUTPUT_CLOCK: + case AVSYS_AUDIO_MODE_OUTPUT_LOW_LATENCY: + case AVSYS_AUDIO_MODE_OUTPUT_VIDEO: + case AVSYS_AUDIO_MODE_OUTPUT_AP_CALL: + if (AVSYS_FAIL(avsys_audio_pasimple_set_volume(p, p->working_vol.level[AVSYS_AUDIO_CHANNEL_LEFT]))) { + avsys_error(AVAUDIO, "can not set volume in %s\n", __func__); + } + break; + default: + break; + } + + *phandle = (avsys_handle_t) handle; + /* set recommended buffer size */ + if (size != NULL) + *size = p->period; + else + avsys_warning(AVAUDIO, "Size is null\n"); + + err = avsys_audio_handle_release_ptr(handle, HANDLE_PTR_MODE_NORMAL); + if (AVSYS_FAIL(err)) { + goto error; + } + + return AVSYS_STATE_SUCCESS; + +error: + if (p) { + 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 : RESION %x\n", err); + + *phandle = (avsys_handle_t)-1; + + return err; +} + +EXPORT_API +int avsys_audio_close(avsys_handle_t handle) +{ + avsys_audio_handle_t *p = NULL; + int err = AVSYS_STATE_ERR_UNKNOWN; + bool cp_audio = false; + bool bt_path = false; + + avsys_info(AVAUDIO, "%s, handle=[%d]\n", __func__, (int)handle); + + AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + 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); + } + + err = avsys_audio_pasimple_close_device(p); + if (AVSYS_FAIL(err)) { + avsys_error_r(AVAUDIO, "audio device close error : %x\n", err); + } + + if (AVSYS_FAIL(avsys_audio_path_check_cp_audio(&cp_audio, &bt_path))) { + avsys_error(AVAUDIO, "Can not check cp audio status\n"); + } + + if (p->during_cp_audio && cp_audio && bt_path) { + /* set cp bt path again */ + avsys_audio_path_set_single_ascn("cp_to_bt"); + } + + AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + avsys_audio_handle_free((int)handle); + + return err; +} + +EXPORT_API +int avsys_audio_ampon(void) +{ + avsys_info(AVAUDIO, "%s\n", __func__); + return avsys_audio_path_ex_set_amp(AVSYS_AUDIO_AMP_ON); +} + +EXPORT_API +int avsys_audio_ampoff(void) +{ + avsys_info(AVAUDIO, "%s\n", __func__); + 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) +{ + avsys_info(AVAUDIO, "%s\n", __func__); + 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) +{ + avsys_info(AVAUDIO, "%s\n", __func__); + 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) +{ + avsys_info(AVAUDIO, "%s\n", __func__); + 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) +{ + avsys_info(AVAUDIO, "%s\n", __func__); + 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, "%s\n", __func__); + + 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, "%s\n", __func__); + + 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; + + avsys_info(AVAUDIO, "%s\n", __func__); + + 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); + + 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; + + avsys_info(AVAUDIO, "%s\n", __func__); + + 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_volume_t fade_volume; + fade_volume.level[AVSYS_AUDIO_CHANNEL_LEFT] = p->setting_vol.level[AVSYS_AUDIO_CHANNEL_LEFT] - (p->fadeup_vol - FADEUP_CALC_BIAS); + fade_volume.level[AVSYS_AUDIO_CHANNEL_RIGHT] = p->setting_vol.level[AVSYS_AUDIO_CHANNEL_LEFT] - (p->fadeup_vol - FADEUP_CALC_BIAS); + + if (fade_volume.level[AVSYS_AUDIO_CHANNEL_LEFT] < 0) { + fade_volume.level[AVSYS_AUDIO_CHANNEL_LEFT] = 0; + } + if (fade_volume.level[AVSYS_AUDIO_CHANNEL_RIGHT] < 0) { + fade_volume.level[AVSYS_AUDIO_CHANNEL_RIGHT] = 0; + } + + avsys_info(AVAUDIO, "fade_volume : %d (%d-(%d)+%d) p->fadeup_m = %d, p->msec_per_period = %d\n", + fade_volume.level[AVSYS_AUDIO_CHANNEL_LEFT],p->setting_vol.level[AVSYS_AUDIO_CHANNEL_LEFT],p->fadeup_vol,FADEUP_CALC_BIAS, + p->fadeup_multiplier, p->msec_per_period + ); + + avsys_audio_logical_volume_convert(&fade_volume, &p->working_vol, &p->gain_setting); + avsys_audio_pasimple_set_volume(p, p->working_vol.level[AVSYS_AUDIO_CHANNEL_LEFT]); + p->fadeup_vol--; + if (p->msec_per_period > 50) + p->fadeup_multiplier = 0; + else + p->fadeup_multiplier = FADE_UP_MULTIPLIER; + } else { + p->fadeup_multiplier--; + } + } else if (p->fadeup_vol <= -1) { + if (p->fadeup_multiplier == 0) { + int fadedown_vol = 0; + avsys_audio_volume_t fade_volume; + + fadedown_vol = (-1) * (p->fadeup_vol) - FADEUP_CALC_BIAS; + fade_volume.level[AVSYS_AUDIO_CHANNEL_LEFT] = fadedown_vol; + fade_volume.level[AVSYS_AUDIO_CHANNEL_RIGHT] = fadedown_vol; + + if (fade_volume.level[AVSYS_AUDIO_CHANNEL_LEFT] < 0) { + fade_volume.level[AVSYS_AUDIO_CHANNEL_LEFT] = 0; + } + if (fade_volume.level[AVSYS_AUDIO_CHANNEL_RIGHT] < 0) { + fade_volume.level[AVSYS_AUDIO_CHANNEL_RIGHT] = 0; + } + + avsys_info(AVAUDIO, "fade_volume : %d (%d-%d) p->fadeup_m = %d, p->msec_per_period = %d\n", + fade_volume.level[AVSYS_AUDIO_CHANNEL_LEFT],p->fadeup_vol,FADEUP_CALC_BIAS, + p->fadeup_multiplier, p->msec_per_period); + + avsys_audio_logical_volume_convert(&fade_volume, &p->working_vol, &p->gain_setting); + avsys_audio_pasimple_set_volume(p, p->working_vol.level[AVSYS_AUDIO_CHANNEL_LEFT]); + if (p->fadeup_vol < -1) { + p->fadeup_vol++; + } else if (p->fadeup_vol == -1) { + p->mute = AVSYS_AUDIO_MUTE; + } + if (p->msec_per_period > 50) + p->fadeup_multiplier = 0; + else + p->fadeup_multiplier = FADE_DOWN_MULTIPLIER; + } else { + p->fadeup_multiplier--; + } + } + err = avsys_audio_pasimple_write(p, buf, size); + + 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, "%s\n", __func__); + + AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + if (p->setting_vol.level[AVSYS_AUDIO_CHANNEL_LEFT] >= p->setting_vol.level[AVSYS_AUDIO_CHANNEL_RIGHT]) { + p->fadeup_vol = p->setting_vol.level[AVSYS_AUDIO_CHANNEL_LEFT]; /* + FADEUP_CALC_BIAS */ + } else { + p->fadeup_vol = p->setting_vol.level[AVSYS_AUDIO_CHANNEL_RIGHT]; /* + FADEUP_CALC_BIAS; */ + } + 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, "%s\n", __func__); + + AVSYS_GET_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + if (p->setting_vol.level[AVSYS_AUDIO_CHANNEL_LEFT] >= p->setting_vol.level[AVSYS_AUDIO_CHANNEL_RIGHT]) { + p->fadeup_vol = (-1) * p->setting_vol.level[AVSYS_AUDIO_CHANNEL_LEFT]; + } else { + p->fadeup_vol = (-1) * p->setting_vol.level[AVSYS_AUDIO_CHANNEL_RIGHT]; + } + p->fadeup_multiplier = 0; + + AVSYS_RELEASE_HANDLE_PTR(HANDLE_PTR_MODE_NORMAL); + + return err; +} + +/* Tuning part */ +EXPORT_API +int avsys_audio_set_volume_table(int gain_type, int dev_type, int step, int lv, int rv) +{ + int ret = avsys_audio_logical_volume_set_to_table(gain_type, dev_type, step, lv, rv); + avsys_audio_handle_t *ptr = NULL; + int handle = -1; + + if (AVSYS_FAIL(ret)) { + return ret; + } + + while(++handle < AVSYS_AUDIO_HANDLE_MAX) { + ptr = NULL; + + if (AVSYS_SUCCESS(avsys_audio_handle_get_ptr(handle, &ptr, HANDLE_PTR_MODE_NORMAL))) { + avsys_audio_logical_volume_convert(&ptr->setting_vol, &ptr->working_vol, &ptr->gain_setting); + avsys_audio_handle_release_ptr(handle, HANDLE_PTR_MODE_NORMAL); + } + } + return AVSYS_STATE_SUCCESS; +} + +EXPORT_API +int avsys_audio_get_volume_table(int gain_type, int dev_type, int step, int *lv, int *rv) +{ + return avsys_audio_logical_volume_get_from_table(gain_type, dev_type, step, lv, rv); +} + +EXPORT_API +int avsys_audio_get_volume_max_ex(int volume_type, int *max_step) +{ + int volume_table = 0; + if (max_step == NULL) { + return AVSYS_STATE_ERR_NULL_POINTER; + } + + volume_table = volume_type; + + return avsys_audio_logical_volume_get_max(volume_table, AVSYS_AUDIO_LVOL_DEV_TYPE_SPK, max_step); +} + +EXPORT_API +int avsys_audio_set_mute(avsys_handle_t handle, int mute) +{ + avsys_info(AVAUDIO, "%s\n", __func__); + + 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, "%s\n", __func__); + + 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, "%s : mute=%d\n", __func__, 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, "%s\n", __func__); + 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) +{ + avsys_info(AVAUDIO, "%s\n", __func__); + + avsys_info(AVAUDIO, "=============================================\n"); + avsys_info(AVAUDIO, " Input Parameters (Basic Information)\n"); + avsys_info(AVAUDIO, "=============================================\n"); + avsys_info(AVAUDIO, " Op Mode = %d (0:out, 1:input)\n", param->mode); + avsys_info(AVAUDIO, " format = %d (0: 8bits, 1:16bits, 2:32bits)\n", param->format); + avsys_info(AVAUDIO, " channel = %d\n", param->channels); + avsys_info(AVAUDIO, " samplerate = %d\n", param->samplerate); + avsys_info(AVAUDIO, " route = %d (0: default, 1: handset)\n", param->bluetooth); + avsys_info(AVAUDIO, " Vol type = %d\n", param->vol_type); + avsys_info(AVAUDIO, "=============================================\n"); + + p->mode = param->mode; + p->channels = param->channels; + p->samplerate = param->samplerate; + p->format = param->format; + p->priority = param->priority; + + if ((param->vol_type < 0) || (param->vol_type >= AVSYS_AUDIO_VOLUME_TYPE_MAX)) { + avsys_error(AVAUDIO, "[%s] Invalid volume type %d. use default system type\n", __func__, param->vol_type); + p->gain_setting.vol_type = AVSYS_AUDIO_VOLUME_TYPE_SYSTEM; + } else { + p->gain_setting.vol_type = param->vol_type; + } + + /* trivial volume value */ + p->setting_vol.level[AVSYS_AUDIO_CHANNEL_LEFT] = 0; + p->setting_vol.level[AVSYS_AUDIO_CHANNEL_RIGHT] = 0; + p->working_vol.level[AVSYS_AUDIO_CHANNEL_LEFT] = 0; + p->working_vol.level[AVSYS_AUDIO_CHANNEL_RIGHT] = 0; + p->fadeup_vol = 0; + + return AVSYS_STATE_SUCCESS; +} + +EXPORT_API +int avsys_audio_earjack_manager_init(int *earjack_type, int *waitfd) +{ + return avsys_audio_path_earjack_init(earjack_type, waitfd); +} + +EXPORT_API +int avsys_audio_earjack_manager_wait(int waitfd, int *current_earjack_type, int *new_earjack_type, int *need_mute) +{ + return avsys_audio_path_earjack_wait(waitfd, current_earjack_type, new_earjack_type, need_mute); +} + +EXPORT_API +int avsys_audio_earjack_manager_process(int new_earjack_type) +{ + return avsys_audio_path_earjack_process(new_earjack_type); +} + +EXPORT_API +int avsys_audio_earjack_manager_deinit(int waitfd) +{ + return avsys_audio_path_earjack_deinit(waitfd); +} + +EXPORT_API +int avsys_audio_earjack_manager_unlock(void) +{ + return avsys_audio_path_earjack_unlock(); +} + +EXPORT_API +int avsys_audio_set_route_policy(avsys_audio_route_policy_t route) +{ + return avsys_audio_path_set_route_policy(route); +} + +EXPORT_API +int avsys_audio_get_route_policy(avsys_audio_route_policy_t *route) +{ + if (route == NULL) + return AVSYS_STATE_ERR_NULL_POINTER; + return avsys_audio_path_get_route_policy(route); +} + +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_ALARM: + case AVSYS_AUDIO_VOLUME_TYPE_CALL: + if (value >= LVOLUME_MAX_BASIC) { + return -1; + } + break; + 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_MEDIA_HL: + case AVSYS_AUDIO_VOLUME_TYPE_EXT_SYSTEM_JAVA: + if (value >= LVOLUME_MAX_MULTIMEDIA) { + return -1; + } + break; + case AVSYS_AUDIO_VOLUME_TYPE_EXT_SYSTEM_ANDROID: + if (value >= LVOLUME_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) +{ + 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_handle_update_volume_by_type(type, value); +} + +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_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; + +} + +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_get_playing_device_info(avsys_audio_playing_devcie_t *dev) +{ + int err = AVSYS_STATE_SUCCESS; + int sink_info = 0; + bool alsa_loud = false; + + if (!dev) + return AVSYS_STATE_ERR_INVALID_PARAMETER; + + err = avsys_audio_pa_ctrl_get_default_sink(&sink_info); + if (AVSYS_FAIL(err)) + return err; + + switch (sink_info) { + case AVSYS_AUDIO_PA_CTL_SINK_UNKNOWN: + avsys_error_r(AVAUDIO, "Unexpected sink information\n"); + err = AVSYS_STATE_ERR_UNAVAILABLE_DEVICE; + break; + case AVSYS_AUDIO_PA_CTL_SINK_ALSA: + err = avsys_audio_path_check_loud(&alsa_loud); + if (AVSYS_FAIL(err)) + break; + if (alsa_loud == true) + *dev = AVSYS_AUDIO_ROUTE_DEVICE_HANDSET; + else + *dev = AVSYS_AUDIO_ROUTE_DEVICE_EARPHONE; + break; + case AVSYS_AUDIO_PA_CTL_SINK_BLUEZ: + *dev = AVSYS_AUDIO_ROUTE_DEVICE_BLUETOOTH; + break; + } + + return err; +} + +EXPORT_API +int avsys_audio_get_capture_status(int *on_capture) +{ + return avsys_audio_handle_current_capture_status(on_capture); +} + +__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..91f080e --- /dev/null +++ b/avsys-common.c @@ -0,0 +1,368 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi <jhchoi.choi@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "avsys-common.h" +#include "avsys-debug.h" +#include "avsys-error.h" + +#include <stdio.h> +#include <memory.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> +#include <pwd.h> +#include <sys/ipc.h> +#include <sys/shm.h> +#include <time.h> + +#define RETRY_EINTR +#include <fcntl.h> +#include <semaphore.h> + +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 in %s (%d)\n",__func__,__LINE__); + break; + case ENFILE: + avsys_error(AVAUDIO,"Too many open files in system %s (%d)\n",__func__,__LINE__); + 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; + + 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: + wait_time.tv_sec = (long int)(time(NULL)) + LOCK_TIMEOUT_SEC; + wait_time.tv_nsec = 0; + ret = sem_timedwait(sem, &wait_time); + if(ret == -1) { + switch(errno) + { + case EINTR: + avsys_critical(AVAUDIO, "Lock RETRY LOCK\n"); + goto retry_lock; + break; + case EINVAL: + avsys_critical(AVAUDIO, "Invalid semaphore\n"); + err = AVSYS_STATE_ERR_INTERNAL; + break; + case EAGAIN: + avsys_critical(AVAUDIO, "EAGAIN\n"); + err = AVSYS_STATE_ERR_INTERNAL; + break; + case ETIMEDOUT: + avsys_critical(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_critical(AVAUDIO,"%s sem value is %d\n",param->key_path, sem_value); + if (sem_value == 0) { + ret = sem_post(sem); + if (ret == -1) { + avsys_critical(AVAUDIO,"sem_post error %s : %d\n", param->key_path, sem_value); + } else { + avsys_critical_r(AVAUDIO,"lock recovery success...try lock again\n"); + goto retry_lock; + } + } else { + avsys_critical(AVAUDIO,"sem value is not 0. but failed sem_timedwait so retry.. : %s\n",param->key_path); + usleep(5); + goto retry_lock; + } + } else { + avsys_critical(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_critical(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_critical(AVAUDIO,"sem_getvalue failed : %s\n",param->key_path); + } + + sem_close(sem); + return err; +} diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..cd205b4 --- /dev/null +++ b/configure.ac @@ -0,0 +1,102 @@ +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"]) + +# 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) + +# 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 +init/Makefile +]) +AC_OUTPUT diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..62ad286 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,7 @@ +avsystem (0.4.13-1) unstable; urgency=low + + * Initial release + * Git: slp/pkgs/a/avsystem + * Tag: avsystem_0.4.13-1 + + -- Hyunseok Lee <hs7388.lee@samsung.com> Wed, 08 Feb 2012 09:56:41 +0900
\ No newline at end of file diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +5 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..096b56b --- /dev/null +++ b/debian/control @@ -0,0 +1,33 @@ +Source: avsystem +Priority: optional +Maintainer: Seungbae Shin <seungbae.shin@samsung.com>, Jeongmo Yang <jm80.yang@samsung.com>, JongHyuk Choi <jhchoi.choi@samsung.com> +Uploaders: YoungHwan Ahn <younghwan_.an@samsung.com> +Build-Depends: debhelper (>= 5), autotools-dev, libasound2-dev, libascenario-dev, libmm-log-dev, libexif-dev, iniparser-dev, libmm-ta-dev, libpulse-dev +Standards-Version: 3.7.2 +Section: libs + +Package: libavsystem-dev +XB-Public-Package: no +Section: libdevel +Architecture: any +Depends: libavsystem-0 (= ${Source-Version}), libavsystem-sdk-dev, libasound2-dev, libpulse-dev +Description: avsystem library development package for sdk build + +Package: libavsystem-sdk-dev +Section: libdevel +Architecture: any +Depends: libavsystem-0 (= ${Source-Version}), libasound2-sdk-dev, libascenario-dev, libmm-log-sdk-dev, libexif-dev, libmm-ta-sdk-dev, libpulse-dev +Description: avsystem library development package for sdk release + +Package: libavsystem-0 +Section: libs +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: avsystem multimedia library package + avsystem provide low level sound / camera / video control method + +Package: libavsystem-0-dbg +Section: debug +Architecture: any +Depends: ${misc:Depends}, libavsystem-0 (= ${Source-Version}) +Description: avsystem library debug package (unstripped) diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..5ff3972 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,16 @@ +Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + +Contact: Jonghyuk Choi <jhchoi.choi@samsung.com> + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + diff --git a/debian/dirs b/debian/dirs new file mode 100644 index 0000000..ca882bb --- /dev/null +++ b/debian/dirs @@ -0,0 +1,2 @@ +usr/bin +usr/sbin diff --git a/debian/docs b/debian/docs new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/docs diff --git a/debian/libavsystem-0.install.in b/debian/libavsystem-0.install.in new file mode 100644 index 0000000..23fff44 --- /dev/null +++ b/debian/libavsystem-0.install.in @@ -0,0 +1,5 @@ +# if your module, creates shared libraries +@PREFIX@/lib/*.so* +@PREFIX@/bin/* +/etc/rc.d/* + diff --git a/debian/libavsystem-dev.install.in b/debian/libavsystem-dev.install.in new file mode 100644 index 0000000..93c1cf5 --- /dev/null +++ b/debian/libavsystem-dev.install.in @@ -0,0 +1,3 @@ +# if your module creates shared libraries +@PREFIX@/include/* + diff --git a/debian/libavsystem-sdk-dev.install.in b/debian/libavsystem-sdk-dev.install.in new file mode 100644 index 0000000..35f395e --- /dev/null +++ b/debian/libavsystem-sdk-dev.install.in @@ -0,0 +1,5 @@ +# if your module creates shared libraries +@PREFIX@/lib/*.la +@PREFIX@/lib/*.a +@PREFIX@/lib/pkgconfig/* + diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..7e1bbe7 --- /dev/null +++ b/debian/rules @@ -0,0 +1,138 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# This file was originally written by Joey Hess and Craig Small. +# As a special exception, when this file is copied by dh-make into a +# dh-make output file, you may use that output file without restriction. +# This special exception was added by Craig Small in version 0.37 of dh-make. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + + +# These are used for cross-compiling and for saving the configure script +# from having to guess our platform (since we know it already) +DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) +DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) +DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH) +DEB_HOST_ARCH_OS ?= $(shell dpkg-architecture -qDEB_HOST_GNU_OS) + +CFLAGS ?= -Wall -g +LDFLAGS ?= +PREFIX ?= /usr +DATADIR ?= /opt + +ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) + CFLAGS += -O0 -fPIC +else + CFLAGS += -O2 -fPIC +endif + +# architecture is not arm +ifneq (, $(findstring arm, $(DEB_HOST_ARCH))) + # do something here for arm architecture + OPTION= +else + # do something here + OPTION= --enable-sdk +endif + +LDFLAGS += -Wl,--rpath=$(PREFIX)/lib -Wl,--hash-style=both -Wl,--as-needed + +configure: configure.ac + dh_buildinfo generate cat + ./autogen.sh + +config.status: configure + dh_testdir + # Add here commands to configure the package. + CFLAGS="$(CFLAGS) -DGST_EXT_TIME_ANALYSIS" LDFLAGS="$(LDFLAGS)" ./configure --prefix=$(PREFIX) $(OPTION) + +build: build-stamp + +build-stamp: config.status + dh_testdir + + # Add here commands to compile the package. + $(MAKE) + #docbook-to-man debian/ncurses.sgml > ncurses.1 + + for f in `find $(CURDIR)/debian/ -name "*.in"`; do \ + cat $$f > $${f%.in}; \ + sed -i -e "s#@PREFIX@#$(PREFIX)#g" $${f%.in}; \ + sed -i -e "s#@DATADIR@#$(DATADIR)#g" $${f%.in}; \ + done + + touch $@ + +clean: + dh_testdir + dh_testroot + rm -f build-stamp + + # Add here commands to clean up after the build process. + -$(MAKE) distclean +ifneq "$(wildcard /usr/share/misc/config.sub)" "" + cp -f /usr/share/misc/config.sub config.sub +endif +ifneq "$(wildcard /usr/share/misc/config.guess)" "" + cp -f /usr/share/misc/config.guess config.guess +endif + + for f in `find $(CURDIR)/debian/ -name "*.in"`; do \ + rm -f $${f%.in}; \ + done + + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + # Add here commands to install the package into debian/ncurses. + $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install + mkdir -p $(CURDIR)/debian/tmp/etc/rc.d/rc3.d/ + ln -s ../init.d/snd_init $(CURDIR)/debian/tmp/etc/rc.d/rc3.d/S30snd_init + mkdir -p $(CURDIR)/debian/tmp/etc/rc.d/rc4.d/ + ln -s ../init.d/snd_init $(CURDIR)/debian/tmp/etc/rc.d/rc4.d/S30snd_init + +# Build architecture-independent files here. +binary-indep: build install +# We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot + dh_installchangelogs + dh_installdocs + dh_buildinfo install + dh_installexamples + dh_install --list-missing --sourcedir=debian/tmp +# dh_installmenu +# dh_installdebconf +# dh_installlogrotate +# dh_installemacsen +# dh_installpam +# dh_installmime +# dh_python +# dh_installinit +# dh_installcron +# dh_installinfo + dh_installman + dh_link + dh_strip --dbg-package=libavsystem-0-dbg + dh_compress + dh_fixperms +# dh_perl + dh_makeshlibs + dh_installdeb + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install @@ -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 <oliva@dcc.unicamp.br>. + +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 <bug-automake@gnu.org>. +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/avsys-audio-alsa.h b/include/avsys-audio-alsa.h new file mode 100644 index 0000000..1711f84 --- /dev/null +++ b/include/avsys-audio-alsa.h @@ -0,0 +1,51 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi <jhchoi.choi@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __AVSYS_AUDIO_ALSA_H__ +#define __AVSYS_AUDIO_ALSA_H__ + +#ifdef __cplusplus + extern "C" { +#endif +#include <avsys-audio-handle.h> + +enum AIF_device_type_t { + AIF2_CAPTURE, + AIF2_PLAYBACK, + AIF3_CAPTURE, + AIF3_PLAYBACK, + AIF_DEVICE_MAX, +}; + +typedef struct { + void *alsa_handle; + int type; +} avsys_audio_alsa_aif_handle_t;; + +int avsys_audio_alsa_open_AIF_device(const int 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); + +#ifdef __cplusplus + } +#endif + +#endif /* __AVSYS_AUDIO_H__ */ diff --git a/include/avsys-audio-ascenario.h b/include/avsys-audio-ascenario.h new file mode 100644 index 0000000..a5f8c24 --- /dev/null +++ b/include/avsys-audio-ascenario.h @@ -0,0 +1,96 @@ +/*
+ * avsystem
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jonghyuk Choi <jhchoi.choi@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#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" + +#define IN 0 +#define OUT 16 + +#define INPUT_CH_0 ((1 << (0 + IN))) /* Main Mic. 0x00000001 */ +#define INPUT_CH_1 ((1 << (1 + IN))) /* Sub Mic. 0x00000002 */ +#define INPUT_CH_2 ((1 << (2 + IN))) /* Stereo Mic. , 0x00000004 */ +#define INPUT_CH_3 ((1 << (3 + IN))) /* Ear Mic. , 0x00000008 */ +#define INPUT_CH_4 ((1 << (4 + IN))) /* BT Mic. 0x00000010 */ +#define INPUT_CH_5 ((1 << (5 + IN))) /* AP 0x00000020 */ +#define INPUT_CH_6 ((1 << (6 + IN))) /* CP 0x00000040 */ +#define INPUT_CH_7 ((1 << (7 + IN))) /* FM Radio 0x00000080 */ +#define INPUT_CH_8 ((1 << (8 + IN))) /* Reserved */ +#define INPUT_CH_9 ((1 << (9 + IN))) /* Reserved */ + +#define OUTPUT_CH_0 ((1 << (0 + OUT))) /* Headset (Earphone) 0x00010000 */ +#define OUTPUT_CH_1 ((1 << (1 + OUT))) /* Left Speaker , 0x00020000 */ +#define OUTPUT_CH_2 ((1 << (2 + OUT))) /* Right Speaker , 0x00040000 */ +#define OUTPUT_CH_3 ((1 << (3 + OUT))) /* Stereo Speaker , 0x00080000 */ +#define OUTPUT_CH_4 ((1 << (4 + OUT))) /* Receiver (Mono) , 0x00100000 */ +#define OUTPUT_CH_5 ((1 << (5 + OUT))) /* BT Headset 0x00200000 */ +#define OUTPUT_CH_6 ((1 << (6 + OUT))) /* CP 0x00400000 */ +#define OUTPUT_CH_7 ((1 << (7 + OUT))) /* AP 0x00800000 */ +#define OUTPUT_CH_8 ((1 << (8 + OUT))) /* Gain */ +#define OUTPUT_CH_9 ((1 << (9 + OUT))) /* Video call gain */ +#define OUTPUT_CH_10 ((1 << (10 + OUT))) /* Video call gain */ +#define OUTPUT_CH_11 ((1 << (11 + OUT))) /* Reserved */ +#define OUTPUT_CH_12 ((1 << (12 + OUT))) /* Reserved */ +#define OUTPUT_CH_13 ((1 << (13 + OUT))) /* Call alert Gain */ + +#define INPUT_MAIN_MIC (INPUT_CH_0) +#define INPUT_SUB_MIC (INPUT_CH_1) +#define INPUT_STEREO_MIC (INPUT_CH_2) +#define INPUT_EAR_MIC (INPUT_CH_3) +#define INPUT_BT_MIC (INPUT_CH_4) +#define INPUT_AP (INPUT_CH_5) +#define INPUT_CP (INPUT_CH_6) +#define INPUT_FMRADIO (INPUT_CH_7) + +#define OUTPUT_HEADSET (OUTPUT_CH_0) +#define OUTPUT_LEFT_SPK (OUTPUT_CH_1) +#define OUTPUT_RIGHT_SPK (OUTPUT_CH_2) +#define OUTPUT_STEREO_SPK (OUTPUT_CH_3) +#define OUTPUT_RECV (OUTPUT_CH_4) +#define OUTPUT_BT_HEADSET (OUTPUT_CH_5) +#define OUTPUT_CP (OUTPUT_CH_6) +#define OUTPUT_AP (OUTPUT_CH_7) + +#define GAIN_MODE (OUTPUT_CH_8) +#define GAIN_VIDEO_CALL (OUTPUT_CH_9) +#define GAIN_VOICE_CALL (OUTPUT_CH_10) +#define GAIN_CALLALERT (OUTPUT_CH_13) +
+/* function prototype */
+int avsys_audio_ascn_bulk_set(int * bulk, int bulk_cnt, AscnResetType clear);
+int avsys_audio_ascn_single_set(char * str);
+
+#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..b05c099 --- /dev/null +++ b/include/avsys-audio-handle.h @@ -0,0 +1,117 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi <jhchoi.choi@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __AVSYS_AUDIO_HANDLE_H__ +#define __AVSYS_AUDIO_HANDLE_H__ + +#include <pthread.h> +#include "avsys-audio-logical-volume.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_MAX, +}; + +enum { + AVSYS_AUDIO_HANDLE_EXT_DEV_NONE = 0x00000000, + AVSYS_AUDIO_HANDLE_EXT_DEV_FMRADIO = 0x00000001, +}; + +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; + avsys_audio_volume_t setting_vol; + avsys_audio_volume_t working_vol; + int fadeup_vol; + int fadeup_multiplier; + char dirty_volume; + + /* routing information */ + char during_cp_audio;/* if this value set 1, this handle created during cp audio status (means call) */ + char path_off; + int stream_index; + int handle_route; + + /* backend specific */ + void *device; +} 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 volume_value[AVSYS_AUDIO_VOLUME_TYPE_MAX]; + int primary_volume_type; + 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 *); +int avsys_audio_handle_dump(void); +int avsys_audio_handle_rejuvenation(void); +int avsys_audio_handle_alloc(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_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_update_volume(avsys_audio_handle_t *p, const int vol_type); +int avsys_audio_handle_update_volume_by_type(const int volume_type, const int volume_value); +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-logical-volume.h b/include/avsys-audio-logical-volume.h new file mode 100644 index 0000000..1b4ad52 --- /dev/null +++ b/include/avsys-audio-logical-volume.h @@ -0,0 +1,87 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi <jhchoi.choi@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __AVSYS_AUDIO_LOGICAL_VOLUME_H__ +#define __AVSYS_AUDIO_LOGICAL_VOLUME_H__ + +#include "avsys-audio.h" + +#define LVOLUME_MAX_MULTIMEDIA 16 /**< same with AVSYS_AUDIO_VOLUME_MAX_MULTIMEDIA */ +#define LVOLUME_MAX_BASIC 8 /**< same with AVSYS_AUDIO_VOLUME_MAX_BASIC */ +#define LVOLUME_MAX_SINGLE 1 /**< same with AVSYS_AUDIO_VOLUME_MAX_SINGLE */ + +#define FADE_UP_MULTIPLIER 1//2 +#define FADE_DOWN_MULTIPLIER 1 + +#define VOLUME_FILE_PATH "/opt/system/volume.txt" + +enum +{ + AVSYS_AUDIO_LVOL_GAIN_TYPE_0 = 0, /* system */ + AVSYS_AUDIO_LVOL_GAIN_TYPE_1, /* notification */ + AVSYS_AUDIO_LVOL_GAIN_TYPE_2, /* alarm */ + AVSYS_AUDIO_LVOL_GAIN_TYPE_3, /* ringtone */ + AVSYS_AUDIO_LVOL_GAIN_TYPE_4, /* media */ + AVSYS_AUDIO_LVOL_GAIN_TYPE_5, /* call */ + AVSYS_AUDIO_LVOL_GAIN_TYPE_6, /* android */ + AVSYS_AUDIO_LVOL_GAIN_TYPE_7, /* java */ + AVSYS_AUDIO_LVOL_GAIN_TYPE_8, /* music (media2) */ + AVSYS_AUDIO_LVOL_GAIN_TYPE_MAX, +}; + +enum +{ + AVSYS_AUDIO_LVOL_DEV_TYPE_SPK, + AVSYS_AUDIO_LVOL_DEV_TYPE_HEADSET, + AVSYS_AUDIO_LVOL_DEV_TYPE_BTHEADSET, + AVSYS_AUDIO_LVOL_DEV_TYPE_MAX, +}; + + +typedef struct { + int max_len; + avsys_audio_volume_t gain[LVOLUME_MAX_MULTIMEDIA]; +} avsys_a_logical_volume_t; + + +typedef struct { + int type; + avsys_a_logical_volume_t devices[AVSYS_AUDIO_LVOL_DEV_TYPE_MAX]; +} avsys_logical_gain_t; + +typedef struct { + int vol_type; + int dev_type; + int max_len; + avsys_audio_volume_t *table; +} avsys_audio_volume_setting_t; + +int avsys_audio_logical_volume_get_max(int vol_type, int dev_type, int *max); +int avsys_audio_logical_volume_set_table(int vol_type, int dev_type, avsys_audio_volume_setting_t *setting); +int avsys_audio_logical_volume_update_table(int dev_type, avsys_audio_volume_setting_t *setting); +int avsys_audio_logical_volume_convert(avsys_audio_volume_t *level, avsys_audio_volume_t *converted, avsys_audio_volume_setting_t *setting); +/* Tuning */ +int avsys_audio_logical_volume_init(void); +int avsys_audio_logical_volume_set_to_table(int gain_type, int dev_type, int step, int lv, int rv); +int avsys_audio_logical_volume_get_from_table(int gain_type, int dev_type, int step, int *lv, int *rv); +int avsys_audio_load_volume_from_file(void); + +#endif /* __AVSYS_AUDIO_LOGICAL_VOLUME_H__ */ diff --git a/include/avsys-audio-pactrl.h b/include/avsys-audio-pactrl.h new file mode 100644 index 0000000..e446c40 --- /dev/null +++ b/include/avsys-audio-pactrl.h @@ -0,0 +1,72 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi <jhchoi.choi@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __AVSYS_AUDIO_PACTRL_H__ +#define __AVSYS_AUDIO_PACTRL_H__ + +#ifdef __cplusplus + extern "C" { +#endif +#include <avsys-audio-handle.h> +#include <pulse/pulseaudio.h> +#include <pulse/thread-mainloop.h> +#include <pulse/error.h> +#include <pulse/gccmacro.h> +#include <pulse/proplist.h> + +/* + * 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 Prorotypes + */ +int avsys_audio_pa_ctrl_volume_by_index(unsigned int idx, int volume, int ch); +int avsys_audio_pa_ctrl_mute_by_index(unsigned int idx, int mute); +int avsys_audio_pa_ctrl_get_default_sink(int *sink); + +#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..06fec34 --- /dev/null +++ b/include/avsys-audio-pasimple.h @@ -0,0 +1,57 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi <jhchoi.choi@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __AVSYS_AUDIO_PASIMPLE_H__ +#define __AVSYS_AUDIO_PASIMPLE_H__ + +#ifdef __cplusplus + extern "C" { +#endif +#include <avsys-audio-handle.h> +#include <pulse/simple.h> +#include <pulse/error.h> +#include <pulse/gccmacro.h> +#include <pulse/proplist.h> + +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); +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_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); + +#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 100644 index 0000000..2f20b46 --- /dev/null +++ b/include/avsys-audio-path.h @@ -0,0 +1,232 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi <jhchoi.choi@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __AVSYS_AUDIO_PATH_H__ +#define __AVSYS_AUDIO_PATH_H__ + +#include "avsys-audio.h" +#include "avsys-audio-handle.h" + +#include <sys/types.h> +#include <stdbool.h> + +enum { + AVSYS_AUDIO_INSERTED_NONE = 0, + AVSYS_AUDIO_INSERTED_3, + AVSYS_AUDIO_INSERTED_4, + AVSYS_AUDIO_INSERTED_AV +}; + +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_CALLALERT, + 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_MAX +}; + +enum avsys_audio_ear_ctrl { + AVSYS_AUDIO_EAR_SWITCH_MANUAL, + AVSYS_AUDIO_EAR_SWITCH_AUTO_WITH_MUTE, + AVSYS_AUDIO_EAR_SWITCH_AUTO_WITHOUT_MUTE, +}; + +struct avsys_audio_jack_event { + struct timeval time; + unsigned short type; + unsigned short code; + int value; +}; + +#define PATH_MASK_MAX 23 +#define GAIN_MASK_MAX 30 +/* sound path status bit */ +#define PS_PATH_NONE (0) +#define PS_AP_TO_SPK (1 << 0) +#define PS_AP_TO_HEADSET (1 << 1) +#define PS_AP_TO_RECV (1 << 2) +#define PS_AP_TO_HDMI (1 << 3) +#define PS_AP_TO_BT (1 << 4) +#define PS_AP_TO_MODEM (1 << 5) +#define PS_MODEM_TO_SPK (1 << 6) +#define PS_MODEM_TO_HEADSET (1 << 7) +#define PS_MODEM_TO_RECV (1 << 8) +#define PS_MODEM_TO_BT (1 << 9) +#define PS_MODEM_TO_AP (1 << 10) +#define PS_FMRADIO_TO_SPK (1 << 11) +#define PS_FMRADIO_TO_HEADSET (1 << 12) +#define PS_MAINMIC_TO_AP (1 << 13) +#define PS_MAINMIC_TO_MODEM (1 << 14) +#define PS_SUBMIC_TO_AP (1 << 15) +#define PS_SUBMIC_TO_MODEM (1 << 16) +#define PS_STEREOMIC_TO_AP (1 << 17) +#define PS_EARMIC_TO_AP (1 << 18) +#define PS_EARMIC_TO_MODEM (1 << 19) +#define PS_BTMIC_TO_AP (1 << 20) +#define PS_BTMIC_TO_MODEM (1 << 21) +#define PS_FMRADIO_TO_AP (1 << 22) +#define PS_CODEC_DISABLE_ON_SUSPEND (1 << 23) +#define PS_CP_TO_AP (1 << PATH_MASK_MAX) + + +/* hw gain status enum */ +#define GS_GAIN_NONE (0) +#define GS_AP_TO_SPK (1 << 0) +#define GS_AP_TO_SPK_CALLALERT (1 << 1) +#define GS_AP_TO_HEADSET (1 << 2) +#define GS_AP_TO_HEADSET_CALLALERT (1 << 3) +#define GS_AP_TO_RECV (1 << 4) +#define GS_AP_TO_HDMI (1 << 5) +#define GS_AP_TO_BT (1 << 6) +#define GS_AP_TO_MODEM (1 << 7) +#define GS_MODEM_TO_SPK_VOICE (1 << 8) +#define GS_MODEM_TO_HEADSET_VOICE (1 << 9) +#define GS_MODEM_TO_RECV_VOICE (1 << 10) +#define GS_MODEM_TO_BT_VOICE (1 << 11) +#define GS_MODEM_TO_AP_VOICE (1 << 12) +#define GS_MODEM_TO_SPK_VIDEO (1 << 13) +#define GS_MODEM_TO_HEADSET_VIDEO (1 << 14) +#define GS_MODEM_TO_RECV_VIDEO (1 << 15) +#define GS_MODEM_TO_BT_VIDEO (1 << 16) +#define GS_MODEM_TO_AP_VIDEO (1 << 17) +#define GS_FMRADIO_TO_SPK (1 << 18) +#define GS_FMRADIO_TO_HEADSET (1 << 19) +#define GS_MAINMIC_TO_AP (1 << 20) +#define GS_MAINMIC_TO_MODEM_VOICE (1 << 21) +#define GS_SUBMIC_TO_AP (1 << 22) +#define GS_SUBMIC_TO_MODEM_VOICE (1 << 23) +#define GS_STEREOMIC_TO_AP (1 << 24) +#define GS_EARMIC_TO_AP (1 << 25) +#define GS_EARMIC_TO_MODEM_VOICE (1 << 26) +#define GS_BTMIC_TO_AP (1 << 27) +#define GS_BTMIC_TO_MODEM_VOICE (1 << 28) +#define GS_FMRADIO_TO_AP (1 << 29) +#define GS_CP_TO_AP (1 << GAIN_MASK_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_FMRADIO (1 << PATH_FIXED_TYPE_FMRADIO) /* 0x00000001 */ +#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 option_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 backup_gain; + path_info_t backup_path; + + gain_info_t pregain; + gain_info_t reqgain; + + option_info_t option; + + /* path fixed information */ + int path_fixed; + pid_t path_fixed_pid[PATH_FIXED_TYPE_MAX]; + + /* hw mute */ + int mute; + + /* For earphone control */ + int inserted; + int ear_auto; + + /* for alsa scenario, aquila */ + gain_status_t gain_status; + path_status_t path_status; + + gain_status_t p_gain_status; + path_status_t p_path_status; + + int lvol_dev_type; + int gain_debug_mode; + + /* For Lock debugging */ + pid_t pathlock_pid[AVSYS_AUDIO_LOCK_SLOT_MAX]; + + /* system route policy */ + avsys_audio_route_policy_t route_policy; + int a2dp_status; + int earpiece_on; +} 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_manage_earjack(void); +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_volume(int handle); + +int avsys_audio_path_earjack_init(int *init_type, int *outfd); +int avsys_audio_path_earjack_wait(int fd, int *current_type, int *new_type, int *is_auto_mute); +int avsys_audio_path_earjack_process(int new_type); +int avsys_audio_path_earjack_deinit(int fd); +int avsys_audio_path_earjack_unlock(void); + +int avsys_audio_path_set_route_policy(avsys_audio_route_policy_t route); +int avsys_audio_path_get_route_policy(avsys_audio_route_policy_t *route); +int avsys_audio_path_check_loud(bool *loud); +int avsys_audio_path_check_cp_audio(bool *cpaudio, bool *btpath); +int avsys_audio_path_set_single_ascn(char *str); + +#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 <jhchoi.choi@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#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..d55d5a1 --- /dev/null +++ b/include/avsys-audio-sync.h @@ -0,0 +1,47 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi <jhchoi.choi@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#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_SOUNDPATH, + AVSYS_AUDIO_SYNC_IDEN_VOLUME, + 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 100644 index 0000000..3853f46 --- /dev/null +++ b/include/avsys-audio.h @@ -0,0 +1,600 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi <jhchoi.choi@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __AVSYS_AUDIO_H__ +#define __AVSYS_AUDIO_H__ + +#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_SINGLE 1 + +/** + * 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 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 */ +}; + + +/* + * Enums for volume types + */ +enum avsys_audio_volume_type_t { + 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_FIXED, + AVSYS_AUDIO_VOLUME_TYPE_EXT_SYSTEM_JAVA, + AVSYS_AUDIO_VOLUME_TYPE_MEDIA_HL, + 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, +}; + +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_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 */ +}; + +/** + * 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 bluetooth; /**< Handle route information. refer. avsys_audio_handle_route_t */ + int vol_type; /**< volume type */ + int allow_mix; +} 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, + AVSYS_AUDIO_PATH_EX_HDMI, + 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, + 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_FMRADIO, + AVSYS_AUDIO_GAIN_EX_VOICEREC, + AVSYS_AUDIO_GAIN_EX_CAMCORDER, + AVSYS_AUDIO_GAIN_EX_CAMERA, + AVSYS_AUDIO_GAIN_EX_GAME, + 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; + + +typedef enum { + AVSYS_AUDIO_ROUTE_POLICY_DEFAULT, + AVSYS_AUDIO_ROUTE_POLICY_IGNORE_A2DP, + AVSYS_AUDIO_ROUTE_POLICY_HANDSET_ONLY, + AVSYS_AUDIO_ROUTE_POLICY_MAX, +}avsys_audio_route_policy_t; /* system global configuration */ + +enum avsys_audio_handle_route_t{ + AVSYS_AUDIO_HANDLE_ROUTE_FOLLOWING_POLICY, + AVSYS_AUDIO_HANDLE_ROUTE_HANDSET_ONLY, +}; /* 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_JACK_AUTO 0x00000001 /*!< Sound path auto change between SPK/Recv and headset */ +#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_LEFT_SPK_ONLY 0x00000004 /*!< AP playback left speaker only */ +#define AVSYS_AUDIO_PATH_OPTION_RIGHT_SPK_ONLY 0x00000008 /*!< AP playback right speaker only */ +#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_FORCED 0x01000000 /*!< Forced sound path setting. only for booting animation */ +#define AVSYS_AUDIO_PATH_OPTION_LEGACY_MODE 0x10000000 /*!< Now Plus Style */ + + +/** + * 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 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 gain_type, int dev_type, int step, int lv, int rv); +int avsys_audio_get_volume_table(int gain_type, int dev_type, int step, int *lv, int *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 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 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 get playback audio device information of system. + * + * @param dev [out] current playback device type + * + * @return This function returns AVSYS_STATE_SUCCESS on success, or negative + * value with error code. + * @remark + * @see avsys_audio_playing_devcie_t + */ +int avsys_audio_get_playing_device_info(avsys_audio_playing_devcie_t *dev); + +/** + * 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_earjack_manager_init(int *earjack_type, int *waitfd); +int avsys_audio_earjack_manager_wait(int waitfd, int *current_earjack_type, int *new_earjack_type, int *need_mute); +int avsys_audio_earjack_manager_process(int new_earjack_type); +int avsys_audio_earjack_manager_deinit(int waitfd); +int avsys_audio_earjack_manager_unlock(void); + +int avsys_audio_set_route_policy(avsys_audio_route_policy_t route); +int avsys_audio_get_route_policy(avsys_audio_route_policy_t *route); +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_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); +/** + @} + */ + +#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 <jhchoi.choi@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __AVSYS_COMMON_H__ +#define __AVSYS_COMMON_H__ + +#include <stdlib.h> +#include <sys/syscall.h> + +#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..6f19daa --- /dev/null +++ b/include/avsys-debug.h @@ -0,0 +1,91 @@ +/* + * avsystem + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jonghyuk Choi <jhchoi.choi@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/** + * 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 <stdio.h> +#include <mm_log.h> +#define AVAUDIO LOG_AVAUDIO +#define AVVIDEO LOG_AVVIDEO +#define AVCAMERA LOG_AVCAMERA +#else +#define AVAUDIO +#define AVVIDEO +#define AVCAMERA +#endif + +#ifdef __DEBUG_MODE__ +#ifdef __USE_LOGMANAGER__ + +#define avsys_info_r(owner, msg, args...) log_print_rel( owner, LOG_CLASS_INFO, "[%05d:%s] "msg, __LINE__, __func__, ##args ) +#define avsys_warning_r(owner, msg, args...) log_print_rel( owner, LOG_CLASS_WARNING, "[%05d:%s] "msg, __LINE__, __func__, ##args ) +#define avsys_error_r(owner, msg, args...) log_print_rel( owner, LOG_CLASS_ERR, "[%05d:%s] "msg, __LINE__, __func__, ##args ) +#define avsys_critical_r(owner, msg, args...) log_print_rel( owner, LOG_CLASS_CRITICAL, "[%05d:%s] "msg, __LINE__, __func__, ##args ) +#define avsys_assert_r(condition) log_assert_rel(( condition )) + +#define avsys_info(owner, msg, args...) log_print_dbg( owner, LOG_CLASS_INFO, "[%05d:%s] "msg, __LINE__, __func__, ##args ) +#define avsys_warning(owner, msg, args...) log_print_dbg( owner, LOG_CLASS_WARNING, "[%05d:%s] "msg, __LINE__, __func__, ##args ) +#define avsys_error(owner, msg, args...) log_print_dbg( owner, LOG_CLASS_ERR, "[%05d:%s] "msg, __LINE__, __func__, ##args ) +#define avsys_critical(owner, msg, args...) log_print_dbg( owner, LOG_CLASS_CRITICAL, "[%05d:%s] "msg, __LINE__, __func__, ##args ) +#define avsys_assert(condition) log_assert_dbg( (condition) ) + +#else /* __USE_LOGMANAGER__ */ + +#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_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_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_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..1be188c --- /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 <jhchoi.choi@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#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_WARING (0x70000000) /**< Waring 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_WARING | AVSYS_IN_PARAMETER) +#define AVSYS_STATE_WAR_INVALID_HANDLE (AVSYS_STATE_WARING | AVSYS_IN_HANDLE) +#define AVSYS_STATE_WAR_INVALID_VALUE (AVSYS_STATE_WARING | AVSYS_IN_VALUE) +#define AVSYS_STATE_WAR_INVALID_MODE (AVSYS_STATE_WARING | AVSYS_IN_MODE) +#define AVSYS_STATE_WAR_INVALID_FORMAT (AVSYS_STATE_WARING | AVSYS_IN_FORMAT) +#define AVSYS_STATE_WAR_INVALID_CHANNEL (AVSYS_STATE_WARING | AVSYS_IN_CHANNEL) +#define AVSYS_STATE_WAR_INVALID_SAMPLERATE (AVSYS_STATE_WARING | AVSYS_IN_SAMPLERATE) +#define AVSYS_STATE_WAR_INVALID_LAYER (AVSYS_STATE_WARING | AVSYS_IN_LAYER) +#define AVSYS_STATE_WAR_INVALID_ROTATE (AVSYS_STATE_WARING | AVSYS_IN_ROTATE) +#define AVSYS_STATE_WAR_NULL_POINTER (AVSYS_STATE_WARING | AVSYS_IN_POINTER) +#define AVSYS_STATE_WAR_UNDERRUN (AVSYS_STATE_WARING | AVSYS_IN_UNDERRUN) +#define AVSYS_STATE_WAR_OVERRUN (AVSYS_STATE_WARING | AVSYS_IN_OVERRUN) +#define AVSYS_STATE_WAR_RANGE_OVER (AVSYS_STATE_WARING | AVSYS_IN_RANGE_OVER) +#define AVSYS_STATE_WAR_RANGE_UNDER (AVSYS_STATE_WARING | AVSYS_IN_RANGE_UNDER) +#define AVSYS_STATE_WAR_ALLOCATION (AVSYS_STATE_WARING | AVSYS_IN_ALLOC) +#define AVSYS_STATE_WAR_INTERNAL (AVSYS_STATE_WARING | AVSYS_IN_INTERNAL) +/*Extra warning for camera*/ +#define AVSYS_STATE_WAR_IO_CONTROL (AVSYS_STATE_WARING | AVSYS_IN_IO_CONTROL) +#define AVSYS_STATE_WAR_UNAVAILABLE_DEVICE (AVSYS_STATE_WARING | AVSYS_IN_DEVICE) +#define AVSYS_STATE_WAR_DEVICE_WAIT_TIMEOUT (AVSYS_STATE_WARING | AVSYS_IN_WAIT_RES) +#define AVSYS_STATE_WAR_DEVICE_NOT_SUPPORT (AVSYS_STATE_WARING | AVSYS_IN_SUPPORT) +#define AVSYS_STATE_WAR_INVALID_STATE_TRANSITION (AVSYS_STATE_WARING | 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_WARING(_A_) (AVSYS_STATE_WARING & (_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 <jhchoi.choi@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#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 <jhchoi.choi@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __AVSYSTEM_H__
+#define __AVSYSTEM_H__
+
+#include <avsys-types.h>
+#include <avsys-audio.h>
+#include <avsys-error.h>
+
+/**
+ @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/init/Makefile.am b/init/Makefile.am new file mode 100644 index 0000000..993ef30 --- /dev/null +++ b/init/Makefile.am @@ -0,0 +1,2 @@ +installinitscriptdir = /etc/rc.d/init.d +installinitscript_SCRIPTS = $(srcdir)/snd_init diff --git a/init/snd_init b/init/snd_init new file mode 100755 index 0000000..f8e75aa --- /dev/null +++ b/init/snd_init @@ -0,0 +1,10 @@ +#!/bin/sh +# +# snd_init sound_initializer +# chkconfig: 2345 30 30 +# description: snd_init runs sound_initializer -i which make shared memory for audio system +# + +if [ -x /usr/bin/sound_initializer ]; then + /usr/bin/sound_initializer -i +fi 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: @@ -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 <pinard@iro.umontreal.ca>, 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 <bug-automake@gnu.org>." + 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.spec b/packaging/avsystem.spec new file mode 100644 index 0000000..8118229 --- /dev/null +++ b/packaging/avsystem.spec @@ -0,0 +1,73 @@ + +Name: avsystem +Summary: Audio Video System +Version: 0.3.50 +Release: 1 +Group: TO_BE/FILLED_IN +License: TO BE FILLED IN +Source0: avsystem-%{version}.tar.bz2 +BuildRequires: pkgconfig(alsa) +BuildRequires: pkgconfig(iniparser) +BuildRequires: pkgconfig(mm-ta) +BuildRequires: pkgconfig(mm-log) +BuildRequires: pkgconfig(libexif) +BuildRequires: pkgconfig(libpulse) +BuildRequires: pkgconfig(libascenario) + + +%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 \ +%ifarch %{ix86} + --enable-slp2 --enable-aquila --enable-pasimple +%else + --enable-slp2 --enable-sdk --enable-aquila --enable-pasimple +%endif + +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} +%make_install + + + +%post -p /sbin/ldconfig + +%files +%defattr(-,root,root,-) +/etc/rc.d/init.d/snd_init +/usr/bin/camera_caps_generator +/usr/bin/sound_initializer +/usr/lib/libavsysaudio.so.0 +/usr/lib/libavsysaudio.so.0.0.1 +/usr/lib/libavsyscamera.so.0 +/usr/lib/libavsyscamera.so.0.0.0 + +%files devel +/usr/lib/libavsysaudio.so +/usr/lib/pkgconfig/*.pc +/usr/lib/libavsyscamera.so +/usr/include/avsystem/avsys-audio.h +/usr/include/avsystem/avsys-cam-exif.h +/usr/include/avsystem/avsys-cam.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 |