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.
17 #include "sttd_recorder.h"
18 #include "sttd_main.h"
22 #define FRAME_LENGTH 160
23 #define BUFFER_LENGTH FRAME_LENGTH * 2
25 static stt_recorder_audio_cb g_audio_cb;
26 static audio_in_h g_audio_in_h;
28 static sttd_recorder_state g_recorder_state = -1;
30 static sttp_audio_type_e g_audio_type;
32 static char g_buffer[BUFFER_LENGTH];
34 static FILE* g_pFile_vol;
36 static char g_temp_vol[64];
44 static char g_temp_file_name[128] = {'\0',};
48 static int g_count = 1;
51 int sttd_recorder_create(stt_recorder_audio_cb callback, sttp_audio_type_e type, int channel, unsigned int sample_rate)
53 if (NULL == callback) {
54 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Input param is NOT valid");
55 return STTD_ERROR_INVALID_PARAMETER;
58 audio_channel_e audio_ch;
59 audio_sample_type_e audio_type;
62 case 1: audio_ch = AUDIO_CHANNEL_MONO; break;
63 case 2: audio_ch = AUDIO_CHANNEL_STEREO; break;
65 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Input channel is not supported");
66 return STTD_ERROR_OPERATION_FAILED;
71 case STTP_AUDIO_TYPE_PCM_S16_LE: audio_type = AUDIO_SAMPLE_TYPE_S16_LE; break;
72 case STTP_AUDIO_TYPE_PCM_U8: audio_type = AUDIO_SAMPLE_TYPE_U8; break;
74 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Invalid Audio Type");
75 return STTD_ERROR_OPERATION_FAILED;
80 ret = audio_in_create(sample_rate, audio_ch, audio_type, &g_audio_in_h);
81 if (AUDIO_IO_ERROR_NONE != ret) {
82 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail to create audio handle : %d", ret);
83 return STTD_ERROR_OPERATION_FAILED;
86 g_audio_cb = callback;
87 g_recorder_state = STTD_RECORDER_STATE_READY;
93 int sttd_recorder_destroy()
96 if (STTD_RECORDER_STATE_RECORDING == g_recorder_state) {
97 ret = audio_in_unprepare(g_audio_in_h);
98 if (AUDIO_IO_ERROR_NONE != ret) {
99 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail to unprepare audio_in");
103 ret = audio_in_destroy(g_audio_in_h);
104 if (AUDIO_IO_ERROR_NONE != ret) {
105 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail to destroy audio_in");
109 g_recorder_state = -1;
111 if (0 == access(STT_AUDIO_VOLUME_PATH, R_OK)) {
112 if (0 == remove(STT_AUDIO_VOLUME_PATH)) {
113 SLOG(LOG_WARN, TAG_STTD, "[Recorder WARN] Fail to remove volume file");
120 static float get_volume_decibel(char* data, int size, sttp_audio_type_e type)
122 #define MAX_AMPLITUDE_MEAN_16 23170.115738161934
123 #define MAX_AMPLITUDE_MEAN_08 89.803909382810
133 unsigned long long square_sum = 0;
135 if (type == STTP_AUDIO_TYPE_PCM_S16_LE)
140 for (i = 0; i < size; i += (depthByte<<1)) {
141 if (depthByte == 2) {
142 pcm16 = (short*)(data + i);
143 square_sum += (*pcm16) * (*pcm16);
145 pcm8 = (char*)(data +i);
146 square_sum += (*pcm8) * (*pcm8);
151 rms = sqrt(square_sum/count);
154 db = 20 * log10(rms/MAX_AMPLITUDE_MEAN_16);
156 db = 20 * log10(rms/MAX_AMPLITUDE_MEAN_08);
161 Eina_Bool __read_audio_func(void *data)
165 if (STTD_RECORDER_STATE_READY == g_recorder_state) {
166 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Exit audio reading func");
170 read_byte = audio_in_read(g_audio_in_h, g_buffer, BUFFER_LENGTH);
172 SLOG(LOG_WARN, TAG_STTD, "[Recorder WARNING] Fail to read audio : %d", read_byte);
173 g_recorder_state = STTD_RECORDER_STATE_READY;
177 if (0 != g_audio_cb(g_buffer, read_byte)) {
178 SLOG(LOG_WARN, TAG_STTD, "[Recorder WARNING] Fail audio callback");
179 sttd_recorder_stop();
183 float vol_db = get_volume_decibel(g_buffer, BUFFER_LENGTH, g_audio_type);
186 fwrite((void*)(&vol_db), sizeof(vol_db), 1, g_pFile_vol);
189 /* write pcm buffer */
190 fwrite(g_buffer, 1, BUFFER_LENGTH, g_pFile);
196 int sttd_recorder_start()
198 if (STTD_RECORDER_STATE_RECORDING == g_recorder_state)
202 ret = audio_in_prepare(g_audio_in_h);
203 if (AUDIO_IO_ERROR_NONE != ret) {
204 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail to prepare audio in : %d", ret);
205 return STTD_ERROR_OPERATION_FAILED;
208 /* Add ecore timer to read audio data */
209 ecore_timer_add(0, __read_audio_func, NULL);
211 g_recorder_state = STTD_RECORDER_STATE_RECORDING;
213 g_pFile_vol = fopen(STT_AUDIO_VOLUME_PATH, "wb+");
215 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail to create Volume File");
223 snprintf(g_temp_file_name, sizeof(g_temp_file_name), "/tmp/stt_temp_%d_%d", getpid(), g_count);
224 SLOG(LOG_DEBUG, TAG_STTD, "[Recorder] Temp file name=[%s]", g_temp_file_name);
227 g_pFile = fopen(g_temp_file_name, "wb+");
229 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] File not found!");
237 int sttd_recorder_stop()
239 if (STTD_RECORDER_STATE_READY == g_recorder_state)
242 g_recorder_state = STTD_RECORDER_STATE_READY;
244 int ret = STTD_ERROR_OPERATION_FAILED;
245 ret = audio_in_unprepare(g_audio_in_h);
246 if (AUDIO_IO_ERROR_NONE != ret) {
247 SLOG(LOG_ERROR, TAG_STTD, "[Recorder ERROR] Fail to unprepare audio_in : %d", ret);
256 SLOG(LOG_ERROR, TAG_STTD, "[Recorder] Recorder stop success");