2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include <Elementary.h>
18 #include <app_common.h>
20 #include <media_content.h>
23 #include "voice-recorder.h"
27 #define VR_AUDIO_SOURCE_SAMPLERATE_LOW 8000
28 #define VR_AUDIO_SOURCE_SAMPLERATE_HIGH 44100
29 #define VR_AUDIO_ENCODER_BITRATE_AMR 12200
30 #define VR_AUDIO_ENCODER_BITRATE_AAC 64000
32 static voice_recorder *recorderhandle = NULL;
34 static void _recorder_create(voice_recorder *view);
35 static void _recorder_start(voice_recorder *view);
36 static void _recorder_stop(voice_recorder *view);
37 static void _recorder_apply_settings(voice_recorder *view);
38 static void _on_recording_status_cb(unsigned long long elapsed_time, unsigned long long file_size, void *user_data);
39 static void _on_recording_limit_reached_cb(recorder_recording_limit_type_e type, void *user_data);
40 static bool _main_file_register(const char *filename);
41 static void _recorder_destroy(voice_recorder *view);
43 void init_voice_recorder(app_control_h service)
45 voice_recorder *recorder = (voice_recorder *)malloc(sizeof(voice_recorder));
47 LOGD("Error Failed to create recorder");
51 _voice_recorder_set_data(recorder);
53 recorder->is_recording = FALSE;
54 recorder->service = service;
55 recorder->limitsize = 1000000;
57 _recorder_create(recorder);
60 void destroy_voice_recorder()
62 LOGD("destroy_voice_recorder()");
63 voice_recorder *recorder = (voice_recorder *)_voice_recorder_get_data();
65 _recorder_destroy(recorder);
67 _voice_recorder_set_data(NULL);
70 void start_voice_recorder()
72 voice_recorder *recorder = (voice_recorder *)_voice_recorder_get_data();
73 _recorder_start(recorder);
76 void stop_voice_recorder()
78 voice_recorder *recorder = (voice_recorder *)_voice_recorder_get_data();
79 _recorder_stop(recorder);
82 void _voice_recorder_set_data(void *data)
84 recorderhandle = (voice_recorder *)data;
87 voice_recorder *_voice_recorder_get_data()
90 return recorderhandle;
95 static void _recorder_create(voice_recorder *recorder)
97 LOGD("_recorder_create");
99 int ret = recorder_create_audiorecorder(&recorder->recorder);
100 if (ret == RECORDER_ERROR_NONE) {
101 recorder_set_recording_status_cb(recorder->recorder, _on_recording_status_cb, recorder);
102 if (recorder->limitsize > 0) {
103 recorder_attr_set_size_limit(recorder->recorder, (recorder->limitsize) / 1024);
105 recorder_set_recording_limit_reached_cb(recorder->recorder, _on_recording_limit_reached_cb, recorder);
107 LOGD("recorder_create_audiorecorder not successful error code: %d", ret);
111 static void _recorder_start(voice_recorder *recorder)
113 LOGD("_recorder_start");
114 if (!recorder->recorder) {
115 LOGD("Error recorder->recorder is null");
119 recorder_state_e rec_state;
120 recorder_get_state(recorder->recorder, &rec_state);
122 if (rec_state == RECORDER_STATE_PAUSED) {
123 recorder_start(recorder->recorder);
127 struct tm localtime = {0, };
128 time_t rawtime = time(NULL);
129 char filename[256] = {'\0', };
130 char *voice_content_path = NULL;
131 storage_get_directory(STORAGE_TYPE_INTERNAL, STORAGE_DIRECTORY_SOUNDS, &voice_content_path);
132 if (voice_content_path == NULL) {
133 LOGD("voice_content_path is NULL");
139 recorder->codec = RECORDER_AUDIO_CODEC_AMR;
140 recorder->file_format = RECORDER_FILE_FORMAT_AMR;
141 recorder->sample_rate = VR_AUDIO_SOURCE_SAMPLERATE_LOW;
142 recorder->bitrate = VR_AUDIO_ENCODER_BITRATE_AMR;
143 if (localtime_r(&rawtime, &localtime) != NULL) {
144 snprintf(filename, sizeof(filename), "Voice-%04i-%02i-%02i_%02i:%02i:%02i.amr",
145 localtime.tm_year + 1900, localtime.tm_mon + 1, localtime.tm_mday,
146 localtime.tm_hour, localtime.tm_min, localtime.tm_sec);
150 recorder->codec = RECORDER_AUDIO_CODEC_AAC;
151 recorder->file_format = RECORDER_FILE_FORMAT_MP4;
152 recorder->sample_rate = VR_AUDIO_SOURCE_SAMPLERATE_HIGH;
153 recorder->bitrate = VR_AUDIO_ENCODER_BITRATE_AAC;
154 if (localtime_r(&rawtime, &localtime) != NULL) {
155 snprintf(filename, sizeof(filename), "Voice-%04i-%02i-%02i_%02i:%02i:%02i.m4a",
156 localtime.tm_year + 1900, localtime.tm_mon + 1, localtime.tm_mday,
157 localtime.tm_hour, localtime.tm_min, localtime.tm_sec);
161 snprintf(recorder->file_path, PATH_MAX, "%s/%s", voice_content_path, filename);
162 LOGD("recorder->file_path = %s", recorder->file_path);
163 _recorder_apply_settings(recorder);
164 free(voice_content_path);
165 recorder_prepare(recorder->recorder);
166 recorder_start(recorder->recorder);
169 static void _recorder_stop(voice_recorder *recorder)
171 LOGD("_recorder_stop");
172 int commitResult = RECORDER_ERROR_NONE;
174 if (recorder->recorder) {
175 commitResult = recorder_commit(recorder->recorder);
176 if (commitResult != RECORDER_ERROR_NONE) {
177 LOGD("recorder_commit failed Error [%d]", recorder_commit);
179 _main_file_register(recorder->file_path);
183 static void _recorder_apply_settings(voice_recorder *recorder)
186 if (recorder->recorder) {
187 error_code = recorder_attr_set_audio_channel(recorder->recorder, 2);
188 if (error_code != RECORDER_ERROR_NONE)
189 LOGW("Failed to set audio channel. error code : %d", error_code);
191 recorder_attr_set_audio_device(recorder->recorder, RECORDER_AUDIO_DEVICE_MIC);
192 error_code = recorder_attr_set_time_limit(recorder->recorder, MAX_TIME);
193 if (error_code != RECORDER_ERROR_NONE)
194 LOGW("Failed to set time limit. error code : %d", error_code);
196 recorder_set_filename(recorder->recorder, recorder->file_path);
197 error_code = recorder_set_file_format(recorder->recorder, recorder->file_format);
198 if (error_code != RECORDER_ERROR_NONE)
199 LOGW("Failed to set file format. error code : %d", error_code);
201 LOGD("file_format: %d", recorder->file_format);
202 error_code = recorder_set_audio_encoder(recorder->recorder, recorder->codec);
203 if (error_code != RECORDER_ERROR_NONE)
204 LOGW("Failed to set audio encoder. error code : %d", error_code);
206 recorder_attr_set_audio_samplerate(recorder->recorder, recorder->sample_rate);
207 recorder_attr_set_audio_encoder_bitrate(recorder->recorder, recorder->bitrate);
209 recorder_prepare(recorder->recorder);
213 static void _on_recording_status_cb(unsigned long long elapsed_time, unsigned long long file_size, void *user_data)
215 voice_recorder *recorder = (voice_recorder *)user_data;
218 recorder_state_e rec_state = RECORDER_STATE_NONE;
219 recorder_get_state(recorder->recorder, &rec_state);
220 if (rec_state == RECORDER_STATE_PAUSED || rec_state == RECORDER_STATE_READY) {
226 static void _on_recording_limit_reached_cb(recorder_recording_limit_type_e type, void *user_data)
228 voice_recorder *recorder = (voice_recorder *)user_data;
230 if (type == RECORDER_RECORDING_LIMIT_TIME) {
231 _recorder_stop(recorder);
232 } else if (type == RECORDER_RECORDING_LIMIT_SIZE) {
233 _recorder_stop(recorder);
238 static bool _main_file_register(const char *filename)
240 LOGD("_main_file_register");
242 media_info_h info = NULL;
244 char *register_file = strdup(filename);
245 if (register_file == NULL) {
246 LOGD("Failed to allocate memory");
250 err_code = media_info_insert_to_db(register_file, &info);
251 if (err_code != MEDIA_CONTENT_ERROR_NONE) {
252 LOGD("failed to media_file_register() : [%s], [%d]", register_file, err_code);
253 media_info_destroy(info);
258 media_info_destroy(info);
264 static void _recorder_destroy(voice_recorder *recorder)
267 LOGD("_recorder_destroy");
268 if (recorder->recorder) {
269 error_code = recorder_cancel(recorder->recorder);
270 if (error_code != RECORDER_ERROR_NONE)
271 LOGW("failed to cancel recorder. error : %d", error_code);
273 recorder_unprepare(recorder->recorder);
274 recorder_destroy(recorder->recorder);
275 recorder->recorder = NULL;