%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Script      : bin2MatData.m
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Description  : This function converts Raw ADC data in bin format to a usable N-D 
%                Matlab variable, stores it format of .mat along with its descriptor.
%
% Inputs       : fileName        -> Takes name as string in .bin format ("Example 'adc_sample_data.bin'")
%                numSamples      -> Non-zero Positive integer
%                numRx           -> Non-zero Positive integer
%                numUniqueChirps -> Non-zero Positive integer
%                numChirpLoops   -> Non-zero Positive integer
%                numFrames       -> Non-zero Positive integer
%                dataInterleave  -> 1 : Interleaved ; 0 : Non-Interleaved
%                complexSampling -> 1 : Complex ; 0 : Real
%                IQSwap          -> 1 : Q-first ; 0 : Q-first
%                frameSelect     -> 0 : Disable ; Non-zero Positive integer : Enable
%
% Outputs      : Creates a .mat file as well with the returned values
%                adcData -> N-D Matlab array
%                dataDesc-> Data descriptor object
%
% Usage        : [adcData, dataDesc] = bin2MatData("adc_sample_data.bin", 1024, 4, 4, ...
%                                                  128, 8, 0, 1, 0, 1);
%
% Author       : Kaushik Gowda
%
% Date         : 24/10/2023
%
% Version      : v1.0 (supported on MATLAB ver R2022b).
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [adcData, dataDesc] = bin2MatData(fileName, numSamples, numRx, numUniqueChirps, ...
                                           numChirpLoops, numFrames, dataInterleave, ...
                                           complexSampling, IQSwap, frameSelect)

    % Read the data from the capture bin file
    read_size = numSamples * numRx*numUniqueChirps*numChirpLoops*2;
    fp = fopen(fileName,"r");
    adcData = fread(fp, read_size, 'int16');
    fclose(fp);
    
    % Check whether the data is real or complex
    if(complexSampling == 1)
        adcData = reshape(adcData, [2 length(adcData)/2]);
        if(IQSwap == 0)
            % Real first
            adcData = adcData(1,:) + 1i*(adcData(2,:));
        else
            % Imag first
            adcData = adcData(2,:) + 1i*(adcData(1,:));
        end
        adcData = squeeze(adcData);
    end

    % Check if the Rx channel data is interleaved or not
    if dataInterleave==0
        adcData = reshape(adcData, [numSamples numRx numUniqueChirps numChirpLoops numFrames]);
    else
        adcData = reshape(adcData, [numRx numSamples numUniqueChirps numChirpLoops numFrames]);
    end
    
    % Consider only the required frame
    if(frameSelect~=0)
        adcData = squeeze(adcData(:,:,:,:,frameSelect));
    end

    % Create a descriptor for future reference
    dataDesc.fileName        = fileName;
    dataDesc.numSamples      = numSamples;
    dataDesc.numRx           = numRx;
    dataDesc.fileName        = fileName;
    dataDesc.numUniqueChirps = numUniqueChirps;
    dataDesc.numChirpLoops   = numChirpLoops;
    dataDesc.numFrames       = numFrames;
    dataDesc.dataInterleave  = dataInterleave;
    dataDesc.complexSampling = complexSampling;
    dataDesc.IQSwap          = IQSwap;
    dataDesc.frameSelect     = frameSelect;

    fileName = extractBetween(fileName, 1, ".bin");   % Strip ".bin" extension
    outFileName = strcat(fileName,".mat");            % Append ".mat" extension
    save(outFileName, "adcData", "dataDesc");         % Copy the data into .mat files

end