summaryrefslogtreecommitdiff
path: root/tizen-audio-session.c
diff options
context:
space:
mode:
Diffstat (limited to 'tizen-audio-session.c')
-rw-r--r--tizen-audio-session.c245
1 files changed, 245 insertions, 0 deletions
diff --git a/tizen-audio-session.c b/tizen-audio-session.c
new file mode 100644
index 0000000..08ef9aa
--- /dev/null
+++ b/tizen-audio-session.c
@@ -0,0 +1,245 @@
+/*
+ * audio-hal
+ *
+ * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "tizen-audio-internal.h"
+
+static const char *__get_session_string_by_idx (uint32_t session_idx)
+{
+ switch (session_idx) {
+ case AUDIO_SESSION_MEDIA: return "media";
+ case AUDIO_SESSION_VOICECALL: return "voicecall";
+ case AUDIO_SESSION_VIDEOCALL: return "videocall";
+ case AUDIO_SESSION_VOIP: return "voip";
+ case AUDIO_SESSION_FMRADIO: return "fmradio";
+ case AUDIO_SESSION_CAMCORDER: return "camcorder";
+ case AUDIO_SESSION_NOTIFICATION: return "notification";
+ case AUDIO_SESSION_ALARM: return "alarm";
+ case AUDIO_SESSION_EMERGENCY: return "emergency";
+ case AUDIO_SESSION_VOICE_RECOGNITION: return "voice_recognition";
+ default: return "invalid";
+ }
+}
+
+static const char *__get_subsession_string_by_idx (uint32_t subsession_idx)
+{
+ switch (subsession_idx) {
+ case AUDIO_SUBSESSION_NONE: return "none";
+ case AUDIO_SUBSESSION_VOICE: return "voice";
+ case AUDIO_SUBSESSION_RINGTONE: return "ringtone";
+ case AUDIO_SUBSESSION_MEDIA: return "media";
+ case AUDIO_SUBSESSION_INIT: return "init";
+ case AUDIO_SUBSESSION_VR_NORMAL: return "vr_normal";
+ case AUDIO_SUBSESSION_VR_DRIVE: return "vr_drive";
+ case AUDIO_SUBSESSION_STEREO_REC: return "stereo_rec";
+ case AUDIO_SUBSESSION_MONO_REC: return "mono_rec";
+ default: return "invalid";
+ }
+}
+
+static const char * __get_sessin_cmd_string (uint32_t cmd)
+{
+ switch (cmd) {
+ case AUDIO_SESSION_CMD_START: return "start";
+ case AUDIO_SESSION_CMD_SUBSESSION: return "subsession";
+ case AUDIO_SESSION_CMD_END: return "end";
+ default: return "invalid";
+ }
+}
+
+audio_return_t _audio_session_init (audio_mgr_t *am)
+{
+ AUDIO_RETURN_VAL_IF_FAIL(am, AUDIO_ERR_PARAMETER);
+
+ am->session.session = AUDIO_SESSION_MEDIA;
+ am->session.subsession = AUDIO_SUBSESSION_NONE;
+ am->session.is_recording = 0;
+ am->session.is_radio_on = 0;
+ am->session.is_call_session = 0;
+
+ return AUDIO_RET_OK;
+}
+
+audio_return_t _audio_session_deinit (audio_mgr_t *am)
+{
+ AUDIO_RETURN_VAL_IF_FAIL(am, AUDIO_ERR_PARAMETER);
+
+ return AUDIO_RET_OK;
+}
+
+audio_return_t audio_set_session (void *userdata, uint32_t session, uint32_t subsession, uint32_t cmd)
+{
+ audio_return_t audio_ret = AUDIO_RET_OK;
+ audio_mgr_t *am = (audio_mgr_t *)userdata;
+ uint32_t prev_subsession = am->session.subsession;
+
+ AUDIO_RETURN_VAL_IF_FAIL(am, AUDIO_ERR_PARAMETER);
+
+ AUDIO_LOG_INFO("session %s:%s(%s)->%s(%s)", __get_sessin_cmd_string(cmd),
+ __get_session_string_by_idx(am->session.session), __get_subsession_string_by_idx(am->session.subsession),
+ __get_session_string_by_idx(session), __get_subsession_string_by_idx(subsession));
+
+ if (cmd == AUDIO_SESSION_CMD_START) {
+ if (am->session.is_call_session) {
+ AUDIO_LOG_ERROR("call active its not possible to have any other session start now");
+ return audio_ret;
+ }
+ am->session.session = session;
+ am->session.subsession = subsession;
+
+ if (session == AUDIO_SESSION_FMRADIO) {
+#ifdef USE_FMRADIO_V4L2_SPRD
+ int media_volume = 0;
+#endif
+ am->session.is_radio_on = 1;
+#ifdef USE_FMRADIO_V4L2_SPRD
+ _fmradio_pcm_open(am, am->device.active_in, am->device.active_out, 0);
+#endif
+ audio_set_route(userdata, session, subsession, am->device.active_in, am->device.active_out, 0);
+#ifdef USE_FMRADIO_V4L2_SPRD
+ audio_get_volume_level(am, AUDIO_VOLUME_TYPE_MEDIA, &media_volume);
+ _set_volume_level_fmradio(am, media_volume);
+ i2s_pin_mux_sel(am, FM_IIS);
+
+ /* change source due to limitation of FM recording */
+ _unload_device_from_ucm(am, NULL);
+ _load_device_from_ucm(am, NULL);
+#endif
+ }
+
+ if ((session == AUDIO_SESSION_VIDEOCALL) ||
+ (session == AUDIO_SESSION_VOICECALL) ||
+ (session == AUDIO_SESSION_VOIP)) {
+ AUDIO_LOG_INFO("set call session");
+ am->session.is_call_session = 1;
+ }
+
+ } else if (cmd == AUDIO_SESSION_CMD_END) {
+
+ if ((session == AUDIO_SESSION_VIDEOCALL) ||
+ (session == AUDIO_SESSION_VOICECALL) ||
+ (session == AUDIO_SESSION_VOIP)) {
+ AUDIO_LOG_INFO("unset call session");
+ am->session.is_call_session = 0;
+ }
+
+ if (am->session.is_call_session) {
+ AUDIO_LOG_ERROR("call active its not possible to have any other session end now");
+ return audio_ret;
+ }
+
+ if (session == AUDIO_SESSION_VIDEOCALL && _audio_modem_is_call_connected(am)) {
+ _unload_device_from_ucm(am, NULL);
+
+ /* close all pcm */
+ if (am->cb_intf.close_all_devices) {
+ am->cb_intf.close_all_devices(am->platform_data);
+ }
+
+ _audio_mixer_control_set_value(am, MIXER_VBC_SWITCH, VBC_ARM_CHANNELID);
+
+ /* close device */
+ _voice_pcm_close(am, 1);
+
+ /* open pcm of default device */
+ _open_device_from_ucm(am, NULL);
+ }
+ if (session == AUDIO_SESSION_MEDIA && (prev_subsession == AUDIO_SUBSESSION_STEREO_REC || AUDIO_SUBSESSION_MONO_REC)) {
+ am->session.is_recording = 0;
+ }
+ if (session != AUDIO_SESSION_FMRADIO && am->session.is_radio_on) {
+ am->session.session = AUDIO_SESSION_FMRADIO;
+ } else {
+ am->session.session = AUDIO_SESSION_MEDIA;
+ }
+ am->session.subsession = AUDIO_SUBSESSION_NONE;
+
+ if (session == AUDIO_SESSION_FMRADIO) {
+ am->session.is_radio_on = 0;
+#ifdef USE_FMRADIO_V4L2_SPRD
+ _fmradio_pcm_close(am);
+#endif
+ audio_ret = _reset_route(am, 0);
+ if (audio_ret != AUDIO_RET_OK) {
+ AUDIO_LOG_ERROR("_reset_route failed with %d", audio_ret);
+ }
+#ifdef USE_FMRADIO_V4L2_SPRD
+ /* change source due to limitation of FM recording */
+ _unload_device_from_ucm(am, NULL);
+ _open_device_from_ucm(am, NULL);
+#endif
+ }
+ } else if (cmd == AUDIO_SESSION_CMD_SUBSESSION) {
+
+ if (am->session.is_call_session) {
+ if ((subsession != AUDIO_SUBSESSION_VOICE) &&
+ (subsession != AUDIO_SUBSESSION_MEDIA) &&
+ (subsession != AUDIO_SUBSESSION_RINGTONE)) {
+ AUDIO_LOG_ERROR("call active we can only have one of AUDIO_SUBSESSION_VOICE AUDIO_SUBSESSION_MEDIA AUDIO_SUBSESSION_RINGTONE as a sub-session");
+ return audio_ret;
+ }
+ }
+
+ am->session.subsession = subsession;
+
+ if (prev_subsession != subsession && am->session.session == AUDIO_SESSION_VIDEOCALL && subsession == AUDIO_SUBSESSION_VOICE) {
+ /* close all pcm */
+ if (am->cb_intf.close_all_devices) {
+ am->cb_intf.close_all_devices(am->platform_data);
+ }
+ if (am->device.active_out & (AUDIO_DEVICE_OUT_SPEAKER | AUDIO_DEVICE_OUT_BT_SCO)) {
+ if (am->cp_type == CP_TG)
+ i2s_pin_mux_sel(am, 1);
+ else if(am->cp_type == CP_W)
+ i2s_pin_mux_sel(am, 0);
+ }
+
+ audio_ret = _set_route_videocall(am, am->device.active_in, am->device.active_out, am->device.route_flag);
+ if (AUDIO_IS_ERROR(audio_ret)) {
+ AUDIO_LOG_WARN("set videocall route return 0x%x", audio_ret);
+ }
+
+ if (_voice_pcm_open(am) < 0) {
+ _voice_pcm_close(am, 1);
+ return AUDIO_ERR_RESOURCE;
+ }
+ _open_device_from_ucm(am, NULL);
+ }
+
+ if (prev_subsession != subsession && subsession == AUDIO_SUBSESSION_VOICE) {
+ am->session.is_radio_on = 0;
+ am->session.is_recording = 0;
+ }
+
+ if (subsession == AUDIO_SUBSESSION_STEREO_REC || subsession == AUDIO_SUBSESSION_MONO_REC) {
+ am->session.is_recording = 1;
+ } else if (am->session.is_recording == 1 && subsession == AUDIO_SUBSESSION_INIT) {
+ am->session.is_recording = 0;
+ }
+ }
+
+ return audio_ret;
+}