pview.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. /*
  2. * Copyright (c) 1983-2023 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. /**************************************************************************
  22. *
  23. * Convert snd data to text format suitable for Pview in Sound Loom
  24. */
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <osbind.h>
  29. #include <math.h>
  30. #include <float.h>
  31. #include <sfsys.h>
  32. #include <cdplib.h>
  33. /*RWD: changed all fprintf tests to < 0 */
  34. #define SHORTMONOSCALE 256.0 /* Scales shorts in range 0-32768 to display in range 0 128 */
  35. #define SHORTSTEREOSCALE 512.0 /* Scales shorts in range 0-32768 to display in stereorange 0 64 */
  36. #define FLOATMONOSCALE 128.0 /* Scales shorts in range 0-32768 to display in range 0 128 */
  37. #define FLOATSTEREOSCALE 64.0 /* Scales shorts in range 0-32768 to display in stereorange 0 64 */
  38. #define VIEW_WIDTH 900.0 /* width of sloom display */
  39. #define F_SECSIZE (512.0)
  40. /* Functions */
  41. static int tidy_up(int,unsigned int);
  42. static int open_in(char*);
  43. static int get_big_buf(void);
  44. static int make_textfile(char *filename);
  45. /*short *bigbuf; */ /* buffer used to read samples from soundfile */
  46. float *bigbuf;
  47. size_t buflen; /* buffer length in samps */
  48. int ifd; /* input soundfile descriptor */
  49. int srate; /* sampling rate of input */
  50. int channels; /* number of channels of input */
  51. int startsamp, endsamp;
  52. const char* cdp_version = "7.1.0";
  53. int main(int argc,char *argv[])
  54. {
  55. unsigned int start = hz1000();
  56. char filename[200];
  57. if(argc==2 && (strcmp(argv[1],"--version") == 0)) {
  58. fprintf(stdout,"%s\n",cdp_version);
  59. fflush(stdout);
  60. return 0;
  61. }
  62. if(argc!=4) {
  63. fprintf(stdout,"ERROR: Wrong number of arguments.\n");
  64. fflush(stdout);
  65. return tidy_up(2,start);
  66. }
  67. if(sscanf(argv[2],"%d",&startsamp)!=1) {
  68. fprintf(stdout,"ERROR: cannot read start sample number.\n");
  69. fflush(stdout);
  70. return tidy_up(2,start);
  71. }
  72. if(sscanf(argv[3],"%d",&endsamp)!=1) {
  73. fprintf(stdout,"ERROR: cannot read end sample number.\n");
  74. fflush(stdout);
  75. return tidy_up(2,start);
  76. }
  77. /* open input file */
  78. if(open_in(argv[1]) < 0)
  79. return tidy_up(2,start);
  80. strcpy(filename,argv[1]);
  81. /* get biggest buffer */
  82. if(get_big_buf() == 0)
  83. return tidy_up(1,start);
  84. /* max soundfiles */
  85. if(make_textfile(filename)<0)
  86. return tidy_up(1,start);
  87. /* tidy up */
  88. return tidy_up(0,start);
  89. }
  90. /**************************** OPEN_IN ****************************
  91. *
  92. * opens input soundfile and gets header
  93. */
  94. int open_in(char *name) /* opens input soundfile and gets header */
  95. {
  96. if( (ifd = sndopenEx(name,0,CDP_OPEN_RDONLY)) < 0 ) {
  97. fprintf(stdout,"INFO: Cannot open file: %s\n\t",name);
  98. fflush(stdout);
  99. return(-1);
  100. }
  101. /* get sampling rate */
  102. if(sndgetprop(ifd,"sample rate", (char *)&srate,sizeof(int)) < 0) {
  103. srate = 44100;
  104. fprintf(stdout,"WARNING: Cannot get sampling rate of %s : Default of 44100 assumed\n",name);
  105. fflush(stdout);
  106. }
  107. /* get channels */
  108. if(sndgetprop(ifd, "channels", (char*)&channels, sizeof(int)) < 0) {
  109. channels = 2;
  110. fprintf(stdout,"WARNING: Cannot get channels of %s Default of STEREO assumed\n",name);
  111. fflush(stdout);
  112. }
  113. return 0;
  114. }
  115. /**************************** GET_BIG_BUF ****************************
  116. *
  117. * allocates memory for the biggest possible buffer
  118. */
  119. int get_big_buf(void)
  120. {
  121. size_t i;
  122. buflen = (size_t) Malloc(-1)-sizeof(float); /* allow for alignment */
  123. /* if less than one sector available */
  124. if( buflen < (F_SECSIZE * sizeof(float)) || (bigbuf=(float*)Malloc(buflen+sizeof(float))) == NULL) {
  125. fprintf(stdout,"ERROR: Failed to allocate float buffer.\n");
  126. fflush(stdout);
  127. return 0;
  128. }
  129. i = ((long)bigbuf+sizeof(float)-1)/sizeof(float)*sizeof(float); /* align bigbuf to word boundary */
  130. bigbuf = (float*)i;
  131. buflen = (size_t)((buflen/F_SECSIZE)*F_SECSIZE);
  132. buflen /= sizeof(float);
  133. buflen /= channels;
  134. buflen *= channels;
  135. return 1;
  136. }
  137. /**************************** MAKE TEXTFILE *****************************/
  138. int make_textfile(char *filename)
  139. {
  140. int sampsgot, n, m, zoomfact;
  141. double gpsample0, gpsample1;
  142. int total_samps_got;
  143. int gpcnt, sampout /*, sampouttrue */;
  144. // int linecount = 0;
  145. /* check header first */
  146. FILE *fp;
  147. /* read and find maximum */
  148. if(channels > 2) {
  149. fprintf(stdout,"ERROR: Process only works with mono or stereo files\n");
  150. fflush(stdout);
  151. return -1;
  152. }
  153. if((fp = fopen("cdptest00.txt","w"))==NULL) {
  154. fprintf(stdout, "ERROR: Failed to open the Sound Loom display file 'cdptest00.txt'\n");
  155. fflush(stdout);
  156. return -1;
  157. }
  158. zoomfact = max(1,(int)ceil((double)(endsamp - startsamp)/VIEW_WIDTH));
  159. if(fprintf(fp,"%d\n",zoomfact) < 1) {
  160. fclose(fp);
  161. fprintf(stdout, "ERROR: Failed to complete data write to Sound Loom display file 'cdptest00.txt'\n");
  162. fflush(stdout);
  163. return -1;
  164. }
  165. gpcnt = 0;
  166. gpsample0 = 0.0;
  167. gpsample1 = 0.0;
  168. total_samps_got = 0;
  169. while((sampsgot = fgetfbufEx(bigbuf,buflen,ifd,1)) > 0 ) {
  170. switch(channels) {
  171. case(1):
  172. for(n=0;n<sampsgot;n++) {
  173. total_samps_got++;
  174. if(total_samps_got <= startsamp)
  175. continue;
  176. else if(total_samps_got > endsamp)
  177. break;
  178. if(zoomfact == 1)
  179. gpsample0 = bigbuf[n];
  180. else
  181. gpsample0 += fabs(bigbuf[n]);
  182. gpcnt++;
  183. if(gpcnt >= zoomfact) {
  184. gpsample0 /= (double)zoomfact;
  185. sampout = (short)round(gpsample0 * FLOATMONOSCALE);
  186. if(fprintf(fp,"%lf %d\n",gpsample0,sampout) < 0) {
  187. fclose(fp);
  188. fprintf(stdout, "ERROR: Failed to complete data write to Sound Loom display file 'cdptest00.txt'\n");
  189. fflush(stdout);
  190. return -1;
  191. }
  192. gpsample0 = 0.0;
  193. gpcnt = 0;
  194. }
  195. }
  196. if(gpcnt > 0) {
  197. gpsample0 /= (double)gpcnt;
  198. sampout = (short)round(gpsample0 * FLOATMONOSCALE);
  199. if(fprintf(fp,"%lf %d\n",gpsample0,sampout) < 0) {
  200. fclose(fp);
  201. fprintf(stdout, "ERROR: Failed to complete data write to Sound Loom display file 'cdptest00.txt'\n");
  202. fflush(stdout);
  203. return -1;
  204. }
  205. }
  206. break;
  207. case(2):
  208. for(n=0,m=1;m<sampsgot;n+=2,m+=2) { /*RWD test was using n */
  209. total_samps_got++;
  210. if(total_samps_got <= startsamp)
  211. continue;
  212. else if(total_samps_got > endsamp)
  213. break;
  214. if(zoomfact == 1) {
  215. gpsample0 = bigbuf[n];
  216. gpsample1 = bigbuf[m];
  217. } else {
  218. gpsample0 += fabs(bigbuf[n]);
  219. gpsample1 += fabs(bigbuf[m]);
  220. }
  221. gpcnt++;
  222. if(gpcnt >= zoomfact) {
  223. gpsample0 /= (double)zoomfact;
  224. gpsample1 /= (double)zoomfact;
  225. sampout = (short)round(gpsample0 * FLOATSTEREOSCALE);
  226. // linecount++;
  227. if(fprintf(fp,"%lf %d\n",gpsample0,sampout) < 0) {
  228. fclose(fp);
  229. fprintf(stdout, "ERROR: Failed to complete data write to Sound Loom display file 'cdptest00.txt'\n");
  230. fflush(stdout);
  231. return -1;
  232. }
  233. sampout = (short)round(gpsample1 * FLOATSTEREOSCALE);
  234. // linecount++;
  235. if(fprintf(fp,"%lf %d\n",gpsample1,sampout) < 0) {
  236. fclose(fp);
  237. fprintf(stdout, "ERROR: Failed to complete data write to Sound Loom display file 'cdptest00.txt'\n");
  238. fflush(stdout);
  239. return -1;
  240. }
  241. gpsample0 = 0.0;
  242. gpsample1 = 0.0;
  243. gpcnt = 0;
  244. }
  245. }
  246. if(gpcnt > 0) {
  247. gpsample0 /= (double)gpcnt;
  248. gpsample1 /= (double)gpcnt;
  249. sampout = (short)round(gpsample0 * FLOATSTEREOSCALE);
  250. // linecount++;
  251. if(fprintf(fp,"%lf %d\n",gpsample0,sampout) < 0) {
  252. fclose(fp);
  253. fprintf(stdout, "ERROR: Failed to complete data write to Sound Loom display file 'cdptest00.txt'\n");
  254. fflush(stdout);
  255. return -1;
  256. }
  257. // sampouttrue = (short)round(gpsample1);
  258. sampout = (short)round(gpsample1 * FLOATSTEREOSCALE);
  259. // linecount++;
  260. if(fprintf(fp,"%lf %d\n",gpsample1,sampout) < 0) {
  261. fclose(fp);
  262. fprintf(stdout, "ERROR: Failed to complete data write to Sound Loom display file 'cdptest00.txt'\n");
  263. fflush(stdout);
  264. return -1;
  265. }
  266. }
  267. break;
  268. default: /*RWD*/
  269. break;
  270. }
  271. /* break; */
  272. }
  273. fclose(fp);
  274. return(0);
  275. }
  276. /**************************** TIDY_UP ****************************
  277. *
  278. * Exit, freeing buffers and closing files where necessary.
  279. */
  280. int tidy_up(int where,unsigned int start)
  281. {
  282. switch(where) {
  283. case 0:
  284. Mfree(bigbuf);
  285. case 1:
  286. sndcloseEx(ifd);
  287. case 2:
  288. // sffinish();
  289. default:
  290. break;
  291. }
  292. while(!(hz1000() - start))
  293. ;
  294. return(1);
  295. }