Copyright (C) Kevin Larke 2009-2020

This file is part of libcm.

libcm is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

libcm is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

See the GNU General Public License distributed with the libcm package or look here: .


cmFrameFile : File reader and writer for time series data as used by cmFeatFile
//
// file  -&gt cmFfFile_t frame*
// frame -&gt cmFfFrame_t mtx*
// mtx   -&gt cmFfMtx_t data*   
//


enum
{
  kInvalidFrameTId  = 0,
  kInvalidStreamId  = 0,
  
  kTocFrameTId = -3,
  kTocStreamId = -3,
  
  kFileFfTId = 'FrmF',
  
};

enum
{
  kOkFfRC = 0,           // 0
  kFileOpenFailFfRC,     // 1
  kFileReadFailFfRC,     // 2 
  kFileWriteFailFfRC,    // 3
  kFileSeekFailFfRC,     // 4
  kFileCloseFailFfRC,    // 5
  kEofFfRC,              // 6
  kInvalidHandleFfRC,    // 7
  kMemAllocErrFfRC,      // 8
  kNotFrameFileFfRC,     // 9
  kUnknownErrFfRC,       // 10
  kNoMatchingFrameFfRC,  // 11
  kInvalidFileModeFfRC,  // 12
  kJsonFailFfRC,         // 13
  kInvalidFrameIdxFfRC,  // 14
  kDuplicateMtxIdFfRC,   // 15 
  kFileTellFailFfRC,     // 16
  kLHeapFailFfRC,        // 17
  kTocFrameRdFailFfRC,   // 18
  kTocRecdNotFoundFfRC,  // 19
  kBufTooSmallFfRC       // 20
};

// row data formats
enum
{
  kInvalidFmtId,  // 0
  kUCharFmtId,    // 1
  kCharFmtId,     // 2
  kUShortFmtId,   // 3 
  kShortFmtId,    // 4
  kULongFmtId,    // 5
  kLongFmtId,     // 6
  kUIntFmtId,     // 7
  kIntFmtId,      // 8
  kLLongFmtId,    // 9
  kULLongFmtId,   // 10
  kOff_tFmtId,    // 11
  kFloatFmtId,    // 12
  kDoubleFmtId,   // 13 
  kStringZFmtId,  // 14 
  kBlobFmtId,     // 15
  kJsonFmtId      // 16
};

enum
{
  kInvalidUId ,   // 0
  kNoUnitsUId,    // 1
  kHzUId,         // 2 
  kRadsUId,       // 3 -pi to pi 
  kAmplUId,       // 4 -1.0 to 1.0
  kPowUId,        // 5 amp^2/2
  k10DbUId,       // 6 10*log10(v)
  k20DbUId,       // 7 20*log10(v) 
  kCntUId,        // 8 count of elements
  kIdxUId,        // 9 element index 
  kBfccUId,       // 10
  kMfccUId,       // 11
  kCepsUId,        // 12
  
  kD1UFl  = 0x80000000  // this is a 1st difference 
};

enum
{
  kTocMId = -2,
  
  
  kInvalidMId = 0, // 0
  kAudioMId,       // 1 
  kMagMId,         // 2
  kPhsMId,         // 3
  kFrqMId,         // 4 measured bin frequecies in Hz
  kTrkMId,         // 5
  kRmsMId,         // 6
  kBinCntMId,      // 7 count of frequency domain bins in frame
  kWndSmpCntMId,   // 8 actual count of samples in FFT window (this is no (binCnt-1)*2)
  kAudSmpCntMId,   // 9 count of audio samples in frame
  kBfccMId,        // 10 vector of BFCC's
  kBfccBandCntMId, // 11 count of coeff's BFCC vector in this frame
  kMfccMId,        // 12 vector of MFCC's 
  kCepsMId,        // 13 vector of cepstral coefficients
  kConstqMId,      // 14 vector of constant
  kDataMId         // 15 blob of misc data
  
};

typedef cmHandle_t cmFrameFileH_t;
typedef unsigned   cmFfRC_t;

