dupl.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  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 <structures.h>
  24. #include <tkglobals.h>
  25. #include <globcon.h>
  26. #include <cdpmain.h>
  27. #include <house.h>
  28. #include <modeno.h>
  29. #include <pnames.h>
  30. #include <filetype.h>
  31. #include <flags.h>
  32. #include <logic.h>
  33. #include <limits.h>
  34. #include <sfsys.h>
  35. #include <osbind.h> /*RWD*/
  36. #include <string.h>
  37. #include <math.h>
  38. static int check_available_space(dataptr dz);
  39. static int copy_textfile(dataptr dz);
  40. extern unsigned int superzargo;
  41. /************************************ DO_DUPLICATES ********************************/
  42. int do_duplicates(dataptr dz)
  43. {
  44. int exit_status;
  45. int n, start, end;
  46. int old_ofd;
  47. int namelen, numlen;
  48. char *outfilename;
  49. //TW REVISION Dec 2002
  50. char prefix_units[] = "_00";
  51. char prefix_tens[] = "_0";
  52. char prefix_hundreds[] = "_";
  53. char *p, *q, *r;
  54. numlen = 4;
  55. switch(dz->mode) {
  56. case(COPYSF):
  57. if(dz->infile->filetype==WORDLIST)
  58. return copy_textfile(dz);
  59. dz->tempsize = dz->insams[0];
  60. switch(dz->infile->filetype) {
  61. case(PITCHFILE):
  62. if((exit_status = write_exact_samps(dz->pitches,dz->insams[0],dz))<0)
  63. return(exit_status);
  64. break;
  65. case(TRANSPOSFILE):
  66. if((exit_status = write_exact_samps(dz->transpos,dz->insams[0],dz))<0)
  67. return(exit_status);
  68. break;
  69. default:
  70. while(dz->samps_left) {
  71. if((exit_status = read_samps(dz->sampbuf[0],dz))<0)
  72. return(exit_status);
  73. if(dz->ssampsread > 0) {
  74. if((exit_status = write_exact_samps(dz->sampbuf[0],dz->ssampsread,dz))<0)
  75. return(exit_status);
  76. } else if(dz->total_samps_read == 0) {
  77. sprintf(errstr,"Failure to read samples from input file.\n");
  78. return(SYSTEM_ERROR);
  79. }
  80. }
  81. if(dz->infile->filetype == ENVFILE)
  82. dz->outfile->window_size = dz->infile->window_size;
  83. break;
  84. }
  85. break;
  86. case(DUPL):
  87. if(!sloom) {
  88. namelen = strlen(dz->wordstor[0]);
  89. q = dz->wordstor[0];
  90. r = dz->wordstor[0] + namelen;
  91. p = r - 1;
  92. while((*p != '\\') && (*p != '/') && (*p != ':')) {
  93. p-- ;
  94. if(p < dz->wordstor[0])
  95. break;
  96. }
  97. if(p > dz->wordstor[0]) {
  98. p++;
  99. while(p <= r)
  100. *q++ = *p++;
  101. }
  102. }
  103. namelen = strlen(dz->wordstor[0]);
  104. superzargo = 0; /* timer-base */
  105. old_ofd = dz->ofd;
  106. if((exit_status = check_available_space(dz))<0)
  107. return(exit_status);
  108. //TW ????
  109. if(!sloom)
  110. dz->ofd = -1;
  111. else
  112. dz->ofd = old_ofd;
  113. if((dz->tempsize = dz->insams[0] * dz->iparam[COPY_CNT])<0)
  114. dz->tempsize = INT_MAX; /* ERROR was LONG_MAX **** Overflows **** */
  115. if(sloom) {
  116. namelen--; /* Drop the 0 at end of name */
  117. start = 0;
  118. end = dz->iparam[COPY_CNT];
  119. } else {
  120. start = 1;
  121. end = dz->iparam[COPY_CNT] + 1;
  122. }
  123. for(n=start;n<end;n++) {
  124. if(sndseekEx(dz->ifd[0],0,0)<0) {
  125. sprintf(errstr,"sndseek() failed.\n");
  126. return(SYSTEM_ERROR);
  127. }
  128. reset_filedata_counters(dz);
  129. if((outfilename = (char *)malloc((namelen + numlen + 1) * sizeof(char)))==NULL) {
  130. sprintf(errstr,"INSUFFICIENT MEMORY for outfilename.\n");
  131. return(MEMORY_ERROR);
  132. }
  133. strcpy(outfilename,dz->wordstor[0]);
  134. if(!sloom) {
  135. if(n<10)
  136. //TW REVISION Dec 2002
  137. insert_new_chars_at_filename_end(outfilename,prefix_units);
  138. else if(n<100)
  139. insert_new_chars_at_filename_end(outfilename,prefix_tens);
  140. else if(n<1000)
  141. insert_new_chars_at_filename_end(outfilename,prefix_hundreds);
  142. else {
  143. sprintf(errstr,"Too many duplicates.\n");
  144. return(PROGRAM_ERROR);
  145. }
  146. insert_new_number_at_filename_end(outfilename,n,0);
  147. } else {
  148. insert_new_number_at_filename_end(outfilename,n,1);
  149. }
  150. dz->process_type = EQUAL_SNDFILE; /* allow sndfile to be created */
  151. if(!sloom || n>0) {
  152. if((exit_status = create_sized_outfile(outfilename,dz))<0) {
  153. if(!sloom) {
  154. if(dz->vflag[IGNORE_COPIES]) {
  155. fprintf(stdout, "INFO: Soundfile %s already exists\n", outfilename);
  156. fflush(stdout);
  157. free(outfilename);
  158. dz->process_type = OTHER_PROCESS;
  159. dz->ofd = -1;
  160. continue;
  161. }
  162. else {
  163. sprintf(errstr, "Soundfile %s already exists: Made %d duplicates only.\n",outfilename,n-1);
  164. free(outfilename);
  165. dz->process_type = OTHER_PROCESS;
  166. dz->ofd = -1;
  167. return(GOAL_FAILED);
  168. }
  169. } else {
  170. dz->process_type = OTHER_PROCESS;
  171. dz->ofd = -1;
  172. return(SYSTEM_ERROR);
  173. }
  174. }
  175. }
  176. dz->process_type = OTHER_PROCESS;
  177. while(dz->samps_left) {
  178. if((exit_status = read_samps(dz->sampbuf[0],dz))<0)
  179. return(exit_status);
  180. if(dz->ssampsread > 0) {
  181. if((exit_status = write_exact_samps(dz->sampbuf[0],dz->ssampsread,dz))<0)
  182. return(exit_status);
  183. }
  184. }
  185. dz->process_type = EQUAL_SNDFILE; /* allows header to be written */
  186. dz->outfiletype = SNDFILE_OUT; /* allows header to be written */
  187. if((exit_status = headwrite(dz->ofd,dz))<0) {
  188. free(outfilename);
  189. return(exit_status);
  190. }
  191. dz->process_type = OTHER_PROCESS; /* restore true status */
  192. dz->outfiletype = NO_OUTPUTFILE; /* restore true status */
  193. if((exit_status = reset_peak_finder(dz))<0)
  194. return(exit_status);
  195. if(sndcloseEx(dz->ofd) < 0) {
  196. fprintf(stdout,"WARNING: Can't close output soundfile %s\n",outfilename);
  197. fflush(stdout);
  198. }
  199. free(outfilename);
  200. dz->ofd = -1;
  201. }
  202. break;
  203. default:
  204. sprintf(errstr,"Unknown case in do_duplicates()\n");
  205. return(PROGRAM_ERROR);
  206. }
  207. return(FINISHED);
  208. }
  209. /************************************ DO_DELETES ********************************/
  210. int do_deletes(dataptr dz)
  211. {
  212. char *outfilename;
  213. int n;
  214. char prefix_units[] = "_00";
  215. char prefix_tens[] = "_0";
  216. char prefix_hundreds[] = "_";
  217. int namelen = strlen(dz->wordstor[0]);
  218. int numlen = 4, unopen, removed;
  219. unopen = 0;
  220. removed = 0;
  221. for(n=1;n<=MAXDUPL;n++) {
  222. if((!dz->vflag[ALL_COPIES]) && unopen >= COPYDEL_OVERMAX)
  223. break;
  224. if((outfilename = (char *)malloc((namelen + numlen + 1) * sizeof(char)))==NULL) {
  225. sprintf(errstr,"INSUFFICIENT MEMORY for outfilename.\n");
  226. return(MEMORY_ERROR);
  227. }
  228. strcpy(outfilename,dz->wordstor[0]);
  229. //TW COMMENT: program not available on Sound Loom
  230. //TW REVISIONs Dec 2002 : to do with sending filename extension in cmdline
  231. if(!sloom) {
  232. if(n<10)
  233. insert_new_chars_at_filename_end(outfilename,prefix_units);
  234. else if(n<100)
  235. insert_new_chars_at_filename_end(outfilename,prefix_tens);
  236. else if(n<1000)
  237. insert_new_chars_at_filename_end(outfilename,prefix_hundreds);
  238. else {
  239. sprintf(errstr,"Too many duplicates.\n");
  240. return(PROGRAM_ERROR);
  241. }
  242. }
  243. insert_new_number_at_filename_end(outfilename,n,0);
  244. if((dz->ofd = sndopenEx(outfilename,0,CDP_OPEN_RDONLY)) < 0) { /*RWD don't need sndopenex... */
  245. unopen++;
  246. dz->ofd = -1;
  247. continue;
  248. }
  249. if(sndunlink(dz->ofd) < 0) {
  250. fprintf(stdout,"WARNING: Can't set output soundfile %s for deletion.\n",outfilename);
  251. fflush(stdout);
  252. dz->ofd = -1;
  253. free(outfilename);
  254. }
  255. if(sndcloseEx(dz->ofd) < 0) {
  256. fprintf(stdout,"WARNING: Can't close output soundfile %s\n",outfilename);
  257. fflush(stdout);
  258. dz->ofd = -1;
  259. free(outfilename);
  260. }
  261. removed++;
  262. free(outfilename);
  263. dz->ofd = -1;
  264. }
  265. fprintf(stdout,"INFO: %d duplicate files removed.\n",removed);
  266. fflush(stdout);
  267. return(FINISHED);
  268. }
  269. /************************************ CHECK_AVAILABLE_SPACE ********************************/
  270. int check_available_space(dataptr dz)
  271. {
  272. unsigned int slots;
  273. int outfilesize;
  274. outfilesize = getdrivefreespace("temp") / sizeof(float);
  275. slots = outfilesize/dz->insams[0];
  276. if(slots < (unsigned int)dz->iparam[COPY_CNT]) {
  277. sprintf(errstr,"Insufficient space on disk to create %d copies.\n"
  278. "You have space for %d copies.\n",dz->iparam[COPY_CNT],slots);
  279. return(GOAL_FAILED);
  280. }
  281. return(FINISHED);
  282. }
  283. /************************************ CHECK_AVAILABLE_DISKSPACE ********************************/
  284. /* used for HOUSE DISK only */
  285. #define LEAVESPACE (10*1024) /* file space that must be left */
  286. #define DEFAULT_SRATE (44100)
  287. int check_available_diskspace(dataptr dz)
  288. {
  289. double secs, mins, hrs;
  290. int srate;
  291. unsigned int outsamps = 0, orig_outsamps;
  292. int m, k, kk, spacecnt;
  293. char temp[800];
  294. unsigned int freespace = getdrivefreespace("temp") - LEAVESPACE;
  295. switch(dz->infile->filetype) {
  296. case(SNDFILE): srate = dz->infile->srate; break;
  297. default: srate = DEFAULT_SRATE; break;
  298. }
  299. sprintf(errstr,"AVAILABLE DISK SPACE (at sample rate %d)\n",srate);
  300. sprintf(temp,"%d",freespace);
  301. strcat(errstr,temp);
  302. spacecnt = 13 - strlen(temp);
  303. for(k=0;k<spacecnt;k++) /* did have ; at end */
  304. strcat(errstr," ");
  305. strcat(errstr,"bytes\n");
  306. splice_multiline_string(errstr,"INFO:");
  307. fflush(stdout);
  308. kk = 0;
  309. while (kk < 4) {
  310. errstr[0] = ENDOFSTR;
  311. switch(kk) {
  312. case(0): outsamps = freespace/2; break;
  313. case(1): outsamps = freespace/3; break;
  314. case(2): outsamps = freespace/4; break;
  315. case(3): outsamps = freespace/sizeof(float); break;
  316. }
  317. sprintf(temp,"%d",outsamps);
  318. strcat(errstr,temp);
  319. spacecnt = 13 - strlen(temp);
  320. for(k=0;k<spacecnt;k++) /* did have ; at end */
  321. strcat(errstr," ");
  322. switch(kk) {
  323. case(0): strcat(errstr,"16-bit samples\n"); break;
  324. case(1): strcat(errstr,"24-bit samples\n"); break;
  325. case(2): strcat(errstr,"32-bit samples\n"); break;
  326. case(3): strcat(errstr,"float samples\n"); break;
  327. }
  328. orig_outsamps = outsamps;
  329. for(m=MONO;m<=STEREO;m++) {
  330. switch(m) {
  331. case(MONO):
  332. outsamps = orig_outsamps;
  333. sprintf(temp,"IN MONO : ");
  334. strcat(errstr,temp);
  335. break;
  336. case(STEREO):
  337. outsamps /= 2;
  338. sprintf(temp,"IN STEREO : ");
  339. strcat(errstr,temp);
  340. break;
  341. }
  342. secs = (double)outsamps/srate;
  343. mins = floor(secs/60.0);
  344. secs -= mins * 60.0;
  345. hrs = floor(mins/60.0);
  346. mins -= hrs * 60.0;
  347. if(hrs > 0.0) {
  348. sprintf(temp,"%.0lf",hrs);
  349. strcat(errstr,temp);
  350. spacecnt = 3 - strlen(temp);
  351. for(k=0;k<spacecnt;k++)
  352. strcat(errstr," ");
  353. strcat(errstr,"hours ");
  354. } else {
  355. for(k=0;k<4 + (int)strlen("hours");k++)
  356. strcat(errstr," ");
  357. }
  358. if(mins > 0.0) {
  359. sprintf(temp,"%.0lf",mins);
  360. strcat(errstr,temp);
  361. spacecnt = 3 - strlen(temp);
  362. for(k=0;k<spacecnt;k++)
  363. strcat(errstr," ");
  364. strcat(errstr,"mins ");
  365. } else {
  366. for(k=0;k<4 + (int)strlen("mins");k++)
  367. strcat(errstr," ");
  368. }
  369. sprintf(temp,"%.3lf",secs);
  370. strcat(errstr,temp);
  371. spacecnt = 7 - strlen(temp);
  372. for(k=0;k<spacecnt;k++)
  373. strcat(errstr," ");
  374. strcat(errstr,"secs\n");
  375. }
  376. splice_multiline_string(errstr,"INFO:");
  377. fflush(stdout);
  378. kk++;
  379. }
  380. return FINISHED;
  381. }
  382. /************************************ COPY_TEXTFILE ********************************/
  383. int copy_textfile(dataptr dz)
  384. {
  385. char temp[200];
  386. int k = 0, n, m, thiswordcnt;
  387. for(n=0;n<dz->linecnt;n++) {
  388. thiswordcnt = dz->wordcnt[n];
  389. for(m=0;m < thiswordcnt;m++) {
  390. if(m == 0) {
  391. //sprintf(temp,dz->wordstor[k++]); /* RWD 07 2010: bad use of sprintf */
  392. strcpy(temp,dz->wordstor[k++]);
  393. } else {
  394. strcat(temp," ");
  395. strcat(temp,dz->wordstor[k++]);
  396. }
  397. }
  398. strcat(temp,"\n");
  399. if(fputs(temp,dz->fp)<0) {
  400. sprintf(errstr,"Failed to write line %d to outfile.\n",n);
  401. return(SYSTEM_ERROR);
  402. }
  403. }
  404. return(FINISHED);
  405. }