lpc_test2_main.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. /*************************************************************************/
  2. /* */
  3. /* Language Technologies Institute */
  4. /* Carnegie Mellon University */
  5. /* Copyright (c) 2001 */
  6. /* All Rights Reserved. */
  7. /* */
  8. /* Permission is hereby granted, free of charge, to use and distribute */
  9. /* this software and its documentation without restriction, including */
  10. /* without limitation the rights to use, copy, modify, merge, publish, */
  11. /* distribute, sublicense, and/or sell copies of this work, and to */
  12. /* permit persons to whom this work is furnished to do so, subject to */
  13. /* the following conditions: */
  14. /* 1. The code must retain the above copyright notice, this list of */
  15. /* conditions and the following disclaimer. */
  16. /* 2. Any modifications must be clearly marked as such. */
  17. /* 3. Original authors' names are not deleted. */
  18. /* 4. The authors' names are not used to endorse or promote products */
  19. /* derived from this software without specific prior written */
  20. /* permission. */
  21. /* */
  22. /* CARNEGIE MELLON UNIVERSITY AND THE CONTRIBUTORS TO THIS WORK */
  23. /* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */
  24. /* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
  25. /* SHALL CARNEGIE MELLON UNIVERSITY NOR THE CONTRIBUTORS BE LIABLE */
  26. /* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
  27. /* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */
  28. /* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
  29. /* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */
  30. /* THIS SOFTWARE. */
  31. /* */
  32. /*************************************************************************/
  33. /* Author: Alan W Black (awb@cs.cmu.edu) */
  34. /* Date: June 2001 */
  35. /*************************************************************************/
  36. /* */
  37. /* residuals etc */
  38. /* */
  39. /*************************************************************************/
  40. #include <stdio.h>
  41. #include <math.h>
  42. #include "cst_wave.h"
  43. #include "cst_track.h"
  44. #include "cst_sigpr.h"
  45. void inv_lpc_filterd(short *sig, float *a, int order, double *res, int size)
  46. {
  47. int i, j;
  48. double r;
  49. for (i = 0; i < order; i++)
  50. {
  51. r = sig[i];
  52. for (j = 1; j < order; j++)
  53. /* if (i-j >= 0) */
  54. r -= a[j] * (double)sig[i - j];
  55. res[i] = r;
  56. }
  57. for (i = order; i < size; i++)
  58. {
  59. r = sig[i];
  60. for (j = 1; j < order; j++)
  61. r -= a[j] * (double)sig[i - j];
  62. res[i] = r;
  63. }
  64. }
  65. cst_wave *find_residual(cst_wave *sig, cst_track *lpc)
  66. {
  67. cst_wave *res;
  68. int i;
  69. double *resd;
  70. int size,start,end;
  71. res = new_wave();
  72. cst_wave_resize(res,sig->num_samples,1);
  73. res->sample_rate = sig->sample_rate;
  74. resd = cst_alloc(double,sig->num_samples);
  75. start = lpc->num_channels;
  76. for (i=0; i<lpc->num_frames; i++)
  77. {
  78. end = (int)((float)sig->sample_rate * lpc->times[i]);
  79. size = end - start;
  80. inv_lpc_filterd(&sig->samples[start],lpc->frames[i],lpc->num_channels,
  81. &resd[start],size);
  82. start = end;
  83. }
  84. for (i=0; i<res->num_samples; i++)
  85. res->samples[i] = resd[i];
  86. cst_free(resd);
  87. return res;
  88. }
  89. void lpc_filterd(short *res, float *a, int order, double *sig, int size)
  90. {
  91. int i, j;
  92. double r;
  93. for (i = 0; i < order; i++)
  94. {
  95. r = res[i];
  96. for (j = 1; j < order; j++)
  97. /* if (i-j >= 0) */
  98. r += a[j] * (double)sig[i - j];
  99. sig[i] = r;
  100. }
  101. for (i = order; i < size; i++)
  102. {
  103. r = res[i];
  104. for (j = 1; j < order; j++)
  105. r += a[j] * (double)sig[i - j];
  106. sig[i] = r;
  107. }
  108. }
  109. cst_wave *reconstruct_wave(cst_wave *res, cst_track *lpc)
  110. {
  111. cst_wave *sig;
  112. int i;
  113. double *sigd;
  114. int start, end, size;
  115. sig = new_wave();
  116. cst_wave_resize(sig,res->num_samples,1);
  117. sig->sample_rate = res->sample_rate;
  118. sigd = cst_alloc(double,sig->num_samples);
  119. start = 0;
  120. for (i=0; i<lpc->num_frames; i++)
  121. {
  122. end = (int)((float)sig->sample_rate * lpc->times[i]);
  123. size = end - start;
  124. lpc_filterd(&res->samples[start],
  125. lpc->frames[i],lpc->num_channels,
  126. &sigd[start],size);
  127. start = end;
  128. }
  129. for (i=0; i<sig->num_samples; i++)
  130. sig->samples[i] = sigd[i];
  131. cst_free(sigd);
  132. return sig;
  133. }
  134. float lpc_min = -2.709040;
  135. float lpc_range = 2.328840+2.709040;
  136. void lpc_filterde(unsigned char *resulaw,
  137. unsigned short *as, int order,
  138. short *sig,
  139. int size)
  140. {
  141. int i, j;
  142. float r;
  143. float *a;
  144. float *sigf;
  145. a = cst_alloc(float,order);
  146. for (i=1; i<order; i++)
  147. a[i] = (((float)as[i]/65535.0)*lpc_range)+lpc_min;
  148. sigf = cst_alloc(float,size);
  149. for (i=0; i<size; i++)
  150. sigf[i] = sig[i];
  151. for (i = 0; i < order; i++)
  152. {
  153. r = cst_ulaw_to_short(resulaw[i]);
  154. for (j = 1; j < order; j++)
  155. /* if (i-j >= 0) */
  156. r += a[j] * (float)sigf[i - j];
  157. sigf[i] = r;
  158. }
  159. for (i = order; i < size; i++)
  160. {
  161. r = cst_ulaw_to_short(resulaw[i]);
  162. for (j = 1; j < order; j++)
  163. r += a[j] * (float)sigf[i - j];
  164. sigf[i] = r;
  165. }
  166. for (i=0; i<size; i++)
  167. sig[i] = sigf[i];
  168. cst_free(sigf);
  169. /* cst_free(a); */
  170. }
  171. cst_wave *reconstruct_wavee(cst_wave *res, cst_track *lpc)
  172. {
  173. cst_wave *sig;
  174. int i,j;
  175. short *sigd;
  176. int start, end, size;
  177. unsigned short *as;
  178. unsigned char *resulaw;
  179. sig = new_wave();
  180. cst_wave_resize(sig,res->num_samples,1);
  181. sig->sample_rate = res->sample_rate;
  182. sigd = cst_alloc(short,sig->num_samples);
  183. as = cst_alloc(unsigned short,lpc->num_channels);
  184. resulaw = cst_alloc(unsigned char, res->num_samples);
  185. for (i=0; i<res->num_samples; i++)
  186. resulaw[i] = cst_short_to_ulaw(res->samples[i]);
  187. start = 0;
  188. for (i=0; i<lpc->num_frames; i++)
  189. {
  190. end = (int)((float)sig->sample_rate * lpc->times[i]);
  191. size = end - start;
  192. for (j=1; j<lpc->num_channels; j++)
  193. as[j] = (((lpc->frames[i][j]-lpc_min)/lpc_range)*65535.0);
  194. lpc_filterde(&resulaw[start],
  195. as,lpc->num_channels,
  196. &sigd[start],size);
  197. start = end;
  198. }
  199. for (i=0; i<sig->num_samples; i++)
  200. sig->samples[i] = sigd[i];
  201. cst_free(sigd);
  202. return sig;
  203. }
  204. cst_wave *dumdum(cst_wave *res,cst_track *lpc)
  205. {
  206. cst_lpcres *lpcres;
  207. int i,j,s;
  208. unsigned short *bbb;
  209. int start,end,size;
  210. FILE *ofd;
  211. lpcres = new_lpcres();
  212. lpcres_resize_frames(lpcres,lpc->num_frames);
  213. lpcres->num_channels = lpc->num_channels-1;
  214. start = 0;
  215. for (i=0; i<lpc->num_frames; i++)
  216. {
  217. bbb = cst_alloc(unsigned short,lpc->num_channels-1);
  218. for (j=1; j<lpc->num_channels; j++)
  219. bbb[j-1] = (unsigned short)
  220. (((lpc->frames[i][j]-lpc_min)/lpc_range)*65535);
  221. lpcres->frames[i] = bbb;
  222. end = lpc->times[i]*res->sample_rate;
  223. lpcres->times[i] = lpc->times[i];
  224. size = end - start;
  225. lpcres->sizes[i] = size;
  226. start = end;
  227. }
  228. lpcres_resize_samples(lpcres,res->num_samples);
  229. lpcres->lpc_min = lpc_min;
  230. lpcres->lpc_range = lpc_range;
  231. lpcres->sample_rate = res->sample_rate;
  232. for (i=0; i<res->num_samples; i++)
  233. lpcres->residual[i] = cst_short_to_ulaw(res->samples[i]);
  234. ofd = fopen("lpc1.lpc","w");
  235. for (s=0,i=0; i<lpcres->num_frames; i++)
  236. {
  237. fprintf(ofd,"%d %d %d\n",i,lpcres->times[i],lpcres->sizes[i]);
  238. for (j=0; j < lpcres->num_channels; j++)
  239. fprintf(ofd,"%d ",lpcres->frames[i][j]);
  240. fprintf(ofd,"\n");
  241. for (j=0; j < lpcres->sizes[i]; j++,s++)
  242. fprintf(ofd,"%d ",lpcres->residual[s]);
  243. fprintf(ofd,"\n");
  244. }
  245. fclose(ofd);
  246. return lpc_resynth(lpcres);
  247. }
  248. int main(int argc, char **argv)
  249. {
  250. /* need that cool argument parser */
  251. cst_wave *w,*res,*sig,*w2, *w3;
  252. cst_track *lpc;
  253. int i;
  254. double r;
  255. if (argc != 3)
  256. {
  257. fprintf(stderr,"usage: lpc_test2 LPC WAVEFILE\n");
  258. return 1;
  259. }
  260. lpc = new_track();
  261. cst_track_load_est(lpc,argv[1]);
  262. sig = new_wave();
  263. cst_wave_load_riff(sig,argv[2]);
  264. res = find_residual(sig,lpc);
  265. w = reconstruct_wave(res,lpc);
  266. cst_wave_save_riff(res,"res.wav");
  267. cst_wave_save_riff(w,"new.wav");
  268. w2 = reconstruct_wavee(res,lpc);
  269. cst_wave_save_riff(w2,"newe.wav");
  270. w3 = dumdum(res,lpc);
  271. cst_wave_save_riff(w3,"newr.wav");
  272. for (r=0.0,i=0; i<sig->num_samples; i++)
  273. r += ((float)sig->samples[i]-(float)w->samples[i]) *
  274. ((float)sig->samples[i]-(float)w->samples[i]);
  275. r /= sig->num_samples;
  276. printf("orig/new %f\n",sqrt(r));
  277. for (r=0.0,i=0; i<sig->num_samples; i++)
  278. r += ((float)sig->samples[i]-(float)w2->samples[i]) *
  279. ((float)sig->samples[i]-(float)w2->samples[i]);
  280. r /= sig->num_samples;
  281. printf("orig/newe %f\n",sqrt(r));
  282. for (r=0.0,i=0; i<sig->num_samples; i++)
  283. r += ((float)sig->samples[i]-(float)w3->samples[i]) *
  284. ((float)sig->samples[i]-(float)w3->samples[i]);
  285. r /= sig->num_samples;
  286. printf("orig/newr %f\n",sqrt(r));
  287. return 0;
  288. }