/***************************************************************************** | |
** °æÈ¨ËùÓÐ (C)2015, ÖÐÐËͨѶ¹É·ÝÓÐÏÞ¹«Ë¾¡£ | |
** | |
** ÎļþÃû³Æ: voice.c | |
** Îļþ±êʶ: | |
** ÄÚÈÝÕªÒª: | |
** ʹÓ÷½·¨: | |
** | |
** ÐÞ¸ÄÈÕÆÚ °æ±¾ºÅ Ð޸ıê¼Ç ÐÞ¸ÄÈË ÐÞ¸ÄÄÚÈÝ | |
** ----------------------------------------------------------------------------- | |
** 2019/09/25 V1.0 Create xxq ´´½¨ | |
** | |
* ******************************************************************************/ | |
#include <stdio.h> | |
#include <unistd.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#include <stdint.h> | |
#include <linux/volte_drv.h> | |
#include <sys/ioctl.h> | |
#include <fcntl.h> | |
#include <tinyalsa/audio_mixer_ctrl.h> | |
#define VOICE_DEV_NAME "/dev/voice_device" | |
typedef struct { | |
int fd; | |
unsigned int state; // 0 close;1 open | |
T_Voice_Para vpara; | |
} T_voiceInfo; | |
T_voiceInfo *voiceinfo = NULL; | |
static int slic_flag = 0; | |
static int slic_flag_already = 0;// 0 not get ,1 already get | |
struct pcm *volte_pcm_voice_out = NULL; | |
struct pcm *volte_pcm_voice_in = NULL; | |
#if 0 | |
T_Voice_Para gsmhwpara = { | |
8000, //8000;16000 | |
0, //// 0 gsm;1 td;2 wcdma;3 lte | |
0//0 hardware dsp;1 soft amr lib | |
}; | |
T_Voice_Para tdnbhwpara = { | |
8000, //8000;16000 | |
1, //// 0 gsm;1 td;2 wcdma;3 lte | |
0,//0 amr-nb;1 amr-wb | |
0//0 hardware dsp;1 soft amr lib | |
}; | |
T_Voice_Para tdnbsfpara = { | |
8000, //8000;16000 | |
1, //// 0 gsm;1 td;2 wcdma;3 lte | |
0,//0 amr-nb;1 amr-wb | |
1//0 hardware dsp;1 soft amr lib | |
}; | |
T_Voice_Para tdwbsfpara = { | |
8000, //8000;16000 | |
1, //// 0 gsm;1 td;2 wcdma;3 lte | |
1,//0 amr-nb;1 amr-wb | |
1//0 hardware dsp;1 soft amr lib | |
}; | |
#endif | |
//static volatile int voiceinfo.fd = 0; | |
int voice_open(T_Voice_Para *para) | |
{ | |
int ret = 0; | |
if (!para) { | |
printf("voice: open para is NULL.\n"); | |
return -1; | |
} | |
voiceinfo = calloc(1, sizeof(T_voiceInfo)); | |
if (!voiceinfo) { | |
printf("voice: open calloc fail!\n"); | |
return -1; | |
} | |
voiceinfo->vpara = *para; | |
voiceinfo->fd = open(VOICE_DEV_NAME, O_RDONLY); | |
if (voiceinfo->fd < 0) { | |
printf("voice lib: open voice device error.\n"); | |
free(voiceinfo); | |
return -1; | |
} | |
ret = ioctl(voiceinfo->fd, VOICE_IOCTL_START, para); | |
if (ret) { | |
printf("voice lib: voice start fd=%d,ret=%d.\n", voiceinfo->fd, ret); | |
goto err; | |
} | |
printf("voice open end !\n"); | |
return 0; | |
err: | |
close(voiceinfo->fd); | |
free(voiceinfo); | |
printf("voice open err end !\n"); | |
return -1; | |
} | |
int voice_close(T_Voice_Para *para) | |
{ | |
int ret = 0; | |
if (!voiceinfo) { | |
printf("voice: close voiceinfo is NUll!\n"); | |
return 0; | |
} | |
ret = ioctl(voiceinfo->fd, VOICE_IOCTL_STOP, para); | |
if (ret) { | |
printf("voice lib: voice stop fd=%d,ret=%d.\n", voiceinfo->fd, ret); | |
} | |
if (voiceinfo->fd >= 0) { | |
close(voiceinfo->fd); | |
} | |
voiceinfo->fd = -1; | |
free(voiceinfo); | |
voiceinfo = NULL; | |
printf("voice close end !\n"); | |
return 0; | |
} | |
int voice_Vploop(int *path) | |
{ | |
int ret = 0; | |
int fd = -1; | |
printf("voice_Vploop: start path=%d!\n",*path); | |
fd = open(VOICE_DEV_NAME, O_RDONLY); | |
if (fd < 0) { | |
printf("voice_Vploop: open voice device error.\n"); | |
return -1; | |
} | |
ret = ioctl(fd, VOICE_IOCTL_VPLOOP, path); | |
if (ret) { | |
printf("voice_Vploop: ret=%d,path=%p.\n", ret, path); | |
close(fd); | |
return -1; | |
} | |
close(fd); | |
return 0; | |
} | |
int voice_GetSlicFlag(void) | |
{ | |
int ret = 0; | |
int fd = -1; | |
int flag = 0; | |
printf("voice_GetSlicFlag: start!\n"); | |
fd = open(VOICE_DEV_NAME, O_RDONLY); | |
if (fd < 0) { | |
printf("voice_GetSlicFlag: open voice device error.\n"); | |
return -1; | |
} | |
ret = ioctl(fd, VOICE_IOCTL_GET_SLIC_USE_FLAG, &flag); | |
if (ret) { | |
printf("voice_GetSlicFlag: ret=%d,flag=%d.\n", ret, flag); | |
close(fd); | |
return -1; | |
} | |
close(fd); | |
slic_flag_already = 1; | |
return flag; | |
} | |
int zDrvVolte_PreOpen(T_ZDrvVolte_Cfg *cfgParam) | |
{ | |
struct mixer *voice_mixer = NULL; | |
struct pcm_config config_voice = {0}; | |
printf(" voice lib zDrvVolte_PreOpen!\n"); | |
if (slic_flag_already == 1) { | |
printf(" voice slic flag already get, slic_flag=%d!\n", slic_flag); | |
if (slic_flag == 1) { | |
return 0; | |
} | |
} else { | |
slic_flag = voice_GetSlicFlag(); | |
printf(" voice slic flag get, slic_flag=%d!\n", slic_flag); | |
if (slic_flag == 1) { | |
return 0; | |
} | |
} | |
//open mixer dev for codec control | |
voice_mixer = mixer_open(0); | |
if (!voice_mixer) { | |
printf("zte voice_mixer open failed!\n"); | |
return -1; | |
} | |
//config mixer dev | |
mix_set_voice_path(voice_mixer, T_OUTPUT_SPEAKER); | |
mix_set_voice_vol(voice_mixer, T_VOICE_VOL_3_LEVEL); | |
//close mixer | |
mixer_close(voice_mixer); | |
voice_mixer = NULL; | |
//open pcm dev for data tranf | |
config_voice.channels = cfgParam->channel_count; | |
config_voice.rate = cfgParam->clock_rate; | |
//buffer num | |
config_voice.period_count = 3; | |
//buffer size | |
config_voice.period_size = cfgParam->samples_per_frame * cfgParam->bits_per_sample / 8; | |
//16-bit signed | |
config_voice.format = PCM_FORMAT_S16_LE; | |
//card 0 dev 1 | |
//23G card 0 dev 2 | |
volte_pcm_voice_out = pcm_open(0, 1, PCM_OUT, &config_voice); | |
if (!pcm_is_ready(volte_pcm_voice_out)) { | |
printf("zte volte_pcm_voice_out open failed!\n"); | |
goto err_ret; | |
} | |
volte_pcm_voice_in = pcm_open(0, 1, PCM_IN, &config_voice); | |
if (!pcm_is_ready(volte_pcm_voice_in)) { | |
printf("zte volte_pcm_voice_in open failed!\n"); | |
goto err_ret; | |
} | |
if (0 != pcm_prepare(volte_pcm_voice_out)) { | |
printf("zte volte_pcm_voice_out pcm_prepare failed!\n"); | |
goto err_ret; | |
} | |
if (0 != pcm_prepare(volte_pcm_voice_in)) { | |
printf("zte volte_pcm_voice_in pcm_prepare failed!\n"); | |
goto err_ret; | |
} | |
return 0; | |
err_ret: | |
pcm_close(volte_pcm_voice_out); | |
volte_pcm_voice_out = NULL; | |
if (volte_pcm_voice_in) { | |
pcm_close(volte_pcm_voice_in); | |
volte_pcm_voice_in = NULL; | |
} | |
return -1; | |
} | |
void zDrvVolte_PreClose(void) | |
{ | |
printf(" voice lib zDrvVolte_PreClose!\n"); | |
if (slic_flag_already == 1) { | |
printf(" voice slic flag already get, slic_flag=%d!\n", slic_flag); | |
if (slic_flag == 1) { | |
return ; | |
} | |
} else { | |
slic_flag = voice_GetSlicFlag(); | |
printf(" voice slic flag get, slic_flag=%d!\n", slic_flag); | |
if (slic_flag == 1) { | |
return ; | |
} | |
} | |
if (volte_pcm_voice_out) { | |
pcm_close(volte_pcm_voice_out); | |
volte_pcm_voice_out = NULL; | |
} | |
if (volte_pcm_voice_in) { | |
pcm_close(volte_pcm_voice_in); | |
volte_pcm_voice_in = NULL; | |
} | |
} | |