#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<fstream>
#include<vector>
#include"msgpack.h"
#include"htra_api.h"
#include<iostream>
#include <filesystem>
using namespace std;

union FloatConversion {// Used to convert the byte order of float type data
    float f;
    uint32_t i;
};
union DoubleConversion {// Used to convert the byte order of double type data
    double d;
    uint64_t i;
};

// This function is used to get the configuration and trace information, the number of packets, and the number of traces in the record file.
int SWP_RecordingConfigurationInfo(const char* FilePath, SWP_Profile_TypeDef* SWP_Profile, SWP_TraceInfo_TypeDef* SWP_TraceInfo, uint32_t* TraceNumbers)
{
    int Status = 0;                              // Function return value variable.
    fstream file;                                 // Create a file stream object for reading the file.
    string FilePath1 = FilePath;                 // FilePath should be the address passed in.
    file.open(FilePath1, ios::in | ios::binary);  // Open the file in binary mode for reading.
    
    if (!file.is_open()) // Check if the file is opened successfully.
    {
        Status = -1000;
        cout << "File opening failed!" << endl;
        return Status;
    }

    uint64_t PacketCount;     // Read PacketCount (the number of packets) from the file.
    file.seekg(64, ios::beg); // Move the file pointer by 64 bytes, to read the value of PacketCount.
    file.read(reinterpret_cast<char*>(&PacketCount), sizeof(PacketCount));


    uint64_t PacketCount_1 = (((PacketCount & 0xff) << 56) | ((PacketCount & 0xff00) << 40) |
        ((PacketCount & 0xff0000) << 24) | ((PacketCount & 0xff000000) << 8) |
        ((PacketCount & 0xff00000000) >> 8) | ((PacketCount & 0xff0000000000) >> 24) |
        ((PacketCount & 0xff000000000000) >> 40) | ((PacketCount & 0xff00000000000000) >> 56)); // Adjust the byte order of PacketCount (big-endian to little-endian conversion).

    uint16_t Length;                                                     // Read Length from the file.
    file.seekg(72 + 10 * 1024 * 1024, ios::beg);                         // Move the file pointer to offset 72 + 10MB to read Length.
    file.read(reinterpret_cast<char*>(&Length), sizeof(Length));
    uint16_t Length_1 = ((Length & 0xff) << 8 | (Length & 0xff00) >> 8); // Adjust the byte order of Length (big-endian to little-endian).
    char* ConfigurationInfo = new char[Length_1];                        // Dynamically allocate memory based on Length_1.
    vector<char> ConfigurationInfo1(Length_1);                           // Use std::vector to store the read content.

    file.read(ConfigurationInfo1.data(), ConfigurationInfo1.size());    // Read the configuration data from the file into ConfigurationInfo1.
    memcpy(ConfigurationInfo, ConfigurationInfo1.data(), ConfigurationInfo1.size()); // Copy the configuration data into the char array.

    // Check if the configuration file content was successfully read.
    if (ConfigurationInfo == NULL)
    {
        Status = -1001;  
        return Status;   
    }

    msgpack_unpacked msg;            // Define an unpack object.
    msgpack_unpacked_init(&msg);     // Initialize the msgpack unpack object.

    size_t length = Length_1;        // Length of the configuration data, corresponding to the read Length_1.
    size_t off = 0;                  // Initialize the offset to 0, indicating unpacking from the start of the data.
    
    SWP_Profile_TypeDef Profile;     // Create a structure Profile to store the unpacked configuration information.

    // Unpack StartFreq_Hz (start frequency in Hz).
    msgpack_unpack_next(&msg, ConfigurationInfo, length, &off); // Unpack the next msgpack object.
    Profile.StartFreq_Hz = (double)msg.data.via.f64;            // Convert the unpacked 64-bit float value to double and store in Profile.StartFreq_Hz.

    // Unpack StopFreq_Hz (stop frequency in Hz).
    msgpack_unpack_next(&msg, ConfigurationInfo, length, &off); // Unpack the next msgpack object.
    Profile.StopFreq_Hz = (double)msg.data.via.f64;             // Convert the unpacked 64-bit float value to double and store in Profile.StopFreq_Hz.

    // Unpack CenterFreq_Hz (center frequency in Hz).
    msgpack_unpack_next(&msg, ConfigurationInfo, length, &off); // Unpack the next msgpack object.
    Profile.CenterFreq_Hz = (double)msg.data.via.f64;           // Convert the unpacked 64-bit float value to double and store in Profile.CenterFreq_Hz.
    // Continue with similar operations for subsequent unpacking.
	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.Span_Hz = (double)msg.data.via.f64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.RefLevel_dBm = (double)msg.data.via.f64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.RBW_Hz = (double)msg.data.via.f64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.VBW_Hz = (double)msg.data.via.f64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.SweepTime = (double)msg.data.via.f64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.TraceBinSize_Hz = (double)msg.data.via.f64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.FreqAssignment = (SWP_FreqAssignment_TypeDef)msg.data.via.i64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.Window = (Window_TypeDef)msg.data.via.i64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.RBWMode = (RBWMode_TypeDef)msg.data.via.i64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.VBWMode = (VBWMode_TypeDef)msg.data.via.i64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.SweepTimeMode = (SweepTimeMode_TypeDef)msg.data.via.i64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.Detector = (Detector_TypeDef)msg.data.via.i64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.TraceFormat = (TraceFormat_TypeDef)msg.data.via.i64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.TraceDetectMode = (TraceDetectMode_TypeDef)msg.data.via.i64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.TraceDetector = (TraceDetector_TypeDef)msg.data.via.i64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.TracePoints = (uint32_t)msg.data.via.u64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.TracePointsStrategy = (TracePointsStrategy_TypeDef)msg.data.via.i64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.TraceAlign = (TraceAlign_TypeDef)msg.data.via.i64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.FFTExecutionStrategy = (FFTExecutionStrategy_TypeDef)msg.data.via.i64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.RxPort = (RxPort_TypeDef)msg.data.via.i64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.SpurRejection = (SpurRejection_TypeDef)msg.data.via.i64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.ReferenceClockSource = (ReferenceClockSource_TypeDef)msg.data.via.i64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.ReferenceClockFrequency = (double)msg.data.via.f64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.EnableReferenceClockOut = (uint8_t)msg.data.via.u64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.SystemClockSource = (SystemClockSource_TypeDef)msg.data.via.i64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.ExternalSystemClockFrequency = (double)msg.data.via.u64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.TriggerSource = (SWP_TriggerSource_TypeDef)msg.data.via.i64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.TriggerEdge = (TriggerEdge_TypeDef)msg.data.via.i64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.TriggerOutMode = (TriggerOutMode_TypeDef)msg.data.via.i64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.TriggerOutPulsePolarity = (TriggerOutPulsePolarity_TypeDef)msg.data.via.i64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.PowerBalance = (uint32_t)msg.data.via.u64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.GainStrategy = (GainStrategy_TypeDef)msg.data.via.i64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.Preamplifier = (PreamplifierState_TypeDef)msg.data.via.i64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.AnalogIFBWGrade = (uint8_t)msg.data.via.u64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.IFGainGrade = (uint8_t)msg.data.via.u64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.EnableDebugMode = (uint8_t)msg.data.via.u64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.CalibrationSettings = (uint8_t)msg.data.via.u64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.Atten = (int8_t)msg.data.via.i64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.TraceType = (SWP_TraceType_TypeDef)msg.data.via.i64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	Profile.LOOptimization = (LOOptimization_TypeDef)msg.data.via.i64;

	off = off * 2; // Multiply the offset off by 2, used to skip certain data blocks or adjust the unpacking position.
    *SWP_Profile = Profile; // Copy the content of the Profile structure to the memory location pointed to by SWP_Profile.
    SWP_TraceInfo_TypeDef TraceInfo; // Define a variable TraceInfo of type SWP_TraceInfo_TypeDef to store trace information.

    msgpack_unpack_next(&msg, ConfigurationInfo, length, &off); // Start unpacking from the ConfigurationInfo data, the unpacked data is stored in msg. length is the total data length, and off is the current unpacking offset, which will be updated to the new position after unpacking.
    TraceInfo.FullsweepTracePoints = (int)msg.data.via.i64; // msg.data.via.i64 is the unpacked 64-bit integer data, representing the number of full sweep trace points.

    msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
    TraceInfo.PartialsweepTracePoints = (int)msg.data.via.i64; // msg.data.via.i64 is the unpacked 64-bit integer data, representing the number of partial sweep trace points.
    // Continue with similar operations for subsequent unpacking.
	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	TraceInfo.TotalHops = (int)msg.data.via.i64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	TraceInfo.UserStartIndex = (uint32_t)msg.data.via.u64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);

	TraceInfo.UserStopIndex = (uint32_t)msg.data.via.u64;
	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);

	TraceInfo.TraceBinBW_Hz = (double)msg.data.via.f64;
	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);

	TraceInfo.StartFreq_Hz = (double)msg.data.via.f64;
	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);

	TraceInfo.AnalysisBW_Hz = (double)msg.data.via.f64;
	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);

	TraceInfo.TraceDetectRatio = (int)msg.data.via.i64;
	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);

	TraceInfo.DecimateFactor = (int)msg.data.via.i64;
	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);

	TraceInfo.FrameTimeMultiple = (float)msg.data.via.f64;
	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);

	TraceInfo.FrameTime = (double)msg.data.via.f64;
	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);

	TraceInfo.EstimateMinSweepTime = (double)msg.data.via.f64;
	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);

	TraceInfo.DataFormat = (DataFormat_TypeDef)msg.data.via.i64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	TraceInfo.SamplePoints = (uint64_t)msg.data.via.u64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	TraceInfo.GainParameter = (uint32_t)msg.data.via.u64;

	msgpack_unpack_next(&msg, ConfigurationInfo, length, &off);
	TraceInfo.DSPPlatform = (DSPPlatform_Typedef)msg.data.via.u64;
	
    msgpack_unpacked_destroy(&msg); // Destroy the unpacked object.
    *SWP_TraceInfo = TraceInfo;     // Copy the content of the TraceInfo structure to the memory location pointed to by SWP_TraceInfo.

    uint32_t TraceNumber1 = PacketCount_1 / (TraceInfo.FullsweepTracePoints / TraceInfo.PartialsweepTracePoints); // Calculate the number of traces based on the point ratio (integer form).
    double TraceNumber2 = (double)PacketCount_1 / (double)(TraceInfo.FullsweepTracePoints / TraceInfo.PartialsweepTracePoints); // Calculate the number of traces using floating-point division to avoid errors caused by integer division.

    // If the floating-point result is greater than the integer result, round up.
    if (TraceNumber2 > TraceNumber1)
    {
        TraceNumber1++;
    }

    *TraceNumbers = TraceNumber1; // Pass the final number of traces to the external pointer.
    file.close();                 // Close the file and release related resources.
    return 0;
}

