b.liu | d440f9f | 2025-04-18 10:44:31 +0800 | [diff] [blame] | 1 | /*-----------------------------------------------------------------------------------------------*/ |
| 2 | /** |
| 3 | @file m_audio.c |
| 4 | @brief audio API example |
| 5 | */ |
| 6 | /*-----------------------------------------------------------------------------------------------*/ |
| 7 | |
| 8 | /*------------------------------------------------------------------------------------------------- |
| 9 | Copyright (c) 2019 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. |
| 10 | Quectel Wireless Solution Proprietary and Confidential. |
| 11 | -------------------------------------------------------------------------------------------------*/ |
| 12 | |
| 13 | /*------------------------------------------------------------------------------------------------- |
| 14 | EDIT HISTORY |
| 15 | This section contains comments describing changes made to the file. |
| 16 | Notice that changes are listed in reverse chronological order. |
| 17 | $Header: $ |
| 18 | when who what, where, why |
| 19 | -------- --- ---------------------------------------------------------- |
| 20 | 2021-11-03 dameng.lin Create. |
| 21 | -------------------------------------------------------------------------------------------------*/ |
| 22 | #include <stdio.h> |
| 23 | #include <stdlib.h> |
| 24 | #include <string.h> |
| 25 | #include <unistd.h> |
| 26 | #include <errno.h> |
| 27 | #include <pthread.h> |
| 28 | |
| 29 | #include "ql_v2/ql_type.h" |
| 30 | #include "ql_v2/ql_audio_pcm.h" |
| 31 | #include "ql_v2/ql_audio_cfg.h" |
| 32 | #include "ql_v2/ql_test_utils.h" |
| 33 | |
| 34 | typedef void (*show_handler_f)(void); |
| 35 | |
| 36 | typedef struct |
| 37 | { |
| 38 | const char *name; |
| 39 | show_handler_f handle; |
| 40 | }audio_show_t; |
| 41 | |
| 42 | typedef struct |
| 43 | { |
| 44 | int playback_dest; |
| 45 | int block_flag; |
| 46 | char file_name[128]; |
| 47 | }audio_playback_info_t; |
| 48 | |
| 49 | static ql_audio_handle_t g_playback_handle = QL_AUDIO_INVALID_HANDLE; |
| 50 | static int g_playback_end = 0; |
| 51 | |
| 52 | |
| 53 | void item_ql_audio_init(void) |
| 54 | { |
| 55 | int ret = 0; |
| 56 | |
| 57 | printf("test ql_audio_init: "); |
| 58 | ret = ql_audio_init(); |
| 59 | if(QL_ERR_OK != ret) |
| 60 | { |
| 61 | printf("Failed to init audio service, ret = %d\n", ret); |
| 62 | } |
| 63 | else |
| 64 | { |
| 65 | printf("Success to init audio service\n"); |
| 66 | } |
| 67 | } |
| 68 | |
| 69 | static void audio_service_error_cb_func(int error) |
| 70 | { |
| 71 | printf("===== Audio Service Abort ===== error = %d\n",error); |
| 72 | } |
| 73 | |
| 74 | static void item_ql_audio_set_service_error_cb(void) |
| 75 | { |
| 76 | int ret = QL_ERR_OK; |
| 77 | |
| 78 | printf("test ql_audio_set_service_error_cb: \n"); |
| 79 | ret = ql_audio_set_service_error_cb(audio_service_error_cb_func); |
| 80 | if(ret != QL_ERR_OK) |
| 81 | { |
| 82 | printf("Failed to ql_audio_set_service_error_cb, ret=%d\n", ret); |
| 83 | } |
| 84 | else |
| 85 | { |
| 86 | printf("Successful\n"); |
| 87 | } |
| 88 | } |
| 89 | |
| 90 | static void item_ql_audio_set_loopback_enable_state(void) |
| 91 | { |
| 92 | int ret = QL_ERR_OK; |
| 93 | int loopback_enable_state = 0; |
| 94 | |
| 95 | printf("test ql_audio_set_loopback_enable_state: \n"); |
| 96 | printf("please enter the loopback enable state(0-1): "); |
| 97 | ret = t_get_int(&loopback_enable_state); |
| 98 | if(ret != 0) |
| 99 | { |
| 100 | printf("Invalid input\n"); |
| 101 | return; |
| 102 | } |
| 103 | |
| 104 | ret = ql_audio_set_loopback_enable_state(loopback_enable_state); |
| 105 | if (QL_ERR_OK != ret) |
| 106 | { |
| 107 | printf("Failed to set loopback enable state, ret = %d\n", ret); |
| 108 | } |
| 109 | else |
| 110 | { |
| 111 | printf("Success to set loopback enable state\n"); |
| 112 | } |
| 113 | } |
| 114 | |
| 115 | static void item_ql_audio_get_loopback_enable_state(void) |
| 116 | { |
| 117 | int ret = QL_ERR_OK; |
| 118 | int32_t loopback_enable_state = 0; |
| 119 | |
| 120 | printf("test ql_audio_get_loopback_enable_state: \n"); |
| 121 | |
| 122 | ret = ql_audio_get_loopback_enable_state(&loopback_enable_state); |
| 123 | if (QL_ERR_OK != ret) |
| 124 | { |
| 125 | printf("Failed to get loopback enable state, ret = %d\n", ret); |
| 126 | } |
| 127 | else |
| 128 | { |
| 129 | printf("Success to get loopback enable state, loopback_enable_state = %d\n", loopback_enable_state); |
| 130 | } |
| 131 | } |
| 132 | |
| 133 | |
| 134 | static void item_ql_audio_set_tx_voice_mic_gain(void) |
| 135 | { |
| 136 | int ret = QL_ERR_OK; |
| 137 | int tx_voice_mic_gain = 0; |
| 138 | |
| 139 | printf("test ql_audio_set_tx_voice_mic_gain: \n"); |
| 140 | printf("please enter the tx voice mic gain(0-65535): "); |
| 141 | ret = t_get_int(&tx_voice_mic_gain); |
| 142 | if(ret != 0) |
| 143 | { |
| 144 | printf("Invalid input\n"); |
| 145 | return; |
| 146 | } |
| 147 | |
| 148 | ret = ql_audio_set_tx_voice_mic_gain(tx_voice_mic_gain); |
| 149 | if (QL_ERR_OK != ret) |
| 150 | { |
| 151 | printf("Failed to set tx voice mic gain, ret = %d\n", ret); |
| 152 | } |
| 153 | else |
| 154 | { |
| 155 | printf("Success to set tx voice mic gain\n"); |
| 156 | } |
| 157 | } |
| 158 | |
| 159 | static void item_ql_audio_get_tx_voice_mic_gain(void) |
| 160 | { |
| 161 | int ret = QL_ERR_OK; |
| 162 | int32_t tx_voice_mic_gain = 0; |
| 163 | |
| 164 | printf("test ql_audio_get_tx_voice_mic_gain: \n"); |
| 165 | |
| 166 | ret = ql_audio_get_tx_voice_mic_gain(&tx_voice_mic_gain); |
| 167 | if (QL_ERR_OK != ret) |
| 168 | { |
| 169 | printf("Failed to get tx voice mic gain, ret = %d\n", ret); |
| 170 | } |
| 171 | else |
| 172 | { |
| 173 | printf("Success to get tx voice mic gain, tx_voice_mic_gain = %d\n", tx_voice_mic_gain); |
| 174 | } |
| 175 | } |
| 176 | |
| 177 | static void item_ql_audio_set_codec_down_vol(void) |
| 178 | { |
| 179 | int ret = QL_ERR_OK; |
| 180 | int down_volume = 0; |
| 181 | |
| 182 | printf("test ql_audio_set_codec_down_vol: \n"); |
| 183 | printf("please enter the codec down volume(0-100): "); |
| 184 | ret = t_get_int(&down_volume); |
| 185 | if(ret != 0) |
| 186 | { |
| 187 | printf("Invalid input\n"); |
| 188 | return; |
| 189 | } |
| 190 | |
| 191 | ret = ql_audio_set_codec_down_vol(down_volume); |
| 192 | if (QL_ERR_OK != ret) |
| 193 | { |
| 194 | printf("Failed to set codec down volume, ret = %d\n", ret); |
| 195 | } |
| 196 | else |
| 197 | { |
| 198 | printf("Success to set codec down volume\n"); |
| 199 | } |
| 200 | } |
| 201 | |
| 202 | static void item_ql_audio_get_codec_down_vol(void) |
| 203 | { |
| 204 | int ret = QL_ERR_OK; |
| 205 | int32_t down_volume = 0; |
| 206 | |
| 207 | printf("test ql_audio_get_codec_down_vol: \n"); |
| 208 | |
| 209 | ret = ql_audio_get_codec_down_vol(&down_volume); |
| 210 | if (QL_ERR_OK != ret) |
| 211 | { |
| 212 | printf("Failed to get codec down volume, ret = %d\n", ret); |
| 213 | } |
| 214 | else |
| 215 | { |
| 216 | printf("Success to codec down volume, down_volume = %d\n", down_volume); |
| 217 | } |
| 218 | } |
| 219 | |
| 220 | void item_ql_audio_deinit(void) |
| 221 | { |
| 222 | int ret = 0; |
| 223 | |
| 224 | printf("test ql_audio_deinit: "); |
| 225 | ret = ql_audio_deinit(); |
| 226 | if(QL_ERR_OK != ret) |
| 227 | { |
| 228 | printf("Failed to deinit audio service, ret = %d\n", ret); |
| 229 | } |
| 230 | else |
| 231 | { |
| 232 | printf("Success to deinit audio service\n"); |
| 233 | } |
| 234 | } |
| 235 | |
| 236 | static int default_playback_state(ql_audio_handle_t handle, void *params, QL_AUDIO_PLAYBACK_STATE_E state) |
| 237 | { |
| 238 | int ret = 0; |
| 239 | |
| 240 | switch(state) |
| 241 | { |
| 242 | case QL_AUDIO_PLAYBACK_STATE_OPEN: |
| 243 | { |
| 244 | printf("QL_AUDIO_PLAYBACK_STATE_OPEN\n"); |
| 245 | break; |
| 246 | } |
| 247 | case QL_AUDIO_PLAYBACK_STATE_PREPARE: |
| 248 | { |
| 249 | printf("QL_AUDIO_PLAYBACK_STATE_PREPARE\n"); |
| 250 | break; |
| 251 | } |
| 252 | case QL_AUDIO_PLAYBACK_STATE_PLAYING: |
| 253 | { |
| 254 | printf("QL_AUDIO_PLAYBACK_STATE_PLAYING\n"); |
| 255 | break; |
| 256 | } |
| 257 | case QL_AUDIO_PLAYBACK_STATE_FINISHED: |
| 258 | { |
| 259 | printf("QL_AUDIO_PLAYBACK_STATE_FINISHED\n"); |
| 260 | g_playback_end = 1; |
| 261 | break; |
| 262 | } |
| 263 | case QL_AUDIO_PLAYBACK_STATE_PAUSE: |
| 264 | { |
| 265 | printf("QL_AUDIO_PLAYBACK_STATE_PAUSE\n"); |
| 266 | break; |
| 267 | } |
| 268 | case QL_AUDIO_PLAYBACK_STATE_ERROR: |
| 269 | { |
| 270 | printf("QL_AUDIO_PLAYBACK_STATE_ERROR\n"); |
| 271 | g_playback_end = 1; |
| 272 | break; |
| 273 | } |
| 274 | default: |
| 275 | { |
| 276 | printf("INVALID PALYBACK STATE\n"); |
| 277 | ret = -1; |
| 278 | break; |
| 279 | } |
| 280 | } |
| 281 | |
| 282 | return ret; |
| 283 | } |
| 284 | |
| 285 | static void *ql_audio_play_file_thread(void *args) |
| 286 | { |
| 287 | int ret = QL_ERR_OK; |
| 288 | uint32_t be_dai_mask = 0; |
| 289 | ql_audio_handle_t handle = QL_AUDIO_INVALID_HANDLE; |
| 290 | |
| 291 | audio_playback_info_t *playback_info = (audio_playback_info_t *)args; |
| 292 | if (NULL == playback_info) |
| 293 | { |
| 294 | printf("invalid params\n"); |
| 295 | return NULL; |
| 296 | } |
| 297 | |
| 298 | switch(playback_info->playback_dest) |
| 299 | { |
| 300 | case 0: |
| 301 | { |
| 302 | be_dai_mask = QL_AUDIO_BE_DAI_MASK_PLAYBACK_PRI_PCM; |
| 303 | break; |
| 304 | } |
| 305 | case 1: |
| 306 | { |
| 307 | be_dai_mask = QL_AUDIO_BE_DAI_MASK_PLAYBACK_VOICE_TX; |
| 308 | break; |
| 309 | } |
| 310 | case 2: |
| 311 | { |
| 312 | be_dai_mask = QL_AUDIO_BE_DAI_MASK_PLAYBACK_PRI_PCM | QL_AUDIO_BE_DAI_MASK_PLAYBACK_VOICE_TX; |
| 313 | break; |
| 314 | } |
| 315 | default: |
| 316 | { |
| 317 | printf("invalid playback destination\n"); |
| 318 | free(playback_info); |
| 319 | playback_info = NULL; |
| 320 | return NULL; |
| 321 | } |
| 322 | } |
| 323 | |
| 324 | handle = ql_audio_playback_open(QL_AUDIO_FE_PCM_DEV_MULTIMEDIA1, be_dai_mask); |
| 325 | if (QL_AUDIO_INVALID_HANDLE >= handle) |
| 326 | { |
| 327 | printf("Failed to open playback\n"); |
| 328 | free(playback_info); |
| 329 | playback_info = NULL; |
| 330 | return NULL; |
| 331 | } |
| 332 | |
| 333 | g_playback_handle = handle; |
| 334 | |
| 335 | printf("playback handle = %d",g_playback_handle); |
| 336 | ql_audio_playback_set_block_flag(g_playback_handle, playback_info->block_flag); |
| 337 | |
| 338 | ret = ql_audio_playback_file_prepare(g_playback_handle, |
| 339 | playback_info->file_name, |
| 340 | NULL, |
| 341 | default_playback_state, |
| 342 | NULL); |
| 343 | if (QL_ERR_OK != ret) |
| 344 | { |
| 345 | printf("Failed to prepare playback file\n"); |
| 346 | free(playback_info); |
| 347 | playback_info = NULL; |
| 348 | ql_audio_playback_close(g_playback_handle); |
| 349 | return NULL; |
| 350 | } |
| 351 | printf("playback handle = %d",g_playback_handle); |
| 352 | |
| 353 | ret = ql_audio_playback_play(g_playback_handle); |
| 354 | if (QL_ERR_OK != ret) |
| 355 | { |
| 356 | printf("Failed to play file\n"); |
| 357 | free(playback_info); |
| 358 | playback_info = NULL; |
| 359 | ql_audio_playback_close(g_playback_handle); |
| 360 | return NULL; |
| 361 | } |
| 362 | |
| 363 | while(0 == g_playback_end) |
| 364 | { |
| 365 | usleep(100 * 1000); |
| 366 | } |
| 367 | |
| 368 | printf("End playing file\n"); |
| 369 | ql_audio_playback_close(g_playback_handle); |
| 370 | g_playback_handle = QL_AUDIO_INVALID_HANDLE; |
| 371 | g_playback_end = 0; |
| 372 | |
| 373 | free(playback_info); |
| 374 | playback_info = NULL; |
| 375 | |
| 376 | return NULL; |
| 377 | } |
| 378 | |
| 379 | static void item_ql_audio_playback_play_file(void) |
| 380 | { |
| 381 | int ret = 0; |
| 382 | pthread_t thread_id; |
| 383 | pthread_attr_t thread_attr; |
| 384 | audio_playback_info_t *playback_info = NULL; |
| 385 | |
| 386 | printf("test ql_audio_playback_play_file: \n"); |
| 387 | |
| 388 | playback_info = (audio_playback_info_t *)malloc(sizeof(audio_playback_info_t)); |
| 389 | if (NULL == playback_info) |
| 390 | { |
| 391 | printf("Failed to malloc memory\n"); |
| 392 | return; |
| 393 | } |
| 394 | memset(playback_info, 0, sizeof(audio_playback_info_t)); |
| 395 | |
| 396 | printf("please enter the file name: "); |
| 397 | ret = t_get_string(playback_info->file_name,sizeof(playback_info->file_name)); |
| 398 | if(ret != 0) |
| 399 | { |
| 400 | printf("Invalid input\n"); |
| 401 | return; |
| 402 | } |
| 403 | |
| 404 | printf("please enter the playback destination(0-To pcm interface / 1-To voice / 2-To pcm interface and voice): "); |
| 405 | ret = t_get_int(&(playback_info->playback_dest)); |
| 406 | if(ret != 0) |
| 407 | { |
| 408 | printf("Invalid input\n"); |
| 409 | return; |
| 410 | } |
| 411 | |
| 412 | printf("please enter the block flag(0-nonblock / 1-block): "); |
| 413 | ret = t_get_int(&(playback_info->block_flag)); |
| 414 | if(ret != 0) |
| 415 | { |
| 416 | printf("Invalid input\n"); |
| 417 | return; |
| 418 | } |
| 419 | |
| 420 | pthread_attr_init(&thread_attr); |
| 421 | pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); |
| 422 | |
| 423 | ret = pthread_create(&thread_id, &thread_attr, ql_audio_play_file_thread, (void *)playback_info); |
| 424 | if (0 > ret) |
| 425 | { |
| 426 | printf("Failed to create play file thread, ret = %d, err = %s\n", ret, strerror(errno)); |
| 427 | } |
| 428 | |
| 429 | pthread_attr_destroy(&thread_attr); |
| 430 | } |
| 431 | |
| 432 | |
| 433 | static audio_show_t audio_show[] = |
| 434 | { |
| 435 | { "ql_audio_init", item_ql_audio_init }, |
| 436 | { "ql_audio_set_service_error_cb", item_ql_audio_set_service_error_cb }, |
| 437 | { "ql_audio_set_loopback_enable_state", item_ql_audio_set_loopback_enable_state }, |
| 438 | { "ql_audio_get_loopback_enable_state", item_ql_audio_get_loopback_enable_state }, |
| 439 | { "ql_audio_set_tx_voice_mic_gain", item_ql_audio_set_tx_voice_mic_gain }, |
| 440 | { "ql_audio_get_tx_voice_mic_gain", item_ql_audio_get_tx_voice_mic_gain }, |
| 441 | { "ql_audio_set_codec_down_vol", item_ql_audio_set_codec_down_vol }, |
| 442 | { "ql_audio_get_codec_down_vol", item_ql_audio_get_codec_down_vol }, |
| 443 | { "ql_audio_playback_play_file", item_ql_audio_playback_play_file }, |
| 444 | { "ql_audio_deinit", item_ql_audio_deinit } |
| 445 | |
| 446 | }; |
| 447 | |
| 448 | int audio_get_int(int *val) |
| 449 | { |
| 450 | int dat; |
| 451 | char *ptr_end = NULL; |
| 452 | char buf[256] = {0}; |
| 453 | |
| 454 | if (NULL == val) |
| 455 | { |
| 456 | return -1; |
| 457 | } |
| 458 | |
| 459 | if (fgets(buf, sizeof(buf), stdin) == NULL) |
| 460 | { |
| 461 | return -1; |
| 462 | } |
| 463 | |
| 464 | if('\0' == buf[0]) |
| 465 | { |
| 466 | return -1; |
| 467 | } |
| 468 | |
| 469 | if('\n' == buf[0]) |
| 470 | { |
| 471 | return 1; |
| 472 | } |
| 473 | |
| 474 | dat = strtol(buf, &ptr_end, 10); |
| 475 | if((NULL != ptr_end) && ('\n' != ptr_end[0])) |
| 476 | { |
| 477 | return -1; |
| 478 | } |
| 479 | |
| 480 | *val = dat; |
| 481 | return 0; |
| 482 | } |
| 483 | |
| 484 | static void dump_audio_show(void) |
| 485 | { |
| 486 | int i = 0; |
| 487 | |
| 488 | for(i = 0; i < sizeof(audio_show)/sizeof(audio_show[0]); i++) |
| 489 | { |
| 490 | printf("%d\t%s\n", i, audio_show[i].name); |
| 491 | } |
| 492 | printf("-1\texit\n"); |
| 493 | } |
| 494 | |
| 495 | |
| 496 | int main(int argc, char **argv) |
| 497 | { |
| 498 | int ret = 0; |
| 499 | int index = 0; |
| 500 | |
| 501 | dump_audio_show(); |
| 502 | |
| 503 | while (1) |
| 504 | { |
| 505 | printf("\n"); |
| 506 | printf("Please enter your choice: "); |
| 507 | ret = audio_get_int(&index); |
| 508 | printf("\n"); |
| 509 | if(ret < 0) |
| 510 | { |
| 511 | printf("Invalid input\n"); |
| 512 | continue; |
| 513 | } |
| 514 | else if(ret == 1) |
| 515 | { |
| 516 | dump_audio_show(); |
| 517 | continue; |
| 518 | } |
| 519 | |
| 520 | if (index == -1) |
| 521 | { |
| 522 | break; |
| 523 | } |
| 524 | |
| 525 | if ((index < 0) || (index >= sizeof(audio_show)/sizeof(audio_show[0]))) |
| 526 | { |
| 527 | printf("Not support index: %d\n", index); |
| 528 | continue; |
| 529 | } |
| 530 | |
| 531 | if (NULL != audio_show[index].handle) |
| 532 | { |
| 533 | audio_show[index].handle(); |
| 534 | } |
| 535 | } |
| 536 | |
| 537 | return 0; |
| 538 | } |
| 539 | |
| 540 | |
| 541 | |