libcm is a C development framework with an emphasis on audio signal processing applications.
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

cmAudioPortFile.c 6.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. #include "cmGlobal.h"
  2. #include "cmRpt.h"
  3. #include "cmErr.h"
  4. #include "cmCtx.h"
  5. #include "cmMem.h"
  6. #include "cmMallocDebug.h"
  7. #include "cmAudioPort.h"
  8. #include "cmAudioPortFile.h"
  9. #include "cmAudioFileDev.h"
  10. typedef struct
  11. {
  12. cmAfdH_t devH;
  13. } cmApDev_t;
  14. typedef struct
  15. {
  16. cmErr_t err;
  17. cmApDev_t* devArray;
  18. unsigned devCnt;
  19. } cmApf_t;
  20. cmApf_t* _cmApf = NULL;
  21. cmApRC_t cmApFileInitialize( cmRpt_t* rpt, unsigned baseApDevIdx )
  22. {
  23. cmApRC_t rc;
  24. if((rc = cmApFileFinalize()) != kOkApRC )
  25. return rc;
  26. _cmApf = cmMemAllocZ(cmApf_t,1);
  27. cmErrSetup(&_cmApf->err,rpt,"Audio Port File");
  28. return rc;
  29. }
  30. cmApRC_t cmApFileFinalize()
  31. {
  32. cmApRC_t rc = kOkApRC;
  33. if( _cmApf == NULL )
  34. return kOkApRC;
  35. unsigned i;
  36. for(i=0; i<_cmApf->devCnt; ++i)
  37. {
  38. cmApRC_t rc0;
  39. if((rc0 = cmApFileDeviceDestroy(i)) != kOkApRC )
  40. rc = rc0;
  41. }
  42. cmMemPtrFree(&_cmApf->devArray);
  43. _cmApf->devCnt = 0;
  44. cmMemPtrFree(&_cmApf);
  45. return rc;
  46. }
  47. unsigned cmApFileDeviceCreate(
  48. const cmChar_t* devLabel,
  49. const cmChar_t* iFn,
  50. const cmChar_t* oFn,
  51. unsigned oBits,
  52. unsigned oChCnt )
  53. {
  54. unsigned i;
  55. // find an available device slot
  56. for(i=0; i<_cmApf->devCnt; ++i)
  57. if( cmAudioFileDevIsValid( _cmApf->devArray[i].devH ) == false )
  58. break;
  59. // if no device slot is availd ...
  60. if( i == _cmApf->devCnt )
  61. {
  62. // ... create a new one
  63. _cmApf->devArray = cmMemResizePZ(cmApDev_t, _cmApf->devArray, _cmApf->devCnt+1);
  64. ++_cmApf->devCnt;
  65. }
  66. // open the file device
  67. if( cmAudioFileDevInitialize( &_cmApf->devArray[i].devH, devLabel, i, iFn, oFn, oBits, oChCnt, _cmApf->err.rpt ) != kOkAfdRC )
  68. {
  69. cmErrMsg(&_cmApf->err,kAudioPortFileFailApRC,"The audio file device initialization failed.");
  70. i = cmInvalidIdx;
  71. }
  72. return i;
  73. }
  74. cmApRC_t cmApFileDeviceDestroy( unsigned devIdx )
  75. {
  76. if( cmAudioFileDevFinalize( &_cmApf->devArray[devIdx].devH ) != kOkAfdRC )
  77. return cmErrMsg(&_cmApf->err,kAudioPortFileFailApRC,"The audio file device finalize failed.");
  78. return kOkApRC;
  79. }
  80. unsigned cmApFileDeviceCount()
  81. { return _cmApf->devCnt; }
  82. const char* cmApFileDeviceLabel( unsigned devIdx )
  83. {
  84. assert( devIdx < cmApFileDeviceCount());
  85. return cmAudioFileDevLabel( _cmApf->devArray[devIdx].devH );
  86. }
  87. unsigned cmApFileDeviceChannelCount( unsigned devIdx, bool inputFl )
  88. {
  89. assert( devIdx < cmApFileDeviceCount());
  90. return cmAudioFileDevChannelCount( _cmApf->devArray[devIdx].devH, inputFl );
  91. }
  92. double cmApFileDeviceSampleRate( unsigned devIdx )
  93. {
  94. assert( devIdx < cmApFileDeviceCount());
  95. return cmAudioFileDevSampleRate( _cmApf->devArray[devIdx].devH );
  96. }
  97. unsigned cmApFileDeviceFramesPerCycle( unsigned devIdx, bool inputFl )
  98. {
  99. assert( devIdx < cmApFileDeviceCount());
  100. return cmAudioFileDevFramesPerCycle( _cmApf->devArray[devIdx].devH, inputFl );
  101. }
  102. cmApRC_t cmApFileDeviceSetup(
  103. unsigned devIdx,
  104. double srate,
  105. unsigned framesPerCycle,
  106. cmApCallbackPtr_t callbackPtr,
  107. void* userCbPtr )
  108. {
  109. assert( devIdx < cmApFileDeviceCount());
  110. if( cmAudioFileDevSetup( _cmApf->devArray[devIdx].devH,srate,framesPerCycle,callbackPtr,userCbPtr) != kOkAfdRC )
  111. return cmErrMsg(&_cmApf->err,kAudioPortFileFailApRC,"The audio file device setup failed.");
  112. return kOkApRC;
  113. }
  114. cmApRC_t cmApFileDeviceStart( unsigned devIdx )
  115. {
  116. assert( devIdx < cmApFileDeviceCount());
  117. if( cmAudioFileDevStart( _cmApf->devArray[devIdx].devH ) != kOkAfdRC )
  118. return cmErrMsg(&_cmApf->err,kAudioPortFileFailApRC,"The audio file device setup failed.");
  119. return kOkApRC;
  120. }
  121. cmApRC_t cmApFileDeviceStop( unsigned devIdx )
  122. {
  123. assert( devIdx < cmApFileDeviceCount());
  124. if( cmAudioFileDevStop( _cmApf->devArray[devIdx].devH ) != kOkAfdRC )
  125. return cmErrMsg(&_cmApf->err,kAudioPortFileFailApRC,"The audio file device setup failed.");
  126. return kOkApRC;
  127. }
  128. bool cmApFileDeviceIsStarted( unsigned devIdx )
  129. {
  130. assert( devIdx < cmApFileDeviceCount());
  131. return cmAudioFileDevIsStarted( _cmApf->devArray[devIdx].devH );
  132. }
  133. void cmApFileReport( cmRpt_t* rpt )
  134. {
  135. unsigned i;
  136. for(i=0; _cmApf->devCnt; ++i)
  137. {
  138. cmRptPrintf(rpt,"%i: ",i);
  139. cmAudioFileDevReport( _cmApf->devArray[i].devH, rpt );
  140. cmRptPrintf(rpt,"\n");
  141. }
  142. }
  143. // device callback function used with cmAudioPortFileTest() note that this assumes
  144. // that the packet buffer contain non-interleaved data.
  145. void _cmApFileTestCb(
  146. cmApAudioPacket_t* inPktArray,
  147. unsigned inPktCnt,
  148. cmApAudioPacket_t* outPktArray,
  149. unsigned outPktCnt )
  150. {
  151. cmApAudioPacket_t* ip = inPktArray;
  152. cmApAudioPacket_t* op = outPktArray;
  153. unsigned opi = 0;
  154. unsigned ipi = 0;
  155. unsigned oci = 0;
  156. unsigned ici = 0;
  157. while(1)
  158. {
  159. if( ici == ip->chCnt)
  160. {
  161. ici = 0;
  162. if( ++ipi >= inPktCnt )
  163. break;
  164. ip = inPktArray + ipi;
  165. }
  166. if( oci == op->chCnt )
  167. {
  168. oci = 0;
  169. if( ++opi >= outPktCnt )
  170. break;
  171. ip = outPktArray + opi;
  172. }
  173. assert( ip->audioFramesCnt == op->audioFramesCnt );
  174. assert( cmIsFlag(ip->flags,kInterleavedApFl)==false && cmIsFlag(ip->flags,kInterleavedApFl)==false );
  175. cmApSample_t* ibp = ((cmApSample_t*)ip->audioBytesPtr) + (ip->audioFramesCnt*ici);
  176. cmApSample_t* obp = ((cmApSample_t*)op->audioBytesPtr) + (op->audioFramesCnt*oci);
  177. memcpy(obp,ibp,ip->audioFramesCnt*sizeof(cmApSample_t));
  178. ++ici;
  179. ++oci;
  180. }
  181. }
  182. void cmApFileTest( cmRpt_t* rpt )
  183. {
  184. unsigned dev0Idx;
  185. const cmChar_t* promptStr = "apf> q=quit 1=start 0=stop\n";
  186. const cmChar_t* label0 = "file0";
  187. const cmChar_t* i0Fn = "/home/kevin/media/audio/McGill-1/1 Audio Track.aiff";
  188. const cmChar_t* o0Fn = "/home/kevin/temp/afd1.aif";
  189. unsigned o0Bits = 16;
  190. unsigned o0ChCnt = 2;
  191. double srate = 44100;
  192. unsigned framesPerCycle = 512;
  193. // initialize audio port file API
  194. if( cmApFileInitialize(rpt,0) != kOkApRC )
  195. return;
  196. // create an audio port file
  197. if((dev0Idx = cmApFileDeviceCreate(label0,i0Fn,o0Fn,o0Bits,o0ChCnt)) == cmInvalidIdx )
  198. goto errLabel;
  199. // configure an audio port file
  200. if( cmApFileDeviceSetup( dev0Idx, srate, framesPerCycle, _cmApFileTestCb, NULL ) != kOkAfdRC )
  201. goto errLabel;
  202. char c;
  203. fputs(promptStr,stderr);
  204. fflush(stdin);
  205. while((c=getchar()) != 'q')
  206. {
  207. switch(c)
  208. {
  209. case '0': cmApFileDeviceStart(dev0Idx); break;
  210. case '1': cmApFileDeviceStop(dev0Idx); break;
  211. }
  212. fputs(promptStr,stderr);
  213. fflush(stdin);
  214. c = 0;
  215. }
  216. errLabel:
  217. //cmApFileDeviceDestroy(dev0Idx);
  218. cmApFileFinalize();
  219. }