2 * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd All Rights Reserved
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 * http://www.apache.org/licenses/LICENSE-2.0
7 * Unless required by applicable law or agreed to in writing, software
8 * distributed under the License is distributed on an "AS IS" BASIS,
9 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 * See the License for the specific language governing permissions and
11 * limitations under the License.
16 #include <mm_player.h>
19 #include <mm_camcorder.h>
20 #include <mm_session.h>
23 #include "sttd_recorder.h"
24 #include "sttd_main.h"
27 #define DEF_TIMELIMIT 120
28 #define DEF_SAMPLERATE 16000
29 #define DEF_BITRATE_AMR 12200
30 #define DEF_MAXSIZE 1024 * 1024 * 5
31 #define DEF_SOURCECHANNEL 1
32 #define DEF_BUFFER_SIZE 1024
35 //#define BUF_SAVE_MODE
38 unsigned int size_limit;
39 unsigned int time_limit;
47 unsigned int samplerate;
48 sttd_recorder_channel channel;
49 sttd_recorder_state state;
50 sttd_recorder_audio_type audio_type;
52 sttvr_audio_cb streamcb;
54 MMHandleType rec_handle;
55 MMHandleType ply_handle;
59 static sttd_recorder_s *g_objRecorer = NULL;
60 static bool g_init = false;
62 static char g_temp_file_name[128] = {'\0',};
69 sttd_recorder_s *__recorder_getinstance();
70 void __recorder_state_set(sttd_recorder_state state);
73 int __recorder_setup();
75 int __recorder_pause();
76 int __recorder_send_buf_from_file();
78 int __recorder_cancel_to_stop();
79 int __recorder_commit_to_stop();
82 /* Event Callback Function */
83 gboolean _mm_recorder_audio_stream_cb (MMCamcorderAudioStreamDataType *stream, void *user_param)
85 sttd_recorder_s *pVr = __recorder_getinstance();
87 if (stream->length > 0 && stream->data) {
90 /* If stream callback is set */
91 if (STTD_RECORDER_PCM_S16 == pVr->audio_type || STTD_RECORDER_PCM_U8 == pVr->audio_type) {
93 /* write pcm buffer */
94 fwrite(stream->data, 1, stream->length, g_pFile);
97 pVr->streamcb(stream->data, stream->length);
107 int _camcorder_message_cb (int id, void *param, void *user_param)
109 MMMessageParamType *m = (MMMessageParamType *)param;
111 sttd_recorder_s *pVr = __recorder_getinstance();
115 case MM_MESSAGE_CAMCORDER_STATE_CHANGED_BY_ASM:
117 case MM_MESSAGE_CAMCORDER_STATE_CHANGED:
119 case MM_MESSAGE_CAMCORDER_MAX_SIZE:
120 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] MM_MESSAGE_CAMCORDER_MAX_SIZE");
121 sttd_recorder_stop();
123 case MM_MESSAGE_CAMCORDER_NO_FREE_SPACE:
124 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] MM_MESSAGE_CAMCORDER_NO_FREE_SPACE");
125 sttd_recorder_cancel();
127 case MM_MESSAGE_CAMCORDER_TIME_LIMIT:
128 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] MM_MESSAGE_CAMCORDER_TIME_LIMIT");
129 sttd_recorder_stop();
131 case MM_MESSAGE_CAMCORDER_ERROR:
132 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] MM_MESSAGE_CAMCORDER_ERROR");
133 sttd_recorder_cancel();
135 case MM_MESSAGE_CAMCORDER_RECORDING_STATUS:
137 case MM_MESSAGE_CAMCORDER_CURRENT_VOLUME:
138 pVr->volume = m->rec_volume_dB;
141 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Other Message=%d", id);
152 sttd_recorder_s *__recorder_getinstance()
156 g_objRecorer = g_malloc0(sizeof(sttd_recorder_s));
158 /* set default value */
159 g_objRecorer->time_limit = DEF_TIMELIMIT;
160 g_objRecorer->size_limit = DEF_MAXSIZE;
161 g_objRecorer->now = 0;
162 g_objRecorer->now_ms = 0;
163 g_objRecorer->frame = 0;
164 g_objRecorer->volume = 0.0f;
165 g_objRecorer->state = STTD_RECORDER_STATE_READY;
166 g_objRecorer->channel = STTD_RECORDER_CHANNEL_MONO;
167 g_objRecorer->audio_type = STTD_RECORDER_PCM_S16;
168 g_objRecorer->samplerate = DEF_SAMPLERATE;
169 g_objRecorer->streamcb = NULL;
175 void __recorder_state_set(sttd_recorder_state state)
177 sttd_recorder_s* pVr = __recorder_getinstance();
181 void __recorder_remove_temp_file()
183 /* NOTE: temp file can cause permission problem */
184 if (0 != access(g_temp_file_name, R_OK|W_OK)) {
185 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] *** You don't have access right to temp file");
187 if (0 != remove(g_temp_file_name)) {
188 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail to remove temp file");
194 /* MMFW Interface functions */
195 int __recorder_setup()
197 sttd_recorder_s *pVr = __recorder_getinstance();
199 /* mm-camcorder preset */
200 MMCamPreset cam_info;
202 int mmf_ret = MM_ERROR_NONE;
204 char* err_attr_name = NULL;
206 cam_info.videodev_type = MM_VIDEO_DEVICE_NONE;
208 /* Create camcorder */
209 mmf_ret = mm_camcorder_create( &pVr->rec_handle, &cam_info);
210 if (MM_ERROR_NONE != mmf_ret) {
211 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail mm_camcorder_create ret=(%X)", mmf_ret);
215 switch (pVr->audio_type) {
216 case STTD_RECORDER_PCM_U8:
217 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] STTD_RECORDER_PCM_U8");
218 err = mm_camcorder_set_attributes(pVr->rec_handle,
220 MMCAM_MODE, MM_CAMCORDER_MODE_AUDIO,
221 MMCAM_AUDIO_DEVICE, MM_AUDIO_DEVICE_MIC,
223 MMCAM_AUDIO_ENCODER, MM_AUDIO_CODEC_AAC,
224 MMCAM_FILE_FORMAT, MM_FILE_FORMAT_3GP,
226 MMCAM_AUDIO_SAMPLERATE, pVr->samplerate,
227 MMCAM_AUDIO_FORMAT, MM_CAMCORDER_AUDIO_FORMAT_PCM_U8,
228 MMCAM_AUDIO_CHANNEL, pVr->channel,
229 MMCAM_AUDIO_INPUT_ROUTE, MM_AUDIOROUTE_CAPTURE_NORMAL,
232 if (MM_ERROR_NONE != err) {
234 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail mm_camcorder_set_attributes ret=(%X)", mmf_ret);
240 case STTD_RECORDER_PCM_S16:
241 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] STTD_RECORDER_PCM_S16");
242 err = mm_camcorder_set_attributes(pVr->rec_handle,
244 MMCAM_MODE, MM_CAMCORDER_MODE_AUDIO,
245 MMCAM_AUDIO_DEVICE, MM_AUDIO_DEVICE_MIC,
246 MMCAM_AUDIO_ENCODER, MM_AUDIO_CODEC_AAC,
247 MMCAM_FILE_FORMAT, MM_FILE_FORMAT_3GP,
248 MMCAM_AUDIO_SAMPLERATE, pVr->samplerate,
249 MMCAM_AUDIO_FORMAT, MM_CAMCORDER_AUDIO_FORMAT_PCM_S16_LE,
250 MMCAM_AUDIO_CHANNEL, pVr->channel,
251 MMCAM_AUDIO_INPUT_ROUTE, MM_AUDIOROUTE_CAPTURE_NORMAL,
254 if (MM_ERROR_NONE != err) {
256 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail mm_camcorder_set_attributes ret=(%X)", mmf_ret);
261 case STTD_RECORDER_AMR:
262 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] STTD_RECORDER_AMR");
263 err = mm_camcorder_set_attributes(pVr->rec_handle,
265 MMCAM_MODE, MM_CAMCORDER_MODE_AUDIO,
266 MMCAM_AUDIO_DEVICE, MM_AUDIO_DEVICE_MIC,
268 MMCAM_AUDIO_ENCODER, MM_AUDIO_CODEC_AMR,
269 MMCAM_FILE_FORMAT, MM_FILE_FORMAT_AMR,
271 MMCAM_AUDIO_SAMPLERATE, pVr->samplerate,
272 MMCAM_AUDIO_CHANNEL, pVr->channel,
274 MMCAM_AUDIO_INPUT_ROUTE, MM_AUDIOROUTE_CAPTURE_NORMAL,
275 MMCAM_TARGET_TIME_LIMIT, pVr->time_limit,
276 MMCAM_TARGET_FILENAME, g_temp_file_name, strlen(g_temp_file_name)+1,
279 if (MM_ERROR_NONE != err) {
281 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail mm_camcorder_set_attributes ret=(%X)", mmf_ret);
287 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder ERROR]");
292 mmf_ret = mm_camcorder_set_audio_stream_callback(pVr->rec_handle, (mm_camcorder_audio_stream_callback)_mm_recorder_audio_stream_cb, NULL);
293 if (MM_ERROR_NONE != err) {
295 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail mm_camcorder_set_audio_stream_callback ret=(%X)", mmf_ret);
299 mmf_ret = mm_camcorder_set_message_callback(pVr->rec_handle, (MMMessageCallback)_camcorder_message_cb, pVr);
300 if (MM_ERROR_NONE != err) {
302 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail mm_camcorder_set_message_callback ret=(%X)", mmf_ret);
306 mmf_ret = mm_camcorder_realize(pVr->rec_handle);
307 if (MM_ERROR_NONE != err) {
309 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail mm_camcorder_realize=(%X)", mmf_ret);
313 /* Camcorder start */
314 mmf_ret = mm_camcorder_start(pVr->rec_handle);
315 if (MM_ERROR_NONE != mmf_ret) {
316 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail mm_camcorder_start=(%X)", mmf_ret);
320 SLOG(LOG_DEBUG, TAG_STTD, " - size_limit=%3d", pVr->size_limit);
321 SLOG(LOG_DEBUG, TAG_STTD, " - time_limit=%3d", pVr->time_limit);
322 SLOG(LOG_DEBUG, TAG_STTD, " - Audio Type=%d", pVr->audio_type);
323 SLOG(LOG_DEBUG, TAG_STTD, " - Sample rates=%d", pVr->samplerate);
324 SLOG(LOG_DEBUG, TAG_STTD, " - channel=%d", pVr->channel);
331 sttd_recorder_s *pVr = __recorder_getinstance();
332 int mmf_ret = MM_ERROR_NONE;
334 /* If recorder already has recording state, cancel */
335 if (STTD_RECORDER_STATE_RECORDING == pVr->state) {
336 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Stop recording first");
337 __recorder_cancel_to_stop();
340 /* Reset frame number */
344 mmf_ret = mm_camcorder_record(pVr->rec_handle);
345 if(MM_ERROR_NONE != mmf_ret ) {
347 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail mm_camcorder_record=(%X)", mmf_ret);
350 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Success mm_camcorder_record");
355 int __recorder_pause()
357 sttd_recorder_s *pVr = __recorder_getinstance();
358 int mmf_ret = MM_ERROR_NONE;
359 MMCamcorderStateType state_now = MM_CAMCORDER_STATE_NONE;
361 /* Get state from MMFW */
362 mmf_ret = mm_camcorder_get_state(pVr->rec_handle, &state_now);
363 if(mmf_ret != MM_ERROR_NONE ) {
364 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail to get state : mm_camcorder_get_state");
368 /* Check recording state */
369 if(MM_CAMCORDER_STATE_RECORDING != state_now) {
370 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Not recording state");
374 /* Pause recording */
375 mmf_ret = mm_camcorder_pause(pVr->rec_handle);
376 if(mmf_ret == MM_ERROR_NONE ) {
377 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] mm_camcorder_pause OK");
384 int __recorder_cancel_to_stop()
386 sttd_recorder_s *pVr = __recorder_getinstance();
387 int mmf_ret = MM_ERROR_NONE;
388 MMCamcorderStateType rec_status = MM_CAMCORDER_STATE_NONE;
390 /* Cancel camcorder */
391 mmf_ret = mm_camcorder_cancel(pVr->rec_handle);
392 if(mmf_ret != MM_ERROR_NONE ) {
393 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail to mm_camcorder_cancel");
398 mmf_ret = mm_camcorder_stop(pVr->rec_handle);
399 if(mmf_ret != MM_ERROR_NONE ) {
400 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail to mm_camcorder_stop");
404 /* Release resouces */
405 mm_camcorder_get_state(pVr->rec_handle, &rec_status);
406 if (MM_CAMCORDER_STATE_READY == rec_status) {
407 mmf_ret = mm_camcorder_unrealize(pVr->rec_handle);
408 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Call mm_camcorder_unrealize ret=(%X)", mmf_ret);
415 int __recorder_commit_to_stop()
417 sttd_recorder_s *pVr = __recorder_getinstance();
418 int mmf_ret = MM_ERROR_NONE;
419 MMCamcorderStateType rec_status = MM_CAMCORDER_STATE_NONE;
421 /* Commit camcorder */
422 mmf_ret = mm_camcorder_commit(pVr->rec_handle);
423 if(mmf_ret != MM_ERROR_NONE ) {
424 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail mm_camcorder_commit=%x", mmf_ret);
428 mmf_ret = mm_camcorder_stop(pVr->rec_handle);
429 if(mmf_ret != MM_ERROR_NONE ) {
430 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail mm_camcorder_stop=%x", mmf_ret);
433 /* Release resouces */
434 mm_camcorder_get_state(pVr->rec_handle, &rec_status);
435 if (MM_CAMCORDER_STATE_READY == rec_status) {
436 mmf_ret = mm_camcorder_unrealize(pVr->rec_handle);
437 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Call mm_camcorder_unrealize ret=(%X)", mmf_ret);
444 int __recorder_send_buf_from_file()
446 sttd_recorder_s *pVr = __recorder_getinstance();
449 if (!pVr->streamcb) {
450 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Return callback is not set");
454 if (STTD_RECORDER_AMR != pVr->audio_type) {
455 #ifndef BUF_SAVE_MODE
462 pFile = fopen(g_temp_file_name, "rb");
464 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] File not found!");
469 size_t read_size = 0;
472 while (!feof(pFile)) {
473 read_size = fread(buff, 1, 1024, pFile);
475 ret = pVr->streamcb((void*)buff, read_size);
478 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail to set recording");
489 int __vr_mmcam_destroy()
492 sttd_recorder_s *pVr = __recorder_getinstance();
494 MMCamcorderStateType rec_status = MM_CAMCORDER_STATE_NONE;
496 mm_camcorder_get_state(pVr->rec_handle, &rec_status);
497 if (rec_status == MM_CAMCORDER_STATE_NULL) {
498 err = mm_camcorder_destroy(pVr->rec_handle);
500 if (MM_ERROR_NONE == err) {
501 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] mm_camcorder_destroy OK");
504 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Error mm_camcorder_destroy %x", err);
513 /* External functions */
514 int sttd_recorder_init()
516 /* Create recorder instance */
517 sttd_recorder_s *pVr = __recorder_getinstance();
519 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail to initialize voice recorder!");
522 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Voice Recorder Initialized p=%p", pVr);
524 /* Set temp file name */
525 snprintf(g_temp_file_name, sizeof(g_temp_file_name), "/tmp/stt_temp_%d", getpid());
526 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Temp file name=[%s]", g_temp_file_name);
533 int sttd_recorder_set(sttd_recorder_audio_type type, sttd_recorder_channel ch, unsigned int sample_rate,
534 unsigned int max_time, sttvr_audio_cb cbfunc)
536 sttd_recorder_s *pVr = __recorder_getinstance();
539 if (STTD_RECORDER_STATE_RECORDING == pVr->state)
540 __recorder_cancel_to_stop();
542 if (STTD_RECORDER_STATE_READY != pVr->state)
543 __vr_mmcam_destroy();
546 pVr->audio_type = type;
548 pVr->samplerate = sample_rate;
549 pVr->time_limit = max_time;
551 /* Stream data Callback function */
553 pVr->streamcb = cbfunc;
558 int sttd_recorder_start()
562 __recorder_remove_temp_file();
565 sttd_recorder_s *pVr = __recorder_getinstance();
567 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail to initialize voice recorder!");
571 if (STTD_RECORDER_AMR != pVr->audio_type) {
573 g_pFile = fopen(g_temp_file_name, "wb+");
575 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] File not found!");
581 /* Check if initialized */
582 ret = __recorder_setup();
584 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail to call __recorder_setup");
585 return STTD_ERROR_OPERATION_FAILED;
588 /* Start camcorder */
589 ret = __recorder_run();
591 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail to call __recorder_run");
592 return STTD_ERROR_OPERATION_FAILED;
595 __recorder_state_set(STTD_RECORDER_STATE_RECORDING);
601 int sttrecorder_pause()
605 ret = __recorder_pause();
607 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail to call __recorder_pause");
612 __recorder_state_set(STTD_RECORDER_STATE_PAUSED);
617 int sttd_recorder_cancel()
620 ret = __recorder_cancel_to_stop();
622 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail to call __recorder_cancel_to_stop");
626 ret = __vr_mmcam_destroy();
628 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail to call __vr_mmcam_destroy");
633 __recorder_state_set(STTD_RECORDER_STATE_READY);
639 int sttd_recorder_stop()
643 ret = __recorder_commit_to_stop();
645 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail to call __recorder_commit_to_stop");
649 ret = __recorder_send_buf_from_file();
651 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail to call __recorder_send_buf_from_file");
655 ret = __vr_mmcam_destroy();
657 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail to call __vr_mmcam_destroy");
661 __recorder_state_set(STTD_RECORDER_STATE_READY);
667 int sttd_recorder_destroy()
669 /* Destroy recorder object */
671 g_free(g_objRecorer);
675 __recorder_state_set(STTD_RECORDER_STATE_READY);
681 int sttd_recorder_state_get(sttd_recorder_state* state)
683 sttd_recorder_s *pVr = __recorder_getinstance();
685 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail to get instance");
695 int sttd_recorder_get_volume(float *vol)
697 sttd_recorder_state state;
699 sttd_recorder_s *pVr = __recorder_getinstance();
701 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail to get instance");
705 sttd_recorder_state_get(&state);
706 if (STTD_RECORDER_STATE_RECORDING != state) {
707 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Not in Recording state");