fader在音频处理中是比较基础的处理。通常用于平滑的调节音量,或是音频的渐入和渐出效果。

比较常见的fader有line和cubic线型的fader。

line fader即fader的渐变过程是线性的。cubic的渐变过程是三次曲线。

fader主要有三个参数,attuationDb, type, timeMs.

line fader:

通过当前的音量curVolumDb,计算fader的初始gain值:startGain = dbToGain(curVolumDb)

fader结束音量为curVolumDb + attuationDb,那么fader结束的gain值为:endGain = dbToGain(curVolumDb + curVolumDb)

将fader的开始到结束的时间timeMs转化为sample为单位:timeInSample = timeMs * sampleRate / 1000.

那么line fader的step为:step = (endGain - startGain) / timeInSample.

初始化curSample为0, curGain= startGain.

每处理一个sample(sample * curGain), curSample加1. curGain加step,直至curSample等于timeInSample,整个fader过程结束。

5s内衰减5db

5s时间fader in

cubic fader:

cubic fader的原理为,将0~1划分为多个段(假设为segNum)。计算每个Segment端点的gain值:segGain.

由于有segNum个段,那么0~1被离散为segNum + 1个点,每个点的segGain[n]值为(n/(segNum +1))^3. n=0,1,2...segNum+1;

将0~1之间的segGain map到startGain ~ endGain之间。

对于0~timeInSample之间的点,我们计算当前的sample处于哪个segment,当curSample是当前segment的第一个点时,将curGain设置成segGain[n].

当前segment按line fader一样的方法计算每个点的gain,每处理一个sample, curGain加step.

5s内衰减5db

5s时间fader in

实现代码如下:

在main函数创建两个thread,readThread, ppThread.

readThread每次读取wav文件256个sample,并每次取出64 sample转化成non-interleave的数据,发送到ppThread中。

定义一个全局的三维数组gPpBuf[chNum][bankNum][sampleNum],将转化成non-interleave的数据放到数组中,维护rp和wp来记录readThread和ppThread的当前读写的bank位置。

