blob: 63ce4633f13b4b9c2f49187debefa61e7202ae77 [file] [log] [blame]
yu.dong8e5f3262023-10-10 03:18:01 -07001#include <stdint.h>
2#include <stdio.h>
3#include <string.h>
4
5#include "liblog/lynq_deflog.h"
6
7#ifdef __cplusplus
8extern "C" {
9#endif
10
11#include "sc_audio.h"
12#include "lynq-qser-audio.h"
13
14#define AUDIO_INIT_MAX_TRY_CNT 100
15
16#define SC_AUDIO_BE_DAI_MIN -1
17#define SC_AUDIO_STREAM_FORMAT_INVALID 0
18
yu.dong72202352023-12-01 00:42:47 -080019sc_audio_handle_t playback_handle = SC_AUDIO_INVALID_HANDLE;
20sc_audio_handle_t capture_handle = SC_AUDIO_INVALID_HANDLE;
21
yu.dong8e5f3262023-10-10 03:18:01 -070022/********************************************************************
23* @brief: _cb_onPlayer, typedef for a callback function that is called
24 when an audio operation is performed
25* @param int [IN]: The result of the audio operation, 0 if successful, non-zero if failed
26* @return : void
27* @todo: NA
28* @see: NA
29* @warning: NA
30*********************************************************************/
31typedef void (*_cb_onPlayer)(int);
32
33/********************************************************************
34* @brief: playback_state_cb, callback function that is called when the audio playback state changes
35* @param handle [IN]: sc_audio_handle_t, the handle of the audio device
36* @param params [IN]: void*, parameters for the callback function
37* @param state [IN]: sc_audio_playback_state_e, the current state of audio playback
38* @return : int, 0 if successful, non-zero if failed
39* @todo: NA
40* @see: NA
41* @warning: NA
42*********************************************************************/
43int playback_state_cb (sc_audio_handle_t handle, void *params, sc_audio_playback_state_e state)
44{
45 LYINFLOG("playback_state_cb handle:0x%lx state:%d\n", handle, state);
46 return 0;
47}
48
49/********************************************************************
50* @brief: capture_state_cb, callback function that is called when the audio capture state changes
51* @param handle [IN]: sc_audio_handle_t, the handle of the audio device
52* @param params [IN]: void*, parameters for the callback function
53* @param state [IN]: sc_audio_capture_state_e, the current state of audio capture
54* @return : int, 0 if successful, non-zero if failed
55* @todo: NA
56* @see: NA
57* @warning: NA
58*********************************************************************/
59int capture_state_cb (sc_audio_handle_t handle, void *params, sc_audio_capture_state_e state)
60{
61 LYINFLOG("capture_state_cb handle:0x%lx state:%d\n", handle, state);
62
63 return 0;
64}
65
66/********************************************************************
67* @brief: get_device_enum, function to convert a device string to its corresponding enum
68* @param device [IN]: const char*, the name of the device
69* @return : sc_audio_fe_pcm_dev_e, the enum corresponding to the device name
70* @todo: NA
71* @see: NA
72* @warning: NA
73*********************************************************************/
74sc_audio_fe_pcm_dev_e get_device_enum(const char* device)
75{
76 if (strcmp(device, "device1") == 0)
77 {
78 return SC_AUDIO_FE_PCM_DEV_MULTIMEDIA1;
79 }
80 else if (strcmp(device, "device2") == 0)
81 {
82 return SC_AUDIO_FE_PCM_DEV_MULTIMEDIA2;
83 }
84 else
85 {
86 return SC_AUDIO_INVALID_HANDLE;
87 }
88}
89
90/********************************************************************
91* @brief: qser_AudPlayer_Open, open the audio device for playback
92* @param device [IN]: char* device, the audio device to be opened for playback
93* @param cb_fun [IN]: _cb_onPlayer, callback function to be called when the audio device is opened
94* @return : int, 0 if successful, non-zero if failed
95* @todo: NA
96* @see: NA
97* @warning: NA
98*********************************************************************/
99int qser_AudPlayer_Open(char* device, _cb_onPlayer cb_fun)
100{
101 int ret = SC_ERR_SUCCESS;
102 int retry_cnt = 0;
103 int audio_is_init = 0;
104
105 sc_audio_fe_pcm_dev_e device_enum = get_device_enum(device); // Convert device string to enum
106
107 while (AUDIO_INIT_MAX_TRY_CNT > retry_cnt)
108 {
109 ret = sc_audio_init();
110 if (SC_ERR_NOT_READY == ret)
111 {
112 LYINFLOG("audio service is not ready, try again, try count = %d\n", (retry_cnt + 1));
113 usleep(200 * 1000);
114 retry_cnt++;
115 }
116 else if (SC_ERR_SUCCESS == ret)
117 {
118 LYINFLOG("Success to initialize audio service\n");
119 audio_is_init = 1;
120 break;
121 }
122 else
123 {
124 LYINFLOG("Failed to initialize audio service, ret = %d\n", ret);
125 break;
126 }
127 }
128 if (1 != audio_is_init)
129 {
130 LYINFLOG("Failed to initialize audio service\n");
131 if (cb_fun != NULL)
132 {
133 cb_fun(-1);
134 }
135 return -1;
136 }
137
138 sc_audio_handle_t device_handle = sc_audio_playback_open(device_enum, SC_AUDIO_FE_PCM_DEV_MIN, SC_AUDIO_OWNER_ID_PLAYER);
139 if (SC_AUDIO_INVALID_HANDLE == device_handle)
140 {
141 LYINFLOG("Failed to open device: %s\n", device);
142 if (cb_fun != NULL)
143 {
144 cb_fun(-1);
145 }
146 return -1;
147 }
148
149 if (cb_fun != NULL)
150 {
151 cb_fun(0);
152 }
153 return 0;
154}
155
156/********************************************************************
157* @brief: qser_AudPlayer_PlayFrmFile, play audio from file
158* @param hdl [IN]: int, handle for the audio device or stream
159* @param fd [IN]: const char*, file descriptor of the audio file
160* @param offset [IN]: int, offset in the audio file
161* @return : success 0, failed -1
162* @todo: NA
163* @see: NA
164* @warning: NA
165*********************************************************************/
166int qser_AudPlayer_PlayFrmFile(int hdl, const char *fd, int offset)
167{
168 int error_line;
169 sc_audio_pcm_config_t pcm_config;
170 int ret = 0;
171 sc_audio_owner_id owner_id = hdl;
172
173 if(NULL== fd || 0 == strlen(fd))
174 {
175 error_line = __LINE__;
176 goto exit;
177 }
178
179 playback_handle = sc_audio_playback_open(SC_AUDIO_FE_PCM_DEV_MULTIMEDIA2,SC_AUDIO_FE_PCM_DEV_MIN,owner_id);
180 if (SC_AUDIO_INVALID_HANDLE == playback_handle)
181 {
182 error_line = __LINE__;
183 goto exit;
184 }
185
186 if(strlen(fd))
187 {
188 ret = sc_audio_playback_file_prepare(playback_handle, fd, NULL, playback_state_cb, NULL);
189 if (SC_ERR_SUCCESS != ret)
190 {
191 error_line = __LINE__;
192 goto exit;
193 }
194 }
195
196 ret = sc_audio_playback_play(playback_handle);
197 if (SC_ERR_SUCCESS != ret)
198 {
199 error_line = __LINE__;
200 goto exit;
201 }
202
203 return 0;
204exit:
205 LYINFLOG("qser_AudPlayer_PlayFrmFile error_line=%d\n",error_line);
206 return -1;
207}
208
209/********************************************************************
yu.dong72202352023-12-01 00:42:47 -0800210* @brief: qser_AudRecorder_StartRecord_Custom, used to capture audio from a file and play it
211* @param file [IN]: char*, the path of the audio file
212* @param period_size [IN]: int, the period size of the PCM buffer
213* @param period_count [IN]: int, the period count of the PCM buffer
214* @param num_channels [IN]: int, the number of channels in the audio
215* @param sample_rate [IN]: int, the sample rate of the audio
216* @return : int, returns 0 if successful, returns -1 if failed
217* @todo: NA
218* @see: NA
219* @warning: NA
220*********************************************************************/
221int qser_AudRecorder_StartRecord_Custom(char *file, int period_size, int period_count, \
222 int num_channels, int sample_rate)
223{
224 int error_line;
225 sc_audio_pcm_config_t pcm_config;
226 int ret = 0;
227
228 if(NULL == file || 0 == strlen(file))
229 {
230 error_line = __LINE__;
231 goto exit;
232 }
233
234 capture_handle = sc_audio_capture_open(SC_AUDIO_FE_PCM_DEV_MULTIMEDIA1, SC_AUDIO_BE_DAI_MIN);
235
236 if (SC_AUDIO_INVALID_HANDLE == capture_handle)
237 {
238 error_line = __LINE__;
239 goto exit;
240 }
241
242 memset(&pcm_config, 0, sizeof(sc_audio_pcm_config_t));
243
244 if(-1 == period_size || -1 == period_count || -1 == num_channels || -1 == sample_rate)
245 {
246 ret = sc_audio_capture_file_prepare(capture_handle, file, SC_AUDIO_STREAM_FORMAT_INVALID, \
247 NULL, capture_state_cb, NULL);
248 }
249 else
250 {
251 pcm_config.period_size = period_size;
252 pcm_config.period_count = period_count;
253 pcm_config.flags = 0;
254 pcm_config.num_channels = num_channels;
255 pcm_config.sample_rate = sample_rate;
256 pcm_config.pcm_format = 2;
257 ret = sc_audio_capture_file_prepare(capture_handle, file, SC_AUDIO_STREAM_FORMAT_INVALID, \
258 &pcm_config, capture_state_cb, NULL);
259 }
260
261 if (SC_ERR_SUCCESS != ret)
262 {
263 error_line = __LINE__;
264 goto exit;
265 }
266
267 ret = sc_audio_capture_record(capture_handle);
268
269 if (SC_ERR_SUCCESS != ret)
270 {
271 error_line = __LINE__;
272 goto exit;
273 }
274
275 return 0;
276
277exit:
278 if (SC_AUDIO_INVALID_HANDLE != capture_handle)
279 {
280 sc_audio_capture_close(capture_handle);
281 }
282 LYINFLOG("player_capture_play_file error_line=%d\n", error_line);
283 return -1;
284}
285
286/********************************************************************
yu.dong8e5f3262023-10-10 03:18:01 -0700287* @brief: qser_AudPlayer_Pause, pause the audio playback
288* @param hdl [IN]: int, handle for the audio device or stream
289* @return : success 0, failed -1
290* @todo: NA
291* @see: NA
292* @warning: NA
293*********************************************************************/
294int qser_AudPlayer_Pause(int hdl)
295{
296 if (SC_AUDIO_INVALID_HANDLE == playback_handle)
297 {
298 LYINFLOG("qser_AudPlayer_Pause handle is invalid.\n");
299 return -1;
300 }
301 if( sc_audio_playback_pause(playback_handle))
302 {
303 LYINFLOG("qser_AudPlayer_Pause sc_audio_playback_pause fail.\n");
304 return -1;
305 }
306 return 0;
307}
308
309/********************************************************************
310* @brief: qser_AudPlayer_Resume, resume the audio playback
311* @param hdl [IN]: int, handle for the audio device or stream
312* @return : success 0, failed -1
313* @todo: NA
314* @see: NA
315* @warning: NA
316*********************************************************************/
317int qser_AudPlayer_Resume(int hdl)
318{
319 if (SC_AUDIO_INVALID_HANDLE == playback_handle)
320 {
321 LYINFLOG("qser_AudPlayer_Resume handle is invalid.\n");
322 return -1;
323 }
324 if( sc_audio_playback_resume(playback_handle))
325 {
326 LYINFLOG("qser_AudPlayer_Resume sc_audio_playback_resume fail.\n");
327 return -1;
328 }
329 return 0;
330}
331
332/********************************************************************
333* @brief: qser_AudPlayer_Stop, stop the audio playback
334* @param hdl [IN]: int, handle for the audio device or stream
335* @return : void
336* @todo: NA
337* @see: NA
338* @warning: NA
339*********************************************************************/
340void qser_AudPlayer_Stop(int hdl)
341{
342 if (SC_AUDIO_INVALID_HANDLE == playback_handle)
343 {
344 LYINFLOG("qser_AudPlayer_Stop handle is invalid.\n");
345 return;
346 }
347
348 if( sc_audio_playback_stop(playback_handle))
349 {
350 LYINFLOG("qser_AudPlayer_Stop sc_audio_playback_stop fail.\n");
351 return;
352 }
353}
354
355/********************************************************************
356* @brief: qser_AudPlayer_Close, close the audio playback
357* @param hdl [IN]: int, handle for the audio device or stream
358* @return : void
359* @todo: NA
360* @see: NA
361* @warning: NA
362*********************************************************************/
363void qser_AudPlayer_Close(int hdl)
364{
365 if (SC_AUDIO_INVALID_HANDLE == playback_handle)
366 {
367 LYINFLOG("qser_AudPlayer_Close handle is invalid.\n");
368 return;
369 }
370 if( sc_audio_playback_stop(playback_handle))
371 {
372 LYINFLOG("qser_AudPlayer_Close sc_audio_playback_stop fail.\n");
373 return;
374 }
375 if( sc_audio_playback_close(playback_handle))
376 {
377 LYINFLOG("qser_AudPlayer_Close sc_audio_playback_close fail.\n");
378 return;
379 }
380
381 playback_handle = SC_AUDIO_INVALID_HANDLE;
382}
383
384/********************************************************************
385* @brief: qser_AudRecorder_Open, open the audio device for recording
386* @param device [IN]: char* device, the audio device to be opened for recording
387* @param cb_fun [IN]: _cb_onPlayer, callback function to be called when the audio device is opened
388* @return : int, 0 if successful, non-zero if failed
389* @todo: NA
390* @see: NA
391* @warning: NA
392*********************************************************************/
393int qser_AudRecorder_Open(char* device, _cb_onPlayer cb_fun)
394{
395 int ret = SC_ERR_SUCCESS;
396 int retry_cnt = 0;
397 int audio_is_init = 0;
398
399 sc_audio_fe_pcm_dev_e device_enum = get_device_enum(device); // Convert device string to enum
400
401 while (AUDIO_INIT_MAX_TRY_CNT > retry_cnt)
402 {
403 ret = sc_audio_init();
404 if (SC_ERR_NOT_READY == ret)
405 {
406 LYINFLOG("audio service is not ready, try again, try count = %d\n", (retry_cnt + 1));
407 usleep(200 * 1000);
408 retry_cnt++;
409 }
410 else if (SC_ERR_SUCCESS == ret)
411 {
412 LYINFLOG("Success to initialize audio service\n");
413 audio_is_init = 1;
414 break;
415 }
416 else
417 {
418 LYINFLOG("Failed to initialize audio service, ret = %d\n", ret);
419 break;
420 }
421 }
422 if (1 != audio_is_init)
423 {
424 LYINFLOG("Failed to initialize audio service\n");
425 if (cb_fun != NULL)
426 {
427 cb_fun(-1);
428 }
429 return -1;
430 }
431
432 sc_audio_handle_t device_handle = sc_audio_playback_open(device_enum, SC_AUDIO_FE_PCM_DEV_MIN, SC_AUDIO_OWNER_ID_PLAYER);
433 if (SC_AUDIO_INVALID_HANDLE == device_handle)
434 {
435 LYINFLOG("Failed to open device: %s\n", device);
436 if (cb_fun != NULL)
437 {
438 cb_fun(-1);
439 }
440 return -1;
441 }
442
443 if (cb_fun != NULL)
444 {
445 cb_fun(0);
446 }
447 return 0;
448}
449
450/********************************************************************
451* @brief: qser_AudRecorder_StartRecord, play a file with capture
452* @param hdl [IN]: int, handle for the audio device or stream
453* @param fd [IN]: const char*, file descriptor of the audio file
454* @param offset [IN]: int, offset in the audio file
455* @return : int, 0 if successful, -1 if failed
456* @todo: NA
457* @see: NA
458* @warning: NA
459*********************************************************************/
460int qser_AudRecorder_StartRecord(int hdl, const char *fd, int offset)
461{
462 int error_line;
463 sc_audio_pcm_config_t pcm_config;
464 int ret = 0;
465 sc_audio_owner_id owner_id = hdl;
466
467 if(NULL== fd || 0 == strlen(fd))
468 {
469 error_line = __LINE__;
470 goto exit;
471 }
472
473 capture_handle = sc_audio_capture_open(SC_AUDIO_FE_PCM_DEV_MULTIMEDIA1,SC_AUDIO_BE_DAI_MIN);
474 if (SC_AUDIO_INVALID_HANDLE == capture_handle)
475 {
476 error_line = __LINE__;
477 goto exit;
478 }
479
480 memset(&pcm_config, 0, sizeof(sc_audio_pcm_config_t));
481
482 ret = sc_audio_capture_file_prepare(capture_handle, fd, SC_AUDIO_STREAM_FORMAT_INVALID, NULL, capture_state_cb, NULL);
483 if (SC_ERR_SUCCESS != ret)
484 {
485 error_line = __LINE__;
486 goto exit;
487 }
488
489 ret = sc_audio_capture_record(capture_handle);
490 if (SC_ERR_SUCCESS != ret)
491 {
492 error_line = __LINE__;
493 goto exit;
494 }
495
496 return 0;
497exit:
498 LYINFLOG("qser_AudRecorder_StartRecord error_line=%d\n",error_line);
499 return -1;
500}
501
502/********************************************************************
503* @brief: qser_AudRecorder_Pause, pause the audio capture
504* @return : int, 0 if successful, -1 if failed
505* @todo: NA
506* @see: NA
507* @warning: NA
508*********************************************************************/
509int qser_AudRecorder_Pause(void)
510{
511 if (SC_AUDIO_INVALID_HANDLE == capture_handle)
512 {
513 LYINFLOG("qser_AudRecorder_Pause capture_handle is invalid.\n");
514 return -1;
515 }
516 if( sc_audio_capture_pause(capture_handle))
517 {
518 LYINFLOG("qser_AudRecorder_Pause sc_audio_capture_pause fail.\n");
519 return -1;
520 }
521 return 0;
522}
523
524/********************************************************************
525* @brief: qser_AudRecorder_Resume, resume the audio capture
526* @return : int, 0 if successful, -1 if failed
527* @todo: NA
528* @see: NA
529* @warning: NA
530*********************************************************************/
531int qser_AudRecorder_Resume(void)
532{
533 if (SC_AUDIO_INVALID_HANDLE == capture_handle)
534 {
535 LYINFLOG("qser_AudRecorder_Resume capture_handle is invalid.\n");
536 return -1;
537 }
538 if( sc_audio_capture_resume(capture_handle))
539 {
540 LYINFLOG("qser_AudRecorder_Resume sc_audio_capture_resume fail.\n");
541 return -1;
542 }
543 return 0;
544}
545
546/********************************************************************
547* @brief: qser_AudRecorder_Stop, stop the audio capture
548* @return : void
549* @todo: NA
550* @see: NA
551* @warning: NA
552*********************************************************************/
553void qser_AudRecorder_Stop(void)
554{
555 if (SC_AUDIO_INVALID_HANDLE == capture_handle)
556 {
557 LYINFLOG("qser_AudRecorder_Stop capture_handle is invalid.\n");
558 return;
559 }
560 if( sc_audio_capture_stop(capture_handle))
561 {
562 LYINFLOG("qser_AudRecorder_Stop sc_audio_capture_stop fail.\n");
563 return;
564 }
565}
566
567/********************************************************************
568* @brief: qser_AudRecorder_Close, close the audio capture
569* @return : void
570* @todo: NA
571* @see: NA
572* @warning: NA
573*********************************************************************/
574void qser_AudRecorder_Close(void)
575{
576 if (SC_AUDIO_INVALID_HANDLE == capture_handle)
577 {
578 LYINFLOG("qser_AudRecorder_Close capture_handle is invalid.\n");
579 return;
580 }
581 if( sc_audio_capture_stop(capture_handle))
582 {
583 LYINFLOG("qser_AudRecorder_Close sc_audio_capture_stop fail.\n");
584 return;
585 }
586 if( sc_audio_capture_close(capture_handle))
587 {
588 LYINFLOG("qser_AudRecorder_Close sc_audio_capture_close fail.\n");
589 return;
590 }
591
592 capture_handle = SC_AUDIO_INVALID_HANDLE;
593}
594
595/********************************************************************
596* @brief: qser_Audio_Deinit, deinitialize the audio system, stop and close any active playback or capture,
597 and uninitialize the audio system
598* @return : void
599* @todo: NA
600* @see: NA
601* @warning: NA
602*********************************************************************/
603void qser_Audio_Deinit(void)
604{
605 if(SC_AUDIO_INVALID_HANDLE != playback_handle)
606 {
607 sc_audio_playback_stop(playback_handle);
608 sc_audio_playback_close(playback_handle);
609 playback_handle = SC_AUDIO_INVALID_HANDLE;
610 }
611
612 if(SC_AUDIO_INVALID_HANDLE != capture_handle)
613 {
614 sc_audio_capture_stop(capture_handle);
615 sc_audio_capture_close(capture_handle);
616 capture_handle = SC_AUDIO_INVALID_HANDLE;
617 }
618
619 sc_audio_uninit();
620}
621
622DEFINE_LYNQ_LIB_LOG(LYNQ_AUDIO)
623
624#ifdef __cplusplus
625}
626#endif