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

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