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;
+}
+
+