#include "platform.h"
#include "hal_headfile.h"
#include "debug.h"
#include "Plxc_Algo_Api.h"
#include "audio.h"
#include "config.h"
#include "resample.h"


extern void get_audio_from_adc(int16_t *audio0, int16_t *audio1, uint32_t num_samples);
extern void get_audio_for_dac_output(int16_t *audio0, int16_t *audio1, uint32_t num_samples);

static  audioListener_s *gAudioPrimitive;
void audioHandlerInit(audioListener_s *Primitives)
{
    gAudioPrimitive = (audioListener_s *)Primitives;
}

/**
 * 降噪算法和codec硬件初始化
 *
 * @param: none
 * @return: none.
 */
void denoise_init(void)
{
//    if ((aec_param.enable) && (aec_param.level))
//    {
//        plxc_set_model_addr((uint32_t)(FW_HEADER->BIN[1].ADDR + 0x4000000));// set ai denoise mod addr
//        plxc_algo_init();//init ai denoise algo
//        plxc_set_denoise_level(aec_param.level * 64); // set ai denoise level
//
//        if (aec_param.iis_rx_function == 2)
//        {
//            plxc_set_audio_callback(get_audio_for_dac_output);// iis rx data for denoise ，and output from dac
//        }
//        else if (aec_param.iis_tx_function == 2)
//        {
//            plxc_set_audio_callback(get_audio_for_iis_tx);// adc data for denoise ，and output from iix_tx
//        }
//        debug("algo_aec_init\n");
//    }
//    aec_param.iis_tx_function = 1;
//    aec_param.iis_rx_function = 1;
}

void denoise_lowpower_callback(uint8_t en)
{
    if (en == ENABLE) /*降噪工作*/
    {
        audio_adc_init();//init adc
        audio_dac_init();//init dac
    }
    else/*降噪暂停*/
    {
        audio_adc_suspend();
        audio_dac_suspend();
    }
}

/**
 * 音频算法计算完成后回调函数,从iis获取数据，经过降噪后，从芯片的DAC输出
 *
 * @param: audio0:音频数据0buff地址
 *         audio1:音频数据1buff地址
 *         num_samples:音频数据的点数
 * @return: none.
 */
void get_audio_for_dac_output(int16_t *audio0, int16_t *audio1, uint32_t num_samples)
{
    uint16_t temp_buff[AUDIO_CALLBACK_LEN * 2];

    if (aec_param.output_option == BOTH_AFTER_DENOISE)/*输出2路降噪后的音频*/
    {
        for (uint16_t i = 0; i < num_samples; i++)
        {
            temp_buff[2 * i + 0] = audio0[i];
            temp_buff[2 * i + 1] = audio0[i];
        }
    }
    else if (aec_param.output_option == BOTH_PRIMITIVE)/*输出2路都是原始数据*/
    {
        for (uint16_t i = 0; i < num_samples; i++)
        {
            temp_buff[2 * i + 0] = audio1[i];
            temp_buff[2 * i + 1] = audio1[i];
        }
    }
    else
    {
        for (uint16_t i = 0; i < num_samples; i++)/*输出1路降噪前，1路降噪后的数据*/
        {
            temp_buff[2 * i + 0] = audio1[i];
            temp_buff[2 * i + 1] = audio0[i];
        }
    }

	if(!sound_play_handle())//有提示音
	{

	}
	else
	{
		dac_write_data((uint8_t *)temp_buff, AUDIO_CALLBACK_LEN); /*向DAC写入降噪后的数据*/
	}

}
/**
 * 提示音重采样接口回调函数，提供重采样后的pcm数据
 *
 * @param: audio:音频数据的缓存地址
 *         num_samples:音频数据字节数
 * @return: none.
 */
void sound_callback(short* addr,uint32_t bytes_length)
{
	uint16_t temp_buff[bytes_length];
	for (uint16_t i = 0; i < bytes_length/2; i++)
	{
		temp_buff[2 * i + 0] = addr[i];
		temp_buff[2 * i + 1] = addr[i];
	}
	dac_write_data((uint8_t *)temp_buff, AUDIO_CALLBACK_LEN); /*向DAC写入降噪后的数据*/
}

/**
 * 音频算法计算完成后回调函数,从adc获取数据，经过降噪后，从芯片的IIS输出
 *
 * @param: audio0:音频数据0buff地址
 *         audio1:音频数据1buff地址
 *         num_samples:音频数据的点数
 * @return: none.
 */
