2 * Copyright (c) 2011 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',};
65 sttd_recorder_s *__recorder_getinstance();
66 void __recorder_state_set(sttd_recorder_state state);
69 int __recorder_setup();
71 int __recorder_pause();
72 int __recorder_send_buf_from_file();
74 int __recorder_cancel_to_stop();
75 int __recorder_commit_to_stop();
78 /* Event Callback Function */
79 gboolean _mm_recorder_audio_stream_cb (MMCamcorderAudioStreamDataType *stream, void *user_param)
81 sttd_recorder_s *pVr = __recorder_getinstance();
83 if (stream->length > 0 && stream->data) {
86 /* If stream callback is set */
87 if (STTD_RECORDER_PCM_S16 == pVr->audio_type || STTD_RECORDER_PCM_U8 == pVr->audio_type) {
89 /* write pcm buffer */
90 fwrite(stream->data, 1, stream->length, g_pFile);
93 pVr->streamcb(stream->data, stream->length);
103 int _camcorder_message_cb (int id, void *param, void *user_param)
105 MMMessageParamType *m = (MMMessageParamType *)param;
107 sttd_recorder_s *pVr = __recorder_getinstance();
111 case MM_MESSAGE_CAMCORDER_STATE_CHANGED_BY_ASM:
113 case MM_MESSAGE_CAMCORDER_STATE_CHANGED:
115 case MM_MESSAGE_CAMCORDER_MAX_SIZE:
116 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] MM_MESSAGE_CAMCORDER_MAX_SIZE");
117 sttd_recorder_stop();
119 case MM_MESSAGE_CAMCORDER_NO_FREE_SPACE:
120 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] MM_MESSAGE_CAMCORDER_NO_FREE_SPACE");
121 sttd_recorder_cancel();
123 case MM_MESSAGE_CAMCORDER_TIME_LIMIT:
124 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] MM_MESSAGE_CAMCORDER_TIME_LIMIT");
125 sttd_recorder_stop();
127 case MM_MESSAGE_CAMCORDER_ERROR:
128 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] MM_MESSAGE_CAMCORDER_ERROR");
129 sttd_recorder_cancel();
131 case MM_MESSAGE_CAMCORDER_RECORDING_STATUS:
133 case MM_MESSAGE_CAMCORDER_CURRENT_VOLUME:
134 pVr->volume = m->rec_volume_dB;
137 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Other Message=%d", id);
148 sttd_recorder_s *__recorder_getinstance()
152 g_objRecorer = g_malloc0(sizeof(sttd_recorder_s));
154 /* set default value */
155 g_objRecorer->time_limit = DEF_TIMELIMIT;
156 g_objRecorer->size_limit = DEF_MAXSIZE;
157 g_objRecorer->now = 0;
158 g_objRecorer->now_ms = 0;
159 g_objRecorer->frame = 0;
160 g_objRecorer->volume = 0.0f;
161 g_objRecorer->state = STTD_RECORDER_STATE_READY;
162 g_objRecorer->channel = STTD_RECORDER_CHANNEL_MONO;
163 g_objRecorer->audio_type = STTD_RECORDER_PCM_S16;
164 g_objRecorer->samplerate = DEF_SAMPLERATE;
165 g_objRecorer->streamcb = NULL;
171 void __recorder_state_set(sttd_recorder_state state)
173 sttd_recorder_s* pVr = __recorder_getinstance();
177 void __recorder_remove_temp_file()
179 /* NOTE: temp file can cause permission problem */
180 if (0 != access(g_temp_file_name, R_OK|W_OK)) {
181 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] *** You don't have access right to temp file");
183 if (0 != remove(g_temp_file_name)) {
184 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail to remove temp file");
190 /* MMFW Interface functions */
191 int __recorder_setup()
193 sttd_recorder_s *pVr = __recorder_getinstance();
195 /* mm-camcorder preset */
196 MMCamPreset cam_info;
198 int mmf_ret = MM_ERROR_NONE;
200 char* err_attr_name = NULL;
202 cam_info.videodev_type = MM_VIDEO_DEVICE_NONE;
204 /* Create camcorder */
205 mmf_ret = mm_camcorder_create( &pVr->rec_handle, &cam_info);
206 if (MM_ERROR_NONE != mmf_ret) {
207 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail mm_camcorder_create ret=(%X)", mmf_ret);
211 switch (pVr->audio_type) {
212 case STTD_RECORDER_PCM_U8:
213 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] STTD_RECORDER_PCM_U8");
214 err = mm_camcorder_set_attributes(pVr->rec_handle,
216 MMCAM_MODE, MM_CAMCORDER_MODE_AUDIO,
217 MMCAM_AUDIO_DEVICE, MM_AUDIO_DEVICE_MIC,
219 MMCAM_AUDIO_ENCODER, MM_AUDIO_CODEC_AAC,
220 MMCAM_FILE_FORMAT, MM_FILE_FORMAT_3GP,
222 MMCAM_AUDIO_SAMPLERATE, pVr->samplerate,
223 MMCAM_AUDIO_FORMAT, MM_CAMCORDER_AUDIO_FORMAT_PCM_U8,
224 MMCAM_AUDIO_CHANNEL, pVr->channel,
225 MMCAM_AUDIO_INPUT_ROUTE, MM_AUDIOROUTE_CAPTURE_NORMAL,
228 if (MM_ERROR_NONE != err) {
230 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail mm_camcorder_set_attributes ret=(%X)", mmf_ret);
236 case STTD_RECORDER_PCM_S16:
237 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] STTD_RECORDER_PCM_S16");
238 err = mm_camcorder_set_attributes(pVr->rec_handle,
240 MMCAM_MODE, MM_CAMCORDER_MODE_AUDIO,
241 MMCAM_AUDIO_DEVICE, MM_AUDIO_DEVICE_MIC,
242 MMCAM_AUDIO_ENCODER, MM_AUDIO_CODEC_AAC,
243 MMCAM_FILE_FORMAT, MM_FILE_FORMAT_3GP,
244 MMCAM_AUDIO_SAMPLERATE, pVr->samplerate,
245 MMCAM_AUDIO_FORMAT, MM_CAMCORDER_AUDIO_FORMAT_PCM_S16_LE,
246 MMCAM_AUDIO_CHANNEL, pVr->channel,
247 MMCAM_AUDIO_INPUT_ROUTE, MM_AUDIOROUTE_CAPTURE_NORMAL,
250 if (MM_ERROR_NONE != err) {
252 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail mm_camcorder_set_attributes ret=(%X)", mmf_ret);
257 case STTD_RECORDER_AMR:
258 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] STTD_RECORDER_AMR");
259 err = mm_camcorder_set_attributes(pVr->rec_handle,
261 MMCAM_MODE, MM_CAMCORDER_MODE_AUDIO,
262 MMCAM_AUDIO_DEVICE, MM_AUDIO_DEVICE_MIC,
264 MMCAM_AUDIO_ENCODER, MM_AUDIO_CODEC_AMR,
265 MMCAM_FILE_FORMAT, MM_FILE_FORMAT_AMR,
267 MMCAM_AUDIO_SAMPLERATE, pVr->samplerate,
268 MMCAM_AUDIO_CHANNEL, pVr->channel,
270 MMCAM_AUDIO_INPUT_ROUTE, MM_AUDIOROUTE_CAPTURE_NORMAL,
271 MMCAM_TARGET_TIME_LIMIT, pVr->time_limit,
272 MMCAM_TARGET_FILENAME, g_temp_file_name, strlen(g_temp_file_name)+1,
275 if (MM_ERROR_NONE != err) {
277 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail mm_camcorder_set_attributes ret=(%X)", mmf_ret);
283 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder ERROR]");
288 mmf_ret = mm_camcorder_set_audio_stream_callback(pVr->rec_handle, (mm_camcorder_audio_stream_callback)_mm_recorder_audio_stream_cb, NULL);
289 if (MM_ERROR_NONE != err) {
291 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail mm_camcorder_set_audio_stream_callback ret=(%X)", mmf_ret);
295 mmf_ret = mm_camcorder_set_message_callback(pVr->rec_handle, (MMMessageCallback)_camcorder_message_cb, pVr);
296 if (MM_ERROR_NONE != err) {
298 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail mm_camcorder_set_message_callback ret=(%X)", mmf_ret);
302 mmf_ret = mm_camcorder_realize(pVr->rec_handle);
303 if (MM_ERROR_NONE != err) {
305 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail mm_camcorder_realize=(%X)", mmf_ret);
309 /* Camcorder start */
310 mmf_ret = mm_camcorder_start(pVr->rec_handle);
311 if (MM_ERROR_NONE != mmf_ret) {
312 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail mm_camcorder_start=(%X)", mmf_ret);
316 SLOG(LOG_DEBUG, TAG_STTD, " - size_limit=%3d", pVr->size_limit);
317 SLOG(LOG_DEBUG, TAG_STTD, " - time_limit=%3d", pVr->time_limit);
318 SLOG(LOG_DEBUG, TAG_STTD, " - Audio Type=%d", pVr->audio_type);
319 SLOG(LOG_DEBUG, TAG_STTD, " - Sample rates=%d", pVr->samplerate);
320 SLOG(LOG_DEBUG, TAG_STTD, " - channel=%d", pVr->channel);
327 sttd_recorder_s *pVr = __recorder_getinstance();
328 int mmf_ret = MM_ERROR_NONE;
330 /* If recorder already has recording state, cancel */
331 if (STTD_RECORDER_STATE_RECORDING == pVr->state) {
332 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Stop recording first");
333 __recorder_cancel_to_stop();
336 /* Reset frame number */
340 mmf_ret = mm_camcorder_record(pVr->rec_handle);
341 if(MM_ERROR_NONE != mmf_ret ) {
343 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail mm_camcorder_record=(%X)", mmf_ret);
346 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Success mm_camcorder_record");
351 int __recorder_pause()
353 sttd_recorder_s *pVr = __recorder_getinstance();
354 int mmf_ret = MM_ERROR_NONE;
355 MMCamcorderStateType state_now = MM_CAMCORDER_STATE_NONE;
357 /* Get state from MMFW */
358 mmf_ret = mm_camcorder_get_state(pVr->rec_handle, &state_now);
359 if(mmf_ret != MM_ERROR_NONE ) {
360 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail to get state : mm_camcorder_get_state");
364 /* Check recording state */
365 if(MM_CAMCORDER_STATE_RECORDING != state_now) {
366 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Not recording state");
370 /* Pause recording */
371 mmf_ret = mm_camcorder_pause(pVr->rec_handle);
372 if(mmf_ret == MM_ERROR_NONE ) {
373 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] mm_camcorder_pause OK");
380 int __recorder_cancel_to_stop()
382 sttd_recorder_s *pVr = __recorder_getinstance();
383 int mmf_ret = MM_ERROR_NONE;
384 MMCamcorderStateType rec_status = MM_CAMCORDER_STATE_NONE;
386 /* Cancel camcorder */
387 mmf_ret = mm_camcorder_cancel(pVr->rec_handle);
388 if(mmf_ret != MM_ERROR_NONE ) {
389 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail to mm_camcorder_cancel");
394 mmf_ret = mm_camcorder_stop(pVr->rec_handle);
395 if(mmf_ret != MM_ERROR_NONE ) {
396 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail to mm_camcorder_stop");
400 /* Release resouces */
401 mm_camcorder_get_state(pVr->rec_handle, &rec_status);
402 if (MM_CAMCORDER_STATE_READY == rec_status) {
403 mmf_ret = mm_camcorder_unrealize(pVr->rec_handle);
404 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Call mm_camcorder_unrealize ret=(%X)", mmf_ret);
411 int __recorder_commit_to_stop()
413 sttd_recorder_s *pVr = __recorder_getinstance();
414 int mmf_ret = MM_ERROR_NONE;
415 MMCamcorderStateType rec_status = MM_CAMCORDER_STATE_NONE;
417 /* Commit camcorder */
418 mmf_ret = mm_camcorder_commit(pVr->rec_handle);
419 if(mmf_ret != MM_ERROR_NONE ) {
420 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail mm_camcorder_commit=%x", mmf_ret);
424 mmf_ret = mm_camcorder_stop(pVr->rec_handle);
425 if(mmf_ret != MM_ERROR_NONE ) {
426 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail mm_camcorder_stop=%x", mmf_ret);
429 /* Release resouces */
430 mm_camcorder_get_state(pVr->rec_handle, &rec_status);
431 if (MM_CAMCORDER_STATE_READY == rec_status) {
432 mmf_ret = mm_camcorder_unrealize(pVr->rec_handle);
433 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Call mm_camcorder_unrealize ret=(%X)", mmf_ret);
440 int __recorder_send_buf_from_file()
442 sttd_recorder_s *pVr = __recorder_getinstance();
445 if (!pVr->streamcb) {
446 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Return callback is not set");
450 if (STTD_RECORDER_AMR != pVr->audio_type) {
451 #ifndef BUF_SAVE_MODE
458 pFile = fopen(g_temp_file_name, "rb");
460 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] File not found!");
465 size_t read_size = 0;
468 while (!feof(pFile)) {
469 read_size = fread(buff, 1, 1024, pFile);
471 ret = pVr->streamcb((void*)buff, read_size);
474 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail to set recording");
485 int __vr_mmcam_destroy()
488 sttd_recorder_s *pVr = __recorder_getinstance();
490 MMCamcorderStateType rec_status = MM_CAMCORDER_STATE_NONE;
492 mm_camcorder_get_state(pVr->rec_handle, &rec_status);
493 if (rec_status == MM_CAMCORDER_STATE_NULL) {
494 err = mm_camcorder_destroy(pVr->rec_handle);
496 if (MM_ERROR_NONE == err) {
497 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] mm_camcorder_destroy OK");
500 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Error mm_camcorder_destroy %x", err);
509 /* External functions */
510 int sttd_recorder_init()
512 /* Create recorder instance */
513 sttd_recorder_s *pVr = __recorder_getinstance();
515 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail to initialize voice recorder!");
518 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Voice Recorder Initialized p=%p", pVr);
520 /* Set temp file name */
521 snprintf(g_temp_file_name, sizeof(g_temp_file_name), "/tmp/stt_temp_%d", getpid());
522 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Temp file name=[%s]", g_temp_file_name);
529 int sttd_recorder_set(sttd_recorder_audio_type type, sttd_recorder_channel ch, unsigned int sample_rate,
530 unsigned int max_time, sttvr_audio_cb cbfunc)
532 sttd_recorder_s *pVr = __recorder_getinstance();
535 if (STTD_RECORDER_STATE_RECORDING == pVr->state)
536 __recorder_cancel_to_stop();
538 if (STTD_RECORDER_STATE_READY != pVr->state)
539 __vr_mmcam_destroy();
542 pVr->audio_type = type;
544 pVr->samplerate = sample_rate;
545 pVr->time_limit = max_time;
547 /* Stream data Callback function */
549 pVr->streamcb = cbfunc;
554 int sttd_recorder_start()
558 __recorder_remove_temp_file();
561 sttd_recorder_s *pVr = __recorder_getinstance();
563 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail to initialize voice recorder!");
567 if (STTD_RECORDER_AMR != pVr->audio_type) {
569 g_pFile = fopen(g_temp_file_name, "wb+");
571 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] File not found!");
577 /* Check if initialized */
578 ret = __recorder_setup();
580 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail to call __recorder_setup");
583 /* Start camcorder */
584 ret = __recorder_run();
586 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail to call __recorder_run");
589 __recorder_state_set(STTD_RECORDER_STATE_RECORDING);
595 int sttrecorder_pause()
599 ret = __recorder_pause();
601 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail to call __recorder_pause");
606 __recorder_state_set(STTD_RECORDER_STATE_PAUSED);
611 int sttd_recorder_cancel()
614 ret = __recorder_cancel_to_stop();
616 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail to call __recorder_cancel_to_stop");
620 ret = __vr_mmcam_destroy();
622 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail to call __vr_mmcam_destroy");
627 __recorder_state_set(STTD_RECORDER_STATE_READY);
633 int sttd_recorder_stop()
637 ret = __recorder_commit_to_stop();
639 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail to call __recorder_commit_to_stop");
643 ret = __recorder_send_buf_from_file();
645 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail to call __recorder_send_buf_from_file");
649 ret = __vr_mmcam_destroy();
651 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail to call __vr_mmcam_destroy");
655 __recorder_state_set(STTD_RECORDER_STATE_READY);
661 int sttd_recorder_destroy()
663 /* Destroy recorder object */
665 g_free(g_objRecorer);
669 __recorder_state_set(STTD_RECORDER_STATE_READY);
675 int sttd_recorder_state_get(sttd_recorder_state* state)
677 sttd_recorder_s *pVr = __recorder_getinstance();
679 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail to get instance");
689 int sttd_recorder_get_volume(float *vol)
691 sttd_recorder_state state;
693 sttd_recorder_s *pVr = __recorder_getinstance();
695 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Fail to get instance");
699 sttd_recorder_state_get(&state);
700 if (STTD_RECORDER_STATE_RECORDING != state) {
701 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Not in Recording state");