lpcomb.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  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. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <math.h>
  23. //lpcomb.cpp
  24. extern "C" {
  25. #include <sfsys.h>
  26. #include <cdplib.h> //NB requires stdio.h etc - time to change this?
  27. }
  28. #include "reverberator.h"
  29. //straight from Csound: nreverb (vdelay.c)
  30. static bool prime( int val )
  31. {
  32. int i, last;
  33. last = (int)sqrt( (double)val );
  34. for ( i = 3; i <= last; i+=2 ) {
  35. if ( (val % i) == 0 ) return false;
  36. }
  37. return true;
  38. }
  39. static int to_prime(double dur,double sr)
  40. {
  41. int time = (int) (dur * sr);
  42. if(time % 2== 0) time += 1;
  43. while(!prime(time))
  44. time +=2;
  45. return time;
  46. }
  47. void
  48. usage()
  49. {
  50. printf("\nusage: lpcomb infile outfile looptime rvbtime filtgain");
  51. exit(0);
  52. }
  53. void
  54. main(int argc,char *argv[])
  55. {
  56. int ifd, ofd;
  57. //double delaytime,gain;
  58. double rvbtime,gain2,filtgain,dloop;
  59. long isr,chans,sampsize,ilooptime;
  60. double sr;
  61. lpcomb *comb1 = 0;
  62. if(sflinit("lpcomb")){
  63. sfperror("lpcomb: initialisation");
  64. exit(1);
  65. }
  66. if(argc < 6)
  67. usage();
  68. dloop = atof(argv[3]);
  69. if(dloop <= 0.0){
  70. fprintf(stderr,"\nlpcomb: invalid looptime parameter");
  71. exit(1);
  72. }
  73. rvbtime = atof(argv[4]);
  74. if(rvbtime <= 0.0){
  75. fprintf(stderr,"\nlpcomb: invalid delay parameter");
  76. exit(1);
  77. }
  78. filtgain = atof(argv[5]);
  79. if((filtgain < 0.0) || (filtgain > 1.0)){
  80. fprintf(stderr,"\nlpcomb: filter gain %lf out of range",filtgain);
  81. exit(1);
  82. }
  83. if(argv[1] != 0) {
  84. if((ifd = sndopen(argv[1])) < 0) {
  85. fprintf(stderr,"Allpass: cannot open input file %s\n", argv[1]);
  86. exit(1);
  87. }
  88. }
  89. if(sndgetprop(ifd,"sample rate",(char *) &isr, sizeof(long)) < 0){
  90. fprintf(stderr,
  91. "\nAllpass: failed to read sample rate for file %s",argv[1]);
  92. exit(1);
  93. }
  94. sr = (double) (isr);
  95. if(sndgetprop(ifd,"channels",(char *) &chans, sizeof(long)) < 0){
  96. fprintf(stderr,
  97. "\nAllpass: failed to read channel data for file %s", argv[1]);
  98. exit(1);
  99. }
  100. if(chans != 1){
  101. fprintf(stderr,"\nAllpass works only on mono files");
  102. exit(1);
  103. }
  104. if(sndgetprop(ifd,"sample type",(char *) &sampsize, sizeof(long)) < 0){
  105. fprintf(stderr,
  106. "\nAllpass: failed to read sample type for file %s", argv[1]);
  107. exit(1);
  108. }
  109. if((ofd = sndcreat(argv[2],-1,sampsize)) < 0) {
  110. fprintf(stderr,"Cannot open output file %s\n",argv[2]);
  111. exit(1);
  112. }
  113. ilooptime = to_prime(dloop, sr);
  114. gain2 = exp( log(0.001)* (dloop/rvbtime)) * (1. - filtgain) ;
  115. printf("\ngain2 = %lf\tfiltgain = %lf",gain2,filtgain);
  116. comb1 = new lpcomb(ilooptime,gain2,filtgain,1.0);
  117. if(!comb1->create()){
  118. printf("\nFailed to create comb filter");
  119. exit(1);
  120. }
  121. stopwatch(1);
  122. for(;;){
  123. int rv;
  124. float ip,op;
  125. if((rv = fgetfloat(&ip,ifd)) < 0){
  126. fprintf(stderr,"\nError in reading file");
  127. exit(1);
  128. }
  129. if(!rv)
  130. break;
  131. op = comb1->tick(ip);
  132. if(fputfloat(&op,ofd) < 1){
  133. fprintf(stderr,"\nError writing to output file");
  134. exit(1);
  135. }
  136. }
  137. stopwatch(0);
  138. sndclose(ifd);
  139. if(sndputprop(ofd,"sample rate", (char *) &isr, sizeof(long)) < 0){
  140. fprintf(stderr,"\nAllpass: failed to write sample rate");
  141. }
  142. if(sndputprop(ofd,"channels",(char *) &chans, sizeof(long)) < 0){
  143. fprintf(stderr,"\nAllpass: failed to write channel data");
  144. }
  145. sndclose(ofd);
  146. delete comb1;
  147. sffinish();
  148. }