| /*-----------------------------------------------------------------------------------------------*/ |
| /** |
| @file m_audio.c |
| @brief audio API example |
| */ |
| /*-----------------------------------------------------------------------------------------------*/ |
| |
| /*------------------------------------------------------------------------------------------------- |
| Copyright (c) 2019 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. |
| Quectel Wireless Solution Proprietary and Confidential. |
| -------------------------------------------------------------------------------------------------*/ |
| |
| /*------------------------------------------------------------------------------------------------- |
| EDIT HISTORY |
| This section contains comments describing changes made to the file. |
| Notice that changes are listed in reverse chronological order. |
| $Header: $ |
| when who what, where, why |
| -------- --- ---------------------------------------------------------- |
| 2021-11-03 dameng.lin Create. |
| -------------------------------------------------------------------------------------------------*/ |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <unistd.h> |
| #include <errno.h> |
| #include <pthread.h> |
| |
| #include "ql_v2/ql_type.h" |
| #include "ql_v2/ql_audio_pcm.h" |
| #include "ql_v2/ql_audio_cfg.h" |
| #include "ql_v2/ql_test_utils.h" |
| |
| typedef void (*show_handler_f)(void); |
| |
| typedef struct |
| { |
| const char *name; |
| show_handler_f handle; |
| }audio_show_t; |
| |
| typedef struct |
| { |
| int playback_dest; |
| int block_flag; |
| char file_name[128]; |
| }audio_playback_info_t; |
| |
| static ql_audio_handle_t g_playback_handle = QL_AUDIO_INVALID_HANDLE; |
| static int g_playback_end = 0; |
| |
| |
| void item_ql_audio_init(void) |
| { |
| int ret = 0; |
| |
| printf("test ql_audio_init: "); |
| ret = ql_audio_init(); |
| if(QL_ERR_OK != ret) |
| { |
| printf("Failed to init audio service, ret = %d\n", ret); |
| } |
| else |
| { |
| printf("Success to init audio service\n"); |
| } |
| } |
| |
| static void audio_service_error_cb_func(int error) |
| { |
| printf("===== Audio Service Abort ===== error = %d\n",error); |
| } |
| |
| static void item_ql_audio_set_service_error_cb(void) |
| { |
| int ret = QL_ERR_OK; |
| |
| printf("test ql_audio_set_service_error_cb: \n"); |
| ret = ql_audio_set_service_error_cb(audio_service_error_cb_func); |
| if(ret != QL_ERR_OK) |
| { |
| printf("Failed to ql_audio_set_service_error_cb, ret=%d\n", ret); |
| } |
| else |
| { |
| printf("Successful\n"); |
| } |
| } |
| |
| static void item_ql_audio_set_loopback_enable_state(void) |
| { |
| int ret = QL_ERR_OK; |
| int loopback_enable_state = 0; |
| |
| printf("test ql_audio_set_loopback_enable_state: \n"); |
| printf("please enter the loopback enable state(0-1): "); |
| ret = t_get_int(&loopback_enable_state); |
| if(ret != 0) |
| { |
| printf("Invalid input\n"); |
| return; |
| } |
| |
| ret = ql_audio_set_loopback_enable_state(loopback_enable_state); |
| if (QL_ERR_OK != ret) |
| { |
| printf("Failed to set loopback enable state, ret = %d\n", ret); |
| } |
| else |
| { |
| printf("Success to set loopback enable state\n"); |
| } |
| } |
| |
| static void item_ql_audio_get_loopback_enable_state(void) |
| { |
| int ret = QL_ERR_OK; |
| int32_t loopback_enable_state = 0; |
| |
| printf("test ql_audio_get_loopback_enable_state: \n"); |
| |
| ret = ql_audio_get_loopback_enable_state(&loopback_enable_state); |
| if (QL_ERR_OK != ret) |
| { |
| printf("Failed to get loopback enable state, ret = %d\n", ret); |
| } |
| else |
| { |
| printf("Success to get loopback enable state, loopback_enable_state = %d\n", loopback_enable_state); |
| } |
| } |
| |
| |
| static void item_ql_audio_set_tx_voice_mic_gain(void) |
| { |
| int ret = QL_ERR_OK; |
| int tx_voice_mic_gain = 0; |
| |
| printf("test ql_audio_set_tx_voice_mic_gain: \n"); |
| printf("please enter the tx voice mic gain(0-65535): "); |
| ret = t_get_int(&tx_voice_mic_gain); |
| if(ret != 0) |
| { |
| printf("Invalid input\n"); |
| return; |
| } |
| |
| ret = ql_audio_set_tx_voice_mic_gain(tx_voice_mic_gain); |
| if (QL_ERR_OK != ret) |
| { |
| printf("Failed to set tx voice mic gain, ret = %d\n", ret); |
| } |
| else |
| { |
| printf("Success to set tx voice mic gain\n"); |
| } |
| } |
| |
| static void item_ql_audio_get_tx_voice_mic_gain(void) |
| { |
| int ret = QL_ERR_OK; |
| int32_t tx_voice_mic_gain = 0; |
| |
| printf("test ql_audio_get_tx_voice_mic_gain: \n"); |
| |
| ret = ql_audio_get_tx_voice_mic_gain(&tx_voice_mic_gain); |
| if (QL_ERR_OK != ret) |
| { |
| printf("Failed to get tx voice mic gain, ret = %d\n", ret); |
| } |
| else |
| { |
| printf("Success to get tx voice mic gain, tx_voice_mic_gain = %d\n", tx_voice_mic_gain); |
| } |
| } |
| |
| static void item_ql_audio_set_codec_down_vol(void) |
| { |
| int ret = QL_ERR_OK; |
| int down_volume = 0; |
| |
| printf("test ql_audio_set_codec_down_vol: \n"); |
| printf("please enter the codec down volume(0-100): "); |
| ret = t_get_int(&down_volume); |
| if(ret != 0) |
| { |
| printf("Invalid input\n"); |
| return; |
| } |
| |
| ret = ql_audio_set_codec_down_vol(down_volume); |
| if (QL_ERR_OK != ret) |
| { |
| printf("Failed to set codec down volume, ret = %d\n", ret); |
| } |
| else |
| { |
| printf("Success to set codec down volume\n"); |
| } |
| } |
| |
| static void item_ql_audio_get_codec_down_vol(void) |
| { |
| int ret = QL_ERR_OK; |
| int32_t down_volume = 0; |
| |
| printf("test ql_audio_get_codec_down_vol: \n"); |
| |
| ret = ql_audio_get_codec_down_vol(&down_volume); |
| if (QL_ERR_OK != ret) |
| { |
| printf("Failed to get codec down volume, ret = %d\n", ret); |
| } |
| else |
| { |
| printf("Success to codec down volume, down_volume = %d\n", down_volume); |
| } |
| } |
| |
| void item_ql_audio_deinit(void) |
| { |
| int ret = 0; |
| |
| printf("test ql_audio_deinit: "); |
| ret = ql_audio_deinit(); |
| if(QL_ERR_OK != ret) |
| { |
| printf("Failed to deinit audio service, ret = %d\n", ret); |
| } |
| else |
| { |
| printf("Success to deinit audio service\n"); |
| } |
| } |
| |
| static int default_playback_state(ql_audio_handle_t handle, void *params, QL_AUDIO_PLAYBACK_STATE_E state) |
| { |
| int ret = 0; |
| |
| switch(state) |
| { |
| case QL_AUDIO_PLAYBACK_STATE_OPEN: |
| { |
| printf("QL_AUDIO_PLAYBACK_STATE_OPEN\n"); |
| break; |
| } |
| case QL_AUDIO_PLAYBACK_STATE_PREPARE: |
| { |
| printf("QL_AUDIO_PLAYBACK_STATE_PREPARE\n"); |
| break; |
| } |
| case QL_AUDIO_PLAYBACK_STATE_PLAYING: |
| { |
| printf("QL_AUDIO_PLAYBACK_STATE_PLAYING\n"); |
| break; |
| } |
| case QL_AUDIO_PLAYBACK_STATE_FINISHED: |
| { |
| printf("QL_AUDIO_PLAYBACK_STATE_FINISHED\n"); |
| g_playback_end = 1; |
| break; |
| } |
| case QL_AUDIO_PLAYBACK_STATE_PAUSE: |
| { |
| printf("QL_AUDIO_PLAYBACK_STATE_PAUSE\n"); |
| break; |
| } |
| case QL_AUDIO_PLAYBACK_STATE_ERROR: |
| { |
| printf("QL_AUDIO_PLAYBACK_STATE_ERROR\n"); |
| g_playback_end = 1; |
| break; |
| } |
| default: |
| { |
| printf("INVALID PALYBACK STATE\n"); |
| ret = -1; |
| break; |
| } |
| } |
| |
| return ret; |
| } |
| |
| static void *ql_audio_play_file_thread(void *args) |
| { |
| int ret = QL_ERR_OK; |
| uint32_t be_dai_mask = 0; |
| ql_audio_handle_t handle = QL_AUDIO_INVALID_HANDLE; |
| |
| audio_playback_info_t *playback_info = (audio_playback_info_t *)args; |
| if (NULL == playback_info) |
| { |
| printf("invalid params\n"); |
| return NULL; |
| } |
| |
| switch(playback_info->playback_dest) |
| { |
| case 0: |
| { |
| be_dai_mask = QL_AUDIO_BE_DAI_MASK_PLAYBACK_PRI_PCM; |
| break; |
| } |
| case 1: |
| { |
| be_dai_mask = QL_AUDIO_BE_DAI_MASK_PLAYBACK_VOICE_TX; |
| break; |
| } |
| case 2: |
| { |
| be_dai_mask = QL_AUDIO_BE_DAI_MASK_PLAYBACK_PRI_PCM | QL_AUDIO_BE_DAI_MASK_PLAYBACK_VOICE_TX; |
| break; |
| } |
| default: |
| { |
| printf("invalid playback destination\n"); |
| free(playback_info); |
| playback_info = NULL; |
| return NULL; |
| } |
| } |
| |
| handle = ql_audio_playback_open(QL_AUDIO_FE_PCM_DEV_MULTIMEDIA1, be_dai_mask); |
| if (QL_AUDIO_INVALID_HANDLE >= handle) |
| { |
| printf("Failed to open playback\n"); |
| free(playback_info); |
| playback_info = NULL; |
| return NULL; |
| } |
| |
| g_playback_handle = handle; |
| |
| printf("playback handle = %d",g_playback_handle); |
| ql_audio_playback_set_block_flag(g_playback_handle, playback_info->block_flag); |
| |
| ret = ql_audio_playback_file_prepare(g_playback_handle, |
| playback_info->file_name, |
| NULL, |
| default_playback_state, |
| NULL); |
| if (QL_ERR_OK != ret) |
| { |
| printf("Failed to prepare playback file\n"); |
| free(playback_info); |
| playback_info = NULL; |
| ql_audio_playback_close(g_playback_handle); |
| return NULL; |
| } |
| printf("playback handle = %d",g_playback_handle); |
| |
| ret = ql_audio_playback_play(g_playback_handle); |
| if (QL_ERR_OK != ret) |
| { |
| printf("Failed to play file\n"); |
| free(playback_info); |
| playback_info = NULL; |
| ql_audio_playback_close(g_playback_handle); |
| return NULL; |
| } |
| |
| while(0 == g_playback_end) |
| { |
| usleep(100 * 1000); |
| } |
| |
| printf("End playing file\n"); |
| ql_audio_playback_close(g_playback_handle); |
| g_playback_handle = QL_AUDIO_INVALID_HANDLE; |
| g_playback_end = 0; |
| |
| free(playback_info); |
| playback_info = NULL; |
| |
| return NULL; |
| } |
| |
| static void item_ql_audio_playback_play_file(void) |
| { |
| int ret = 0; |
| pthread_t thread_id; |
| pthread_attr_t thread_attr; |
| audio_playback_info_t *playback_info = NULL; |
| |
| printf("test ql_audio_playback_play_file: \n"); |
| |
| playback_info = (audio_playback_info_t *)malloc(sizeof(audio_playback_info_t)); |
| if (NULL == playback_info) |
| { |
| printf("Failed to malloc memory\n"); |
| return; |
| } |
| memset(playback_info, 0, sizeof(audio_playback_info_t)); |
| |
| printf("please enter the file name: "); |
| ret = t_get_string(playback_info->file_name,sizeof(playback_info->file_name)); |
| if(ret != 0) |
| { |
| printf("Invalid input\n"); |
| return; |
| } |
| |
| printf("please enter the playback destination(0-To pcm interface / 1-To voice / 2-To pcm interface and voice): "); |
| ret = t_get_int(&(playback_info->playback_dest)); |
| if(ret != 0) |
| { |
| printf("Invalid input\n"); |
| return; |
| } |
| |
| printf("please enter the block flag(0-nonblock / 1-block): "); |
| ret = t_get_int(&(playback_info->block_flag)); |
| if(ret != 0) |
| { |
| printf("Invalid input\n"); |
| return; |
| } |
| |
| pthread_attr_init(&thread_attr); |
| pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); |
| |
| ret = pthread_create(&thread_id, &thread_attr, ql_audio_play_file_thread, (void *)playback_info); |
| if (0 > ret) |
| { |
| printf("Failed to create play file thread, ret = %d, err = %s\n", ret, strerror(errno)); |
| } |
| |
| pthread_attr_destroy(&thread_attr); |
| } |
| |
| |
| static audio_show_t audio_show[] = |
| { |
| { "ql_audio_init", item_ql_audio_init }, |
| { "ql_audio_set_service_error_cb", item_ql_audio_set_service_error_cb }, |
| { "ql_audio_set_loopback_enable_state", item_ql_audio_set_loopback_enable_state }, |
| { "ql_audio_get_loopback_enable_state", item_ql_audio_get_loopback_enable_state }, |
| { "ql_audio_set_tx_voice_mic_gain", item_ql_audio_set_tx_voice_mic_gain }, |
| { "ql_audio_get_tx_voice_mic_gain", item_ql_audio_get_tx_voice_mic_gain }, |
| { "ql_audio_set_codec_down_vol", item_ql_audio_set_codec_down_vol }, |
| { "ql_audio_get_codec_down_vol", item_ql_audio_get_codec_down_vol }, |
| { "ql_audio_playback_play_file", item_ql_audio_playback_play_file }, |
| { "ql_audio_deinit", item_ql_audio_deinit } |
| |
| }; |
| |
| int audio_get_int(int *val) |
| { |
| int dat; |
| char *ptr_end = NULL; |
| char buf[256] = {0}; |
| |
| if (NULL == val) |
| { |
| return -1; |
| } |
| |
| if (fgets(buf, sizeof(buf), stdin) == NULL) |
| { |
| return -1; |
| } |
| |
| if('\0' == buf[0]) |
| { |
| return -1; |
| } |
| |
| if('\n' == buf[0]) |
| { |
| return 1; |
| } |
| |
| dat = strtol(buf, &ptr_end, 10); |
| if((NULL != ptr_end) && ('\n' != ptr_end[0])) |
| { |
| return -1; |
| } |
| |
| *val = dat; |
| return 0; |
| } |
| |
| static void dump_audio_show(void) |
| { |
| int i = 0; |
| |
| for(i = 0; i < sizeof(audio_show)/sizeof(audio_show[0]); i++) |
| { |
| printf("%d\t%s\n", i, audio_show[i].name); |
| } |
| printf("-1\texit\n"); |
| } |
| |
| |
| int main(int argc, char **argv) |
| { |
| int ret = 0; |
| int index = 0; |
| |
| dump_audio_show(); |
| |
| while (1) |
| { |
| printf("\n"); |
| printf("Please enter your choice: "); |
| ret = audio_get_int(&index); |
| printf("\n"); |
| if(ret < 0) |
| { |
| printf("Invalid input\n"); |
| continue; |
| } |
| else if(ret == 1) |
| { |
| dump_audio_show(); |
| continue; |
| } |
| |
| if (index == -1) |
| { |
| break; |
| } |
| |
| if ((index < 0) || (index >= sizeof(audio_show)/sizeof(audio_show[0]))) |
| { |
| printf("Not support index: %d\n", index); |
| continue; |
| } |
| |
| if (NULL != audio_show[index].handle) |
| { |
| audio_show[index].handle(); |
| } |
| } |
| |
| return 0; |
| } |
| |
| |
| |