add_af_ql_audio
Change-Id: I24a1fc20566049713e950f5f8e4cad6045c51723
diff --git a/mbtk/libmbtk_audio/src/mbtk_pcm_stream.c b/mbtk/libmbtk_audio/src/mbtk_pcm_stream.c
index 5c592fc..c811a9a 100755
--- a/mbtk/libmbtk_audio/src/mbtk_pcm_stream.c
+++ b/mbtk/libmbtk_audio/src/mbtk_pcm_stream.c
@@ -6,6 +6,7 @@
#include "mbtk_log.h"
#include "mbtk_audio_internal.h"
+#include "audio_if_audio_hw_mrvl.h"
#define LOCK_FILE "/var/run/mbtk_audio.lock"
#define AUDIO_DEBUG 0
@@ -524,3 +525,414 @@
return 0;
}
+
+typedef enum {
+ AUD_PLAYER_ERROR = -1,
+ AUD_PLAYER_START = 0,
+ AUD_PLAYER_PAUSE,
+ AUD_PLAYER_RESUME,
+ AUD_PLAYER_NODATA, //Buff no data and play tread will sleep
+ AUD_PLAYER_LESSDATA, //Buff has less data
+ AUD_PLAYER_FINISHED,
+} Enum_AudPlayer_State;
+
+struct mopen_audio_t
+{
+ int device;
+ audio_hw_device_t *audio_ahw_dev_ubus;
+ struct audio_stream_in *stream_in;
+ struct audio_stream_out *stream_out;
+ int pcm_packet_size; //320:NB, 640:WB
+ int pipe_data;
+ int fd[2];
+ pthread_t pid;
+ mbtk_audio_state_enum state;
+ pthread_mutex_t _cond_mutex;
+ pthread_mutex_t _stream_mutex;
+ void *usrData;
+};
+
+static struct mopen_audio_t *internal_hdl = NULL;
+typedef int (*_play_callback)(int hdl, int result);
+
+
+static int config_parameters_new(int in_out, int NBWB)
+{
+ unsigned int direction = 0xFF, type, srcdst, priority, dest;
+ char kvpair[128];
+ struct str_parms *param = NULL;
+ int data[5];
+ const char *key = NULL;
+ bool update_vcm = false;
+
+ direction = in_out;/* 0-play, 1-record */
+ type = NBWB; /* 0:PCM_NB_BUF_SIZE, 1:PCM_WB_BUF_SIZE */
+ srcdst = 1;/* 0-None, 1-Near end, 2-Far end, 3-Both ends */
+ priority = 1;/* 0-Do not combine(override), 1-Combine */
+ dest = 1;/* 0-Near codec, 1-Near Vocoder */
+
+ memset(kvpair, 0x00, sizeof(kvpair));
+ sprintf(kvpair, "%s=%d;%s=%d;%s=%d;%s=%d;%s=%d", VCM_CONFIG_DIRECTION, direction,
+ VCM_CONFIG_TYPE, type, VCM_CONFIG_SRC_DST, srcdst,
+ VCM_CONFIG_PRIORITY, priority, VCM_CONFIG_DEST, dest);
+
+ LOGD("%s: config information kvpair is %s.\n", __FUNCTION__, kvpair);
+
+ //extract the parameter and config from string
+ param = str_parms_create_str(kvpair);
+ if (!param) {
+ printf("%s: param create str is null!", __FUNCTION__);
+ return -1;
+ }
+
+ //set vcm configurations
+ key = VCM_CONFIG_DIRECTION;
+ if (str_parms_get_int(param, key, &data[0]) == 0) {
+ update_vcm = true;
+ str_parms_del(param, key);
+ }
+ key = VCM_CONFIG_TYPE;
+ if (str_parms_get_int(param, key, &data[1]) == 0) {
+ update_vcm = true;
+ str_parms_del(param, key);
+ }
+ key = VCM_CONFIG_SRC_DST;
+ if (str_parms_get_int(param, key, &data[2]) == 0) {
+ update_vcm = true;
+ str_parms_del(param, key);
+ }
+ key = VCM_CONFIG_PRIORITY;
+ if (str_parms_get_int(param, key, &data[3]) == 0) {
+ update_vcm = true;
+ str_parms_del(param, key);
+ }
+ key = VCM_CONFIG_DEST;
+ if (str_parms_get_int(param, key, &data[4]) == 0) {
+ update_vcm = true;
+ str_parms_del(param, key);
+ }
+
+ //printf("Direction is %d, Type is %d, Src_Dst is %d, Priority is %d, Dest is %d. \n",data[0], data[1], data[2], data[3], data[4]);
+
+ if (update_vcm) {
+ configure_vcm(data); /*TODO check if all inputs got all values successfully*/
+ }
+
+ return 0;
+}
+
+static int audio_open_pcm_new(void *dev_hdl, int num_channels, int rate, int in_out)
+{
+ struct mopen_audio_t *pcxt = (struct mopen_audio_t *)dev_hdl;
+ int nb_wb;
+
+ //Support 8k/16k & mono wave file
+ if (((rate != 8000) && (rate != 16000))
+ || (num_channels != 1) ) {
+ LOGD("%s: error wave file:rate = %d, num_channels = %d!! \n",
+ __FUNCTION__,rate, num_channels);
+ return -1;
+ }
+
+ LOGD("%s: success open, rate = %d, num_channels = %d.\n",
+ __FUNCTION__, rate, num_channels);
+
+ if ((8000 == rate) && (1 == num_channels)) {
+ nb_wb = 0;//NB
+ pcxt->pcm_packet_size = 320;
+ } else if ((16000 == rate) && (1 == num_channels)) {
+ nb_wb = 1;//WB
+ pcxt->pcm_packet_size = 640;
+ }
+
+ //config playback parameters.
+ config_parameters_new(in_out, nb_wb);
+ pcxt->device = in_out;
+ return 0;
+}
+
+static void mbtk_audio_set_status_new(void* hdl, mbtk_audio_state_enum _status)
+{
+ struct mopen_audio_t *pcxt = (struct mopen_audio_t *)hdl;
+ if (NULL == hdl || NULL == internal_hdl)
+ return 0;
+ pthread_mutex_lock(&pcxt->_cond_mutex);
+ pcxt->state = _status;
+ pthread_mutex_unlock(&pcxt->_cond_mutex);
+}
+
+mbtk_audio_handle mbtk_audio_open_new(mbtk_audio_dev_enum dev, int flag, int rate, void *usrData)
+{
+ int value = 1;
+ struct mopen_audio_t *aud_hdl = NULL;
+ int ret;
+
+ if(internal_hdl)
+ {
+ printf("Audio device inited\n");
+ return internal_hdl;
+ }
+
+ aud_hdl = (struct mopen_audio_t *) calloc(1, sizeof(struct mopen_audio_t));
+ if (!aud_hdl)
+ {
+ fprintf(stderr, "\n%s:Failed to allocate audio hdl!, errno=%d\n", __FUNCTION__, errno);
+ return NULL;
+ }
+ memset(aud_hdl, 0, sizeof(struct mopen_audio_t));
+
+ //init global variables
+ aud_hdl->audio_ahw_dev_ubus = audio_hal_install();
+ if (aud_hdl->audio_ahw_dev_ubus == NULL) {
+ LOGD("%s: audio_hal_install failed!\n", __FUNCTION__);
+ goto error;
+ }
+
+ ret = audio_open_pcm_new(aud_hdl, flag, rate, dev);
+ if (ret)
+ {
+ LOGD("\n%s: pcm open error, errno=%d\n", __FUNCTION__, errno);
+ goto error;
+ }
+
+ ret = aud_hdl->audio_ahw_dev_ubus->open_output_stream(aud_hdl->audio_ahw_dev_ubus, 0,
+ aud_hdl->audio_ahw_dev_ubus->get_supported_devices(aud_hdl->audio_ahw_dev_ubus),
+ AUDIO_OUTPUT_FLAG_DIRECT, NULL, &aud_hdl->stream_out, 0);
+
+ if (ret < 0) {
+ LOGD("%s: error opening output device. rc = %d\n", __FUNCTION__, ret);
+ goto error;
+ }
+
+ pthread_mutex_init(&aud_hdl->_cond_mutex, NULL);
+ aud_hdl->usrData = usrData;
+ aud_hdl->state = AUDIO_OPEN;
+ /* printf("Mbtk_Audio_Open aud_hdl[%x][%x][%x]\n", aud_hdl, aud_hdl->_mixer_ctl, aud_hdl->_pcm); */
+ internal_hdl = aud_hdl;
+
+ return (void *)aud_hdl;
+
+error:
+ value = 0;
+ free(aud_hdl);
+ return NULL;
+}
+
+int mbtk_audio_play_file_new(void *dev_hdl, int file_fd, int offset)
+{
+ unsigned bufsize = 0;
+ char *data = NULL;
+ int first_set = 0;
+ int file_data_sz = 0;
+ int res = 0;
+ int ret;
+
+ char cmd[128] = {0};
+ bool flay_flag = TRUE;
+ int i = 0;
+
+
+ struct mopen_audio_t *pcxt = (struct mopen_audio_t *)dev_hdl;
+ _play_callback audio_play_cb = (_play_callback)pcxt->usrData;
+ if (NULL == dev_hdl || NULL == internal_hdl)
+ return -1;
+
+
+ if(AUDIO_RUNNING == pcxt->state)
+ return -2;
+
+ // file_data_sz = mbtk_wav_pcm16Le_check(file_fd);
+ bufsize = pcxt->pcm_packet_size;
+ data = calloc(1, bufsize);
+ if (!data) {
+ fprintf(stderr, "\n%s:could not allocate %d bytes\n",__FUNCTION__,bufsize);
+ pthread_exit(NULL);
+ }
+ if(offset)
+ {
+ lseek(file_fd, offset, SEEK_SET);
+ }
+
+ mbtk_audio_set_status_new(dev_hdl, AUDIO_RUNNING);
+ int all_size = 0;
+
+ system("echo 1 >/sys/class/gpio/gpio19/value");
+ while (pcxt->state != AUDIO_STOP)
+ {
+ res = read(file_fd, data, bufsize);
+ // printf("%s:read : %d bytes\n", __FUNCTION__, res);
+ if(res == 0 || res < 0)
+ {
+ LOGD("read:[%d]", res);
+ break;
+ }
+
+ all_size += res;
+// if (file_data_sz < all_size || file_data_sz == all_size) {
+// printf("aplay size :%d - %d\n", file_data_sz, all_size);
+ // break;
+ // }
+
+ while(AUDIO_PAUSE == pcxt->state)
+ {
+ usleep(80000);
+ audio_play_cb(pcxt, AUD_PLAYER_PAUSE);
+ }
+
+ if ((0 == first_set || AUDIO_RESUME == pcxt->state))
+ {
+ first_set = 1;
+ mbtk_audio_set_status_new(dev_hdl, AUDIO_RUNNING);
+ audio_play_cb(pcxt, AUD_PLAYER_RESUME);
+ }
+
+ ret = pcxt->stream_out->write(pcxt->stream_out, data, bufsize);
+ if (ret < 0) {
+ LOGD("%s: error writing (child).\n", __FUNCTION__);
+ audio_play_cb(pcxt, AUD_PLAYER_ERROR);
+ break;
+ } else if (ret < (signed int)pcxt->pcm_packet_size) {
+ LOGD("%s: wrote less than buffer size, rc=%d.\n", __FUNCTION__, ret);
+ audio_play_cb(pcxt, AUD_PLAYER_LESSDATA);
+ break;
+ }
+
+ }
+ if (audio_play_cb)
+ audio_play_cb(pcxt, AUD_PLAYER_FINISHED);
+
+ LOGD("file_data_sz :%d - all_size: %d\n", file_data_sz, all_size);
+ mbtk_audio_set_status_new(dev_hdl, AUDIO_OPEN);
+ free(data);
+ system("echo 0 >/sys/class/gpio/gpio19/value");
+
+ return 0;
+}
+
+int mbtk_audio_play_stream_new(void *dev_hdl, const void *pData, int len, int gain )
+{
+ unsigned bufsize = 0;
+ char *data = NULL;
+ int first_set = 0;
+ int res = 0;
+ int ret = 0;
+ int read_size = 0;
+ char *p = (char *)pData;
+
+ char cmd[128] = {0};
+ bool flay_flag = TRUE;
+ int i = 0;
+
+ struct mopen_audio_t *pcxt = (struct mopen_audio_t *)dev_hdl;
+
+ if (NULL == dev_hdl || NULL == internal_hdl || pData == NULL)
+ return -1;
+
+ if(AUDIO_RUNNING == pcxt->state)
+ return -2;
+
+ bufsize = pcxt->pcm_packet_size;
+ data = calloc(1, bufsize);
+ if (!data) {
+ fprintf(stderr, "\n%s:could not allocate %d bytes\n",__FUNCTION__,bufsize);
+ pthread_exit(NULL);
+ }
+
+ if(pcxt->state == AUDIO_OPEN)
+ {
+ mbtk_audio_set_status_new(dev_hdl, AUDIO_RUNNING);
+
+ }
+
+ // system("echo 1 >/sys/class/gpio/gpio19/value");
+ while (pcxt->state != AUDIO_STOP)
+ {
+
+ memcpy(data,p+read_size, bufsize );
+ read_size += bufsize;
+
+ if(read_size > len)
+ {
+ // printf(">[%d]\n", read_size);
+ break;
+ }
+
+ while(AUDIO_PAUSE == pcxt->state)
+ {
+ usleep(80000);
+ }
+
+ if ((0 == first_set || AUDIO_RESUME == pcxt->state))
+ {
+ first_set = 1;
+ mbtk_audio_set_status_new(dev_hdl, AUDIO_RUNNING);
+ }
+
+ ret = pcxt->stream_out->write(pcxt->stream_out, data, bufsize);
+ if (ret < 0) {
+ LOGD("%s: error writing (child).\n", __FUNCTION__);
+ break;
+ } else if (ret < (signed int)pcxt->pcm_packet_size) {
+ LOGD("%s: wrote less than buffer size, rc=%d.\n", __FUNCTION__, ret);
+ break;
+ }
+
+ if(read_size == len)
+ {
+ // printf("=[%d]", read_size);
+ break;
+ }
+
+ i++;
+ if(i == 3) // 该值可以自行调节
+ {
+ if(flay_flag && gain != 50)
+ {
+ sprintf(cmd, "ubus call audio_if config_dspgain \"{\'type\':1, \'gain\':%d}\"", gain);
+ system(cmd);
+
+ flay_flag = FALSE;
+ usleep(80000);
+ }
+ }
+
+ }
+
+ if(pcxt->state != AUDIO_STOP)
+ {
+ mbtk_audio_set_status_new(dev_hdl, AUDIO_OPEN);
+ }
+ // system("echo 0 >/sys/class/gpio/gpio19/value");
+ free(data);
+ return 0;
+}
+
+int mbtk_audio_close_new(void *dev_hdl)
+{
+ printf("mbtk_audio_close()\n");
+ int value = 0;
+ struct mopen_audio_t *_hdl = (struct mopen_audio_t *)dev_hdl;
+
+ if (NULL == _hdl || NULL == internal_hdl )
+ {
+ printf("mbtk_audio_close() fail dev_hdl is NULL\n");
+ return -1;
+ }
+
+ mbtk_audio_set_status_new(_hdl, AUDIO_STOP);
+
+ vcm_playback_drain(0);//wait for drain the AP audiostub queue.
+ usleep(80000);//delay 80ms until DSP play out its buffered data.
+ _hdl->stream_out->common.standby(&_hdl->stream_out->common);
+ _hdl->audio_ahw_dev_ubus->close_output_stream(_hdl->audio_ahw_dev_ubus, _hdl->stream_out);
+
+ audio_hal_uninstall();
+ pthread_mutex_destroy(&_hdl->_cond_mutex);
+ free(_hdl);
+ _hdl = NULL;
+ internal_hdl = NULL;
+
+ return 0;
+}
+
+