void get_audio_for_iis_tx(int16_t *audio0, int16_t *audio1, uint32_t num_samples)
{
    uint16_t temp_buff[AUDIO_CALLBACK_LEN * 2];

    if (aec_param.output_option == BOTH_AFTER_DENOISE)/*输出2路降噪后的音频*/
    {
        for (uint16_t i = 0; i < num_samples; i++)
        {
            temp_buff[2 * i + 0] = audio0[i];
            temp_buff[2 * i + 1] = audio0[i];
        }
    }
    else if (aec_param.output_option == BOTH_PRIMITIVE)/*输出2路都是原始数据*/
    {
        for (uint16_t i = 0; i < num_samples; i++)
        {
            temp_buff[2 * i + 0] = audio1[i];
            temp_buff[2 * i + 1] = audio1[i];
        }
    }
    else
    {
        for (uint16_t i = 0; i < num_samples; i++)/*输出1路降噪前，1路降噪后的数据*/
        {
            temp_buff[2 * i + 0] = audio1[i];
            temp_buff[2 * i + 1] = audio0[i];
        }
    }
    src1_write_data((uint8_t *)temp_buff, AUDIO_CALLBACK_LEN);//将ADC的数据，写入SRC，通过IIS输出
}

/**
 * 向算法输入ADC原始音频数据
 *
 * @param: audio:原始音频数据的缓存地址
 *         num_samples:音频数据的点数
 * @return: none.
 */

void push_primitive_audio_from_adc(int16_t *audio, uint32_t num_samples)
{
    int16_t audio_buffer[2][AUDIO_CALLBACK_LEN];

    for (uint16_t i = 0; i < AUDIO_CALLBACK_LEN; i++) //用于两通道数据
    {
        audio_buffer[0][i] = audio[i * 2];         // ch0 audio data
        audio_buffer[1][i] = audio[i * 2 + 1];     // ch1 audio data
    }

    if (aec_param.iis_tx_function == 1) //iis tx disable denoise
    {
        get_audio_for_iis_tx(audio_buffer[0], audio_buffer[1], AUDIO_CALLBACK_LEN);//双通到录音
        return;
    }

    if ((aec_param.enable == ENABLE) && (aec_param.level != 0))
    {
        if ((gAudioPrimitive != (void *)0) && (gAudioPrimitive->audioListener != (void *)0))
        {
            if (aec_param.mian_mic_option == MIC_0)
            {
                gAudioPrimitive->audioListener(0, (uint32_t)audio_buffer[0], (uint32_t)audio_buffer[1]);
            }
            else
            {
                gAudioPrimitive->audioListener(0, (uint32_t)audio_buffer[1], (uint32_t)audio_buffer[0]);
            }
        }
    }
    else//降噪关闭，直接输出原始数据
    {
        if (aec_param.mian_mic_option == MIC_0)
        {
            get_audio_for_iis_tx(audio_buffer[0], audio_buffer[0], AUDIO_CALLBACK_LEN);
        }
        else
        {
            get_audio_for_iis_tx(audio_buffer[1], audio_buffer[1], AUDIO_CALLBACK_LEN);
        }
    }
}
/**
 * 向算法输入来自IIS的音频数据
 *
 * @param: audio:原始音频数据的缓存地址
 *         num_samples:音频数据的点数
 * @return: none.
 */
void push_primitive_audio_from_iis_rx(int16_t *audio, uint32_t num_samples)
{
    int16_t audio_buffer[2][AUDIO_CALLBACK_LEN];

    for (uint16_t i = 0; i < AUDIO_CALLBACK_LEN; i++) //用于两通道数据
    {
        audio_buffer[0][i] = audio[i * 2];         // ch0 audio data
        audio_buffer[1][i] = audio[i * 2 + 1];     // ch1 audio data
    }

    if (aec_param.iis_rx_function == 1) //iis rx disable denoise
    {
        get_audio_for_dac_output(audio_buffer[0], audio_buffer[1], AUDIO_CALLBACK_LEN);
        return;
    }

    if ((aec_param.enable == ENABLE) && (aec_param.level != 0))
    {
        if ((gAudioPrimitive != (void *)0) && (gAudioPrimitive->audioListener != (void *)0))
        {
            if (aec_param.mian_mic_option == MIC_0)
            {
                gAudioPrimitive->audioListener(0, (uint32_t)audio_buffer[0], (uint32_t)audio_buffer[0]);
            }
            else
            {
                gAudioPrimitive->audioListener(0, (uint32_t)audio_buffer[1], (uint32_t)audio_buffer[1]);
            }
        }
    }
    else
    {
        if (aec_param.mian_mic_option == MIC_0)
        {
            get_audio_for_dac_output(audio_buffer[0], audio_buffer[0], AUDIO_CALLBACK_LEN);
        }
        else
        {
            get_audio_for_dac_output(audio_buffer[1], audio_buffer[1], AUDIO_CALLBACK_LEN);
        }
    }
}
