// 信号生成模块
// Author: 周涛
// Date: 2023-7-18

#include "includes.h"
#include "signal_public.h"

////定义本模块的全局变量
// 频点
// TODO，22400, 23000这两个频点被苹果手机抑制了
// const int16 gSignal_awFrequency[9] = {18200, 18800, 19400, 20000, 20600, 21200, 21800, 22400, 23000};
const int16 gSignal_awFrequency[9] = {17000, 17600, 18200, 18800, 19400, 20000, 20600, 21200, 21800};
volatile int16 gSignal_awSignal[SIGNAL_LR_FRAME_LEN] = {0};                         // 信号队列
volatile int32 gSignal_adwOneSecondSendList[SIGNAL_SIGNAL_SECOND_SEND_TIMES] = {0}; // 一秒信号发送队列

// 导入全局变量
extern const float gSignal_fConvCoe[6736]; // 滤波器

// 模块初始化
void signal_gen_init()
{
    SYS_MEMSET(gSignal_awSignal, 0, sizeof(int16) * SIGNAL_LR_FRAME_LEN);
    SYS_MEMSET(gSignal_adwOneSecondSendList, 0, sizeof(int32) * SIGNAL_SIGNAL_SECOND_SEND_TIMES);

    return;
}

// 生成A信号和B信号，保存到全局变量中
// byCarrierID:载波ID，从0到8
uint8 signal_gen_gen_ab_signal(uint8 byCarrierID)
{

    uint8 byFlag = 0;
    // 生成信号
    byFlag = signal_gen_gen_signal(byCarrierID);
    if (!byFlag)
    {
        return 0;
    }

    return 1;
}

// 根据载波编号生成信号
// byCarrierID:载波ID，0-8
uint8 signal_gen_gen_signal(uint8 byCarrierID)
{
    // 基带信号参数
    flt32 fBaseRoot = SIGNAL_BASE_ROOT_LEN;
    flt32 fBaseReal = 0;
    flt32 fBaseImag = 0;
    flt32 fBaseFactor = 0; // 基本信号因子
    flt32 fBaseTmp = 0;

    // 频带信号参数
    flt32 fBandReal = 0;
    flt32 fBandImag = 0;

    // 变频参数
    uint16 wfrequency = 0;  // 信号频率
    flt32 fDucFactor = 0;   // 变频因子
    flt32 fDucReal = 0.0;   // 变频信号实部
    flt32 fDucImag = 0.0;   // 变频信号虚部
    flt32 fDucRadian = 0.0; // 变频弧度

    // 量化参数
    uint32 dwQuantizationFactor = 4194304; // 量化因子，2的22次方
    int32 dwData = 0;
    int16 awDataList[2] = {0};
    uint16 wCounter = 0;

    // 输入参数容错处理
    if (byCarrierID < 0 || byCarrierID > 8)
    {
        return 0;
    }

    // 计算参数
    wfrequency = gSignal_awFrequency[byCarrierID]; // 载波频率
    fDucFactor = SIGNAL_TWO_PI * wfrequency / SIGNAL_SAMPLE_RATIO;
    fBaseFactor = -SIGNAL_ONE_PI * fBaseRoot / SIGNAL_BASE_LEN; // 基带信号因子

    ////生成信号
    for (uint16 i = 0; i < SIGNAL_CONV_LEN; i++)
    {
        //// 生成变频因子
        fDucRadian = fDucFactor * i;
        fDucRadian = fmod(fDucRadian, SIGNAL_TWO_PI); // 去掉2PI的整数部分
        fDucReal = cosf(fDucRadian);                  // 变频因子实部
        fDucImag = sinf(fDucRadian);                  // 变频因子虚部

        //// 生成基带信号
        fBandReal = 0;
        fBandImag = 0;
        for (uint16 j = 0; j < SIGNAL_BASE_LEN; j++)
        {
            // 生成基带信号
            fBaseTmp = j * (j + 1) * fBaseFactor;
            fBaseTmp = fmod(fBaseTmp, SIGNAL_TWO_PI);
            fBaseReal = cosf(fBaseTmp);
            fBaseImag = sinf(fBaseTmp);

            // 基带信号滤波
            fBandReal += gSignal_fConvCoe[i + j] * fBaseReal; // 基带信号实部
            fBandImag += gSignal_fConvCoe[i + j] * fBaseImag; // 基带信号虚部
        }

        ////调制信号(将基带信号调制成频带信号)，只保留信号实部
        signal_gen_complex_multiply_real(&fBandReal, &fBandImag, fDucReal, fDucImag);

        //// 量化处理
        // 量化
        dwData = round(fBandReal * dwQuantizationFactor);

        // 大端转换(DMA半字，I2S24Bit)
        dwData = dwData << 8;
        SYS_MEMCPY(awDataList, &dwData, sizeof(int16) * 2);

        // 组织左右声道数据
        gSignal_awSignal[wCounter] = awDataList[1]; // 左通道高字节
        wCounter++;
        gSignal_awSignal[wCounter] = awDataList[0]; // 左通道低字节
        wCounter++;

        gSignal_awSignal[wCounter] = awDataList[1]; // 右通道高字节
        wCounter++;
        gSignal_awSignal[wCounter] = awDataList[0]; // 右通道低字节
        wCounter++;
    }

    return 1;
}

// 复数相乘(只保留实部)
// (a + bi) * (c + di) = (ac - bd) + (ad + bc)i
// @param [inout]real1 复数1的实部
// @param [inout]imag1 复数1的虚部
// @param real2 复数2的实部
// @param imag2 复数2的虚部
void signal_gen_complex_multiply_real(float *real1, float *imag1, float real2, float imag2)
{
    float temp_real = *real1 * real2 - (*imag1) * imag2;
    float temp_imag = *real1 * imag2 + real2 * (*imag1);
    *real1 = temp_real;
    *imag1 = temp_imag;
}

// 根据时隙生成信号发送队列
// byTimeslot:信号发送时隙，取值，0，1，2，3
uint8 signal_gen_signal_send_list(uint8 byTimeslot)
{
    uint8 index = 0;

    // 参数容错处理
    if (byTimeslot < 0 || byTimeslot > 3)
    {
        return 0;
    }

    // 根据基站时隙，组织一秒信号的发送队列
    index = (SIGNAL_SIGNAL_SLOT_LEN * byTimeslot) / SIGNAL_SIGNAL_DMA_SEND_LEN;
    for (uint8 i = 0; i < SIGNAL_LR_FRAME_SEND_TIMES; i++)
    {
        gSignal_adwOneSecondSendList[index + i] = (uint32)&gSignal_awSignal[i * SIGNAL_SIGNAL_DMA_SEND_LEN];
    }

    return 1;
}

// 返回信号发送队列地址
// pdwData:信号
// bySignalFlag：信号标识，1：A信号，2:B信号
void signal_gen_query_signal_send_list(int32 **pdwSignalSendList)
{
    *pdwSignalSendList = gSignal_adwOneSecondSendList;

    return;
}

// 查询信号首地址
void signal_gen_query_signal_head_address(int32 **pdwSignalAddress)
{
    *pdwSignalAddress = (int32 *)gSignal_adwOneSecondSendList;
}