在ppThread中,每次接收到64sample做fader处理。

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<errno.h>
  4. #include<string.h>
  5. #include<pthread.h>
  6. #include<math.h>
  7. typedef struct{
  8. char chunkId[];//"RIFF"
  9. unsigned long chunkSize;
  10. char format[];//"WAVE"
  11. }WAVE_RIFF;
  12. typedef struct{
  13. char chunkId[];//"fmt"
  14. unsigned long chunkSize;
  15. unsigned short audioFormat;
  16. unsigned short chNum;
  17. unsigned long sampleRate;
  18. unsigned long byteRate;//SampleRate * NumChannels * BitsPerSample/8
  19. unsigned short blockAlign;//NumChannels * BitsPerSample/8
  20. unsigned short bitsPerSample;//8,16,32
  21. }WAVE_FMT;
  22. typedef struct{
  23. char chunkId[];//"data"
  24. unsigned long chunkSize;//NumSamples * NumChannels * BitsPerSample/8
  25. }WAVE_DATA;
  26. typedef struct
  27. {
  28. char fileName[];
  29. FILE *fp;
  30. long pos;
  31. unsigned long totalSampleNum;
  32. WAVE_RIFF riffChunk;
  33. WAVE_FMT fmtChunk;
  34. WAVE_DATA dataChunk;
  35. }WAVE_INFO;
  36.  
  37. #define READ_SAMPLES 256
  38. #define PP_SAMPLES 64
  39. typedef struct
  40. {
  41. unsigned short chNum;
  42. unsigned short bankNum;
  43. unsigned long samplesPerBank;
  44. unsigned short bytesPerSample;
  45. unsigned short bankRp;
  46. unsigned short bankWp;
  47. unsigned char ***pData;
  48. unsigned char fgEos;
  49. }PP_BUF_T;
  50.  
  51. typedef enum
  52. {
  53. FADER_TYPE_LINE,
  54. FADER_TYPE_CUBIC,
  55. }FADER_TYPE_E;
  56. typedef struct
  57. {
  58. float attuationDb;
  59. FADER_TYPE_E type;
  60. unsigned long timeMs;
  61. }FADER_PARAM_T;
  62.  
  63. typedef struct
  64. {
  65. FADER_PARAM_T faderParams;
  66. unsigned long timeInSample;
  67. float curVolumDb;
  68. float curGain;
  69. float startGain;
  70. float targetGain;
  71. unsigned long curSample;
  72. unsigned long sampleRate;
  73. float *segGain;
  74. unsigned short segNum;
  75. }FADER_HANDLE_T;
  76. typedef struct
  77. {
  78. short **pData;
  79. unsigned short chNum;
  80. unsigned short samples;
  81. unsigned short bytesPerSample;
  82. }DATA_INFO_T;
  83. PP_BUF_T gPpBuf;
  84. FADER_HANDLE_T gFaderHandle;
  85. unsigned char fgEnd = ;
  86. float mapSegGainToRealGain(FADER_HANDLE_T *pFaderHandle, float segGain)
  87. {
  88. float deltaGain = pFaderHandle->targetGain - pFaderHandle->startGain;
  89. float realGain = deltaGain * segGain + pFaderHandle->startGain;
  90. return realGain;
  91. }
  92. void faderPrepareShape(FADER_HANDLE_T *pFaderHandle, unsigned short segNum)
  93. {
  94. unsigned short segIdx;
  95. pFaderHandle->segGain = (float *)malloc((segNum + ) * sizeof(float));
  96. pFaderHandle->segNum = segNum;
  97. float tmp;
  98. if (pFaderHandle->faderParams.type != FADER_TYPE_CUBIC)
  99. return;
  100. //0~1 divide into N seg.
  101. for (segIdx = ; segIdx < segNum + ; segIdx++)
  102. {
  103. tmp = (float)segIdx / segNum;
  104. pFaderHandle->segGain[segIdx] = tmp * tmp * tmp;
  105. pFaderHandle->segGain[segIdx] = mapSegGainToRealGain(pFaderHandle, pFaderHandle->segGain[segIdx]);
  106. }
  107. }
  108. float dbToGain(float db)
  109. {
  110. return pow(, db/);
  111. }
  112. void faderInit(FADER_HANDLE_T *pFaderHandle, float attuationDb, FADER_TYPE_E type, unsigned long timeMs, unsigned long sampleRate, float curVolumDb)
  113. {
  114. pFaderHandle->faderParams.attuationDb = attuationDb;
  115. pFaderHandle->faderParams.type = type;
  116. pFaderHandle->faderParams.timeMs = timeMs;
  117. pFaderHandle->timeInSample = timeMs * sampleRate / ;
  118. pFaderHandle->curGain = pFaderHandle->startGain = dbToGain(curVolumDb);
  119. pFaderHandle->targetGain = dbToGain(curVolumDb + attuationDb);
  120. pFaderHandle->curSample = ;
  121. faderPrepareShape(pFaderHandle, );
  122. printf("faderInit\n");
  123. }
  124.  
  125. void faderCalGain(FADER_HANDLE_T *pFaderHandle)
  126. {
  127. printf("faderCalcGain\n");
  128. float startGainInCurSeg, endGainInCurSeg, step;
  129. float deltaGain = pFaderHandle->targetGain - pFaderHandle->startGain;
  130. unsigned long samplesInSeg = pFaderHandle->timeInSample / pFaderHandle->segNum;
  131. unsigned short curSeg = (float)pFaderHandle->curSample / samplesInSeg;
  132. unsigned long startSampleInCurSeg = samplesInSeg * curSeg;
  133. switch (pFaderHandle->faderParams.type)
  134. {
  135. case FADER_TYPE_LINE:
  136. step = deltaGain / pFaderHandle->timeInSample;
  137. pFaderHandle->curGain += deltaGain / pFaderHandle->timeInSample;
  138. //pFaderHandle->curGain = pFaderHandle->startGain + deltaGain * pFaderHandle->curSample / pFaderHandle->timeInSample;
  139. break;
  140. case FADER_TYPE_CUBIC:
  141. startGainInCurSeg = pFaderHandle->segGain[curSeg];
  142. endGainInCurSeg = pFaderHandle->segGain[curSeg + ];
  143. step = (endGainInCurSeg - startGainInCurSeg) / samplesInSeg;
  144. if (pFaderHandle->curSample == startSampleInCurSeg)
  145. pFaderHandle->curGain = startGainInCurSeg;
  146. else
  147. pFaderHandle->curGain += step;
  148. break;
  149. }
  150. printf("curGain:%f, curSample:%ld, timeInSample:%ld\n", pFaderHandle->curGain, pFaderHandle->curSample, pFaderHandle->timeInSample);
  151. }
  152.  
  153. void fader(FADER_HANDLE_T *pFaderHandle, DATA_INFO_T *pDataInfo)
  154. {
  155. unsigned short sampleIdx, chIdx;
  156. for (sampleIdx = ; sampleIdx < pDataInfo->samples; sampleIdx++)
  157. {
  158. if (pFaderHandle->curSample != pFaderHandle->timeInSample)
  159. {
  160. faderCalGain(pFaderHandle);
  161. pFaderHandle->curSample++;
  162. }
  163. for (chIdx = ; chIdx < pDataInfo->chNum; chIdx++)
  164. {
  165. pDataInfo->pData[chIdx][sampleIdx] *= pFaderHandle->curGain;
  166. }
  167. }
  168. }
  169. void printWaveHeader(WAVE_INFO *pWaveInfo)
  170. {
  171. printf("fileName:%s\n", pWaveInfo->fileName);
  172. printf("riff chunk:\n");
  173. printf("chunkId:%c%c%c%c\n", pWaveInfo->riffChunk.chunkId[], pWaveInfo->riffChunk.chunkId[], pWaveInfo->riffChunk.chunkId[], pWaveInfo->riffChunk.chunkId[]);
  174. printf("chunkSize:%ld\n", pWaveInfo->riffChunk.chunkSize);
  175. printf("format:%c%c%c%c\n", pWaveInfo->riffChunk.format[], pWaveInfo->riffChunk.format[], pWaveInfo->riffChunk.format[], pWaveInfo->riffChunk.format[]);
  176. printf("fmt chunk:\n");
  177. printf("chunkId:%c%c%c\n", pWaveInfo->fmtChunk.chunkId[], pWaveInfo->fmtChunk.chunkId[], pWaveInfo->fmtChunk.chunkId[]);
  178. printf("chunkSize:%ld\n", pWaveInfo->fmtChunk.chunkSize);
  179. printf("audioFormat:%d\n", pWaveInfo->fmtChunk.audioFormat);
  180. printf("chNum:%d\n", pWaveInfo->fmtChunk.chNum);
  181. printf("sampleRate:%ld\n", pWaveInfo->fmtChunk.sampleRate);
  182. printf("byteRate:%ld\n", pWaveInfo->fmtChunk.byteRate);
  183. printf("blockAlign:%d\n", pWaveInfo->fmtChunk.blockAlign);
  184. printf("bitsPerSample:%d\n", pWaveInfo->fmtChunk.bitsPerSample);
  185. printf("data chunk:\n");
  186. printf("chunkId:%c%c%c%c\n", pWaveInfo->dataChunk.chunkId[], pWaveInfo->dataChunk.chunkId[], pWaveInfo->dataChunk.chunkId[], pWaveInfo->dataChunk.chunkId[]);
  187. printf("chunkSize:%ld\n", pWaveInfo->dataChunk.chunkSize);
  188.  
  189. }
  190. void initWaveInfo(WAVE_INFO *pWaveInfo, unsigned short chNum, unsigned long sampleRate, unsigned short bitsPerSample)
  191. {
  192. //strncpy(pWaveInfo->riffChunk.chunkId, "RIFF", 4);
  193. pWaveInfo->riffChunk.chunkId[] = 'R';
  194. pWaveInfo->riffChunk.chunkId[] = 'I';
  195. pWaveInfo->riffChunk.chunkId[] = 'F';
  196. pWaveInfo->riffChunk.chunkId[] = 'F';
  197. pWaveInfo->riffChunk.chunkSize = ;
  198. //strncpy(pWaveInfo->riffChunk.format, "WAVE", 4);
  199. pWaveInfo->riffChunk.format[] = 'W';
  200. pWaveInfo->riffChunk.format[] = 'A';
  201. pWaveInfo->riffChunk.format[] = 'V';
  202. pWaveInfo->riffChunk.format[] = 'E';
  203. //strncpy(pWaveInfo->fmtChunk.chunkId, "fmt", 3);
  204. pWaveInfo->fmtChunk.chunkId[] = 'f';
  205. pWaveInfo->fmtChunk.chunkId[] = 'm';
  206. pWaveInfo->fmtChunk.chunkId[] = 't';
  207. pWaveInfo->fmtChunk.chunkId[] = ' ';
  208. pWaveInfo->fmtChunk.chunkSize = sizeof(WAVE_FMT) - ;
  209. pWaveInfo->fmtChunk.audioFormat = ;
  210. pWaveInfo->fmtChunk.chNum = chNum;
  211. pWaveInfo->fmtChunk.sampleRate = sampleRate;
  212. pWaveInfo->fmtChunk.byteRate = sampleRate * chNum * bitsPerSample / ;
  213. pWaveInfo->fmtChunk.blockAlign = chNum * bitsPerSample / ;
  214. pWaveInfo->fmtChunk.bitsPerSample = bitsPerSample;
  215. //strncpy(pWaveInfo->dataChunk.chunkId, "data", 4);
  216. pWaveInfo->dataChunk.chunkId[] = 'd';
  217. pWaveInfo->dataChunk.chunkId[] = 'a';
  218. pWaveInfo->dataChunk.chunkId[] = 't';
  219. pWaveInfo->dataChunk.chunkId[] = 'a';
  220.  
  221. pWaveInfo->dataChunk.chunkSize = ;
  222. pWaveInfo->totalSampleNum = ;
  223. ///printWaveHeader(pWaveInfo);
  224. }
  225.  
  226. void rwRiffChunk(WAVE_INFO *pWaveInfo, unsigned char fgRead)
  227. {
  228. if (fgRead)
  229. {
  230. fread((char *)&pWaveInfo->riffChunk.chunkId, , , pWaveInfo->fp);
  231. fread((char *)&pWaveInfo->riffChunk.chunkSize, , , pWaveInfo->fp);
  232. fread((char *)&pWaveInfo->riffChunk.format, , , pWaveInfo->fp);
  233. }
  234. else
  235. {
  236. fwrite((char *)&pWaveInfo->riffChunk.chunkId, , , pWaveInfo->fp);
  237. fwrite((char *)&pWaveInfo->riffChunk.chunkSize, , , pWaveInfo->fp);
  238. fwrite((char *)&pWaveInfo->riffChunk.format, , , pWaveInfo->fp);
  239. }
  240. }
  241. void rwFmtChunk(WAVE_INFO *pWaveInfo, unsigned char fgRead)
  242. {
  243. if (fgRead)
  244. {
  245. fread((char *)&pWaveInfo->fmtChunk.chunkId, , , pWaveInfo->fp);
  246. fread((char *)&pWaveInfo->fmtChunk.chunkSize, , , pWaveInfo->fp);
  247. fread((char *)&pWaveInfo->fmtChunk.audioFormat, , , pWaveInfo->fp);
  248. fread((char *)&pWaveInfo->fmtChunk.chNum, , , pWaveInfo->fp);
  249. fread((char *)&pWaveInfo->fmtChunk.sampleRate, , , pWaveInfo->fp);
  250. fread((char *)&pWaveInfo->fmtChunk.byteRate, , , pWaveInfo->fp);
  251. fread((char *)&pWaveInfo->fmtChunk.blockAlign, , , pWaveInfo->fp);
  252. fread((char *)&pWaveInfo->fmtChunk.bitsPerSample, , , pWaveInfo->fp);
  253. }
  254. else
  255. {
  256. fwrite((char *)&pWaveInfo->fmtChunk.chunkId, , , pWaveInfo->fp);
  257. fwrite((char *)&pWaveInfo->fmtChunk.chunkSize, , , pWaveInfo->fp);
  258. fwrite((char *)&pWaveInfo->fmtChunk.audioFormat, , , pWaveInfo->fp);
  259. fwrite((char *)&pWaveInfo->fmtChunk.chNum, , , pWaveInfo->fp);
  260. fwrite((char *)&pWaveInfo->fmtChunk.sampleRate, , , pWaveInfo->fp);
  261. fwrite((char *)&pWaveInfo->fmtChunk.byteRate, , , pWaveInfo->fp);
  262. fwrite((char *)&pWaveInfo->fmtChunk.blockAlign, , , pWaveInfo->fp);
  263. fwrite((char *)&pWaveInfo->fmtChunk.bitsPerSample, , , pWaveInfo->fp);
  264.  
  265. }
  266. }
  267. void rwDataChunk(WAVE_INFO *pWaveInfo, unsigned char fgRead)
  268. {
  269. if (fgRead)
  270. {
  271. fread((char *)&pWaveInfo->dataChunk.chunkId, , , pWaveInfo->fp);
  272. fread((char *)&pWaveInfo->dataChunk.chunkSize, , , pWaveInfo->fp);
  273. }
  274. else
  275. {
  276. fwrite((char *)&pWaveInfo->dataChunk.chunkId, , , pWaveInfo->fp);
  277. fwrite((char *)&pWaveInfo->dataChunk.chunkSize, , , pWaveInfo->fp);
  278. }
  279. }
  280.  
  281. void readWaveHeader(char *fileName, WAVE_INFO *pWaveInfo)
  282. {
  283. size_t retSize;
  284. strncpy(pWaveInfo->fileName, fileName, strlen(fileName));
  285. pWaveInfo->fp = fopen(fileName, "rb");
  286. if (pWaveInfo->fp == NULL)
  287. {
  288. printf("fopen fail, errno:%d\n", errno);
  289. return;
  290. }
  291. #if 0
  292. retSize = fread((char *)&pWaveInfo->riffChunk, sizeof(WAVE_RIFF), , pWaveInfo->fp);
  293. retSize = fread((char *)&pWaveInfo->fmtChunk, sizeof(WAVE_FMT), , pWaveInfo->fp);
  294. retSize = fread((char *)&pWaveInfo->dataChunk, sizeof(WAVE_DATA), , pWaveInfo->fp);
  295. #endif
  296. rwRiffChunk(pWaveInfo, );
  297. rwFmtChunk(pWaveInfo, );
  298. rwDataChunk(pWaveInfo, );
  299. pWaveInfo->pos = ftell(pWaveInfo->fp);
  300. pWaveInfo->totalSampleNum = pWaveInfo->dataChunk.chunkSize / (pWaveInfo->fmtChunk.bitsPerSample / );
  301. fclose(pWaveInfo->fp);
  302. printWaveHeader(pWaveInfo);
  303. }
  304.  
  305. void initPpBuf(unsigned short chNum, unsigned short bankNum, unsigned long samplesPerBank, unsigned short bytesPerSample)
  306. {
  307. unsigned short chIdx, bankIdx;
  308. gPpBuf.chNum = chNum;
  309. gPpBuf.bankNum = bankNum;
  310. gPpBuf.samplesPerBank = samplesPerBank;
  311. gPpBuf.bytesPerSample = bytesPerSample;
  312.  
  313. gPpBuf.bankRp = gPpBuf.bankWp = ;
  314. gPpBuf.fgEos = ;
  315. gPpBuf.pData = (unsigned char ***)malloc(chNum * sizeof(unsigned char **));
  316. for (chIdx = ; chIdx < chNum; chIdx++)
  317. {
  318. gPpBuf.pData[chIdx] = (unsigned char **)malloc(bankNum * sizeof(unsigned char *));
  319. for (bankIdx =; bankIdx < bankNum; bankIdx++)
  320. {
  321. gPpBuf.pData[chIdx][bankIdx] = (unsigned char *) malloc(samplesPerBank * bytesPerSample * sizeof(unsigned char));
  322. }
  323. }
  324. }
  325.  
  326. int sendData(unsigned char *writeBuffer, unsigned short chNum)
  327. {
  328. unsigned short sampleIdx, chIdx, byteIdx;
  329. //printf("sendData, wp:%d, rp:%d\n", gPpBuf.bankWp, gPpBuf.bankRp);
  330. if ((gPpBuf.bankWp + ) % gPpBuf.bankNum == gPpBuf.bankRp)
  331. {
  332. //full
  333. return ;
  334. }
  335. else
  336. {
  337. for (sampleIdx = ; sampleIdx < PP_SAMPLES; sampleIdx++)
  338. {
  339. for (chIdx =; chIdx < chNum; chIdx++)
  340. {
  341. for (byteIdx = ; byteIdx < gPpBuf.bytesPerSample; byteIdx++)
  342. {
  343. gPpBuf.pData[chIdx][gPpBuf.bankWp][sampleIdx * gPpBuf.bytesPerSample + byteIdx] = writeBuffer[(chIdx + sampleIdx * chNum) * gPpBuf.bytesPerSample + byteIdx];
  344. }
  345. }
  346. }
  347. gPpBuf.bankWp = (gPpBuf.bankWp + ) % gPpBuf.bankNum;
  348. }
  349. return ;
  350. }
  351.  
  352. int recvData(unsigned char **readBuffer)
  353. {
  354. unsigned short chIdx;
  355. //printf("recvData, wp:%d, rp:%d\n", gPpBuf.bankWp, gPpBuf.bankRp);
  356. if (gPpBuf.bankWp == gPpBuf.bankRp)
  357. {
  358. //empty
  359. return ;
  360. }
  361. else
  362. {
  363. for (chIdx = ; chIdx < gPpBuf.chNum; chIdx++)
  364. {
  365. memcpy(&readBuffer[chIdx][], &gPpBuf.pData[chIdx][gPpBuf.bankRp][], PP_SAMPLES * gPpBuf.bytesPerSample * sizeof(unsigned char));
  366. }
  367. gPpBuf.bankRp = (gPpBuf.bankRp + ) % gPpBuf.bankNum;
  368. }
  369. return ;
  370. }
  371. void *readThread(void *arg)
  372. {
  373. char *fileName = (char *)arg;
  374. size_t retSize;
  375. WAVE_INFO waveInfo;
  376. memset(&waveInfo, , sizeof(WAVE_INFO));
  377. unsigned long bytesPerLoop;
  378. unsigned short loopIdx, loop;
  379. unsigned long readCount = ;
  380. readWaveHeader(fileName, &waveInfo);
  381. unsigned long readSize = READ_SAMPLES * waveInfo.fmtChunk.chNum * waveInfo.fmtChunk.bitsPerSample / ;
  382. printf("readSize:%ld\n", readSize);
  383. unsigned char *readBuffer = (unsigned char *)malloc(readSize * sizeof(unsigned char));
  384. waveInfo.fp = fopen(fileName, "rb");
  385. fseek(waveInfo.fp, waveInfo.pos, SEEK_SET);
  386. while ()
  387. {
  388. retSize = fread(readBuffer, readSize, , waveInfo.fp);
  389. if (retSize <= )
  390. {
  391. printf("fread fail,retSize:%d, %s, eof:%d, readCount:%ld\n", (int) retSize, strerror(errno), feof(waveInfo.fp), readCount);
  392. gPpBuf.fgEos = ;
  393. break;
  394. }
  395. else
  396. {
  397. bytesPerLoop = PP_SAMPLES *waveInfo.fmtChunk.chNum * waveInfo.fmtChunk.bitsPerSample / ;
  398. loop = readSize / bytesPerLoop;
  399. loopIdx = ;
  400. while (loopIdx < loop)
  401. {
  402. if ( != sendData(readBuffer + loopIdx * bytesPerLoop, waveInfo.fmtChunk.chNum))
  403. {
  404. usleep();
  405. }
  406. else
  407. {
  408. loopIdx++;
  409. }
  410. }
  411. readCount++;
  412. }
  413. }
  414. return NULL;
  415. }
  416. void pp(DATA_INFO_T *pDataInfo)
  417. {
  418. fader(&gFaderHandle, pDataInfo);
  419. }
  420.  
  421. void saveOneChInWave(unsigned char *pData, unsigned long size, WAVE_INFO *pWaveInfo)
  422. {
  423. size_t retSize = ;
  424. if (pWaveInfo->fp == NULL)
  425. {
  426. pWaveInfo->fp = fopen(pWaveInfo->fileName, "wb");
  427. #if 0
  428. retSize = fwrite((char *)&pWaveInfo->riffChunk, sizeof(WAVE_RIFF), , pWaveInfo->fp);
  429. retSize = fwrite((char *)&pWaveInfo->fmtChunk, sizeof(WAVE_FMT), , pWaveInfo->fp);
  430. retSize = fwrite((char *)&pWaveInfo->dataChunk, sizeof(WAVE_DATA), , pWaveInfo->fp);
  431. #endif
  432. rwRiffChunk(pWaveInfo, );
  433. rwFmtChunk(pWaveInfo, );
  434. rwDataChunk(pWaveInfo, );
  435. }
  436. retSize = fwrite(pData, size, , pWaveInfo->fp);
  437. pWaveInfo->totalSampleNum += (size / pWaveInfo->fmtChunk.chNum / (pWaveInfo->fmtChunk.bitsPerSample / ));
  438. pWaveInfo->pos = ftell(pWaveInfo->fp);
  439. }
  440.  
  441. void updateWaveHeader(WAVE_INFO *pWaveInfo)
  442. {
  443. size_t retSize;
  444. pWaveInfo->riffChunk.chunkSize = pWaveInfo->pos - ;
  445. pWaveInfo->dataChunk.chunkSize = pWaveInfo->totalSampleNum * pWaveInfo->fmtChunk.chNum * pWaveInfo->fmtChunk.bitsPerSample / ;
  446. fseek(pWaveInfo->fp, , SEEK_SET);
  447. #if 0
  448. retSize = fwrite((char *)&pWaveInfo->riffChunk, sizeof(WAVE_RIFF), , pWaveInfo->fp);
  449. retSize = fwrite((char *)&pWaveInfo->fmtChunk, sizeof(WAVE_FMT), , pWaveInfo->fp);
  450. retSize = fwrite((char *)&pWaveInfo->dataChunk, sizeof(WAVE_DATA), , pWaveInfo->fp);
  451. #endif
  452. rwRiffChunk(pWaveInfo, );
  453. rwFmtChunk(pWaveInfo, );
  454. rwDataChunk(pWaveInfo, );
  455. fclose(pWaveInfo->fp);
  456.  
  457. printWaveHeader(pWaveInfo);
  458. }
  459. void *ppThread(void *arg)
  460. {
  461. char *fileName = (char *)arg;
  462. WAVE_INFO waveInfo;
  463. memset(&waveInfo, , sizeof(waveInfo));
  464. strncpy(waveInfo.fileName, fileName, strlen(fileName));
  465. printf("out file:%s\n", waveInfo.fileName);
  466. waveInfo.fp = NULL;
  467. initWaveInfo(&waveInfo, , , );
  468. unsigned char **readBuffer = (unsigned char **)malloc(gPpBuf.chNum * sizeof(unsigned char *));
  469. unsigned short chIdx;
  470. for(chIdx = ; chIdx < gPpBuf.chNum; chIdx++)
  471. {
  472. readBuffer[chIdx] = (unsigned char *)malloc(PP_SAMPLES * gPpBuf.bytesPerSample * sizeof(unsigned char));
  473. }
  474. while ()
  475. {
  476. if ( != recvData(readBuffer))
  477. {
  478. if (gPpBuf.fgEos)
  479. break;
  480. usleep();
  481. }
  482. else
  483. {
  484. DATA_INFO_T dataInfo;
  485. dataInfo.chNum = gPpBuf.chNum;
  486. dataInfo.samples = PP_SAMPLES;
  487. dataInfo.bytesPerSample = gPpBuf.bytesPerSample;
  488. dataInfo.pData = (short **)readBuffer;
  489. pp(&dataInfo);
  490. saveOneChInWave(readBuffer[], PP_SAMPLES * gPpBuf.bytesPerSample, &waveInfo);
  491. }
  492. }
  493. updateWaveHeader(&waveInfo);
  494. fgEnd = ;
  495. }
  496.  
  497. int main(int argc, char **argv)
  498. {
  499. #if 0
  500. WAVE_INFO inputWaveInfo, outputWaveInfo;
  501. readWaveHeader(argv[], &inputWaveInfo);
  502. //initWaveInfo(&outputWaveInfo, 2, 48000, 16);
  503. #endif
  504.  
  505. #if 1
  506. pthread_t readThreadId, ppThreadId;
  507. initPpBuf(, , PP_SAMPLES, );
  508. memset(&gFaderHandle, , sizeof(FADER_HANDLE_T));
  509. float curVolumDb = -;
  510. float attuationDb = ;
  511. FADER_TYPE_E type = FADER_TYPE_LINE;
  512. unsigned long timeMs = ;
  513. unsigned long sampleRate = ;
  514. faderInit(&gFaderHandle, attuationDb, type, timeMs, sampleRate, curVolumDb);
  515. pthread_create(&readThreadId, NULL, readThread, argv[]);
  516. pthread_create(&ppThreadId, NULL, ppThread, argv[]);
  517. while(!fgEnd)
  518. {
  519. sleep();
  520. }
  521. #endif
  522. return ;
  523. }