// This function is used to obtain the frequency array, power array, and MeasAuxInfo packet information of the traces in the selected recording file.
int SWP_RecordingPowerSpectralDensityInfo(const char* FilePath, double Freq_Hz[], float PowerSpec_dBm[], MeasAuxInfo_TypeDef MeasAuxInfo[])
{

    int Status = 0; // Define a variable for the function return value.
    fstream file; // Create an fstream object to open and read the file.
    string FilePath1 = FilePath; // Store the file path in a string variable.
    file.open(FilePath1, ios::in | ios::binary); // Open the file in binary read mode.

    // Check whether the file was successfully opened.
    if (!file.is_open())
    {
        cout << "The log file failed to open!" << endl;
        Status = -1000;
        return Status; // Return error status.
    }

    uint32_t APIVersion; // Read the API version information.
    file.seekg(8, ios::beg); // Move the file pointer to the 8th byte position.
    file.read(reinterpret_cast<char*>(&APIVersion), sizeof(APIVersion)); // Read the API version from the file into the APIVersion variable.
    uint32_t APIVersion_1 = ((APIVersion & 0xFF) << 24) | ((APIVersion & 0xFF00) << 8) | ((APIVersion & 0xFF0000) >> 8) | ((APIVersion & 0xFF000000) >> 24); // Convert byte order from big-endian to little-endian.
    uint16_t x = (uint16_t)(((APIVersion_1) & 0xffff0000) >> 16);
    uint8_t y = (uint8_t)(((APIVersion_1) & 0x0000ff00) >> 8);
    uint8_t z = (uint8_t)((APIVersion_1) & 0x000000ff);

    // Check whether it is version 55.
    if (y != 55)
    {
        cout << "The file is not version 55, please select the version 55 file" << endl;
        Status = -1002;
        return Status;
    }

    uint64_t PacketCount; // Read the total number of data packets recorded in the file.
    file.seekg(64, ios::beg); // Move the file pointer to the 64th byte position.
    file.read(reinterpret_cast<char*>(&PacketCount), sizeof(PacketCount)); // Read the number of packets from the file into the PacketCount variable.
    uint64_t PacketCount_1 = (((PacketCount & 0xff) << 56) 
        | ((PacketCount & 0xff00) << 40) | ((PacketCount & 0xff0000) << 24) 
        | ((PacketCount & 0xff000000) << 8) | ((PacketCount & 0xff00000000) >> 8) 
        | ((PacketCount & 0xff0000000000) >> 24) | ((PacketCount & 0xff000000000000) >> 40) | ((PacketCount & 0xff00000000000000) >> 56)); // Convert byte order from big-endian to little-endian.

    uint16_t Length; // Read the length of the frequency array, power array, and other data packets.
    file.seekg(72 + 10 * 1024 * 1024, ios::beg); // Move the file pointer to the specified offset.
    file.read(reinterpret_cast<char*>(&Length), sizeof(Length));
    uint16_t Length_1 = ((Length & 0xff) << 8 | (Length & 0xff00) >> 8);

    // Store file content and parse data packets.
    char ch; // Temporary variable used to read characters from the file one by one.
    vector<char> MeasAuxInfo_ALL; // Store all the read data packet contents.

    // Locate the start position of the data packets.
    file.seekg(74 + 10 * 1024 * 1024 + Length_1, ios::beg); // 74: file header offset, 10MB: skip the first 10MB of data, Length_1: dynamically calculated offset.

    while (file.get(ch)) // Continuously read each character from the file until the end of the file.
    {
        MeasAuxInfo_ALL.push_back(ch);
    }

    vector<double> Freq_all; // Store frequency data of type double.
    vector<float> Power_all; // Store power data of type float.
    uint32_t index = 0;      // Current data packet index, initialized to 0.
    double Freq;             // Used to store the frequency of the current data packet.
    float Power_1 = 0;       // Used to store the power of the current data packet, initialized to 0.

    for (uint64_t i = 0; i < PacketCount_1; i++) // Traverse all data packets.
    {
        int CountLength; // The byte length of a data packet.
        memcpy(&CountLength, MeasAuxInfo_ALL.data() + index, sizeof(int)); // Read the byte length from the data.
        int CountLength_1 = (((CountLength & 0xff) << 24) | ((CountLength & 0xff00) << 8) | ((CountLength & 0xff0000) >> 8) | ((CountLength & 0xff000000) >> 24)); // Convert byte order (big-endian -> little-endian).

        int points = ((CountLength_1 - 56) / 12); // Calculate the number of valid data points, excluding the fixed 56-byte header (each point occupies 12 bytes).
        double points1 = ((double)(CountLength_1 - 56) / (double)12); // Calculate the precise number of points (floating-point value) to avoid integer division errors.

        // If the floating-point number of points is greater than the integer number, add one point to ensure complete data.
        if (points1 > points) // Check the frequency array size of one packet of data.
        {
            points += 1;
        }

        index += sizeof(int); // Update the index to skip the CountLength field and prepare to read frequency data.
        for (int i = 0; i < points; i++) // Read frequency data (each frequency occupies 8 bytes).
        {
            memcpy(&Freq, MeasAuxInfo_ALL.data() + index, sizeof(double));
            Freq_all.push_back(Freq); // Store the frequency value into the Freq_all container.
            index += sizeof(double);  // Update the index to point to the next data.
        }

        for (int i = 0; i < points; i++) // Read power data (each power occupies 4 bytes).
        {
            memcpy(&Power_1, MeasAuxInfo_ALL.data() + index, sizeof(float));
            Power_all.push_back(Power_1); // Store the power value into the Power_all container.
            index += sizeof(float);       // Update the index to point to the next data.
        }
		
		int Hopindex;													// Read the Hopindex value and perform byte order conversion.
		memcpy(&Hopindex, MeasAuxInfo_ALL.data() + index, sizeof(int)); // Read Hopindex (4 bytes) from the data.
		
		index += sizeof(int);                                                                                                                     // Update the index to point to the next data position.
		int Hopindex_1 = ((Hopindex & 0xFF) << 24) | ((Hopindex & 0xFF00) << 8) | ((Hopindex & 0xFF0000) >> 8) | ((Hopindex & 0xFF000000) >> 24); // Perform big-endian to little-endian byte order conversion for Hopindex.

		int Frameindex;																																		// Read the Frameindex value and perform byte order conversion.
		memcpy(&Frameindex, MeasAuxInfo_ALL.data() + index, sizeof(int));																					// Read Frameindex (4 bytes) from the data.
		index += sizeof(int);																													            // Update the index to point to the next data position.
		int Frameindex_1 = ((Frameindex & 0xFF) << 24) | ((Frameindex & 0xFF00) << 8) | ((Frameindex & 0xFF0000) >> 8) | ((Frameindex & 0xFF000000) >> 24); // Perform big-endian to little-endian byte order conversion for Frameindex.
	
		uint32_t MaxIndex;													 // Read the MaxIndex value and perform byte order conversion.
		memcpy(&MaxIndex, MeasAuxInfo_ALL.data() + index, sizeof(uint32_t)); // Read MaxIndex (4 bytes, uint32_t type) from the data.
		
		index += sizeof(uint32_t);                                                                                                                     // Update the index to point to the next data position.
		uint32_t MaxIndex_1 = ((MaxIndex & 0xFF) << 24) | ((MaxIndex & 0xFF00) << 8) | ((MaxIndex & 0xFF0000) >> 8) | ((MaxIndex & 0xFF000000) >> 24); // Perform big-endian to little-endian byte order conversion for MaxIndex.
		MeasAuxInfo[i].MaxIndex = MaxIndex_1;                                                                                                          // Store the converted MaxIndex into the MeasAuxInfo structure.

		union FloatConversion u;																							  // Define a union for converting between float and int byte representations.
		memcpy(&u.f, MeasAuxInfo_ALL.data() + index, sizeof(float));														  // Read MaxPower (4 bytes) from the data.
		index += sizeof(float);																								  // Update the index to point to the next data position.
		float MaxPower = ((u.i & 0xFF) << 24) | ((u.i & 0xFF00) << 8) | ((u.i & 0xFF0000) >> 8) | ((u.i & 0xFF000000) >> 24); // Convert the byte order of MaxPower from big-endian to little-endian.
		u.i = MaxPower;																										  // Assign the adjusted byte order back to the union.
		MeasAuxInfo[i].MaxPower_dBm = u.f;																					  // Store the converted MaxPower (in dBm) into the MeasAuxInfo structure.

		// Subsequent comments are the same as above.
		int16_t Temperature;
		memcpy(&Temperature, MeasAuxInfo_ALL.data() + index, sizeof(int16_t));
		index += sizeof(int16_t);
		int16_t Temperature_1 = ((Temperature & 0xff) << 8 | (Temperature & 0xff00) >> 8);
		MeasAuxInfo[i].Temperature = Temperature_1 * 0.01;

		uint16_t RFState;
		memcpy(&RFState, MeasAuxInfo_ALL.data() + index, sizeof(uint16_t));
		index += sizeof(uint16_t);
		uint16_t RFState_1 = ((RFState & 0xff) << 8 | (RFState & 0xff00) >> 8);
		MeasAuxInfo[i].RFState = RFState_1;

		uint16_t BBState;
		memcpy(&BBState, MeasAuxInfo_ALL.data() + index, sizeof(uint16_t)); 
		index += sizeof(uint16_t);
		uint16_t BBState_1 = ((BBState & 0xff) << 8 | (BBState & 0xff00) >> 8);
		MeasAuxInfo[i].BBState = BBState_1;

		uint16_t GainPattern;
		memcpy(&GainPattern, MeasAuxInfo_ALL.data() + index, sizeof(uint16_t));
		index += sizeof(uint16_t);
		uint16_t GainPattern_1 = ((GainPattern & 0xff) << 8 | (GainPattern & 0xff00) >> 8);
		MeasAuxInfo[i].GainPattern = GainPattern_1;

		uint32_t ConvertPattern;
		memcpy(&ConvertPattern, MeasAuxInfo_ALL.data() + index, sizeof(uint32_t));
		index += sizeof(uint32_t);
		uint32_t ConvertPattern_1 = ((ConvertPattern & 0xFF) << 24) | ((ConvertPattern & 0xFF00) << 8) | ((ConvertPattern & 0xFF0000) >> 8) | ((ConvertPattern & 0xFF000000) >> 24);
		MeasAuxInfo[i].ConvertPattern = ConvertPattern_1;

		union DoubleConversion q;
		memcpy(&q.d, MeasAuxInfo_ALL.data() + index, sizeof(double));
		index += sizeof(double);
		uint64_t SysTimeStamp = ((q.i & 0xFF) << 56) | ((q.i & 0xFF00) << 40) | ((q.i & 0xFF0000) << 24) | ((q.i & 0xFF000000) << 8) | ((q.i >> 8) & 0xFF000000) | ((q.i >> 24) & 0xFF0000) | ((q.i >> 40) & 0xFF00) | ((q.i >> 56) & 0xFF);
		q.i = SysTimeStamp;
		MeasAuxInfo[i].SysTimeStamp = q.d;

		union DoubleConversion A;
		memcpy(&A.d, MeasAuxInfo_ALL.data() + index, sizeof(double));
		index += sizeof(double);
		uint64_t AbsoluteTimeStamp = ((A.i & 0xFF) << 56) | ((A.i & 0xFF00) << 40) | ((A.i & 0xFF0000) << 24) | ((A.i & 0xFF000000) << 8) | ((A.i >> 8) & 0xFF000000) | ((A.i >> 24) & 0xFF0000) | ((A.i >> 40) & 0xFF00) | ((A.i >> 56) & 0xFF);
		A.i = AbsoluteTimeStamp;
		MeasAuxInfo[i].AbsoluteTimeStamp = A.d;

		union FloatConversion L;
		memcpy(&L.f, MeasAuxInfo_ALL.data() + index, sizeof(float));
		index += sizeof(float);
		float Latitude = ((L.i & 0xFF) << 24) | ((L.i & 0xFF00) << 8) | ((L.i & 0xFF0000) >> 8) | ((L.i & 0xFF000000) >> 24);
		L.i = Latitude;
		MeasAuxInfo[i].Latitude = L.f;

		union FloatConversion Lo;
		memcpy(&Lo.f, MeasAuxInfo_ALL.data() + index, sizeof(float));
		index += sizeof(float);
		float Longitude = ((Lo.i & 0xFF) << 24) | ((Lo.i & 0xFF00) << 8) | ((Lo.i & 0xFF0000) >> 8) | ((Lo.i & 0xFF000000) >> 24);
		Lo.i = Longitude;
		MeasAuxInfo[i].Longitude = Lo.f;
	}
	// Traverse the Freq_all array and assign each element to the Freq_Hz array.
	for (int i = 0; i < Freq_all.size(); i++)
	{
		Freq_Hz[i] = Freq_all[i];
		PowerSpec_dBm[i] = Power_all[i];
	}
	file.close(); // Close the file and release file resources.
	return 0;
}
int SWPMode_PlayBack()
{
	
	int Status = 0;														 // Define the function return value variable.
	const char* FilePath = "./data/004d_20250116_105012.part1.spectrum"; // Modify the recorded file name as needed, e.g., 0022_20241225_094515.part1.spectrum.
	SWP_Profile_TypeDef SWP_Profile;									 // Store the SWP_Profile_TypeDef structure.
	SWP_TraceInfo_TypeDef TraceInfo;									 // Store the SWP_TraceInfo_TypeDef structure.
	uint32_t TraceNumber = 0;											 // Define the number of traces.

	string FilePath_last = "./data/";		  // The file save path is ./data/.
	if (!(filesystem::exists(FilePath_last))) // Check if the directory exists, create it if it does not.
	{
		filesystem::create_directories(FilePath_last); // Attempt to create the directory and its parent directories.
		cout << "dataFolder address :Htra_RecordingandPlayBack\\data" << endl;
		if (filesystem::create_directories(FilePath_last)) {
			cout << "Failed to create a directory: \"" << FilePath_last << "\" " << endl;
			return 0;
		}
	}

	Status = SWP_RecordingConfigurationInfo(FilePath, &SWP_Profile, &TraceInfo, &TraceNumber); // Read the recording configuration, trace information, and number of traces from the specified file.
	if (Status != 0)																		   // If reading the configuration fails, output an error message and return.
	{
		cout << "There was a problem reading the file!" << endl;
		return 0;
	}

	vector<float>Power(TraceInfo.FullsweepTracePoints * TraceNumber);          // Store the amplitude values from the recorded file.
	vector<double>Freq(TraceInfo.FullsweepTracePoints * TraceNumber);          // Store the frequency values from the recorded file.
	vector<MeasAuxInfo_TypeDef>MeasAuxInfo(TraceInfo.TotalHops * TraceNumber); // Store the MeasAuxInfo structure information.

	Status = SWP_RecordingPowerSpectralDensityInfo(FilePath, Freq.data(), Power.data(), MeasAuxInfo.data()); // Call the function to read power spectral density data from the file.
	
	char FileName[255];                           // Define a file name character array.
	sprintf(FileName, "./data/SWPMode_Data.txt"); // Format the file name as "SWPMode_Data.txt".
	fstream File1;                                // Create an fstream object to operate the file.
	File1.open(FileName, ios::out);               // Open the file in write mode.
	
	for (int j = 0; j < TraceInfo.FullsweepTracePoints * TraceNumber; j++) // Write frequency and power data to the file, outputting one frequency and power value per line separated by a tab.
	{
		File1 << Freq[j] << "\t" << Power[j] << "\n";
	}
	
	File1.close(); // Close the file stream to save and release resources.

	return 0;
}