// mtx desc record
typedef struct
{
  unsigned type;
  unsigned fmtId;
  unsigned unitsId;
  unsigned rowCnt;
  unsigned colCnt;
} cmFfMtx_t;

// frame desc record
typedef struct
{
  unsigned type;
  unsigned mtxCnt;
  unsigned flags;      // used internally to track time format (seconds or samples)
  unsigned streamId;
  
  union
  {
    unsigned sampleIdx;
    double   seconds;
  } tm;
  
} cmFfFrame_t;


// file desc record
typedef struct
{
  cmChar_t*   filenameStr;
  unsigned    version;
  unsigned    frameCnt;       // count of frames in all streams
  double      srate;          // sample rate for all frames
} cmFfFile_t;

extern cmFrameFileH_t cmFrameFileNullHandle;

cmFfRC_t           cmFrameFileCreate(  cmFrameFileH_t* hPtr, const char* fn, double srate, cmCtx_t* ctx );

// The fileDescPtrPtr is optional. Set to NULL to ignore.
cmFfRC_t           cmFrameFileOpen(    cmFrameFileH_t* hPtr, const char* fn, cmCtx_t* ctx, const cmFfFile_t** fileDescPtrPtr );
cmFfRC_t           cmFrameFileClose(   cmFrameFileH_t* hPtr );
bool               cmFrameFileIsValid( cmFrameFileH_t h );
const cmFfFile_t*  cmFrameFileDesc(    cmFrameFileH_t h );

// Return the count of frames in the requested stream.
unsigned           cmFrameFileFrameCount( cmFrameFileH_t h, unsigned streamId );

// Create a frame in a file created via cmFrameFileCreate().
// Set 'sampleIdx' to -1 if seconds is being used instead of samples. 
cmFfRC_t cmFrameFileFrameCreate( cmFrameFileH_t h, unsigned frameType, unsigned streamId, unsigned sampleIdx, double secs  );

// (W) Complete and write a frame created via an earilier call
// to cmFrameFileFrameCreate()
cmFfRC_t cmFrameFileFrameClose(  cmFrameFileH_t h );

// (W) Fill a frame with matrix data. The frame must have been created
// via an earlier call to cmFrameFileCreate().
cmFfRC_t cmFrameFileWriteMtxUChar(   cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const unsigned char*            p, unsigned rn, unsigned cn );
cmFfRC_t cmFrameFileWriteMtxChar(    cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const char*                     p, unsigned rn, unsigned cn );
cmFfRC_t cmFrameFileWriteMtxUShort(  cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const unsigned short*           p, unsigned rn, unsigned cn );
cmFfRC_t cmFrameFileWriteMtxShort(   cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const short*                    p, unsigned rn, unsigned cn );
cmFfRC_t cmFrameFileWriteMtxULong(   cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const unsigned long*            p, unsigned rn, unsigned cn );
cmFfRC_t cmFrameFileWriteMtxLong(    cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const long*                     p, unsigned rn, unsigned cn );
cmFfRC_t cmFrameFileWriteMtxUInt(    cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const unsigned*                 p, unsigned rn, unsigned cn );
cmFfRC_t cmFrameFileWriteMtxInt(     cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const int*                      p, unsigned rn, unsigned cn );
cmFfRC_t cmFrameFileWriteMtxULLong(  cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const unsigned long long*       p, unsigned rn, unsigned cn );
cmFfRC_t cmFrameFileWriteMtxLLong(   cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const long long*                p, unsigned rn, unsigned cn );
cmFfRC_t cmFrameFileWriteMtxOff_t(   cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const off_t*                    p, unsigned rn, unsigned cn );
cmFfRC_t cmFrameFileWriteMtxFloat(   cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const float*                    p, unsigned rn, unsigned cn );
cmFfRC_t cmFrameFileWriteMtxDouble(  cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const double*                   p, unsigned rn, unsigned cn );
cmFfRC_t cmFrameFileWriteMtxBlob(    cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const void*                     p, unsigned rn, unsigned cn );  
cmFfRC_t cmFrameFileWriteMtxStringZ( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const char* p );
cmFfRC_t cmFrameFileWriteMtxJson(    cmFrameFileH_t h, unsigned mtxType, cmJsonH_t jsH, const cmJsonNode_t* nodePtr );

