libcm is a C development framework with an emphasis on audio signal processing applications.
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

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. }