libcm is a C development framework with an emphasis on audio signal processing applications.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

cmFrameFile.c 65KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212
  1. //| Copyright: (C) 2009-2020 Kevin Larke <contact AT larke DOT org>
  2. //| License: GNU GPL version 3.0 or above. See the accompanying LICENSE file.
  3. #include "cmPrefix.h"
  4. #include "cmGlobal.h"
  5. #include "cmFloatTypes.h"
  6. #include "cmRpt.h"
  7. #include "cmErr.h"
  8. #include "cmCtx.h"
  9. #include "cmMem.h"
  10. #include "cmMallocDebug.h"
  11. #include "cmJson.h"
  12. #include "cmFrameFile.h"
  13. #include "cmLinkedHeap.h"
  14. #include "cmMath.h"
  15. #include "cmVectOps.h"
  16. /*
  17. File Type: 4 0
  18. Chunk Bytes: 4 4
  19. Frame Count: 4 8
  20. Version: 4 16
  21. EOF Frm Offs:8 20
  22. Sample Rate: 8 28 32
  23. Frame Type: 4 36 // Note: Update cmFrameFileFrameSkip()
  24. Chunk Bytes: 4 40 // if the size of this header changes.
  25. Mtx Count: 4 44
  26. Stream Id: 4 48
  27. Flags: 4 52
  28. Sample Idx 4 56
  29. Seconds: 8 60 32
  30. Mtx Type: 4 68
  31. Data Bytes: 4 72
  32. Format Id: 4 76
  33. Units Id: 4 80
  34. Row Cnt: 4 86
  35. Col Cnt: 4 90 24
  36. */
  37. #define _cmFfSwap16(fl,v) ((fl) ? cmSwap16(v) : (v))
  38. #define _cmFfSwap32(fl,v) ((fl) ? cmSwap32(v) : (v))
  39. #define _cmFfSwap64(fl,v) ((fl) ? cmSwap64(v) : (v))
  40. #define _cmFfWrSwapF(fl,v) ((fl) ? cmFfSwapFloatToUInt(v) : (*((unsigned*)&(v))))
  41. #define _cmFfRdSwapF(fl,v) ((fl) ? cmFfSwapUIntToFloat(v) : (*((float*)&(v))))
  42. #define _cmFfWrSwapD(fl,v) ((fl) ? cmFfSwapDoubleToULLong(v) : (*((unsigned long long*)&(v))))
  43. #define _cmFfRdSwapD(fl,v) ((fl) ? cmFfSwapULLongToDouble(v) : (*((double*)&(v))))
  44. enum
  45. {
  46. kSampleIdxTimeFl = 0x01,
  47. kSecondsTimeFl = 0x02
  48. };
  49. typedef struct _cmFfOffs_str
  50. {
  51. unsigned frmIdx; // absolute frame index for this mtx
  52. off_t offs; // file offset for mtx header
  53. struct _cmFfOffs_str* linkPtr;
  54. } _cmFfOffs_t;
  55. typedef struct
  56. {
  57. _cmFfOffs_t* beg;
  58. _cmFfOffs_t* end;
  59. unsigned cnt;
  60. } _cmFfOffsList_t;
  61. typedef struct _cmFfToC_str
  62. {
  63. unsigned streamId; //
  64. unsigned mtxType; // kInvalidMId when used with frmToC
  65. unsigned mtxUnitsId; // kInvalidUId when used with frmToC
  66. unsigned mtxFmtId; // kInvalidFmtId when used with frmToC
  67. _cmFfOffsList_t offsList; //
  68. unsigned lastFrmIdx; // used to prevent duplicate records during ToC creation
  69. struct _cmFfToC_str* linkPtr;
  70. } _cmFfToC_t;
  71. // private matrix desc record
  72. typedef struct
  73. {
  74. cmFfMtx_t m; // public mtx description record
  75. unsigned byteCnt; // bytes in this->dataPtr block
  76. void* dataPtr; // pointer to data for this mtx
  77. } _cmFfMtx_t;
  78. // private frame desc record
  79. typedef struct
  80. {
  81. cmFfFrame_t f; // public frame description record
  82. unsigned byteCnt; // byte count of frame file chunk
  83. _cmFfMtx_t* mtxArray; // mtx ctl record array
  84. char* dataPtr; // all memory used by all mtx's in this frame
  85. } _cmFfFrame_t;
  86. typedef struct
  87. {
  88. cmErr_t err;
  89. cmCtx_t ctx;
  90. FILE* fp; //
  91. bool writeFl; // file is open for writing
  92. unsigned fileChkByteCnt; //
  93. unsigned nxtFrmIdx; // index of the next frame after the current frame
  94. unsigned curFrmIdx; // write: not used read:index of currently loaded frame
  95. off_t frameOffset; // read: offset to first mtx hdr in cur frame
  96. // write:offset to cur frame hdr
  97. off_t rewOffset; // rewind offset (first frame)
  98. off_t eofOffset; // last frame (offset data frame)
  99. cmFfFile_t f; // file header
  100. _cmFfFrame_t frame; // cur frame
  101. cmLHeapH_t lhH; // linked heap handle
  102. _cmFfToC_t* mtxToC; // one ToC recd for each existing matrix stream/type/units/fmt combination
  103. _cmFfToC_t* frmToC; // one ToC recd for each stream
  104. void* writeMtxMem;
  105. bool swapFl;
  106. } cmFf_t;
  107. typedef struct
  108. {
  109. unsigned fmtId;
  110. unsigned wordByteCnt;
  111. const char* label;
  112. } _cmFfFmt_t;
  113. _cmFfFmt_t _cmFfFmtArray[] =
  114. {
  115. { kUCharFmtId, 1, "char" },
  116. { kCharFmtId, 1, "uchar" },
  117. { kUShortFmtId, 2, "ushort" },
  118. { kShortFmtId, 2, "short" },
  119. { kULongFmtId, 4, "ulong" },
  120. { kLongFmtId, 4, "long" },
  121. { kUIntFmtId, 4, "uint" },
  122. { kIntFmtId, 4, "int" },
  123. { kLLongFmtId, 8, "llong" },
  124. { kULLongFmtId, 8, "ullong" },
  125. { kOff_tFmtId, sizeof(off_t), "off_t"},
  126. { kFloatFmtId, 4, "float" },
  127. { kDoubleFmtId, 8, "double" },
  128. { kStringZFmtId, 1, "string" },
  129. { kBlobFmtId, 1, "blob" },
  130. { kJsonFmtId, 1, "json" },
  131. { kInvalidFmtId, 0, "<invalid>" }
  132. };
  133. cmFrameFileH_t cmFrameFileNullHandle = { NULL };
  134. /*
  135. void _cmFfPrint( cmFf_t* p, const char* fmt, ... )
  136. {
  137. va_list vl;
  138. va_start(vl,fmt);
  139. if( p == NULL || p->vPrintFunc == NULL )
  140. vfprintf(stderr,fmt,vl);
  141. else
  142. p->vPrintFunc(p->rptDataPtr,fmt,vl);
  143. va_end(vl);
  144. }
  145. cmFfRC_t _cmFfVError( cmFf_t* p, cmFfRC_t rc, int sysErrCode, const char* fmt, va_list vl )
  146. {
  147. int bufCharCnt = 256;
  148. char buf0[bufCharCnt+1];
  149. char buf1[bufCharCnt+1];
  150. char buf2[bufCharCnt+1];
  151. snprintf(buf0,bufCharCnt,"cmFrameFile Error: (%i): ",rc );
  152. vsnprintf(buf1,bufCharCnt,fmt,vl);
  153. snprintf(buf2,bufCharCnt,"System Error: ");
  154. unsigned sn = strlen(buf0) + strlen(buf1);
  155. sn += sysErrCode == 0 ? 0 : strlen(buf2) + strlen(strerror(sysErrCode));
  156. char buf3[sn+1];
  157. buf3[sn] = 0;
  158. buf3[0] = 0;
  159. strncpy(buf3, buf0, sn-strlen(buf3) );
  160. strncat(buf3, buf1, sn-strlen(buf3) );
  161. if( sysErrCode )
  162. {
  163. strncat(buf3,buf2, sn - strlen(buf3) );
  164. strncat(buf3,strerror(sysErrCode), sn - strlen(buf3) );
  165. }
  166. assert(strlen(buf3)==sn);
  167. _cmFfPrint(p,"%s\n",buf3);
  168. return rc;
  169. }
  170. */
  171. cmFfRC_t _cmFfVError( cmFf_t* p, cmFfRC_t rc, int sysErrCode, const char* fmt, va_list vl )
  172. {
  173. if( p != NULL )
  174. return cmErrVSysMsg(&p->err,rc,sysErrCode,fmt,vl);
  175. printf("cmFrameFile Error: rc=%i ",rc);
  176. vprintf(fmt,vl);
  177. printf("\n");
  178. if( sysErrCode )
  179. printf("cmFrameFile System Error code=%i %s\n\n",sysErrCode,strerror(sysErrCode));
  180. return rc;
  181. }
  182. cmFfRC_t _cmFfError( cmFf_t* p, cmFfRC_t rc, int sysErrCode, const char* fmt, ... )
  183. {
  184. va_list vl;
  185. va_start(vl,fmt);
  186. _cmFfVError( p, rc, sysErrCode, fmt, vl );
  187. va_end(vl);
  188. return rc;
  189. }
  190. cmFf_t* _cmFfHandleToPtr( cmFrameFileH_t h )
  191. {
  192. cmFf_t* p = (cmFf_t*)h.h;
  193. if( p == NULL )
  194. _cmFfError(NULL,kInvalidHandleFfRC,0,"Null handle.");
  195. assert( p != NULL);
  196. return p;
  197. }
  198. _cmFfFmt_t* _cmFfIdToFmtPtr( unsigned fmtId )
  199. {
  200. unsigned i;
  201. for(i=0; _cmFfFmtArray[i].fmtId != kInvalidFmtId; ++i)
  202. if( _cmFfFmtArray[i].fmtId == fmtId )
  203. break;
  204. return _cmFfFmtArray + i;
  205. }
  206. const void* _cmFfSwapVector( void* dV, const void* sV, unsigned n, unsigned bn )
  207. {
  208. unsigned i;
  209. switch( bn )
  210. {
  211. case 1:
  212. return sV;
  213. case 2:
  214. {
  215. const unsigned short* x = (const unsigned short*)sV;
  216. unsigned short* y = (unsigned short*)dV;
  217. for(i=0; i<n; ++i)
  218. y[i] = cmSwap16(x[i]);
  219. }
  220. break;
  221. case 4:
  222. {
  223. const unsigned long* x = (const unsigned long*)sV;
  224. unsigned long* y = (unsigned long*)dV;
  225. for(i=0; i<n; ++i)
  226. y[i] = cmSwap32(x[i]);
  227. }
  228. break;
  229. case 8:
  230. {
  231. // on 32 bit linux this is very slow
  232. const unsigned long long* x = (const unsigned long long*)sV;
  233. unsigned long long* y = (unsigned long long*)dV;
  234. for(i=0; i<n; ++i)
  235. y[i] = cmSwap64(x[i]);
  236. }
  237. break;
  238. default:
  239. { assert(0); }
  240. }
  241. return dV;
  242. }
  243. cmFfRC_t _cmFfWrite( cmFf_t* p, const void* dataPtr, unsigned byteCnt )
  244. {
  245. if(fwrite(dataPtr,byteCnt,1,p->fp) != 1 )
  246. return _cmFfError( p, kFileWriteFailFfRC, errno, "File write failed." );
  247. p->fileChkByteCnt += byteCnt;
  248. p->frame.byteCnt += byteCnt;
  249. return kOkFfRC;
  250. }
  251. cmFfRC_t _cmFfWriteOff_t( cmFf_t* p, off_t v )
  252. {
  253. cmFfRC_t rc;
  254. assert(sizeof(off_t)==8);
  255. v = _cmFfSwap64(p->swapFl,v);
  256. if((rc = _cmFfWrite(p,&v,sizeof(v))) != kOkFfRC )
  257. return rc;
  258. return kOkFfRC;
  259. }
  260. cmFfRC_t _cmFfWriteUInt( cmFf_t* p, unsigned v )
  261. {
  262. cmFfRC_t rc;
  263. v = _cmFfSwap32(p->swapFl,v);
  264. if((rc = _cmFfWrite(p,&v,sizeof(v))) != kOkFfRC )
  265. return rc;
  266. return kOkFfRC;
  267. }
  268. cmFfRC_t _cmFfWriteUIntV( cmFf_t* p, const unsigned* vp, unsigned n )
  269. {
  270. unsigned i;
  271. cmFfRC_t rc;
  272. for(i=0; i<n; ++i)
  273. if((rc = _cmFfWriteUInt( p, vp[i] )) != kOkFfRC )
  274. return rc;
  275. return kOkFfRC;
  276. }
  277. cmFfRC_t _cmFfWriteDouble( cmFf_t* p, double v )
  278. {
  279. cmFfRC_t rc;
  280. unsigned long long vv = _cmFfWrSwapD(p->swapFl,v);
  281. if((rc = _cmFfWrite(p, &vv, sizeof(vv))) != kOkFfRC )
  282. return rc;
  283. return kOkFfRC;
  284. }
  285. cmFfRC_t _cmFfRead( cmFf_t* p, void* vp, unsigned bn )
  286. {
  287. if(fread(vp,bn,1,p->fp) != 1 )
  288. {
  289. if( feof(p->fp) )
  290. return kEofFfRC;
  291. return _cmFfError( p, kFileReadFailFfRC, errno, "File read failed.");
  292. }
  293. return kOkFfRC;
  294. }
  295. cmFfRC_t _cmFfReadOff_t( cmFf_t* p, off_t* vp )
  296. {
  297. cmFfRC_t rc;
  298. assert( sizeof(off_t)==8);
  299. if((rc = _cmFfRead(p,vp,sizeof(*vp))) != kOkFfRC )
  300. return rc;
  301. *vp = _cmFfSwap64(p->swapFl,*vp);
  302. return kOkFfRC;
  303. }
  304. cmFfRC_t _cmFfReadUInt( cmFf_t* p, unsigned* vp )
  305. {
  306. cmFfRC_t rc;
  307. if((rc = _cmFfRead(p,vp,sizeof(*vp))) != kOkFfRC )
  308. return rc;
  309. *vp = _cmFfSwap32(p->swapFl,*vp);
  310. return kOkFfRC;
  311. }
  312. cmFfRC_t _cmFfReadDouble( cmFf_t* p, double* vp )
  313. {
  314. cmFfRC_t rc;
  315. unsigned long long v;
  316. if((rc = _cmFfRead(p,&v,sizeof(v))) != kOkFfRC )
  317. return rc;
  318. *vp = _cmFfRdSwapD(p->swapFl,v);
  319. return rc;
  320. }
  321. cmFfRC_t _cmFfTell( cmFf_t* p, off_t* offsPtr )
  322. {
  323. if((*offsPtr = ftello( p->fp )) == -1 )
  324. return _cmFfError( p, kFileTellFailFfRC, errno, "File tell failed.");
  325. return kOkFfRC;
  326. }
  327. cmFfRC_t _cmFfSeek( cmFf_t* p, int whence, off_t offset )
  328. {
  329. //if( p->writeFl )
  330. // return _cmFfError( p, kInvalidFileModeFfRC, 0, "Cannot seek on file opened for writing.");
  331. if(fseeko(p->fp, offset, whence) != 0 )
  332. return _cmFfError( p, kFileSeekFailFfRC, errno, "File seek failed.");
  333. return kOkFfRC;
  334. }
  335. //-------------------------------------------------------------------------------------------
  336. // append a _cmFfOffs_t record to a _cmFfOffsList
  337. void _cmFfAppendOffsList( cmFf_t* p, _cmFfOffsList_t* lp, unsigned frmIdx, unsigned offs )
  338. {
  339. _cmFfOffs_t* op = (_cmFfOffs_t*)cmLHeapAllocZ( p->lhH, sizeof(_cmFfOffs_t) );
  340. op->frmIdx = frmIdx;
  341. op->offs = offs;
  342. if( lp->end != NULL )
  343. lp->end->linkPtr = op;
  344. else
  345. {
  346. assert( lp->beg == NULL );
  347. }
  348. lp->end = op;
  349. if( lp->beg == NULL )
  350. {
  351. assert( lp->end == op );
  352. lp->beg = op;
  353. }
  354. ++lp->cnt;
  355. }
  356. // locate a ToC record in a ToC list
  357. _cmFfToC_t* _cmFfFindToCPtr( cmFf_t* p, _cmFfToC_t* cp, unsigned streamId, unsigned mtxType, unsigned mtxUnitsId, unsigned mtxFmtId )
  358. {
  359. while( cp != NULL )
  360. {
  361. if( cp->streamId==streamId && cp->mtxType==mtxType && cp->mtxUnitsId==mtxUnitsId && cp->mtxFmtId==mtxFmtId )
  362. break;
  363. cp = cp->linkPtr;
  364. }
  365. return cp;
  366. }
  367. cmFfRC_t _cmFfAppendToC( cmFf_t* p, _cmFfToC_t** tocPtrPtr, unsigned streamId, unsigned mtxType, unsigned mtxUnitsId, unsigned mtxFmtId, unsigned absFrameIdx, off_t fileOffset )
  368. {
  369. cmFfRC_t rc = kOkFfRC;
  370. _cmFfToC_t* tocPtr = *tocPtrPtr;
  371. _cmFfToC_t* cp;
  372. // use p->eofOffset as a flags to prevent appending the TOC matrices themselves to the TOC
  373. if( p->writeFl && p->eofOffset != cmInvalidIdx )
  374. return rc;
  375. // find the contents record associated with this matrix stream,type,fmt,units
  376. if(( cp = _cmFfFindToCPtr(p,tocPtr,streamId,mtxType,mtxUnitsId,mtxFmtId)) == NULL )
  377. {
  378. // no existing contents recd was found so create a new one
  379. cp = (_cmFfToC_t*)cmLHeapAllocZ( p->lhH, sizeof(_cmFfToC_t));
  380. cp->streamId = streamId;
  381. cp->mtxType = mtxType;
  382. cp->mtxUnitsId = mtxUnitsId;
  383. cp->mtxFmtId = mtxFmtId;
  384. cp->linkPtr = tocPtr;
  385. cp->lastFrmIdx = cmInvalidIdx;
  386. //printf("create : stream:%i type:0x%x units:%i fmt:%i\n",streamId,mtxType,mtxUnitsId,mtxFmtId);
  387. *tocPtrPtr = cp;
  388. }
  389. assert( p->nxtFrmIdx > 0 );
  390. // verify that this frame does not have multiple matrixes of the same type
  391. // (this would result in multiple identical _cmFfOffs_t records being written for the same _cmFfToC_t record)
  392. if( absFrameIdx == cp->lastFrmIdx )
  393. rc = _cmFfError( p, kDuplicateMtxIdFfRC, 0, "Duplicate matrix types were found in the same frame: stream:%i type:%i units:%i fmt:%i.",streamId, mtxType, mtxUnitsId, mtxFmtId );
  394. cp->lastFrmIdx = absFrameIdx;
  395. _cmFfAppendOffsList(p, &cp->offsList, absFrameIdx, fileOffset );
  396. return rc;
  397. }
  398. cmFfRC_t _cmFfAppendMtxToC( cmFf_t* p, unsigned streamId, unsigned mtxType, unsigned mtxUnitsId, unsigned mtxFmtId, unsigned absFrameIdx, off_t mtxFileOff )
  399. { return _cmFfAppendToC(p, &p->mtxToC, streamId, mtxType, mtxUnitsId, mtxFmtId, absFrameIdx, mtxFileOff ); }
  400. cmFfRC_t _cmFfAppendFrameToC( cmFf_t* p, unsigned streamId, unsigned absFrameIdx, off_t frmFileOff )
  401. { return _cmFfAppendToC(p, &p->frmToC, streamId, kInvalidMId, kInvalidUId, kInvalidFmtId, absFrameIdx, frmFileOff ); }
  402. //-------------------------------------------------------------------
  403. cmFfRC_t _cmFfWriteOffsList( cmFrameFileH_t h, _cmFfOffsList_t* lp, unsigned mtxId, void** arrayPtrPtr, unsigned* extraV, unsigned extraN )
  404. {
  405. cmFfRC_t rc = kOkFfRC;
  406. unsigned i = 0;
  407. unsigned j = 0;
  408. unsigned n = (extraN + lp->cnt * sizeof(unsigned)) + (lp->cnt * sizeof(unsigned long long));
  409. // allocate memory
  410. *arrayPtrPtr = cmMemResizeZ( unsigned, *arrayPtrPtr, n );
  411. unsigned *idxV = (unsigned*)(*arrayPtrPtr);
  412. off_t* offV = (off_t*)(idxV + extraN + lp->cnt);
  413. // store the extra values
  414. for(i=0; i<extraN; ++i)
  415. idxV[i] = extraV[i];
  416. _cmFfOffs_t* op = lp->beg;
  417. while( op != NULL )
  418. {
  419. idxV[i] = op->frmIdx;
  420. ++i;
  421. offV[j] = op->offs;
  422. ++j;
  423. op = op->linkPtr;
  424. }
  425. assert( i == extraN + lp->cnt );
  426. assert( j == lp->cnt );
  427. // write the frame index vector
  428. if((rc = cmFrameFileWriteMtxUInt(h, mtxId, kInvalidUId, idxV, extraN + lp->cnt, 1 )) != kOkFfRC )
  429. goto errLabel;
  430. // write the frame offset vector
  431. if((rc = cmFrameFileWriteMtxOff_t(h, mtxId, kInvalidUId, offV, lp->cnt, 1 )) != kOkFfRC )
  432. goto errLabel;
  433. errLabel:
  434. return rc;
  435. }
  436. cmFfRC_t _cmFfWriteToC( cmFrameFileH_t h, _cmFfToC_t* tocPtr, unsigned* mtxIdPtr, void** memPtr )
  437. {
  438. cmFfRC_t rc = kOkFfRC;
  439. // write the mtx offset matrix
  440. _cmFfToC_t* cp = tocPtr;
  441. while( cp != NULL )
  442. {
  443. enum { hdrN = 4 };
  444. unsigned hdrV[hdrN];
  445. // add 4 elements to the frame index vector containing header information
  446. hdrV[0] = cp->streamId;
  447. hdrV[1] = cp->mtxType;
  448. hdrV[2] = cp->mtxUnitsId;
  449. hdrV[3] = cp->mtxFmtId;
  450. //printf("write : stream:%i type:0x%x units:%i fmt:%i\n",cp->streamId,cp->mtxType,cp->mtxUnitsId,cp->mtxFmtId);
  451. if((rc = _cmFfWriteOffsList(h,&cp->offsList,*mtxIdPtr,memPtr,hdrV,hdrN)) != kOkFfRC )
  452. goto errLabel;
  453. --(*mtxIdPtr);
  454. cp = cp->linkPtr;
  455. }
  456. errLabel:
  457. return rc;
  458. }
  459. cmFfRC_t _cmFfWriteTocFrame( cmFrameFileH_t h )
  460. {
  461. cmFfRC_t rc = kOkFfRC;
  462. cmFf_t* p = _cmFfHandleToPtr(h);
  463. void* uV = NULL;
  464. unsigned mtxId = kTocMId;
  465. // seek to the end of the file
  466. if((rc = _cmFfSeek(p,SEEK_END,0)) != kOkFfRC )
  467. goto errLabel;
  468. // store the offset to this frame
  469. if((rc = _cmFfTell(p,&p->eofOffset)) != kOkFfRC )
  470. goto errLabel;
  471. // create the offset data frame
  472. if((rc = cmFrameFileFrameCreate(h, kTocFrameTId, kTocStreamId, cmInvalidIdx, DBL_MAX)) != kOkFfRC )
  473. goto errLabel;
  474. // write the frame offset ToC
  475. if((rc = _cmFfWriteToC(h, p->frmToC, &mtxId, &uV )) != kOkFfRC )
  476. goto errLabel;
  477. // write the mtx offset ToC
  478. if((rc = _cmFfWriteToC(h, p->mtxToC, &mtxId, &uV )) != kOkFfRC )
  479. goto errLabel;
  480. // write the EOF frame
  481. if((rc = cmFrameFileFrameClose(h)) != kOkFfRC )
  482. goto errLabel;
  483. // decrease the frameCnt so that the eof frame is not included in the file header frame count
  484. //--p->f.frameCnt;
  485. errLabel:
  486. cmMemPtrFree(&uV);
  487. return rc;
  488. }
  489. cmFfRC_t _cmFfLoadTocFrame( cmFrameFileH_t h )
  490. {
  491. cmFf_t* p = _cmFfHandleToPtr(h);
  492. cmFfRC_t rc = kOkFfRC;
  493. const cmFfFrame_t* frmDescPtr = NULL;
  494. off_t orgOff;
  495. unsigned i,j,k;
  496. if((rc = _cmFfTell(p,&orgOff)) != kOkFfRC )
  497. goto errLabel;
  498. if((rc = _cmFfSeek(p,SEEK_SET,p->eofOffset)) != kOkFfRC )
  499. goto errLabel;
  500. if((rc = cmFrameFileFrameNext(h, kTocFrameTId, kTocStreamId )) != kOkFfRC )
  501. {
  502. rc = _cmFfError( p, kTocFrameRdFailFfRC, 0, "Error reading EOF frame header.");
  503. goto errLabel;
  504. }
  505. if((rc = cmFrameFileFrameLoad(h, &frmDescPtr)) != kOkFfRC )
  506. {
  507. rc = _cmFfError( p, kTocFrameRdFailFfRC, 0, "Error loading EOF frame.");
  508. goto errLabel;
  509. }
  510. for(i=0,j=0; i<frmDescPtr->mtxCnt; i+=2,++j)
  511. {
  512. const cmFfMtx_t* frmIdxMtxDescPtr = NULL;
  513. const cmFfMtx_t* offsMtxDescPtr = NULL;
  514. const unsigned* frmIdxV;
  515. const off_t* frmOffV;
  516. // read the frame index vector
  517. if((frmIdxV = cmFrameFileMtxUInt( h, kTocMId-j, kInvalidUId, &frmIdxMtxDescPtr )) == NULL )
  518. {
  519. rc = _cmFfError( p, kTocFrameRdFailFfRC, 0, "Matrix frame index read failed for matrix type id %i.",kTocMId-j);
  520. goto errLabel;
  521. }
  522. // read the offset vector
  523. if((frmOffV = cmFrameFileMtxOff_t( h, kTocMId-j, kInvalidUId, &offsMtxDescPtr )) == NULL )
  524. {
  525. rc = _cmFfError( p, kTocFrameRdFailFfRC, 0, "Matrix frame offset read failed for matrix type id %i.",kTocMId-j);
  526. goto errLabel;
  527. }
  528. assert( frmIdxMtxDescPtr->rowCnt>=4 && frmIdxMtxDescPtr->rowCnt-4 == offsMtxDescPtr->rowCnt );
  529. // decode the frame index header
  530. unsigned streamId = frmIdxV[0];
  531. unsigned mtxType = frmIdxV[1];
  532. unsigned mtxUnitsId = frmIdxV[2];
  533. unsigned mtxFmtId = frmIdxV[3];
  534. // increment the frame index vector passed the header
  535. frmIdxV += 4;
  536. bool frmTocFl = mtxType==kInvalidMId && mtxUnitsId==kInvalidUId && mtxFmtId==kInvalidUId;
  537. for(k=0; k<offsMtxDescPtr->rowCnt && rc==kOkFfRC; ++k)
  538. {
  539. if( frmTocFl )
  540. rc = _cmFfAppendFrameToC(p, streamId, frmIdxV[k], frmOffV[k] );
  541. else
  542. rc = _cmFfAppendMtxToC(p, streamId, mtxType, mtxUnitsId, mtxFmtId, frmIdxV[k], frmOffV[k] );
  543. }
  544. }
  545. if((rc = _cmFfSeek(p,SEEK_SET,orgOff)) != kOkFfRC )
  546. goto errLabel;
  547. errLabel:
  548. return rc;
  549. }
  550. //--------------------------------------------------------------------
  551. cmFfRC_t _cmFrameFileFree( cmFf_t* p )
  552. {
  553. cmFfRC_t rc = kOkFfRC;
  554. if( p == NULL )
  555. return rc;
  556. // free the frame data ptr
  557. cmMemPtrFree(&p->frame.dataPtr);
  558. // free the mtx array ptr
  559. cmMemPtrFree(&p->frame.mtxArray);
  560. // close the file
  561. if( p->fp != NULL )
  562. {
  563. if( fclose(p->fp) == EOF )
  564. rc = _cmFfError(p,kFileCloseFailFfRC,errno,"File close failed.");
  565. else
  566. p->fp = NULL;
  567. }
  568. cmMemPtrFree(&p->writeMtxMem);
  569. // release the filename string
  570. cmMemPtrFree(&p->f.filenameStr);
  571. cmLHeapDestroy(&p->lhH);
  572. cmMemPtrFree(&p);
  573. return rc;
  574. }
  575. cmFfRC_t cmFrameFileCreate( cmFrameFileH_t* hPtr, const char* fn, double srate, cmCtx_t* ctx )
  576. {
  577. cmFfRC_t rc;
  578. // be sure the handle is not already in use
  579. if( (rc = cmFrameFileClose(hPtr)) != kOkFfRC )
  580. return rc;
  581. unsigned version = 0;
  582. cmFf_t* p;
  583. // allocate the file object
  584. if((p = cmMemAllocZ( cmFf_t, 1 )) == NULL )
  585. return _cmFfError(NULL,kMemAllocErrFfRC,0,"Memory allocation failed.");
  586. cmErrSetup(&p->err,&ctx->rpt,"FrameFile");
  587. p->ctx = *ctx;
  588. // create the linked heap
  589. if( cmLHeapIsValid(p->lhH = cmLHeapCreate( 16384, ctx )) == false )
  590. {
  591. rc = _cmFfError( p, kLHeapFailFfRC,0,"Linked heap create failed.");
  592. goto errLabel;
  593. }
  594. // create the output file
  595. if((p->fp = fopen(fn,"w+b")) == NULL )
  596. {
  597. rc = _cmFfError( p,kFileOpenFailFfRC,errno,"Unable to create the file:'%s'.",fn);
  598. goto errLabel;
  599. }
  600. // type, byteCnt, frameCnt, , version
  601. unsigned v[] = { kFileFfTId, 0, 0, version };
  602. if((rc = _cmFfWriteUIntV( p, v, sizeof(v)/sizeof(unsigned) ) ) != kOkFfRC )
  603. goto errLabel;
  604. // eof frame offset
  605. if((rc = _cmFfWriteOff_t( p, p->eofOffset)) != kOkFfRC )
  606. goto errLabel;
  607. // file sample rate
  608. if((rc = _cmFfWriteDouble( p, srate ) ) != kOkFfRC )
  609. goto errLabel;
  610. p->writeFl = true;
  611. p->fileChkByteCnt = 4 * sizeof(unsigned); // hdr bytes after byteCnt
  612. p->nxtFrmIdx = 1;
  613. p->curFrmIdx = cmInvalidIdx;
  614. p->frameOffset = cmInvalidIdx;
  615. p->eofOffset = cmInvalidIdx;
  616. p->f.frameCnt = 0;
  617. p->f.srate = srate;
  618. p->f.version = version;
  619. p->f.filenameStr = cmMemResizeStr(p->f.filenameStr,fn);
  620. p->swapFl = false;
  621. hPtr->h = p;
  622. if((rc = _cmFfTell( p, &p->rewOffset )) != kOkFfRC )
  623. goto errLabel;
  624. return rc;
  625. errLabel:
  626. _cmFrameFileFree(p);
  627. return rc;
  628. }
  629. cmFfRC_t cmFrameFileOpen( cmFrameFileH_t* hPtr, const char* fn, cmCtx_t* ctx, const cmFfFile_t** fileDescPtrPtr )
  630. {
  631. cmFfRC_t rc = kOkFfRC;
  632. cmFf_t* p;
  633. unsigned fileId;
  634. if( fileDescPtrPtr != NULL )
  635. *fileDescPtrPtr = NULL;
  636. // be sure the handle is not already in use
  637. if((rc = cmFrameFileClose(hPtr)) != kOkFfRC )
  638. return rc;
  639. // allocate the file object
  640. if((p = cmMemAllocZ( cmFf_t, 1 )) == NULL )
  641. return _cmFfError(NULL,kMemAllocErrFfRC,0,"Memory allocation failed.");
  642. cmErrSetup(&p->err,&ctx->rpt,"Frame File");
  643. p->ctx = *ctx;
  644. // create the linked heap
  645. if( cmLHeapIsValid(p->lhH = cmLHeapCreate( 2048, ctx )) == false )
  646. {
  647. rc = _cmFfError( p, kLHeapFailFfRC,0,"Linked heap create failed.");
  648. goto errLabel;
  649. }
  650. // open the file for reading
  651. if((p->fp = fopen(fn,"r+b")) == NULL )
  652. {
  653. rc = _cmFfError( p,kFileOpenFailFfRC,errno,"Unable to open the file:'%s'.",fn);
  654. goto errLabel;
  655. }
  656. p->writeFl = false;
  657. // file type id
  658. if((rc = _cmFfReadUInt( p, &fileId ) ) != kOkFfRC )
  659. goto errLabel;
  660. // verify that this is a frame file
  661. if( fileId != kFileFfTId )
  662. {
  663. if( cmSwap32(fileId) == kFileFfTId )
  664. p->swapFl = true;
  665. else
  666. {
  667. rc = _cmFfError( p,kNotFrameFileFfRC,0,"'%s' is not a frame file.",fn);
  668. goto errLabel;
  669. }
  670. }
  671. // file chunk size
  672. if((rc = _cmFfReadUInt( p, &p->fileChkByteCnt ) ) != kOkFfRC )
  673. goto errLabel;
  674. // file frame count
  675. if((rc = _cmFfReadUInt( p, &p->f.frameCnt ) ) != kOkFfRC )
  676. goto errLabel;
  677. // file format version
  678. if((rc = _cmFfReadUInt( p, &p->f.version ) ) != kOkFfRC )
  679. goto errLabel;
  680. // eof offset
  681. if((rc = _cmFfReadOff_t( p, &p->eofOffset) ) != kOkFfRC )
  682. goto errLabel;
  683. // file sample rate
  684. if((rc = _cmFfReadDouble( p, &p->f.srate ) ) != kOkFfRC )
  685. goto errLabel;
  686. p->f.filenameStr = cmMemResizeStr(p->f.filenameStr,fn);
  687. p->nxtFrmIdx = 0;
  688. p->curFrmIdx = cmInvalidIdx;
  689. p->frameOffset = cmInvalidIdx;
  690. hPtr->h = p;
  691. if((rc = _cmFfLoadTocFrame(*hPtr)) != kOkFfRC )
  692. goto errLabel;
  693. if((rc = _cmFfTell(p,&p->rewOffset)) != kOkFfRC )
  694. goto errLabel;
  695. if( fileDescPtrPtr != NULL )
  696. *fileDescPtrPtr = &p->f;
  697. return rc;
  698. errLabel:
  699. _cmFrameFileFree(p);
  700. hPtr->h = NULL;
  701. return rc;
  702. }
  703. cmFfRC_t cmFrameFileClose( cmFrameFileH_t* hp )
  704. {
  705. cmFfRC_t rc;
  706. if( hp== NULL || cmFrameFileIsValid(*hp)==false)
  707. return kOkFfRC;
  708. cmFf_t* p = _cmFfHandleToPtr(*hp);
  709. if( p->fp != NULL )
  710. {
  711. // update the file header
  712. if( p->writeFl )
  713. {
  714. if((rc = _cmFfWriteTocFrame(*hp)) != kOkFfRC )
  715. return rc;
  716. // rewind into the file header
  717. if((rc = _cmFfSeek( p, SEEK_SET, sizeof(unsigned) )) != kOkFfRC )
  718. return rc;
  719. // update the file chunk size
  720. if((rc = _cmFfWriteUInt( p, p->fileChkByteCnt ) ) != kOkFfRC )
  721. return rc;
  722. // update the file frame count
  723. if((rc = _cmFfWriteUInt( p, p->f.frameCnt ) ) != kOkFfRC )
  724. return rc;
  725. // rewrite the version
  726. if((rc = _cmFfWriteUInt( p, p->f.version ) ) != kOkFfRC )
  727. return rc;
  728. // update the eof frame offset
  729. if((rc = _cmFfWriteOff_t(p, p->eofOffset ) ) != kOkFfRC )
  730. return rc;
  731. }
  732. }
  733. _cmFrameFileFree(p);
  734. hp->h = NULL;
  735. return kOkFfRC;
  736. }
  737. bool cmFrameFileIsValid( cmFrameFileH_t h )
  738. { return h.h != NULL; }
  739. const cmFfFile_t* cmFrameFileDesc( cmFrameFileH_t h )
  740. {
  741. cmFf_t* p = _cmFfHandleToPtr(h);
  742. return &p->f;
  743. }
  744. unsigned cmFrameFileFrameCount( cmFrameFileH_t h, unsigned streamId )
  745. {
  746. cmFf_t* p = _cmFfHandleToPtr(h);
  747. _cmFfToC_t* cp = p->frmToC;
  748. while(cp != NULL )
  749. {
  750. if( cp->streamId == streamId )
  751. return cp->offsList.cnt;
  752. cp = cp->linkPtr;
  753. }
  754. return 0;
  755. }
  756. cmFfRC_t cmFrameFileFrameCreate( cmFrameFileH_t h, unsigned frameType, unsigned streamId, unsigned sampleIdx, double secs )
  757. {
  758. cmFfRC_t rc;
  759. cmFf_t* p = _cmFfHandleToPtr(h);
  760. unsigned flags = sampleIdx == -1 ? kSecondsTimeFl : kSampleIdxTimeFl;
  761. if( p->writeFl == false )
  762. return _cmFfError( p, kInvalidFileModeFfRC, 0, "Cannot create new frames on frame files opened in read mode.");
  763. // save the frame offset for later use in cmFrameFileCloseFrame()
  764. if((rc = _cmFfTell(p,&p->frameOffset)) != kOkFfRC )
  765. return rc;
  766. // update the frame offset list
  767. assert( p->nxtFrmIdx > 0 );
  768. rc = _cmFfAppendFrameToC(p, streamId, p->nxtFrmIdx-1, p->frameOffset );
  769. // frame: type, byteCnt, mtxCnt, streamId, flags, sampleIdx
  770. unsigned v[] = { frameType, 0, 0, streamId, flags, sampleIdx };
  771. if((rc = _cmFfWriteUIntV( p, v, sizeof(v)/sizeof(unsigned) ) ) != kOkFfRC )
  772. return rc;
  773. if((rc = _cmFfWriteDouble( p, secs)) != kOkFfRC )
  774. return rc;
  775. p->frame.f.type = frameType;
  776. p->frame.byteCnt = 6 * sizeof(unsigned);
  777. p->frame.f.mtxCnt = 0;
  778. p->frame.f.streamId = streamId;
  779. p->frame.f.flags = flags;
  780. p->frame.f.tm.seconds = 0;
  781. return rc;
  782. }
  783. cmFfRC_t cmFrameFileFrameClose( cmFrameFileH_t h )
  784. {
  785. cmFfRC_t rc = kOkFfRC;
  786. if( h.h == NULL )
  787. return kOkFfRC;
  788. cmFf_t* p = _cmFfHandleToPtr(h);
  789. // frames open in read-mode do not need to be closed
  790. if( p->writeFl == false )
  791. return kOkFfRC;
  792. assert( p->frameOffset != 0 );
  793. // store the current file position
  794. off_t offs; // = ftello(p->fp);
  795. if((rc = _cmFfTell(p,&offs)) != kOkFfRC )
  796. return rc;
  797. // seek to the frame byte count
  798. if((rc = _cmFfSeek( p, SEEK_SET, p->frameOffset+sizeof(unsigned) )) != kOkFfRC )
  799. return rc;
  800. // write frame byteCnt
  801. if((rc = _cmFfWriteUInt( p, p->frame.byteCnt ) ) != kOkFfRC )
  802. return rc;
  803. // write frame mtxCnt
  804. if((rc = _cmFfWriteUInt( p, p->frame.f.mtxCnt ) ) != kOkFfRC )
  805. return rc;
  806. p->f.frameCnt++;
  807. p->nxtFrmIdx++;
  808. p->frameOffset = 0;
  809. p->frame.byteCnt = 0;
  810. memset( &p->frame.f, 0, sizeof(p->frame.f));
  811. // jump back to the end of the file
  812. return _cmFfSeek(p, SEEK_SET, offs );
  813. }
  814. cmFfRC_t _cmFrameFileWriteMtx( cmFf_t* p, unsigned type, unsigned unitsId, unsigned fmtId, const void* dataPtr, unsigned rn, unsigned cn, bool writeTocFl )
  815. {
  816. cmFfRC_t rc;
  817. // track the file offset to this matrix
  818. if( p->writeFl && writeTocFl )
  819. {
  820. off_t fileOff;
  821. // get file offs to this mtx
  822. if((rc = _cmFfTell(p,&fileOff)) != kOkFfRC )
  823. return rc;
  824. assert( p->nxtFrmIdx >= 1 );
  825. // append a recd representing this matrix to the mtx TOC
  826. rc = _cmFfAppendMtxToC(p, p->frame.f.streamId, type, unitsId, fmtId, p->nxtFrmIdx-1, fileOff );
  827. }
  828. unsigned wordByteCnt = _cmFfIdToFmtPtr(fmtId)->wordByteCnt;
  829. unsigned byteCnt = rn*cn*wordByteCnt;
  830. // write the mtx header
  831. // mtx: type, byteCnt, fmtId, unitsId, rowCnt, colCnt
  832. unsigned v[] = { type, byteCnt, fmtId, unitsId, rn, cn };
  833. if((rc = _cmFfWriteUIntV( p, v, sizeof(v)/sizeof(unsigned))) != kOkFfRC )
  834. return rc;
  835. const void* src_buf = dataPtr;
  836. if( p->swapFl )
  837. {
  838. p->writeMtxMem = cmMemResize( char, p->writeMtxMem, byteCnt );
  839. src_buf = _cmFfSwapVector(p->writeMtxMem,src_buf,rn*cn,wordByteCnt);
  840. }
  841. // write the mtx data
  842. if(( rc = _cmFfWrite(p,src_buf,byteCnt)) != kOkFfRC )
  843. return rc;
  844. // write pad - all matrices must end on 64 bit boundaries
  845. unsigned n = byteCnt % 8;
  846. if( n )
  847. {
  848. assert( n < 8 );
  849. char v[8];
  850. memset(v,0,8);
  851. if(( rc = _cmFfWrite(p,v,n)) != kOkFfRC )
  852. return rc;
  853. }
  854. ++p->frame.f.mtxCnt;
  855. return kOkFfRC;
  856. }
  857. cmFfRC_t cmFrameFileWriteMtx( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, unsigned dataFmtId, const void* dataPtr, unsigned rn, unsigned cn )
  858. {
  859. cmFf_t* p = _cmFfHandleToPtr(h);
  860. return _cmFrameFileWriteMtx(p, mtxType, unitsId, dataFmtId, dataPtr, rn, cn, true );
  861. }
  862. cmFfRC_t cmFrameFileWriteMtxUChar( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const unsigned char* dataPtr, unsigned rn, unsigned cn )
  863. { return cmFrameFileWriteMtx( h, mtxType, unitsId, kUCharFmtId, dataPtr, rn, cn ); }
  864. cmFfRC_t cmFrameFileWriteMtxChar( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const char* dataPtr, unsigned rn, unsigned cn )
  865. { return cmFrameFileWriteMtx( h, mtxType, unitsId, kCharFmtId, dataPtr, rn, cn ); }
  866. cmFfRC_t cmFrameFileWriteMtxUShort( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const unsigned short* dataPtr, unsigned rn, unsigned cn )
  867. { return cmFrameFileWriteMtx( h, mtxType, unitsId, kUShortFmtId, dataPtr,rn,cn ); }
  868. cmFfRC_t cmFrameFileWriteMtxShort( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const short* dataPtr, unsigned rn, unsigned cn )
  869. { return cmFrameFileWriteMtx( h, mtxType, unitsId, kShortFmtId, dataPtr, rn, cn ); }
  870. cmFfRC_t cmFrameFileWriteMtxULong( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const unsigned long* dataPtr, unsigned rn, unsigned cn )
  871. { return cmFrameFileWriteMtx( h, mtxType, unitsId, kULongFmtId, dataPtr, rn, cn );}
  872. cmFfRC_t cmFrameFileWriteMtxLong( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const long* dataPtr, unsigned rn, unsigned cn )
  873. { return cmFrameFileWriteMtx( h, mtxType, unitsId, kLongFmtId, dataPtr, rn, cn );}
  874. cmFfRC_t cmFrameFileWriteMtxUInt( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const unsigned* dataPtr, unsigned rn, unsigned cn )
  875. { return cmFrameFileWriteMtx( h, mtxType, unitsId, kUIntFmtId, dataPtr, rn, cn );}
  876. cmFfRC_t cmFrameFileWriteMtxInt( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const int* dataPtr, unsigned rn, unsigned cn )
  877. { return cmFrameFileWriteMtx( h, mtxType, unitsId, kIntFmtId, dataPtr, rn, cn );}
  878. cmFfRC_t cmFrameFileWriteMtxULLong( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const unsigned long long* dataPtr, unsigned rn, unsigned cn )
  879. { return cmFrameFileWriteMtx( h, mtxType, unitsId, kULLongFmtId, dataPtr, rn, cn );}
  880. cmFfRC_t cmFrameFileWriteMtxLLong( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const long long* dataPtr, unsigned rn, unsigned cn )
  881. { return cmFrameFileWriteMtx( h, mtxType, unitsId, kLLongFmtId, dataPtr, rn, cn );}
  882. cmFfRC_t cmFrameFileWriteMtxOff_t( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const off_t* dataPtr, unsigned rn, unsigned cn )
  883. { return cmFrameFileWriteMtx( h, mtxType, unitsId, kOff_tFmtId, dataPtr, rn, cn );}
  884. cmFfRC_t cmFrameFileWriteMtxFloat( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const float* dataPtr, unsigned rn, unsigned cn )
  885. { return cmFrameFileWriteMtx( h, mtxType, unitsId, kFloatFmtId, dataPtr, rn, cn ); }
  886. cmFfRC_t cmFrameFileWriteMtxDouble( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const double* dataPtr, unsigned rn, unsigned cn )
  887. { return cmFrameFileWriteMtx( h, mtxType, unitsId, kDoubleFmtId, dataPtr, rn, cn ); }
  888. cmFfRC_t cmFrameFileWriteMtxBlob( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const void* dataPtr, unsigned rn, unsigned cn )
  889. { return cmFrameFileWriteMtx( h, mtxType, unitsId, kBlobFmtId, dataPtr, rn, cn ); }
  890. cmFfRC_t cmFrameFileWriteMtxStringZ( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, const char* stringPtr )
  891. {
  892. unsigned n = strlen(stringPtr);
  893. return cmFrameFileWriteMtx( h, mtxType, kInvalidUId, kStringZFmtId, stringPtr, n+1, 1 );
  894. }
  895. cmFfRC_t cmFrameFileWriteMtxJson( cmFrameFileH_t h, unsigned mtxType, cmJsonH_t jsH, const cmJsonNode_t* nodePtr )
  896. {
  897. cmFf_t* p = _cmFfHandleToPtr(h);
  898. void* buf = NULL;
  899. unsigned bufByteCnt = 0;
  900. if( cmJsonSerializeTree( jsH, nodePtr, &buf, &bufByteCnt ) != kOkJsRC )
  901. return _cmFfError(p,kJsonFailFfRC,0,"JSON serialuze failed.");
  902. return _cmFrameFileWriteMtx(p, mtxType, kNoUnitsUId, kJsonFmtId, buf, 1, bufByteCnt, true );
  903. }
  904. // Can only be called when p->fp is pointed to the beginning of a frame.
  905. // Leaves file pointing to frame header 'flags' field.
  906. cmFfRC_t _cmFrameFileFrameSeek( cmFf_t* p, unsigned keyFrameTypeId, unsigned keyFrameStreamId )
  907. {
  908. cmFfRC_t rc = kOkFfRC;
  909. while( rc == kOkFfRC )
  910. {
  911. // frame type
  912. if((rc = _cmFfReadUInt(p,&p->frame.f.type)) != kOkFfRC )
  913. break;
  914. // frame byte count
  915. if((rc = _cmFfReadUInt(p,&p->frame.byteCnt)) != kOkFfRC )
  916. break;
  917. // frame mtx count
  918. if((rc = _cmFfReadUInt(p,&p->frame.f.mtxCnt)) != kOkFfRC )
  919. return rc;
  920. // frame stream id
  921. if((rc = _cmFfReadUInt(p,&p->frame.f.streamId)) != kOkFfRC )
  922. break;
  923. // condition: no match on type
  924. if( (keyFrameTypeId == kInvalidFrameTId) && (keyFrameStreamId == kInvalidFrameTId || keyFrameStreamId == p->frame.f.streamId) )
  925. break;
  926. // condition: match on type
  927. if( (keyFrameTypeId == p->frame.f.type) && (keyFrameStreamId == kInvalidFrameTId || keyFrameStreamId == p->frame.f.streamId) )
  928. break;
  929. // goto the next frame
  930. if((rc = _cmFfSeek(p,SEEK_CUR,p->frame.byteCnt - (2*sizeof(unsigned)))) != kOkFfRC )
  931. break;
  932. ++p->nxtFrmIdx;
  933. }
  934. return rc;
  935. }
  936. cmFfRC_t cmFrameFileRewind( cmFrameFileH_t h )
  937. {
  938. cmFf_t* p = _cmFfHandleToPtr(h);
  939. p->nxtFrmIdx = 0;
  940. return _cmFfSeek(p,SEEK_SET,p->rewOffset);
  941. }
  942. cmFfRC_t cmFrameFileSeek( cmFrameFileH_t h, unsigned streamId, unsigned frameIdx )
  943. {
  944. cmFfRC_t rc = kOkFfRC;
  945. cmFf_t* p = _cmFfHandleToPtr(h);
  946. unsigned i = 0;
  947. _cmFfToC_t* tocPtr;
  948. // locate the frame TOC recd assoc'd with stream id
  949. if((tocPtr = _cmFfFindToCPtr(p, p->frmToC, streamId, kInvalidMId, kInvalidUId, kInvalidFmtId )) == NULL )
  950. {
  951. rc = _cmFfError(p,kTocRecdNotFoundFfRC,0,"Unable to locate the TOC record for stream id %i.",streamId);
  952. goto errLabel;
  953. }
  954. // locate the TOC offset recd assoc'd with frameIdx
  955. _cmFfOffs_t* cp = tocPtr->offsList.beg;
  956. for(; cp != NULL && i!=frameIdx; ++i )
  957. cp = cp->linkPtr;
  958. // if the frame index was not valid
  959. if( cp == NULL )
  960. {
  961. rc = _cmFfError(p,kInvalidFrameIdxFfRC,0,"%i is an invalid frame index for stream id %i.",frameIdx,streamId);
  962. goto errLabel;
  963. }
  964. // seek to the beginning of the frame
  965. if((rc = _cmFfSeek(p,SEEK_SET,cp->offs)) != kOkFfRC )
  966. goto errLabel;
  967. errLabel:
  968. return rc;
  969. }
  970. // Can only be called when p->fp is pointed to the beginning of a frame.
  971. cmFfRC_t cmFrameFileFrameNext( cmFrameFileH_t h, unsigned keyFrameTypeId, unsigned keyFrameStreamId )
  972. {
  973. cmFfRC_t rc;
  974. cmFf_t* p = _cmFfHandleToPtr(h);
  975. unsigned sampleIdx;
  976. double seconds;
  977. // go to the requested frame
  978. if((rc = _cmFrameFileFrameSeek(p, keyFrameTypeId, keyFrameStreamId)) != kOkFfRC )
  979. return rc;
  980. // frame flags
  981. if((rc = _cmFfReadUInt(p,&p->frame.f.flags)) != kOkFfRC )
  982. return rc;
  983. // frame sample idx
  984. if((rc = _cmFfReadUInt(p,&sampleIdx)) != kOkFfRC )
  985. return rc;
  986. // frame seconds
  987. if((rc = _cmFfReadDouble(p,&seconds)) != kOkFfRC )
  988. return rc;
  989. if( cmIsFlag(p->frame.f.flags,kSampleIdxTimeFl) )
  990. p->frame.f.tm.sampleIdx = sampleIdx;
  991. if( cmIsFlag(p->frame.f.flags,kSecondsTimeFl) )
  992. p->frame.f.tm.seconds = seconds;
  993. return rc;
  994. }
  995. cmFfRC_t _cmFrameFileCheckForDuplicateMtxId( cmFrameFileH_t h )
  996. {
  997. cmFfRC_t rc = kOkFfRC;
  998. cmFf_t* p = _cmFfHandleToPtr(h);
  999. unsigned i;
  1000. for(i=0; i<p->frame.f.mtxCnt; ++i)
  1001. {
  1002. unsigned mtxIdx = cmFrameFileMtxIndex(h, p->frame.mtxArray[i].m.type, p->frame.mtxArray[i].m.unitsId, p->frame.mtxArray[i].m.fmtId );
  1003. assert( mtxIdx != cmInvalidIdx );
  1004. if( mtxIdx != i )
  1005. {
  1006. rc = _cmFfError( p, kDuplicateMtxIdFfRC, 0, "Duplicate matrix signatures exist form type:%i units:%i fmt:%i at frame index %i.", p->frame.mtxArray[i].m.type, p->frame.mtxArray[i].m.unitsId, p->frame.mtxArray[i].m.fmtId,p->nxtFrmIdx );
  1007. goto errLabel;
  1008. }
  1009. }
  1010. errLabel:
  1011. return rc;
  1012. }
  1013. // read a matrix header and data
  1014. cmFfRC_t _cmFfReadMtx( cmFf_t* p, _cmFfMtx_t* mp, void* buf, unsigned bufByteCnt )
  1015. {
  1016. cmFfRC_t rc;
  1017. if((rc = _cmFfReadUInt(p,&mp->m.type)) != kOkFfRC )
  1018. goto errLabel;
  1019. if((rc = _cmFfReadUInt(p,&mp->byteCnt)) != kOkFfRC )
  1020. goto errLabel;
  1021. if((rc = _cmFfReadUInt(p,&mp->m.fmtId)) != kOkFfRC )
  1022. goto errLabel;
  1023. if((rc = _cmFfReadUInt(p,&mp->m.unitsId)) != kOkFfRC )
  1024. goto errLabel;
  1025. if((rc = _cmFfReadUInt(p,&mp->m.rowCnt)) != kOkFfRC )
  1026. goto errLabel;
  1027. if((rc = _cmFfReadUInt(p,&mp->m.colCnt)) != kOkFfRC )
  1028. goto errLabel;
  1029. if( buf != NULL )
  1030. {
  1031. if( mp->byteCnt > bufByteCnt )
  1032. {
  1033. rc = _cmFfError(p,kBufTooSmallFfRC,0, "Matrix buffer too small to complete the read.");
  1034. goto errLabel;
  1035. }
  1036. // read in the mtx data
  1037. if((rc = _cmFfRead(p,buf,mp->byteCnt)) != kOkFfRC )
  1038. goto errLabel;
  1039. if( p->swapFl )
  1040. {
  1041. // swap on read
  1042. _cmFfSwapVector(buf,buf,mp->m.rowCnt*mp->m.colCnt, _cmFfIdToFmtPtr(mp->m.fmtId)->wordByteCnt );
  1043. }
  1044. }
  1045. errLabel:
  1046. return rc;
  1047. }
  1048. cmFfRC_t cmFrameFileFrameLoad( cmFrameFileH_t h, const cmFfFrame_t** frameDescPtrPtr )
  1049. {
  1050. cmFfRC_t rc;
  1051. cmFf_t* p = _cmFfHandleToPtr(h);
  1052. unsigned i;
  1053. if(frameDescPtrPtr != NULL)
  1054. *frameDescPtrPtr = NULL;
  1055. // store pointer to matrix data offset - for use in cmFrameFileFrameUpdate()
  1056. if((rc = _cmFfTell(p,&p->frameOffset)) != kOkFfRC )
  1057. goto errLabel;
  1058. // create a block of memory large enough to hold the entire frame
  1059. // (this is more than is actually needed because it includes the mtx header records)
  1060. p->frame.dataPtr = cmMemResizeZ( char, p->frame.dataPtr, p->frame.byteCnt );
  1061. // create a mtx array to hold each mtx record
  1062. p->frame.mtxArray = cmMemResizeZ( _cmFfMtx_t, p->frame.mtxArray, p->frame.f.mtxCnt );
  1063. char* dp = p->frame.dataPtr;
  1064. unsigned emptyByteCnt = p->frame.byteCnt;
  1065. // for each matrix in this frame
  1066. for(i=0; i<p->frame.f.mtxCnt; ++i)
  1067. {
  1068. _cmFfMtx_t* mp = p->frame.mtxArray + i;
  1069. mp->dataPtr = dp;
  1070. // read the matrix header and data
  1071. if((rc = _cmFfReadMtx(p, mp, dp, emptyByteCnt )) != kOkFfRC )
  1072. goto errLabel;
  1073. // read any pad bytes
  1074. unsigned n = mp->byteCnt % 8;
  1075. if( n )
  1076. {
  1077. char v[8];
  1078. if((rc = _cmFfRead(p,v,n)) != kOkFfRC )
  1079. goto errLabel;
  1080. }
  1081. // verify the buffer size
  1082. if(mp->byteCnt > emptyByteCnt )
  1083. {
  1084. rc = _cmFfError(p,kBufTooSmallFfRC,0, "Matrix buffer too small to complete the read.");
  1085. goto errLabel;
  1086. }
  1087. emptyByteCnt -= mp->byteCnt; // decrement the available buffer space
  1088. dp += mp->byteCnt; // advance the matrix data buffer pointer
  1089. }
  1090. if(rc==kOkFfRC && frameDescPtrPtr != NULL)
  1091. *frameDescPtrPtr = &p->frame.f;
  1092. // verify that duplicate matrx signatures do not exist.
  1093. // (only the first of the duplicate will be accessable)
  1094. assert( _cmFrameFileCheckForDuplicateMtxId(h) == kOkFfRC );
  1095. p->curFrmIdx = p->nxtFrmIdx;
  1096. ++p->nxtFrmIdx;
  1097. errLabel:
  1098. return rc;
  1099. }
  1100. cmFfRC_t cmFrameFileFrameSkip( cmFrameFileH_t h )
  1101. {
  1102. cmFfRC_t rc = kOkFfRC;
  1103. cmFf_t* p = _cmFfHandleToPtr(h);
  1104. unsigned hdrBytes = 32 - 8; // sizeof(frame hdr) - (sizeof(hdr.type) + sizeof(hdr.chkbyteCnt))
  1105. assert(hdrBytes<=p->frame.byteCnt);
  1106. if((rc = _cmFfSeek( p, SEEK_CUR, p->frame.byteCnt - hdrBytes)) == kOkFfRC )
  1107. {
  1108. ++p->nxtFrmIdx;
  1109. }
  1110. return rc;
  1111. }
  1112. cmFfRC_t cmFrameFileFrameLoadNext( cmFrameFileH_t h, unsigned frameTypeId, unsigned streamId, const cmFfFrame_t** frameDescPtrPtr )
  1113. {
  1114. cmFfRC_t rc;
  1115. if((rc = cmFrameFileFrameNext(h,frameTypeId,streamId)) != kOkFfRC )
  1116. return rc;
  1117. return cmFrameFileFrameLoad(h,frameDescPtrPtr);
  1118. }
  1119. cmFfRC_t cmFrameFileFrameUpdate( cmFrameFileH_t h )
  1120. {
  1121. cmFfRC_t rc = kOkFfRC;
  1122. cmFf_t* p = _cmFfHandleToPtr(h);
  1123. unsigned i = 0;
  1124. off_t offs;
  1125. if((rc = _cmFfTell(p,&offs)) != kOkFfRC )
  1126. goto errLabel;
  1127. // seek to the matrix data
  1128. if((rc = _cmFfSeek(p, SEEK_SET, p->frameOffset )) != kOkFfRC )
  1129. goto errLabel;
  1130. // for each matrix
  1131. for(i=0; i<p->frame.f.mtxCnt; ++i)
  1132. {
  1133. const _cmFfMtx_t* m = p->frame.mtxArray + i;
  1134. // rewrite each matrix
  1135. if((rc = _cmFrameFileWriteMtx(p, m->m.type, m->m.unitsId, m->m.fmtId, m->dataPtr, m->m.rowCnt, m->m.colCnt, false )) != kOkFfRC )
  1136. goto errLabel;
  1137. // cmFrameFileWriteMtx increments the matrix count - so we decrement it here
  1138. --p->frame.f.mtxCnt;
  1139. }
  1140. // restore the file position
  1141. if((rc = _cmFfSeek(p, SEEK_SET, offs )) != kOkFfRC )
  1142. goto errLabel;
  1143. errLabel:
  1144. return rc;
  1145. }
  1146. const cmFfFrame_t* cmFrameFileFrameDesc( cmFrameFileH_t h )
  1147. {
  1148. cmFf_t* p = _cmFfHandleToPtr(h);
  1149. return &p->frame.f;
  1150. }
  1151. unsigned cmFrameFileFrameLoadedIndex( cmFrameFileH_t h )
  1152. {
  1153. cmFf_t* p = _cmFfHandleToPtr(h);
  1154. return p->curFrmIdx;
  1155. }
  1156. unsigned cmFrameFileMtxIndex( cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId, unsigned fmtId )
  1157. {
  1158. cmFf_t* p = _cmFfHandleToPtr(h);
  1159. unsigned i;
  1160. for(i=0; i<p->frame.f.mtxCnt; ++i)
  1161. {
  1162. if( mtxTypeId==kInvalidMId || mtxTypeId == p->frame.mtxArray[i].m.type )
  1163. if( unitsId==kInvalidUId || unitsId == p->frame.mtxArray[i].m.unitsId )
  1164. if( fmtId==kInvalidFmtId || fmtId == p->frame.mtxArray[i].m.fmtId )
  1165. return i;
  1166. }
  1167. return cmInvalidIdx;
  1168. }
  1169. const cmFfMtx_t* cmFrameFileMtxDesc( cmFrameFileH_t h, unsigned mtxIdx )
  1170. { cmFf_t* p = _cmFfHandleToPtr(h);
  1171. assert( mtxIdx < p->frame.f.mtxCnt );
  1172. return &p->frame.mtxArray[ mtxIdx ].m;
  1173. }
  1174. void* _cmFrameFileMtxIndexDataPtr( cmFrameFileH_t h, unsigned dataFmtId, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr )
  1175. {
  1176. if( mtxIdx == cmInvalidIdx )
  1177. return NULL;
  1178. cmFf_t* p = _cmFfHandleToPtr(h);
  1179. assert( mtxIdx < p->frame.f.mtxCnt );
  1180. assert( p->frame.mtxArray[mtxIdx].m.fmtId == dataFmtId );
  1181. if( descPtrPtr != NULL )
  1182. *descPtrPtr = &p->frame.mtxArray[ mtxIdx ].m;
  1183. return p->frame.mtxArray[mtxIdx].dataPtr;
  1184. }
  1185. unsigned char* cmFrameFileMtxIndexUChar( cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr )
  1186. { return (unsigned char*)_cmFrameFileMtxIndexDataPtr( h, kUCharFmtId, mtxIdx, descPtrPtr ); }
  1187. char* cmFrameFileMtxIndexChar( cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr )
  1188. { return (char*)_cmFrameFileMtxIndexDataPtr( h, kCharFmtId, mtxIdx, descPtrPtr ); }
  1189. unsigned short* cmFrameFileMtxIndexUShort( cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr )
  1190. { return (unsigned short*) _cmFrameFileMtxIndexDataPtr( h, kUShortFmtId, mtxIdx, descPtrPtr ); }
  1191. short* cmFrameFileMtxIndexShort( cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr )
  1192. { return (short*)_cmFrameFileMtxIndexDataPtr( h, kShortFmtId, mtxIdx, descPtrPtr ); }
  1193. unsigned long* cmFrameFileMtxIndexULong( cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr )
  1194. { return (unsigned long*)_cmFrameFileMtxIndexDataPtr( h, kULongFmtId, mtxIdx, descPtrPtr ); }
  1195. long* cmFrameFileMtxIndexLong( cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr )
  1196. { return (long*) _cmFrameFileMtxIndexDataPtr( h, kLongFmtId, mtxIdx, descPtrPtr ); }
  1197. unsigned* cmFrameFileMtxIndexUInt( cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr )
  1198. { return (unsigned*) _cmFrameFileMtxIndexDataPtr( h, kUIntFmtId, mtxIdx, descPtrPtr ); }
  1199. int* cmFrameFileMtxIndexInt( cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr )
  1200. { return (int*) _cmFrameFileMtxIndexDataPtr( h, kIntFmtId, mtxIdx, descPtrPtr ); }
  1201. unsigned long long* cmFrameFileMtxIndexULLong( cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr )
  1202. { return (unsigned long long*) _cmFrameFileMtxIndexDataPtr( h, kULLongFmtId, mtxIdx, descPtrPtr ); }
  1203. long long* cmFrameFileMtxIndexLLong( cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr )
  1204. { return (long long*) _cmFrameFileMtxIndexDataPtr( h, kLLongFmtId, mtxIdx, descPtrPtr ); }
  1205. off_t* cmFrameFileMtxIndexOff_t( cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr )
  1206. { return (off_t*) _cmFrameFileMtxIndexDataPtr( h, kOff_tFmtId, mtxIdx, descPtrPtr ); }
  1207. float* cmFrameFileMtxIndexFloat( cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr )
  1208. { return (float*)_cmFrameFileMtxIndexDataPtr( h, kFloatFmtId, mtxIdx, descPtrPtr ); }
  1209. double* cmFrameFileMtxIndexDouble( cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr )
  1210. { return (double*)_cmFrameFileMtxIndexDataPtr( h, kDoubleFmtId, mtxIdx, descPtrPtr ); }
  1211. char* cmFrameFileMtxIndexStringZ( cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr )
  1212. { return (char*)_cmFrameFileMtxIndexDataPtr( h, kStringZFmtId, mtxIdx, descPtrPtr ); }
  1213. void* cmFrameFileMtxIndexBlob( cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr )
  1214. { return _cmFrameFileMtxIndexDataPtr( h, kBlobFmtId, mtxIdx, descPtrPtr );}
  1215. cmJsonH_t cmFrameFileMtxIndexJson( cmFrameFileH_t h, unsigned mtxIdx, const cmFfMtx_t** descPtrPtr )
  1216. {
  1217. cmFfRC_t rc = kOkFfRC;
  1218. const void* buf;
  1219. const cmFfMtx_t* dp = NULL;
  1220. cmJsRC_t jsRC;
  1221. cmJsonH_t jsH = cmJsonNullHandle;
  1222. cmFf_t* p = _cmFfHandleToPtr(h);
  1223. if( descPtrPtr != NULL )
  1224. *descPtrPtr = NULL;
  1225. if( (buf= _cmFrameFileMtxIndexDataPtr( h, kJsonFmtId, mtxIdx, &dp)) == NULL )
  1226. goto errLabel;
  1227. if((jsRC = cmJsonInitialize( &jsH, &p->ctx )) != kOkJsRC )
  1228. {
  1229. rc = _cmFfError(p,kJsonFailFfRC,0,"JSON object allocation failed.");
  1230. goto errLabel;
  1231. }
  1232. if((jsRC = cmJsonDeserialize( jsH, buf, NULL )) != kOkJsRC )
  1233. {
  1234. rc = _cmFfError(p, kJsonFailFfRC, 0, "JSON deserialization failed.");
  1235. goto errLabel;
  1236. }
  1237. errLabel:
  1238. if( rc != kOkFfRC )
  1239. cmJsonFinalize(&jsH);
  1240. else
  1241. if( descPtrPtr != NULL )
  1242. *descPtrPtr = dp;
  1243. return jsH;
  1244. }
  1245. unsigned char* cmFrameFileMtxUChar( cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId, const cmFfMtx_t** descPtrPtr )
  1246. { return (unsigned char*)_cmFrameFileMtxIndexDataPtr( h, kUCharFmtId, cmFrameFileMtxIndex(h,mtxTypeId,unitsId, kUCharFmtId), descPtrPtr ); }
  1247. char* cmFrameFileMtxChar( cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId, const cmFfMtx_t** descPtrPtr )
  1248. { return (char*)_cmFrameFileMtxIndexDataPtr( h, kCharFmtId, cmFrameFileMtxIndex(h,mtxTypeId,unitsId,kCharFmtId), descPtrPtr ); }
  1249. unsigned short* cmFrameFileMtxUShort( cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId, const cmFfMtx_t** descPtrPtr )
  1250. { return (unsigned short*)_cmFrameFileMtxIndexDataPtr( h, kUShortFmtId, cmFrameFileMtxIndex(h,mtxTypeId,unitsId,kUShortFmtId), descPtrPtr); }
  1251. short* cmFrameFileMtxShort( cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId, const cmFfMtx_t** descPtrPtr )
  1252. { return (short*)_cmFrameFileMtxIndexDataPtr( h, kShortFmtId, cmFrameFileMtxIndex(h,mtxTypeId,unitsId,kShortFmtId), descPtrPtr); }
  1253. unsigned long* cmFrameFileMtxULong( cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId, const cmFfMtx_t** descPtrPtr )
  1254. { return (unsigned long*)_cmFrameFileMtxIndexDataPtr( h, kULongFmtId, cmFrameFileMtxIndex(h,mtxTypeId,unitsId,kULongFmtId), descPtrPtr ); }
  1255. long* cmFrameFileMtxLong( cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId, const cmFfMtx_t** descPtrPtr )
  1256. { return (long*)_cmFrameFileMtxIndexDataPtr( h, kLongFmtId, cmFrameFileMtxIndex(h,mtxTypeId,unitsId,kLongFmtId), descPtrPtr ); }
  1257. unsigned* cmFrameFileMtxUInt( cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId, const cmFfMtx_t** descPtrPtr )
  1258. { return (unsigned*)_cmFrameFileMtxIndexDataPtr( h, kUIntFmtId, cmFrameFileMtxIndex(h,mtxTypeId,unitsId,kUIntFmtId), descPtrPtr ); }
  1259. int* cmFrameFileMtxInt( cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId, const cmFfMtx_t** descPtrPtr )
  1260. { return (int*)_cmFrameFileMtxIndexDataPtr( h, kIntFmtId, cmFrameFileMtxIndex(h,mtxTypeId,unitsId,kIntFmtId), descPtrPtr ); }
  1261. unsigned long long* cmFrameFileMtxULLong( cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId, const cmFfMtx_t** descPtrPtr )
  1262. { return (unsigned long long*)_cmFrameFileMtxIndexDataPtr( h, kULLongFmtId, cmFrameFileMtxIndex(h,mtxTypeId,unitsId,kULLongFmtId), descPtrPtr ); }
  1263. long long* cmFrameFileMtxLLong( cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId, const cmFfMtx_t** descPtrPtr )
  1264. { return (long long*)_cmFrameFileMtxIndexDataPtr( h, kLLongFmtId, cmFrameFileMtxIndex(h,mtxTypeId,unitsId,kLLongFmtId), descPtrPtr ); }
  1265. off_t* cmFrameFileMtxOff_t( cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId, const cmFfMtx_t** descPtrPtr )
  1266. { return (off_t*)_cmFrameFileMtxIndexDataPtr( h, kOff_tFmtId, cmFrameFileMtxIndex(h,mtxTypeId,unitsId,kOff_tFmtId), descPtrPtr ); }
  1267. float* cmFrameFileMtxFloat( cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId, const cmFfMtx_t** descPtrPtr )
  1268. { return (float*)_cmFrameFileMtxIndexDataPtr( h, kFloatFmtId, cmFrameFileMtxIndex(h,mtxTypeId,unitsId,kFloatFmtId), descPtrPtr ); }
  1269. double* cmFrameFileMtxDouble( cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId, const cmFfMtx_t** descPtrPtr )
  1270. { return (double*)_cmFrameFileMtxIndexDataPtr( h, kDoubleFmtId, cmFrameFileMtxIndex(h,mtxTypeId,unitsId,kDoubleFmtId), descPtrPtr ); }
  1271. char* cmFrameFileMtxStringZ( cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId, const cmFfMtx_t** descPtrPtr )
  1272. { return (char*)_cmFrameFileMtxIndexDataPtr( h, kStringZFmtId, cmFrameFileMtxIndex(h,mtxTypeId,unitsId,kStringZFmtId), descPtrPtr ); }
  1273. void* cmFrameFileMtxBlob( cmFrameFileH_t h, unsigned mtxTypeId, unsigned unitsId, const cmFfMtx_t** descPtrPtr )
  1274. { return _cmFrameFileMtxIndexDataPtr( h, kBlobFmtId, cmFrameFileMtxIndex(h,mtxTypeId,unitsId,kBlobFmtId), descPtrPtr ); }
  1275. cmJsonH_t cmFrameFileMtxJson( cmFrameFileH_t h, unsigned mtxTypeId, const cmFfMtx_t** descPtrPtr )
  1276. { return cmFrameFileMtxIndexJson(h, cmFrameFileMtxIndex(h,mtxTypeId,kNoUnitsUId,kJsonFmtId), descPtrPtr ); }
  1277. cmFfRC_t cmFrameFileMtxSize( cmFrameFileH_t h, unsigned streamId, unsigned mtxType, unsigned unitsId, unsigned fmtId, unsigned* frmCntPtr, unsigned* rowCntPtr, unsigned* colCntPtr, unsigned* eleCntPtr )
  1278. {
  1279. cmFfRC_t rc = kOkFfRC;
  1280. cmFf_t* p = _cmFfHandleToPtr(h);
  1281. _cmFfToC_t* tocPtr;
  1282. _cmFfOffs_t* op;
  1283. _cmFfMtx_t mtx;
  1284. *frmCntPtr = 0;
  1285. *eleCntPtr = 0;
  1286. *rowCntPtr = 0;
  1287. *colCntPtr = 0;
  1288. if((tocPtr = _cmFfFindToCPtr(p, p->mtxToC, streamId, mtxType, unitsId, fmtId )) == NULL )
  1289. {
  1290. rc = _cmFfError( p, kTocRecdNotFoundFfRC, 0, "Unable to locate the requested matrix in stream:%i mtx:%i units:%i fmt:%i.",streamId, mtxType, unitsId, fmtId );
  1291. goto errLabel;
  1292. }
  1293. op = tocPtr->offsList.beg;
  1294. while(op != NULL )
  1295. {
  1296. if((rc = _cmFfSeek(p,SEEK_SET, op->offs )) != kOkFfRC )
  1297. goto errLabel;
  1298. if((rc = _cmFfReadMtx(p,&mtx,NULL,0)) != kOkFfRC )
  1299. goto errLabel;
  1300. *frmCntPtr += 1;
  1301. *eleCntPtr += mtx.m.rowCnt * mtx.m.colCnt;
  1302. if( mtx.m.rowCnt > *rowCntPtr )
  1303. *rowCntPtr = mtx.m.rowCnt;
  1304. if( mtx.m.colCnt > *colCntPtr )
  1305. *colCntPtr = mtx.m.colCnt;
  1306. op = op->linkPtr;
  1307. }
  1308. errLabel:
  1309. return rc;
  1310. }
  1311. cmFfRC_t _cmFrameFileMtxLoad( cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned fmtId, unsigned frmIdx, unsigned frmCnt, void* buf, unsigned bufEleCnt, unsigned* outCntPtr )
  1312. {
  1313. cmFfRC_t rc = kOkFfRC;
  1314. cmFf_t* p = _cmFfHandleToPtr(h);
  1315. char* dp = buf;
  1316. unsigned wordByteCnt = _cmFfIdToFmtPtr(fmtId)->wordByteCnt;
  1317. int dpn = bufEleCnt*wordByteCnt;
  1318. _cmFfToC_t* tocPtr;
  1319. _cmFfMtx_t mtx;
  1320. unsigned fi;
  1321. if( outCntPtr != NULL )
  1322. *outCntPtr = 0;
  1323. if((tocPtr = _cmFfFindToCPtr(p, p->mtxToC, streamId, mtxTypeId, unitsId, fmtId )) == NULL )
  1324. {
  1325. rc = _cmFfError( p, kTocRecdNotFoundFfRC, 0, "Unable to locate the requested matrix in stream:%i mtx:%i units:%i fmt:%i.",streamId, mtxTypeId, unitsId, fmtId );
  1326. goto errLabel;
  1327. }
  1328. _cmFfOffs_t* op = tocPtr->offsList.beg;
  1329. for(fi=0; op != NULL && (frmCnt==-1 || fi<(frmIdx+frmCnt)); ++fi )
  1330. {
  1331. if( frmIdx<=fi )
  1332. {
  1333. if((rc = _cmFfSeek(p,SEEK_SET, op->offs )) != kOkFfRC )
  1334. goto errLabel;
  1335. if((rc = _cmFfReadMtx(p,&mtx,dp,dpn)) != kOkFfRC )
  1336. goto errLabel;
  1337. int readByteCnt = mtx.m.rowCnt * mtx.m.colCnt * wordByteCnt;
  1338. if( readByteCnt > dpn )
  1339. {
  1340. rc = _cmFfError( p, kBufTooSmallFfRC, 0, "The matrix load buffer is too small.");
  1341. goto errLabel;
  1342. }
  1343. dpn -= readByteCnt;
  1344. dp += readByteCnt;
  1345. }
  1346. op = op->linkPtr;
  1347. }
  1348. if( outCntPtr != NULL )
  1349. *outCntPtr = bufEleCnt - (dpn/wordByteCnt);
  1350. errLabel:
  1351. return rc;
  1352. }
  1353. cmFfRC_t cmFrameFileMtxLoadUChar( cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt, unsigned char* buf, unsigned eleCnt, unsigned* outCntPtr )
  1354. { return _cmFrameFileMtxLoad( h, streamId, mtxTypeId, unitsId, kUCharFmtId, frmIdx, frmCnt, buf, eleCnt, outCntPtr ); }
  1355. cmFfRC_t cmFrameFileMtxLoadChar( cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt, char* buf, unsigned eleCnt, unsigned* outCntPtr )
  1356. { return _cmFrameFileMtxLoad( h, streamId, mtxTypeId, unitsId, kCharFmtId, frmIdx, frmCnt, buf, eleCnt, outCntPtr ); }
  1357. cmFfRC_t cmFrameFileMtxLoadUShort( cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt, unsigned short* buf, unsigned eleCnt, unsigned* outCntPtr )
  1358. { return _cmFrameFileMtxLoad( h, streamId, mtxTypeId, unitsId, kUShortFmtId, frmIdx, frmCnt, buf, eleCnt, outCntPtr ); }
  1359. cmFfRC_t cmFrameFileMtxLoadShort( cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt, short* buf, unsigned eleCnt, unsigned* outCntPtr )
  1360. { return _cmFrameFileMtxLoad( h, streamId, mtxTypeId, unitsId, kShortFmtId, frmIdx, frmCnt, buf, eleCnt, outCntPtr ); }
  1361. cmFfRC_t cmFrameFileMtxLoadULong( cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt, unsigned long* buf, unsigned eleCnt, unsigned* outCntPtr )
  1362. { return _cmFrameFileMtxLoad( h, streamId, mtxTypeId, unitsId, kULongFmtId, frmIdx, frmCnt, buf, eleCnt, outCntPtr ); }
  1363. cmFfRC_t cmFrameFileMtxLoadLong( cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt, long* buf, unsigned eleCnt, unsigned* outCntPtr )
  1364. { return _cmFrameFileMtxLoad( h, streamId, mtxTypeId, unitsId, kLongFmtId, frmIdx, frmCnt, buf, eleCnt, outCntPtr ); }
  1365. cmFfRC_t cmFrameFileMtxLoadUInt( cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt, unsigned int* buf, unsigned eleCnt, unsigned* outCntPtr )
  1366. { return _cmFrameFileMtxLoad( h, streamId, mtxTypeId, unitsId, kUIntFmtId, frmIdx, frmCnt, buf, eleCnt, outCntPtr ); }
  1367. cmFfRC_t cmFrameFileMtxLoadInt( cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt, int* buf, unsigned eleCnt, unsigned* outCntPtr )
  1368. { return _cmFrameFileMtxLoad( h, streamId, mtxTypeId, unitsId, kIntFmtId, frmIdx, frmCnt, buf, eleCnt, outCntPtr ); }
  1369. cmFfRC_t cmFrameFileMtxLoadULLong( cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt, unsigned long long* buf, unsigned eleCnt, unsigned* outCntPtr )
  1370. { return _cmFrameFileMtxLoad( h, streamId, mtxTypeId, unitsId, kULLongFmtId, frmIdx, frmCnt, buf, eleCnt, outCntPtr ); }
  1371. cmFfRC_t cmFrameFileMtxLoadLLong( cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt, long long* buf, unsigned eleCnt, unsigned* outCntPtr )
  1372. { return _cmFrameFileMtxLoad( h, streamId, mtxTypeId, unitsId, kLLongFmtId, frmIdx, frmCnt, buf, eleCnt, outCntPtr ); }
  1373. cmFfRC_t cmFrameFileMtxLoadFloat( cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt, float* buf, unsigned eleCnt, unsigned* outCntPtr )
  1374. { return _cmFrameFileMtxLoad( h, streamId, mtxTypeId, unitsId, kFloatFmtId, frmIdx, frmCnt, buf, eleCnt, outCntPtr ); }
  1375. cmFfRC_t cmFrameFileMtxLoadDouble( cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt, double* buf, unsigned eleCnt, unsigned* outCntPtr )
  1376. { return _cmFrameFileMtxLoad( h, streamId, mtxTypeId, unitsId, kDoubleFmtId, frmIdx, frmCnt, buf, eleCnt, outCntPtr ); }
  1377. cmFfRC_t cmFrameFileMtxLoadStringZ( cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt, char* buf, unsigned eleCnt, unsigned* outCntPtr )
  1378. { return _cmFrameFileMtxLoad( h, streamId, mtxTypeId, unitsId, kStringZFmtId, frmIdx, frmCnt, buf, eleCnt, outCntPtr ); }
  1379. cmFfRC_t cmFrameFileMtxLoadBlob( cmFrameFileH_t h, unsigned streamId, unsigned mtxTypeId, unsigned unitsId, unsigned frmIdx, unsigned frmCnt, void* buf, unsigned eleCnt, unsigned* outCntPtr )
  1380. { return _cmFrameFileMtxLoad( h, streamId, mtxTypeId, unitsId, kUCharFmtId, frmIdx, frmCnt, buf, eleCnt, outCntPtr ); }
  1381. void _cmFrameFilePrint( cmRpt_t* rpt, const char* fmt, ... )
  1382. {
  1383. assert(rpt != NULL);
  1384. va_list vl;
  1385. va_start(vl,fmt);
  1386. cmRptVPrintf(rpt,fmt,vl);
  1387. va_end(vl);
  1388. }
  1389. cmFfRC_t _cmFrameFileMtxReport( const cmFf_t* p, unsigned mtxIdx, cmRpt_t* rpt )
  1390. {
  1391. assert( mtxIdx < p->frame.f.mtxCnt );
  1392. const _cmFfMtx_t* mp = p->frame.mtxArray + mtxIdx;
  1393. _cmFrameFilePrint(rpt," type:0x%x units:0x%x fmtId:0x%x rowCnt:%i colCnt:%i byteCnt:%i\n",mp->m.type,mp->m.unitsId,mp->m.fmtId,mp->m.rowCnt,mp->m.colCnt,mp->byteCnt);
  1394. return kOkFfRC;
  1395. }
  1396. cmFfRC_t _cmFrameFileFrameReport( const cmFf_t* p, cmRpt_t* rpt )
  1397. {
  1398. unsigned i;
  1399. _cmFrameFilePrint(rpt,"type:0x%x mtxCnt:%i flags:0x%x streamId:%i byteCnt:%i\n", p->frame.f.type,p->frame.f.mtxCnt,p->frame.f.flags,p->frame.f.streamId,p->frame.byteCnt);
  1400. for(i=0; i<p->frame.f.mtxCnt; ++i)
  1401. _cmFrameFileMtxReport(p,i,rpt);
  1402. return kOkFfRC;
  1403. }
  1404. void _cmFrameFileContentsReport(const cmFf_t* p, const _cmFfToC_t* tocPtr, cmRpt_t* rpt )
  1405. {
  1406. const _cmFfToC_t* cp = tocPtr;
  1407. unsigned i;
  1408. for(i=0; cp != NULL; ++i )
  1409. {
  1410. bool frmFl = cp->mtxType==kInvalidMId && cp->mtxUnitsId==kInvalidUId && cp->mtxFmtId==kInvalidFmtId;
  1411. _cmFrameFilePrint( rpt, "%i streamId:%i ",i, cp->streamId );
  1412. if( !frmFl )
  1413. _cmFrameFilePrint( rpt, "type:%i units:%i fmt:%i ",cp->mtxType, cp->mtxUnitsId, cp->mtxFmtId );
  1414. _cmFrameFilePrint( rpt, "cnt:%i\n", cp->offsList.cnt );
  1415. cp = cp->linkPtr;
  1416. }
  1417. }
  1418. cmFfRC_t cmFrameFileReport( cmFrameFileH_t h, bool summOnlyFl, cmRpt_t* rpt )
  1419. {
  1420. cmFfRC_t rc = kOkFfRC;
  1421. cmFf_t* p = _cmFfHandleToPtr(h);
  1422. if(p->writeFl )
  1423. return _cmFfError( p, kInvalidFileModeFfRC, 0, "Cannot report on files opened in write mode.");
  1424. _cmFrameFilePrint(rpt,"frames:%i srate:%f\n",p->f.frameCnt,p->f.srate);
  1425. _cmFrameFilePrint(rpt,"Frame Contents:\n");
  1426. _cmFrameFileContentsReport(p, p->frmToC, rpt );
  1427. _cmFrameFilePrint(rpt,"Matrix Contents:\n");
  1428. _cmFrameFileContentsReport(p, p->mtxToC, rpt );
  1429. if( summOnlyFl )
  1430. {
  1431. unsigned i;
  1432. if((rc = cmFrameFileRewind(h)) != kOkFfRC )
  1433. goto errLabel;
  1434. for(i=0; cmFrameFileFrameLoadNext(h,kInvalidFrameTId,kInvalidStreamId,NULL) == kOkFfRC; ++i)
  1435. {
  1436. _cmFrameFilePrint(rpt," %i ",i);
  1437. if((rc = _cmFrameFileFrameReport(p,rpt)) != kOkFfRC )
  1438. break;
  1439. }
  1440. assert(i==p->f.frameCnt);
  1441. }
  1442. errLabel:
  1443. return rc;
  1444. }
  1445. cmFfRC_t cmFrameFileNameReport( const char* fn, bool summOnlyFl, cmCtx_t* ctx )
  1446. {
  1447. cmFrameFileH_t h;
  1448. cmFfRC_t rc0,rc1;
  1449. if((rc0 = cmFrameFileOpen( &h, fn, ctx, NULL)) != kOkFfRC )
  1450. return rc0;
  1451. rc0 = cmFrameFileReport(h,summOnlyFl,&ctx->rpt);
  1452. rc1 = cmFrameFileClose(&h);
  1453. return rc0 != kOkFfRC ? rc0 : rc1;
  1454. }
  1455. /*
  1456. void cmFrameFileVTestPrintFunc( void* userDataPtr, const char* fmt, va_list vl )
  1457. {
  1458. vfprintf(stdout,fmt,vl);
  1459. }
  1460. */
  1461. cmFfRC_t _cmFrameFileTestMtx( cmFrameFileH_t h, unsigned mtxType, unsigned unitsId, unsigned mtxCnt, unsigned i, bool modFl )
  1462. {
  1463. cmFfRC_t rc = kOkFfRC;
  1464. const cmFfMtx_t* mtxDescPtr = NULL;
  1465. unsigned j,k;
  1466. for(j=0; j<mtxCnt; ++j)
  1467. {
  1468. long* dp = NULL;
  1469. double* ddp = NULL;
  1470. if( j == 3 )
  1471. {
  1472. if((ddp = cmFrameFileMtxDouble(h, mtxType + j, unitsId, &mtxDescPtr )) == NULL )
  1473. {
  1474. printf("READ ERROR\n");
  1475. goto errLabel;
  1476. }
  1477. }
  1478. else
  1479. {
  1480. if((dp = cmFrameFileMtxLong(h, mtxType + j, unitsId, &mtxDescPtr )) == NULL )
  1481. {
  1482. printf("READ ERROR\n");
  1483. goto errLabel;
  1484. }
  1485. }
  1486. printf("%2i %2i : ",i,j);
  1487. // print the mtx data
  1488. if( j == 3 )
  1489. {
  1490. for(k=0; k<mtxDescPtr->colCnt*mtxDescPtr->rowCnt; k++)
  1491. {
  1492. printf("%2.0f ",ddp[k]);
  1493. // if pass 1 modify the data
  1494. if( modFl )
  1495. ++ddp[k];
  1496. }
  1497. }
  1498. else
  1499. {
  1500. for(k=0; k<mtxDescPtr->colCnt*mtxDescPtr->rowCnt; k++)
  1501. {
  1502. printf("%2li ",dp[k]);
  1503. // if pass 1 modify the data
  1504. if( modFl )
  1505. ++dp[k];
  1506. }
  1507. }
  1508. printf("\n");
  1509. }
  1510. errLabel:
  1511. return rc;
  1512. }
  1513. cmFfRC_t cmFrameFileTest2( const char* fn, cmCtx_t* ctx )
  1514. {
  1515. cmFfRC_t rc;
  1516. cmFrameFileH_t ffH;
  1517. const cmFfFile_t* descPtr;
  1518. if((rc = cmFrameFileOpen(&ffH, fn, ctx, &descPtr )) != kOkFfRC )
  1519. goto errLabel;
  1520. rc = cmFrameFileClose(&ffH);
  1521. errLabel:
  1522. return rc;
  1523. }
  1524. cmFfRC_t cmFrameFileTest( const char* fn, cmCtx_t* ctx )
  1525. {
  1526. //return cmFrameFileTest2("/media/disk/home/kevin/temp/temp0.ft");
  1527. cmFfRC_t rc = kOkFfRC;
  1528. double srate = 44100;
  1529. unsigned frameType = 0x32333435;
  1530. unsigned streamId = 1;
  1531. unsigned sampleIdx = 0;
  1532. unsigned unitsId = kNoUnitsUId;
  1533. cmFrameFileH_t h;
  1534. const cmFfFile_t* fileDescPtr = NULL;
  1535. const cmFfFrame_t* frmDescPtr = NULL;
  1536. unsigned mtxType = 0x40414243;
  1537. unsigned i,j,k,m;
  1538. if((rc = cmFrameFileCreate( &h, fn, srate, ctx )) != kOkFfRC )
  1539. return rc;
  1540. // create 3 frames
  1541. for(i=0; i<3; ++i,sampleIdx++)
  1542. {
  1543. if((rc = cmFrameFileFrameCreate(h, frameType, streamId, sampleIdx, 0 )) == kOkFfRC )
  1544. {
  1545. long data[] = { 0,1,2,3,4,5,6,7,8,9,10 };
  1546. double ddata[] = { 10,11,12,13,14,15,16,17,18,19,20 };
  1547. unsigned n = sizeof(data)/sizeof(data[0]);
  1548. for(j=0; j<n; ++j)
  1549. data[j] += i;
  1550. // write 3 matrices
  1551. for(k=0; k<3; ++k)
  1552. {
  1553. if((rc = cmFrameFileWriteMtxLong( h, mtxType + k, unitsId, data, n, 1 )) != kOkFfRC )
  1554. return rc;
  1555. }
  1556. if((rc = cmFrameFileWriteMtxDouble( h, mtxType + k, unitsId, ddata, n, 1 )) != kOkFfRC )
  1557. return rc;
  1558. if((rc = cmFrameFileFrameClose(h)) != kOkFfRC )
  1559. return rc;
  1560. }
  1561. }
  1562. if((rc = cmFrameFileClose(&h)) != kOkFfRC )
  1563. return rc;
  1564. if((rc = cmFrameFileOpen( &h, fn, ctx,&fileDescPtr )) != kOkFfRC )
  1565. return rc;
  1566. // make two passes:
  1567. // pass 1: read/print/modify
  1568. // pass 2: read/print
  1569. for(m=0; m<2; ++m)
  1570. {
  1571. // report the overall file format and types
  1572. if((rc = cmFrameFileReport( h, false, &ctx->rpt )) != kOkFfRC )
  1573. goto errLabel;
  1574. // rewind the file
  1575. if((rc = cmFrameFileRewind(h)) != kOkFfRC )
  1576. goto errLabel;
  1577. // for each frame
  1578. for(i=0; cmFrameFileFrameLoadNext(h,kInvalidFrameTId,kInvalidStreamId,&frmDescPtr)==kOkFfRC; ++i)
  1579. {
  1580. if( frmDescPtr->type == kTocFrameTId )
  1581. break;
  1582. // print each matrix in this frame
  1583. if((rc = _cmFrameFileTestMtx( h, mtxType, unitsId, frmDescPtr->mtxCnt, i, m==0 )) != kOkFfRC )
  1584. goto errLabel;
  1585. // if pass 1 write the modified data back to disk
  1586. if( m == 0 )
  1587. if((rc = cmFrameFileFrameUpdate(h)) != kOkFfRC )
  1588. goto errLabel;
  1589. } // end frame loop
  1590. } // end pass loop
  1591. if((rc = cmFrameFileClose(&h)) != kOkFfRC )
  1592. goto errLabel;
  1593. //
  1594. // test cmFrameFileSeek() by seeking to frame 'fi'
  1595. //
  1596. printf("seek test\n");
  1597. unsigned fi = 2;
  1598. if((rc = cmFrameFileOpen( &h, fn,ctx,&fileDescPtr )) != kOkFfRC )
  1599. goto errLabel;
  1600. if((rc = cmFrameFileSeek( h, streamId, fi )) != kOkFfRC )
  1601. goto errLabel;
  1602. if((rc = cmFrameFileFrameLoadNext(h,kInvalidFrameTId,kInvalidStreamId,&frmDescPtr)) != kOkFfRC )
  1603. goto errLabel;
  1604. if((rc = _cmFrameFileTestMtx( h, mtxType, unitsId, frmDescPtr->mtxCnt, fi, false )) != kOkFfRC )
  1605. goto errLabel;
  1606. //
  1607. // test cmFrameFileMtxSize
  1608. //
  1609. unsigned frmCnt = 0;
  1610. unsigned rowCnt = 0;
  1611. unsigned colCnt = 0;
  1612. unsigned eleCnt = 0;
  1613. if((rc = cmFrameFileMtxSize(h, streamId, mtxType, unitsId, kLongFmtId, &frmCnt, &rowCnt, &colCnt, &eleCnt )) != kOkFfRC )
  1614. goto errLabel;
  1615. printf("frames:%i rows:%i cols:%i eles:%i\n",frmCnt,rowCnt,colCnt,eleCnt);
  1616. if(1)
  1617. {
  1618. unsigned actualEleCnt;
  1619. unsigned eleCnt = frmCnt*rowCnt*colCnt;
  1620. long buf[ eleCnt ];
  1621. if((rc = cmFrameFileMtxLoadLong(h, streamId, mtxType, unitsId, 0, -1, buf, eleCnt, &actualEleCnt )) == kOkFfRC )
  1622. {
  1623. cmVOI_Print(&ctx->rpt,rowCnt,frmCnt,(int*)buf);
  1624. }
  1625. }
  1626. errLabel:
  1627. if( rc != kOkFfRC )
  1628. printf("ERROR:%i\n",rc);
  1629. if((rc = cmFrameFileClose(&h)) != kOkFfRC )
  1630. return rc;
  1631. return rc;
  1632. }