多通道波形文件存储

多通道波形文件存储


最近在做一个多通道信号数据采集的项目,遇到这样的问题“在一个文件中如何去存储多个通道的实时波形数据”,初步定义了如下方式:将“一定时间”内不同通道采样点数据集合划分为一个数据块,“一定时间”在文件头信息中有定义(即数据块持续时间),采样数据集合点数将在每个通道头中有定义,以上两要素可以直接被采样率所影响。如此便可在一个文件中存储不同采样率多通道的波形数据,也可以保证不同通道间的数据在时间序列上的同步。

文件结构

多通道波形文件存储_第1张图片

文件头和通道头定义

struct  File_Head_Info    {
    char    szTotal_Head_Size[8];           /// 文件头总字节数(文件头+通道头)
    char    szReserved_Data[44];            /// 保留的字节数
    char    szTotal_Data_Block[8];          /// 数据块总数
    char    szData_Block_Duration[8];       /// 以秒为单位的一个数据块持续时间
    char    szSignal_Number [4];            /// 数据块中的通道数
};
struct  Channel_Info    {
        char    szSamples_In_A_Record[8];       /// 一个数据记录块中的采样数据数
        char    szMaintain[32];                 /// 保留值,共32字节,必须填为0
};

文件读取伪代码

short *Format::ReadChannelData(int channel, int &smpcount, int&samplerate)
{
    smpcount = 0;
    //通道数超过了存储的通道数
    if(channel >= m__Head.lSignal_Number)
    {
        smpcount = 0;
        samplerate = 0;
        return NULL;
    }

    ///1.------------------  获取要使用到的基本信息. ----------------------------
    int     iSignal_Num     = (int)m__Head.lSignal_Number;      /// 信号数
    int     iTotal_Block    = (int)m__Head.lTotal_Data_Block;   /// 总的数据块数
    int     iHead_Size      = (int)m__Head.lTotal_Head_Size;        /// 文件头大小(基本信息头+通道信息头)  

    ///1.1 ----------------  计算1个数据块内所有通道的采样点总字节数. ------------
    long    lData_In_A_Record   = 0;
    for( int i=0; isizeof( short );
    }

    samplerate = m_Cha_Info[channel].fSample_Rate;

    ////开始解析数据的位置
    char*   pStart          = m_DataSource + iHead_Size;

    ////分配一个通道的内存
    long lTotleLen = m_Cha_Info[channel].lSamples_In_A_Record * iTotal_Block;
    short* relBuff = new short[lTotleLen];

    ////读取所有的块数据
    for ( int i=0; ifor( int j=0; j///2.1 --------  通道数相同,提取数据. -----------------------------
            if( channel == j )
            {
               int size     = (m_Cha_Info[j].lSamples_In_A_Record) * sizeof(short);
                memcpy( (char*)( relBuff + smpcount), pStart, size );
                smpcount    += m_Cha_Info[j].lSamples_In_A_Record;
                pStart      += size;
            }
            ///2.2 --------  通道数不同跳过数据. -----------------------------
            else
            {
                pStart += m_Cha_Info[j].lSamples_In_A_Record * sizeof( short );
            }
        }
    }
    return relBuff;
}

数据写入伪代码

int FormatPlat::Write2File(int chanle, short *data, int sampleCount)
{
    //判断通道个数
    if(chanle >= m__Head.lSignal_Number || sampleCount <= 0 )
    {
        return 0;
    }

    int     iSignal_Num     = (int)m__Head.lSignal_Number;      /// 信号数
    int     iTotal_Block    = (int)m__Head.lTotal_Data_Block;   /// 总的数据块数
    int     iHead_Size      = (int)m__Head.lTotal_Head_Size;        /// 文件头大小(基本信息头+通道信息头)

    ///1.1 ----------------  计算1个数据块内所有通道的采样点总字节数. ------------
    long    lData_In_A_Record   = 0;
    for( int i=0; isizeof( short );
    }

    //定位当前块
   long long lCurBlock =  m_iSeqSumNum[chanle] / m_Cha_Info[chanle].lSamples_In_A_Record;
   //在当前block的偏移位置
   long long lseek = m_iSeqSumNum[chanle] % m_Cha_Info[chanle].lSamples_In_A_Record;
   //数据块内剩余的点数
    long surplus = m_Cha_Info[chanle].lSamples_In_A_Record - lseek;

   //偏移到对应的通道的起始位置
   char*    pStart          = m_DataSource + iHead_Size;
   pStart += lCurBlock * lData_In_A_Record;
   for( int i=0; isizeof( short );
   }
   pStart +=  lseek * sizeof(short);


   //剩余未写入的数据
   long lSurCount = sampleCount;
   while(lSurCount > 0)
   {
       //当块内部小于剩余数据的长度
        if(surplus < lSurCount)
        {
             memcpy(pStart , data, sizeof(short) * surplus);
             data += surplus;

             //移动到下一数据块的起始位置
             pStart += lData_In_A_Record - (m_Cha_Info[chanle].lSamples_In_A_Record -surplus) * sizeof(short);
             lSurCount -= surplus;
             surplus = m_Cha_Info[chanle].lSamples_In_A_Record;
        }
        else
        {
            memcpy(pStart, data, lSurCount * sizeof(short));
            lSurCount = 0;
        }
   }

   m_iSeqSumNum[chanle] += sampleCount;
}

你可能感兴趣的:(技术知识库)