fader的更多相关文章

  1. 关于 CSS 反射倒影的研究思考

    原文地址:https://css-tricks.com/state-css-reflections 译者:nzbin 友情提示:由于演示 demo 的兼容性,推荐火狐浏览.该文章篇幅较长,内容庞杂,有 ...

  2. jQuery动画高级用法——详解animation中的.queue()函数

    http://www.cnblogs.com/zhwl/p/4328279.html $('#object').hide('slow').queue(function(next){     $(thi ...

  3. Audio 的一些小笔记

    1.在做项目的过程中,对于volume 我们有一个volume curve,就是 0~63 step,每个step对应一个dB值,例如0step对应-90dB, 63 step对应0dB.关于这个0d ...

  4. Stealth视频教程学习笔记(第一章)

    Stealth视频教程学习笔记(第一章) 本文是对Unity官方视频教程Stealth的学习笔记.在此之前,本人整理了Stealth视频的英文字幕,并放到了优酷上.本文将分别对各个视频进行学习总结,提 ...

  5. Android Animation学习(三) ApiDemos解析:XML动画文件的使用

    Android Animation学习(三) ApiDemos解析:XML动画文件的使用 可以用XML文件来定义Animation. 文件必须有一个唯一的根节点: <set>, <o ...

  6. FadeTop – 定时休息提醒工具

    FadeTop 是款定时休息提醒工具,其特色是当设定时间到达时,将桌面渐变为指定的颜色,强制提醒但不影响桌面的任何操作 FadeTop is a visual break reminder for W ...

  7. 【JQuery NoviceToNinja系列】01 开篇 Html页面设计和布局

    01 开篇 Html页面设计和布局 index.html <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml ...

  8. Flex “跑马灯”效果(自定义“跑马灯”控件)

    自定义类(BroadCastMarquee.as): package marquee { import flash.events.MouseEvent; import flash.events.Tim ...

  9. jQuery动画高级用法(上)——详解animation中的.queue()动画队列插队函数

    决定对animate方面做一些总结,希望能给大家一些启发和帮助 从一个实际应用谈起 今天不谈animate().fadeIn().fadeOut().slideUp().show().hide()诸如 ...

随机推荐

  1. PAT (Basic Level) Practice (中文)1047 编程团体赛 (20 分)

    编程团体赛的规则为:每个参赛队由若干队员组成:所有队员独立比赛:参赛队的成绩为所有队员的成绩和:成绩最高的队获胜. 现给定所有队员的比赛成绩,请你编写程序找出冠军队. 输入格式: 输入第一行给出一个正 ...

  2. 在Windows启动pyspark shell:Failed to find Spark jars directory. You need to build Spark before running this program

    D:\Develop tools\spark-2.2.0-bin-hadoop2.7\bin>pyspark2.cmd 'tools\spark-2.2.0-bin-hadoop2.7\bin\ ...

  3. 【Vue2.x笔记3】从源码看watch对象

    初始化 function initWatch (vm: Component, watch: Object) { for (const key in watch) { const handler = w ...

  4. SYZOJP186 你猜猜是不是DP 二分+hash解法

    SYZOJP186 你猜猜是不是DP题解 题目传送门 现在给两个仅包含小写字母的字符串a,b ,求a 与b的最长公共连续子串的长度. 对于20%的数据,a,b长度 ∈ [1, 200] 对于50%的数 ...

  5. C++-POJ3070-Fibonacci-[矩阵乘法][快速幂]

    #include <cstdio> ][];}; ,MOD=1e4; Matrix A,B,O,I; Matrix Mul(Matrix A,Matrix B){ Matrix C=O; ...

  6. shell变量内字符替换和变量字符修改

    vi test.sh a= #将${a}里的第一个123替换为321 b=${a//}; echo "echo variable a" echo $a echo "ech ...

  7. Winform form窗体已弹出框的形式出现并回传值

    From2(弹出框)回传数据到From1 Form1(数据接收form): public string Sstr; private void button1_Click(object sender, ...

  8. flask操作

    models.py class CompanyGoodsModel(Base): id=Column(Integer, primary_key=True) company_id = Column(In ...

  9. MySQL 分组并多行拼接 group_concat 用法

    数据源 user name     age 小红 18 小明 18 小芳 19 ------------------------------------------------------------ ...

  10. 一点点学习PS--实战三

    本节实战,练习多张图片合成,调色相饱和度,剪贴蒙版的使用场景,人物内发光,人物轮廓光以及多种图层混合模式的使用,深入了解图层蒙版 1.工具使用 (1)多边形套锁工具:适用于棱角分明的抠图区域,选中了区 ...