blob: 1944fb50cecca7b0e9495e3a2cbbff2733ce7b7c [file] [log] [blame]
/*-----------------------------------------------------------------------------------------------*/
/**
@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;
}