genrespframe2.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /*
  2. * Copyright (c) 1983-2013 Richard Dobson and Composers Desktop Project Ltd
  3. * http://people.bath.ac.uk/masrwd
  4. * http://www.composersdesktop.com
  5. * This file is part of the CDP System.
  6. * The CDP System is free software; you can redistribute it
  7. * and/or modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * The CDP System is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  14. * See the GNU Lesser General Public License for more details.
  15. * You should have received a copy of the GNU Lesser General Public
  16. * License along with the CDP System; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. *
  19. */
  20. /* genrespframe2.cpp */
  21. /* generate m/c pvoc frames containing impulse response */
  22. extern "C"
  23. {
  24. #include <portsf.h>
  25. }
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <math.h>
  29. #include <string.h>
  30. #ifdef _DEBUG
  31. #include <assert.h>
  32. #endif
  33. /* deinterleave input buffer of insize samps to array of chans buffers */
  34. void mc_split(double* inbuf,double** out,int insize,int chans);
  35. extern "C"{
  36. void fft_(double *, double *,int,int,int,int);
  37. void fftmx(double *,double *,int,int,int,int,int,int *,double *,double *,double *,double *,int *,int[]);
  38. void reals_(double *,double *,int,int);
  39. }
  40. /* read impulse data from soundfile */
  41. /* return 0 for error, or size of impulse */
  42. /*we assume pvsys initialized by caller */
  43. int genimpframe2(int ifd, double*** outbufs, double* rms,int imchans, double scalefac)
  44. {
  45. int i,j;
  46. double *insbuf = 0;
  47. double **inbuf = *outbufs;
  48. int fftsize = 1;
  49. int inframes;
  50. double* rmsfac = 0;
  51. double* ampsum = 0;
  52. double maxrmsfac = 0.0;
  53. #ifdef _DEBUG
  54. double *re,*im,*mag, maxampsum;
  55. #endif
  56. inframes = psf_sndSize(ifd); // m/c frames
  57. if(inframes <= 0)
  58. return 0;
  59. while(fftsize < inframes*2) /* convolution style - double-length */
  60. fftsize <<= 1;
  61. printf("impulse length = %d frames, fftsize = %d\n",inframes,fftsize);
  62. insbuf = new double[inframes * imchans];
  63. #ifdef _DEBUG
  64. re = new double[fftsize/2+1];
  65. im = new double[fftsize/2+1];
  66. mag = new double[fftsize/2+1];
  67. #endif
  68. for(i=0;i < imchans;i++){
  69. inbuf[i] = new double[fftsize+2];
  70. if(inbuf[i]==NULL){
  71. puts("no memory for file buffer!\n");
  72. return 0;
  73. }
  74. memset(inbuf[i],0,(fftsize+2)* sizeof(double));
  75. }
  76. if(inframes != psf_sndReadDoubleFrames(ifd,insbuf,inframes)){
  77. fprintf(stderr,"Error reading impulse data\n");
  78. delete [] insbuf;
  79. // and do other cleanup!
  80. return 0;
  81. }
  82. rmsfac = new double[imchans];
  83. ampsum = new double[imchans];
  84. for(i=0;i< imchans;i++) {
  85. rmsfac[i] = 0.0;
  86. ampsum[i] = 0.0;
  87. }
  88. /* do user scaling first */
  89. for(i = 0;i < inframes * imchans;i++)
  90. insbuf[i] *= scalefac;
  91. /* now try to adjust rms */
  92. for(i = 0;i < inframes;i++) {
  93. for(j=0;j < imchans;j++){
  94. double val = insbuf[i*imchans + j];
  95. ampsum[j] += fabs(val);
  96. rmsfac[j] += val*val;
  97. }
  98. }
  99. for(j=0;j < imchans;j++){
  100. // rmsfac = sqrt(rmsfac);
  101. rmsfac[j] /= inframes;
  102. rmsfac[j] = sqrt(rmsfac[j]);
  103. ampsum[j] /= inframes;
  104. if(rmsfac[j] > maxrmsfac)
  105. maxrmsfac = rmsfac[j];
  106. #ifdef _DEBUG
  107. if(ampsum[j] > maxampsum)
  108. maxampsum = ampsum[j];
  109. #endif
  110. }
  111. /* do the rescaling! */
  112. #ifdef _DEBUG
  113. printf("ampsum = %.4f\n",maxampsum);
  114. #endif
  115. // now deinterleave to each inbuf
  116. mc_split(insbuf,inbuf,inframes * imchans,imchans);
  117. for(i=0;i < imchans;i++){
  118. double *anal = inbuf[i];
  119. //rfftwnd_one_real_to_complex(forward_plan[i],inbuf[i],NULL);
  120. fft_(anal,anal+1,1,fftsize/2,1,-2);
  121. reals_(anal,anal+1,fftsize/2,-2);
  122. }
  123. #ifdef _DEBUG
  124. /* in order to look at it all */
  125. double magmax = 0.0;
  126. double magsum = 0.0;
  127. for(i=0;i < fftsize/2+1;i++){
  128. double thisre, thisim;
  129. thisre =inbuf[0][i*2];
  130. thisim = inbuf[0][i*2+1];
  131. re[i] = thisre;
  132. im[i] = thisim;
  133. mag[i] = sqrt(thisre*thisre + thisim*thisim);
  134. magsum += (mag[i] * mag[i]);
  135. if(mag[i] > magmax)
  136. magmax = mag[i];
  137. }
  138. magsum = sqrt(magsum);
  139. printf("maxamp of FFT = %.4f\n",magmax);
  140. printf("mean level of FFT = %.4f\n",magsum / (fftsize/2+1));
  141. #endif
  142. delete [] rmsfac;
  143. delete [] ampsum;
  144. #ifdef _DEBUG
  145. delete [] re;
  146. delete [] im;
  147. delete [] mag;
  148. #endif
  149. *rms = maxrmsfac;
  150. return inframes;
  151. }
  152. /* convert from input double buffer (read from mono text impulse file) */
  153. int genimpframe1(double *insbuf, double*** outbuf, int npoints, double scalefac)
  154. {
  155. int i;
  156. double **inbuf = *outbuf;
  157. int fftsize = 1;
  158. int insamps;
  159. #ifdef _DEBUG
  160. double *re,*im,*mag;
  161. #endif
  162. insamps = npoints; // m/c frames
  163. if(insamps <= 0)
  164. return 0;
  165. while(fftsize < insamps*2) /* convolution style - double-length */
  166. fftsize <<= 1;
  167. printf("infile size = %d,impulse framesize = %d\n",insamps,fftsize);
  168. #ifdef _DEBUG
  169. re = new double[fftsize/2+1];
  170. im = new double[fftsize/2+1];
  171. mag = new double[fftsize/2+1];
  172. #endif
  173. inbuf[0] = new double[fftsize+2];
  174. if(inbuf[0]==NULL){
  175. puts("no memory for file buffer!\n");
  176. return 0;
  177. }
  178. memset(inbuf[0],0,(fftsize+2)* sizeof(double));
  179. #ifdef _DEBUG
  180. double ampsum = 0.0;
  181. #endif
  182. for(i = 0;i < insamps;i++) {
  183. #ifdef _DEBUG
  184. ampsum += fabs(insbuf[i]);
  185. #endif
  186. insbuf[i] *= scalefac;
  187. }
  188. #ifdef _DEBUG
  189. printf("amplitude sum of impulse file = %f\n",ampsum);
  190. #endif
  191. memcpy(inbuf[0],insbuf,npoints* sizeof(double));
  192. //rfftwnd_one_real_to_complex(forward_plan,inbuf[0],NULL);
  193. double *anal = inbuf[0];
  194. fft_(anal,anal+1,1,fftsize/2,1,-2);
  195. reals_(anal,anal+1,fftsize/2,-2);
  196. #ifdef _DEBUG
  197. /* in order to look at it all */
  198. for(i=0;i < fftsize/2+1;i++){
  199. double thisre, thisim;
  200. thisre =inbuf[0][i*2];
  201. thisim = inbuf[0][i*2+1];
  202. re[i] = thisre;
  203. im[i] = thisim;
  204. mag[i] = sqrt(thisre*thisre + thisim*thisim);
  205. }
  206. #endif
  207. #ifdef _DEBUG
  208. delete [] re;
  209. delete [] im;
  210. delete [] mag;
  211. #endif
  212. return insamps;
  213. }