// (R/W) Rewind to the first frame. Must call cmFrameFileFrameNext() 
// following successful execution of this function to maintain correct
// alignment.
cmFfRC_t          cmFrameFileRewind( cmFrameFileH_t h );

// (R/W) Seek to the frame at index 'frameIdx'.  Must call cmFrameFileFrameNext() 
// following successful execution of this function to maintain correct
// alignment.
cmFfRC_t          cmFrameFileSeek( cmFrameFileH_t h, unsigned streamId, unsigned frameIdx );

// (R/W) Seek to the next frame in stream frameStreamId with type frameTypeId.
// Set frameTypeId to kInvalidFrameTId to return any frame type.
// Set frameStreamId to kInvalidStreamId to return any stream type.
// This function must be followed by a call to cmFrameFileFrameLoad()
// or cmFrameFileSkip().
cmFfRC_t           cmFrameFileFrameNext(     cmFrameFileH_t h, unsigned frameTypeId, unsigned streamId );

// (R/W) Load the matrix data associated with the current frame. 
// This function can only be called after a successful call to 
// cmFrameFileFrameNext(). 
// The frameDescPtrPtr is optional. Set to NULL to ignore.
cmFfRC_t           cmFrameFileFrameLoad(     cmFrameFileH_t h, const cmFfFrame_t** frameDescPtrPtr );

// (R/W) Skip over the matrix data associated with the current frame. 
// This is an alternative to cmFrameFileLoad().
cmFfRC_t           cmFrameFileFrameSkip(     cmFrameFileH_t h ); 

// (R/W) Combines cmFrameFileFrameNext() and cmFrameFileFrameLoad()
// into a single call.
cmFfRC_t           cmFrameFileFrameLoadNext( cmFrameFileH_t h, unsigned frameTypeId, unsigned streamId, const cmFfFrame_t** frameDescPtrPtr );

// (R/W) Write the current frame back to disk. 
cmFfRC_t           cmFrameFileFrameUpdate( cmFrameFileH_t h );

// Return the current frame description record.
const cmFfFrame_t* cmFrameFileFrameDesc( cmFrameFileH_t h );

// Currently loaded frame index.
unsigned           cmFrameFileFrameLoadedIndex( cmFrameFileH_t h );

// Return the index of the frame with type 'mtxTypeId', units 'unitsId', and format 'fmtId'
// or cmInvalidIdx if the specified frame is not found.
// Set mtxTypeId to kInvalidMId to return any mtx type.
// Set unitsId to kInvalidUId to return a mtx with any units.
// Set fmtId to kInvalidFmtId to return a mtx with any fmt.
unsigned           cmFrameFileMtxIndex(      cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId, unsigned fmtId );

// Return a matrix description record.
const cmFfMtx_t*   cmFrameFileMtxDesc(       cmFrameFileH_t h, unsigned mtxIdx );

// Access matrix data.
//Set descPtr to NULL if the matrix desc is not needed.
unsigned char*      cmFrameFileMtxIndexUChar(   cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr );
char*               cmFrameFileMtxIndexChar(    cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr );
unsigned short*     cmFrameFileMtxIndexUShort(  cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr );
short*              cmFrameFileMtxIndexShort(   cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr );
unsigned long*      cmFrameFileMtxIndexULong(   cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr );
long*               cmFrameFileMtxIndexLong(    cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr );
unsigned*           cmFrameFileMtxIndexUInt(    cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr );
int*                cmFrameFileMtxIndexInt(     cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr );
unsigned long long* cmFrameFileMtxIndexULLong(  cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr );
long long*          cmFrameFileMtxIndexLLong(   cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr );
off_t*              cmFrameFileMtxIndexOff_t(   cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr );
float*              cmFrameFileMtxIndexFloat(   cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr );
double*             cmFrameFileMtxIndexDouble(  cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr );
char*               cmFrameFileMtxIndexStringZ( cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr );
void*               cmFrameFileMtxIndexBlob(    cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr );
// (The caller is responsible for invoking cmJsonFinalize() to finalize the returned json handle.)
cmJsonH_t           cmFrameFileMtxIndexJson(    cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr );

// Return a pointer to the data, and optionally the descPtr, for a matrix with the given 
// type,units and format in the current frame.
// The following functions are implmented in terms of
// cmFrameFileMtxIndexXXX() and cmFrameFileMtxIndex().
unsigned char*      cmFrameFileMtxUChar(   cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId,  const cmFfMtx_t** descPtrPtr );
char*               cmFrameFileMtxChar(    cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId,  const cmFfMtx_t** descPtrPtr );
unsigned short*     cmFrameFileMtxUShort(  cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId,  const cmFfMtx_t** descPtrPtr );
short*              cmFrameFileMtxShort(   cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId,  const cmFfMtx_t** descPtrPtr );
unsigned long*      cmFrameFileMtxULong(   cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId,  const cmFfMtx_t** descPtrPtr );
long*               cmFrameFileMtxLong(    cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId,  const cmFfMtx_t** descPtrPtr );
unsigned*           cmFrameFileMtxUInt(    cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId,  const cmFfMtx_t** descPtrPtr );
int*                cmFrameFileMtxInt(     cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId,  const cmFfMtx_t** descPtrPtr );
unsigned long long* cmFrameFileMtxULLong(  cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId,  const cmFfMtx_t** descPtrPtr );
long long*          cmFrameFileMtxLLong(   cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId,  const cmFfMtx_t** descPtrPtr );
off_t*              cmFrameFileMtxOff_t(   cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId,  const cmFfMtx_t** descPtrPtr );
float*              cmFrameFileMtxFloat(   cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId,  const cmFfMtx_t** descPtrPtr );
double*             cmFrameFileMtxDouble(  cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId,  const cmFfMtx_t** descPtrPtr );
char*               cmFrameFileMtxStringZ( cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId,  const cmFfMtx_t** descPtrPtr );
void*               cmFrameFileMtxBlob(    cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId,  const cmFfMtx_t** descPtrPtr );
// (The caller is responsible for invoking cmJsonFinalize() to finalize the returned json handle.)
cmJsonH_t           cmFrameFileMtxJson(    cmFrameFileH_t h, unsigned mtxTypeId,                                   const cmFfMtx_t** descPtrPtr );


// Return the max row cnt, max col count, and total element count
// for all matrices which match the given stream/mtx/units/fmt
// combination.  Note that if the returned ele count is less than
// maxRowCnt * maxColCnt * cmFrameFileFrameCount(streamId) then
// some matched matrices contain fewer than maxRowCnt/maxColCnt
// rows/columns.
cmFfRC_t cmFrameFileMtxSize( cmFrameFileH_t h, unsigned streamId, unsigned mtxType, unsigned unitsId, unsigned fmtId, unsigned* frameCntPtr, unsigned* rowCntPtr, unsigned* colCntPtr, unsigned* eleCntPtr );

