#include <stdio.h>
#include <string.h>
#include <vector>
#include <iostream>
#include "htra_api.h" 
#include "example.h"
using namespace std;

#define IS_USB 1 //默认使用的是USB型设备，若使用的是网口型设备则将IS_USB定义为0。

//以解调1GHz，-20dBm，调制率为3kHz，频偏为75kHz的FM信号，并分析其解调灵敏度为例。

int IQS_AudioAnalysis()
{
	int Status = 0;      //函数的返回。
	void* Device = NULL; //当前设备的内存地址。
	int DevNum = 0;      //指定设备号。

	BootProfile_TypeDef BootProfile; //启动配置结构体，包括物理接口、供电方式等。
	BootInfo_TypeDef BootInfo;       //启动信息结构体，包括设备信息、USB速率等。

	BootProfile.DevicePowerSupply = USBPortAndPowerPort; //使用USB数据端口及独立电源端口双供电。

#if IS_USB==1
	//配置USB接口。
	BootProfile.PhysicalInterface = USB;
#else 
	//配置ETH接口。
	BootProfile.PhysicalInterface = ETH;
	BootProfile.ETH_IPVersion = IPv4;
	BootProfile.ETH_RemotePort = 5000;
	BootProfile.ETH_ReadTimeOut = 5000;
	BootProfile.ETH_IPAddress[0] = 192;
	BootProfile.ETH_IPAddress[1] = 168;
	BootProfile.ETH_IPAddress[2] = 1;
	BootProfile.ETH_IPAddress[3] = 100;
#endif

	Status = Device_Open(&Device, DevNum, &BootProfile, &BootInfo); //打开设备。

	Device_Open_ErrorHandling(Status, &Device, DevNum, &BootProfile, &BootInfo); //当Status不为0时，根据Status的返回值进行相对应的错误处理。

	IQStream_TypeDef IQStream;          //存放IQ数据包数据，包括IQ数据、配置信息等。
	IQS_Profile_TypeDef IQS_ProfileIn;  //IQS输入配置，包括起始频率、终止频率、RBW、参考电平等。
	IQS_Profile_TypeDef IQS_ProfileOut; //IQS输出配置。
	IQS_StreamInfo_TypeDef StreamInfo;  //当前配置下IQ数据信息，包括带宽, IQ单路采样率等。

	Status = IQS_ProfileDeInit(&Device, &IQS_ProfileIn); //初始化配置IQS模式的相关参数。

	IQS_ProfileIn.CenterFreq_Hz = 1e9;    //配置中心频率。
	IQS_ProfileIn.RefLevel_dBm = 0;        //配置参考电平。
	IQS_ProfileIn.DataFormat = Complex16bit; //配置IQ数据格式。
	IQS_ProfileIn.TriggerMode = Adaptive;    //配置触发模式。
	IQS_ProfileIn.TriggerSource = Bus;       //配置触发源为内部总线触发。
	IQS_ProfileIn.DecimateFactor = 64;      //配置抽取倍数。
	IQS_ProfileIn.BusTimeout_ms = 5000;      //配置Bus超时时间。

	Status = IQS_Configuration(&Device, &IQS_ProfileIn, &IQS_ProfileOut, &StreamInfo); //下发IQS模式的相关配置。
	
	IQS_Configuration_ErrorHandling(Status, &Device, DevNum, &BootProfile, &BootInfo, &IQS_ProfileIn, &IQS_ProfileOut, &StreamInfo); //当Status不为0时，根据Status的返回值进行相对应的错误处理。

	//Demod
	void* AnalogMod = NULL; //调制解调相关信息的内存地址。
	ASD_Open(&AnalogMod);   //开启调制解调功能。
	double carrierOffsetHz = 0;

	vector<float> audio(StreamInfo.PacketSamples);     //创建存放解调后音频数据的数组。


	//DSP
	void* DSP = NULL; //数字信号处理相关信息的内存地址。
	DSP_Open(&DSP);   //启用数字信号处理功能。

	Status = IQS_BusTriggerStart(&Device); //触发设备。若触发源为外部触发，则不需要调用此函数。

	//音频分析
	DSP_AudioAnalysis_TypeDef  AudioAnalysis; //启动音频分析结构体。
	int num = 0;
	
	while (num < 100)
	{
		Status = IQS_GetIQStream_PM1(&Device, &IQStream); //获取IQ数据。
		if (Status == APIRETVAL_NoError)
		{
			ASD_Demodulate_FM(&AnalogMod, &IQStream, 0, audio.data(), &carrierOffsetHz);  //对IQ数据进行FM解调。

			vector<double> Audio(audio.begin(), audio.end()); //音频数据类型转换。

			DSP_AudioAnalysis(Audio.data(), StreamInfo.PacketSamples,  StreamInfo.IQSampleRate, &AudioAnalysis);

			num++;
		}

		else //当Status不为0时，根据Status的返回值进行相对应的错误处理。
		{
			IQS_ErrorHandlingExceptOpenAndConfiguration(Status, &Device, DevNum, &BootProfile, &BootInfo, &IQS_ProfileIn, &IQS_ProfileOut, &StreamInfo);
		}
	}

	Status = IQS_BusTriggerStop(&Device); //调用IQS_BusTriggerStop停止触发设备。若触发源为外部触发，则不需要调用此函数。

	DSP_Close(&DSP);       //关闭数字信号处理功能。
	ASD_Close(&AnalogMod); //关闭调制解调。

	Status = Device_Close(&Device); //关闭设备。

	return 0;
}
