brkdur.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. /*
  2. * Copyright (c) 1983-2013 Trevor Wishart and Composers Desktop Project Ltd
  3. * http://www.trevorwishart.co.uk
  4. * http://www.composersdesktop.com
  5. *
  6. This file is part of the CDP System.
  7. The CDP System is free software; you can redistribute it
  8. and/or modify it under the terms of the GNU Lesser General Public
  9. License as published by the Free Software Foundation; either
  10. version 2.1 of the License, or (at your option) any later version.
  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. See the
  14. 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
  18. 02111-1307 USA
  19. *
  20. */
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <ctype.h>
  24. #include <math.h>
  25. #include <string.h>
  26. #define CALCLIM (0.00002)
  27. #define FLTERR (0.00002)
  28. #define ONE_OVER_LN2 (1.442695)
  29. #define BIGARRAY 200
  30. #define ENDOFSTR ('\0')
  31. #define NEWLINE ('\n')
  32. int read_brkdata(double **bbrk,FILE *fp,int mode);
  33. void get_dur(double *bbrk,int bbrksize,double in_dur,int mode);
  34. double cntevents(double dur,double s0,double s1);
  35. int sizeq(double f1,double f2);
  36. int get_float_from_within_string(char **str,double *val);
  37. //double round(double a);
  38. int flteq(double a,double b);
  39. const char* cdp_version = "7.1.0";
  40. int main(int argc,char * argv [])
  41. {
  42. double *bbrk, in_dur;
  43. FILE *fp;
  44. int bbrksize, mode;
  45. if(argc==2 && (strcmp(argv[1],"--version") == 0)) {
  46. fprintf(stdout,"%s\n",cdp_version);
  47. fflush(stdout);
  48. return 0;
  49. }
  50. if(argc!=4) {
  51. fprintf(stdout,"ERROR: Bad function call.\n");
  52. fflush(stdout);
  53. return(0);
  54. }
  55. if(sscanf(argv[2],"%d",&mode)!=1) {
  56. fprintf(stdout,"ERROR: Failed to read mode.\n");
  57. fflush(stdout);
  58. return(0);
  59. }
  60. if(sscanf(argv[3],"%lf",&in_dur)!=1) {
  61. fprintf(stdout,"ERROR: Failed to read input file duration.\n");
  62. fflush(stdout);
  63. return(0);
  64. }
  65. if((fp = fopen(argv[1],"r"))==NULL) {
  66. fprintf(stdout,"ERROR: Failed to open file %s\n",argv[1]);
  67. fflush(stdout);
  68. return(0);
  69. }
  70. if((bbrksize = read_brkdata(&bbrk,fp,mode))<=0)
  71. return(0);
  72. get_dur(bbrk,bbrksize,in_dur,mode);
  73. return(1);
  74. }
  75. void get_dur(double *bbrk,int bbrksize,double in_dur,int mode)
  76. {
  77. int n, m;
  78. double lasttime, lastval, thistime, thisval, newtime = 0;
  79. int done;
  80. double tratio;
  81. /*RWD need init */
  82. thistime = 0;
  83. lasttime = bbrk[0];
  84. lastval = bbrk[1];
  85. if(mode == 1) {
  86. for(n = 1; n <bbrksize * 2; n+=2)
  87. bbrk[n] = pow(2.0,bbrk[n]/12.0);
  88. }
  89. done = 0;
  90. for(m=2,n= 1;n<bbrksize;m+=2,n++) {
  91. thistime = bbrk[m];
  92. thisval = bbrk[m+1];
  93. if((in_dur > 0.0) && (thistime > in_dur)) {
  94. done = 1;
  95. tratio = (in_dur - lasttime)/(thistime - lasttime);
  96. if(!flteq(tratio,0.0)) {
  97. thistime = in_dur;
  98. thisval = ((thisval - lastval) * tratio) + lastval;
  99. newtime += cntevents(thistime - lasttime,lastval,thisval);
  100. }
  101. } else {
  102. newtime += cntevents(thistime - lasttime,lastval,thisval);
  103. }
  104. if(done)
  105. break;
  106. lasttime = thistime;
  107. lastval = thisval;
  108. }
  109. if(!done && (thistime < in_dur)) {
  110. thistime = in_dur;
  111. thisval = lastval;
  112. newtime += cntevents(thistime - lasttime,lastval,thisval);
  113. }
  114. fprintf(stdout,"INFO: DURATION is %lf\n",newtime);
  115. fflush(stdout);
  116. }
  117. /*************************** CNTEVENTS *****************************/
  118. double cntevents(double dur,double s0,double s1)
  119. {
  120. double f1 = dur,f2;
  121. if(sizeq(s1,s0))
  122. return((f1*2.0)/(s1+s0));
  123. f2 = s1-s0;
  124. f1 /= f2;
  125. f2 = s1/s0;
  126. f2 = log(f2);
  127. f1 *= f2;
  128. return(fabs(f1));
  129. }
  130. /**************************** SIZEQ *******************************/
  131. int sizeq(double f1,double f2)
  132. {
  133. double upperbnd, lowerbnd;
  134. upperbnd = f2 + CALCLIM;
  135. lowerbnd = f2 - CALCLIM;
  136. if((f1>upperbnd) || (f1<lowerbnd))
  137. return(0);
  138. return(1);
  139. }
  140. /**************************** READ_BRKDATA *******************************/
  141. int read_brkdata(double **bbrk, FILE *fp,int mode)
  142. {
  143. double *p, *w, zmax, zmin, lasttime = 0; /*RWD added init */
  144. char *q, temp[400];
  145. int is_time = 1, is_insert = 0,cnt = 0;
  146. int arraysize = BIGARRAY;
  147. if(mode == 1) {
  148. zmax = 120.0;
  149. zmin = -120.0;
  150. } else {
  151. zmax = 1000.0;
  152. zmin = 0.001;
  153. }
  154. if((*bbrk = (double *)malloc(arraysize * sizeof(double)))==NULL) {
  155. fprintf(stdout,"ERROR: INSUFFICIENT MEMORY to store input brktable data.\n");
  156. fflush(stdout);
  157. return(0);
  158. }
  159. p = *bbrk;
  160. cnt = 0;
  161. while(fgets(temp,200,fp)==temp) { /* READ AND TEST BRKPNT VALS */
  162. q = temp;
  163. while(get_float_from_within_string(&q,p)) {
  164. if(is_time) {
  165. if(cnt==0) {
  166. if(*p < 0.0) {
  167. fprintf(stdout,"ERROR: First timeval (%lf) in brkpntfile is less than zero.\n",*p);
  168. fflush(stdout);
  169. return(0);
  170. } else if (*p > 0.0) {
  171. is_insert = 1;
  172. }
  173. } else {
  174. if(is_insert) { /* Force val at time zero */
  175. p += 2;
  176. cnt += 2;
  177. w = p;
  178. *p = *(p-2);
  179. p--;
  180. *p = *(p-2);
  181. p--;
  182. *p = *(p-2);
  183. (*bbrk)[0] = 0.0;
  184. p = w;
  185. is_insert = 0;
  186. }
  187. if(*p <= lasttime) {
  188. fprintf(stdout,"ERROR: Times (%lf & %lf) in brkpntfile are not in increasing order.\n",*p,lasttime);
  189. fflush(stdout);
  190. return(0);
  191. }
  192. }
  193. lasttime = *p;
  194. } else {
  195. if(*p < zmin || *p > zmax) {
  196. fprintf(stdout,"ERROR: Time stretch values are out of range (%lf to %lf)\n",zmin, zmax);
  197. fflush(stdout);
  198. return(0);
  199. }
  200. }
  201. is_time = !is_time;
  202. p++;
  203. if(++cnt >= arraysize) {
  204. arraysize += BIGARRAY;
  205. if((*bbrk = (double *)realloc((char *)(*bbrk),arraysize * sizeof(double)))==NULL) {
  206. fprintf(stdout,"ERROR: INSUFFICIENT MEMORY to reallocate input brktable data.\n");
  207. fflush(stdout);
  208. return(0);
  209. }
  210. p = (*bbrk) + cnt;
  211. }
  212. }
  213. }
  214. if(cnt < 4) {
  215. fprintf(stdout,"ERROR: Not enough data in brkpnt file.\n");
  216. fflush(stdout);
  217. return(0);
  218. }
  219. if(cnt&1) {
  220. fprintf(stdout,"ERROR: Data not paired correctly in brkpntfile.\n");
  221. fflush(stdout);
  222. return(0);
  223. }
  224. return cnt/2;
  225. }
  226. /************************** GET_FLOAT_FROM_WITHIN_STRING **************************/
  227. int get_float_from_within_string(char **str,double *val)
  228. {
  229. char *p, *valstart;
  230. int decimal_point_cnt = 0, has_digits = 0;
  231. p = *str;
  232. while(isspace(*p))
  233. p++;
  234. valstart = p;
  235. switch(*p) {
  236. case('-'): break;
  237. case('.'): decimal_point_cnt=1; break;
  238. default:
  239. if(!isdigit(*p))
  240. return(0);
  241. has_digits = 1;
  242. break;
  243. }
  244. p++;
  245. while(!isspace(*p) && *p!=NEWLINE && *p!=ENDOFSTR) {
  246. if(isdigit(*p))
  247. has_digits = 1;
  248. else if(*p == '.') {
  249. if(++decimal_point_cnt>1)
  250. return(0);
  251. } else
  252. return(0);
  253. p++;
  254. }
  255. if(!has_digits || sscanf(valstart,"%lf",val)!=1)
  256. return(0);
  257. *str = p;
  258. return(1);
  259. }
  260. #if 0
  261. //RWD: not used in this file; would need to be renamed.
  262. double round(double a)
  263. {
  264. int b;
  265. if(a >= 0.0)
  266. b = (int)floor(a + 0.5);
  267. else {
  268. a = -a;
  269. b = (int)floor(a + 0.5);
  270. b = -b;
  271. }
  272. return b;
  273. }
  274. #endif
  275. int flteq(double a,double b)
  276. {
  277. double hibnd = a + FLTERR;
  278. double lobnd = a - FLTERR;
  279. if(b >= lobnd && b <= hibnd)
  280. return 1;
  281. return 0;
  282. }