// Load a buffer with all of the data which matches a given 
// stream/mtx/unit/fmt combination in the given range of frames.
// 'frmIdx' specifies the frame index relative to the given stream id as opposed to 
// and absolute frame index.
// Set frmCnt to -1 to include all frames following 'frmIdx'.
// *outCntPtr is set to the actual number of elements copied into the buffer
// The data is packed into the return buffer by copying columwise from the source.
// matrices to the buf[].  If all of the matrices are not of a fixed known size
// it may therefore be difficult to distinguish where one frames data ends and
// the next begins.
cmFfRC_t cmFrameFileMtxLoadUChar(   cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt,  unsigned char*      buf, unsigned eleCnt, unsigned* outCntPtr );
cmFfRC_t cmFrameFileMtxLoadChar(    cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt,  char*               buf, unsigned eleCnt, unsigned* outCntPtr );
cmFfRC_t cmFrameFileMtxLoadUShort(  cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt,  unsigned short*     buf, unsigned eleCnt, unsigned* outCntPtr );
cmFfRC_t cmFrameFileMtxLoadShort(   cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt,  short*              buf, unsigned eleCnt, unsigned* outCntPtr );
cmFfRC_t cmFrameFileMtxLoadULong(   cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt,  unsigned long*      buf, unsigned eleCnt, unsigned* outCntPtr );
cmFfRC_t cmFrameFileMtxLoadLong(    cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt,  long*               buf, unsigned eleCnt, unsigned* outCntPtr );
cmFfRC_t cmFrameFileMtxLoadUInt(    cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt,  unsigned int*       buf, unsigned eleCnt, unsigned* outCntPtr );
cmFfRC_t cmFrameFileMtxLoadInt(     cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt,  int*                buf, unsigned eleCnt, unsigned* outCntPtr );
cmFfRC_t cmFrameFileMtxLoadULLong(  cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt,  unsigned long long* buf, unsigned eleCnt, unsigned* outCntPtr );
cmFfRC_t cmFrameFileMtxLoadLLong(   cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt,  long long*          buf, unsigned eleCnt, unsigned* outCntPtr );
cmFfRC_t cmFrameFileMtxLoadOff_t(   cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt,  off_t*              buf, unsigned eleCnt, unsigned* outCntPtr );
cmFfRC_t cmFrameFileMtxLoadFloat(   cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt,  float*              buf, unsigned eleCnt, unsigned* outCntPtr );
cmFfRC_t cmFrameFileMtxLoadDouble(  cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt,  double*             buf, unsigned eleCnt, unsigned* outCntPtr );
cmFfRC_t cmFrameFileMtxLoadStringZ( cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt,  char*               buf, unsigned eleCnt, unsigned* outCntPtr );
cmFfRC_t cmFrameFileMtxLoadBlob(    cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt,  void*               buf, unsigned eleCnt, unsigned* outCntPtr );

cmFfRC_t cmFrameFileReport( cmFrameFileH_t h, bool summOnlyFl, cmRpt_t* rpt );
cmFfRC_t cmFrameFileNameReport( const char* fn, bool summOnlyFl, cmCtx_t* ctx );

cmFfRC_t cmFrameFileTest( const char* fn, cmCtx_t* ctx );

#if CM_FLOAT_SMP == 1
#define cmFrameFileMtxLoadSample  cmFrameFileMtxLoadFloat
#define cmFrameFileWriteMtxSample cmFrameFileWriteMtxFloat
#define cmFrameFileMtxIndexSample cmFrameFileMtxIndexFloat
#define cmFrameFileMtxSample      cmFrameFileMtxFloat
#define kSampleFmtId              kFloatFmtId
#else
#define cmFrameFileMtxLoadSample  cmFrameFileMtxLoadDouble
#define cmFrameFileWriteMtxSample cmFrameFileWriteMtxDouble
#define cmFrameFileMtxIndexSample cmFrameFileMtxIndexDouble
#define cmFrameFileMtxSample      cmFrameFileMtxDouble
#define kSampleFmtId              kDoubleFmtId
#endif

#if CM_FLOAT_REAL == 1
#define cmFrameFileMtxLoadReal  cmFrameFileMtxLoadFloat
#define cmFrameFileWriteMtxReal cmFrameFileWriteMtxFloat
#define cmFrameFileMtxIndexReal cmFrameFileMtxIndexFloat
#define cmFrameFileMtxReal      cmFrameFileMtxFloat
#define kRealFmtId              kFloatFmtId
#else
#define cmFrameFileMtxLoadReal  cmFrameFileMtxLoadDouble
#define cmFrameFileWriteMtxReal cmFrameFileWriteMtxDouble
#define cmFrameFileMtxIndexReal cmFrameFileMtxIndexDouble
#define cmFrameFileMtxReal      cmFrameFileMtxDouble
#define kRealFmtId              kDoubleFmtId
#endif