libcm is a C development framework with an emphasis on audio signal processing applications.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

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