26d4cfad54a007396ec3e300426c120b1ba7bc1c
[apps/core/preloaded/ug-camera-efl.git] / src / cam_sound.c
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *        http://floralicense.org/license/
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17
18 #include <sound_manager.h>
19 #include <wav_player.h>
20 #include <pthread.h>
21 #include <vconf.h>
22 #include <errno.h>
23 #include <sys/time.h>
24 #include "cam.h"
25 #include "cam_sound.h"
26 /*
27 #include "cam_sound_private.h"
28 */
29 #include "cam_debug.h"
30 #include "cam_ta.h"
31 #include "cam_mm.h"
32
33 #define SOUND_TIMEOUT_SEC       2
34
35 static gchar **sound_files = NULL;
36 #ifdef USE_CAMERA_APP_SHUTTER_SOUND
37 pthread_mutex_t sound_lock = PTHREAD_MUTEX_INITIALIZER;
38 pthread_cond_t sound_cond = PTHREAD_COND_INITIALIZER;
39 #endif
40
41 static void cam_sound_callback(int id, void *data);
42
43 gboolean cam_sound_init(GError **error)
44 {
45         debug_fenter(LOG_UI);
46
47         if (!sound_files) {
48                 sound_files = g_new0(gchar *, CAM_SOUND_EFFECT_NUM);
49                 g_return_val_if_fail(sound_files, FALSE);
50
51                 int i;
52                 for (i = 0; i < CAM_SOUND_EFFECT_NUM; i++)
53                         sound_files[i] = NULL;
54 #ifdef USE_CAMERA_APP_SHUTTER_SOUND
55                 cam_sound_set(CAM_SOUND_EFFECT_SHUTTER1, SOUND_PATH "/Shutter_01.wav");
56                 cam_sound_set(CAM_SOUND_EFFECT_SHUTTER2, SOUND_PATH "/Shutter_02.wav");
57                 cam_sound_set(CAM_SOUND_EFFECT_SHUTTER3, SOUND_PATH "/Shutter_03.wav");
58                 cam_sound_set(CAM_SOUND_EFFECT_REC_START1, SOUND_PATH "/cam_start_01.wav");
59                 cam_sound_set(CAM_SOUND_EFFECT_REC_START2, SOUND_PATH "/cam_start_02.wav");
60                 cam_sound_set(CAM_SOUND_EFFECT_REC_START3, SOUND_PATH "/cam_start_03.wav");
61                 cam_sound_set(CAM_SOUND_EFFECT_REC_COMMIT1, SOUND_PATH "/cam_stop_01.wav");
62                 cam_sound_set(CAM_SOUND_EFFECT_REC_COMMIT2, SOUND_PATH "/cam_stop_02.wav");
63                 cam_sound_set(CAM_SOUND_EFFECT_REC_COMMIT3, SOUND_PATH "/cam_stop_03.wav");
64 #endif
65                 cam_sound_set(CAM_SOUND_EFFECT_TICK, SOUND_PATH "/count.wav");
66                 cam_sound_set(CAM_SOUND_EFFECT_AF_OK, SOUND_PATH "/af_ok.wav");
67                 cam_sound_set(CAM_SOUND_EFFECT_AF_FAIL, SOUND_PATH "/af_fail.wav");
68
69         }
70 #ifdef USE_CAMERA_APP_SHUTTER_SOUND
71         pthread_mutex_init(&sound_lock, NULL);
72         pthread_cond_init(&sound_cond, NULL);
73 #endif
74         return TRUE;
75 }
76
77 void cam_sound_finalize(void)
78 {
79         debug_fenter(LOG_UI);
80
81         if (sound_files) {
82                 int i;
83                 for (i = 0; i < CAM_SOUND_EFFECT_NUM; i++) {
84                         if (sound_files[i]) {
85                                 g_free(sound_files[i]);
86                                 sound_files[i] = NULL;
87                         }
88                 }
89                 g_free(sound_files);
90                 sound_files = NULL;
91         }
92 #ifdef USE_CAMERA_APP_SHUTTER_SOUND
93         pthread_mutex_destroy(&sound_lock);
94         pthread_cond_destroy(&sound_cond);
95 #endif
96 }
97
98 void cam_sound_set(int index, const gchar *file)
99 {
100         debug_msg(LOG_UI, "%d:%s", index, file ? file : "NULL");
101         g_return_if_fail(sound_files);
102         if (sound_files[index]) {
103                 g_free(sound_files[index]);
104                 sound_files[index] = NULL;
105         }
106         if (file)
107                 sound_files[index] = g_strdup(file);
108 }
109
110 const gchar *cam_sound_get(int index)
111 {
112         debug_fenter(LOG_UI);
113         g_return_val_if_fail(sound_files, NULL);
114         return sound_files[index];
115 }
116
117 gboolean cam_sound_is_silent_mode(void)
118 {
119         int sound_on = -1;
120         if (!vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &sound_on)) {
121                 if (sound_on == FALSE) {
122                         cam_debug(LOG_SND, "sound off mode ");
123                         return TRUE;
124                 }
125         }
126         return FALSE;
127 }
128
129 gboolean cam_sound_set_mic()
130 {
131         int ret = SOUND_MANAGER_ERROR_NONE;
132         bool is_available = FALSE;
133         sound_route_e route_to_active = SOUND_ROUTE_IN_MIC;
134
135         /* Check if earphone mic is available */
136         is_available = sound_manager_is_route_available(SOUND_ROUTE_IN_WIRED_ACCESSORY);
137
138         /* If earphone mic is available, use earphone mic, otherwise use phone mic */
139         route_to_active = (is_available)? SOUND_ROUTE_IN_WIRED_ACCESSORY : SOUND_ROUTE_IN_MIC;
140         cam_debug(LOG_SND, "sound route is [%d]", route_to_active);
141
142         ret = sound_manager_set_active_route(route_to_active);
143         if (ret != SOUND_MANAGER_ERROR_NONE) {
144                 cam_critical(LOG_SND, "sound_manager_set_active_route [%d]) failed", route_to_active);
145         }
146
147         return ret;
148 }
149
150 static void cam_sound_callback(int id, void *data)
151 {
152         struct appdata *ad = (struct appdata *)data;
153         cam_ret_if(ad == NULL);
154
155 #ifdef USE_CAMERA_APP_SHUTTER_SOUND
156         cam_debug(LOG_MM, "release cond");
157
158         /*We can not set value to  sond_cond.
159            Bacause it can be assigned PTHREAD_COND_INITIALIZER only.
160            PTHREAD_COND_INITIALIZER is the MECRO of pthread.
161            So We use the sound_files, When the sound_cond is destroied, this value set to NULL.
162          */
163         if (sound_files)
164                 pthread_cond_broadcast(&sound_cond);
165
166         ad->play_rec_sound--;
167         DEBUG_TRACE("ad->play_rec_sound=%d", ad->play_rec_sound);
168 #endif
169         return;
170 }
171
172 gboolean cam_sound_play(int index, void *data)
173 {
174         struct appdata *ad = (struct appdata *)data;
175         cam_retv_if(ad == NULL, FALSE);
176
177 #ifdef CAMERA_MACHINE_I686
178         return TRUE;
179 #endif
180         int step = 0, handle = 0;
181 #ifdef USE_CAMERA_APP_SHUTTER_SOUND
182         gboolean sync = FALSE;
183         struct timespec timeout;
184         struct timeval tv;
185 #endif
186
187         g_return_val_if_fail(sound_files, FALSE);
188         g_return_val_if_fail(index >= 0 && index < CAM_SOUND_EFFECT_NUM, FALSE);
189
190         debug_msg(LOG_UI, "%s", sound_files[index]);
191
192         if (!sound_files[index]) {
193                 return FALSE;
194         }
195
196         if (cam_sound_is_silent_mode()) {
197                 warn_msg(LOG_SND, "Silent mode now");
198                 return FALSE;
199         }
200 #ifdef USE_CAMERA_APP_SHUTTER_SOUND
201         if (index == CAM_SOUND_EFFECT_REC_START1
202             || index == CAM_SOUND_EFFECT_REC_START2
203             || index == CAM_SOUND_EFFECT_REC_START3 || FALSE) {
204                 sync = TRUE;
205         }
206 #endif
207
208         cam_debug(LOG_MM, " Volume step : %d", step);
209 #ifdef USE_CAMERA_APP_SHUTTER_SOUND
210
211         if (EBUSY == pthread_mutex_trylock(&sound_lock)) {
212                 cam_critical(LOG_SND,
213                              "another effect sound is playing, try later");
214                 return FALSE;
215         }
216 #endif
217
218         if (WAV_PLAYER_ERROR_NONE ==
219             wav_player_start(sound_files[index], SOUND_TYPE_MEDIA,  cam_sound_callback, ad, &handle)) {
220 #ifdef USE_CAMERA_APP_SHUTTER_SOUND
221                 ad->play_rec_sound++;
222                 DEBUG_TRACE("ad->play_rec_sound=%d", ad->play_rec_sound);
223                 if (sync) {
224                         gettimeofday(&tv, NULL);
225                         timeout.tv_sec = tv.tv_sec + SOUND_TIMEOUT_SEC;
226                         timeout.tv_nsec = tv.tv_usec;
227                         if (ETIMEDOUT ==
228                             pthread_cond_timedwait(&sound_cond, &sound_lock,
229                                                    &timeout)) {
230                                 if (handle > 0) {
231                                         if (WAV_PLAYER_ERROR_NONE != wav_player_stop(handle) {
232                                                 cam_critical(LOG_SND, "sound play failed");
233                                         }
234                                 }
235                         }
236                 }
237 #endif
238         } else {
239                 cam_critical(LOG_SND, "effect sound play failed");
240 #ifdef USE_CAMERA_APP_SHUTTER_SOUND
241                 pthread_mutex_unlock(&sound_lock);
242 #endif
243                 return FALSE;
244         }
245 #ifdef USE_CAMERA_APP_SHUTTER_SOUND
246         pthread_mutex_unlock(&sound_lock);
247 #endif
248         return TRUE;
249 }