newscales.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850
  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. * Generating melodic (etc) output using tones of defined spectrum, in non-tempered tunings.
  23. *
  24. * Get list of notes, times, amplitudes, durs from textlisting or MIDI device: LOOM INTERFACE
  25. *
  26. * Map to a different temperament if required : LOOM INTERFACE
  27. *
  28. * Generate list of frequencies, amplitudes, durations required
  29. * Find the MAXIMUM duration at each frequency
  30. *
  31. * Define the spectrum of the synthesized tones,
  32. * from a listing of harmonics and their relative amplitudes: LOOM INTERFACE
  33. *
  34. * Synthesis the max-duration(+safety note) required at each frequency
  35. *
  36. * Cut shorter notes to size by editing the maxlength notes
  37. * Here must associate each output file with appropriate output time/amp info (for mix)
  38. *
  39. * Employ any envelope-shaping, vib, trem, jitter required
  40. * Create a mixfile to mix the resulting events
  41. * Check output level, reset mixamplitude
  42. * Run mix
  43. */
  44. // USAGE: newscales outfile datafile spectrumfile srate
  45. #define SC_SYN_SRATE (0)
  46. #define MAXLEVEL (0.9)
  47. #include <stdio.h>
  48. #include <stdlib.h>
  49. #include <structures.h>
  50. #include <tkglobals.h>
  51. #include <globcon.h>
  52. #include <cdpmain.h>
  53. #include <synth.h>
  54. #include <processno.h>
  55. #include <modeno.h>
  56. #include <pnames.h>
  57. #include <flags.h>
  58. #include <arrays.h>
  59. #include <math.h>
  60. #include <logic.h>
  61. #include <speccon.h>
  62. #include <sfsys.h>
  63. #include <osbind.h>
  64. #include <string.h>
  65. //TW UPDATE
  66. #include <limits.h>
  67. #include <filetype.h>
  68. #include <filetype.h>
  69. #include <ctype.h>
  70. #include <srates.h>
  71. #ifdef unix
  72. #define round(x) lround((x))
  73. #endif
  74. char errstr[2400];
  75. int anal_infiles = 1;
  76. int sloom = 0;
  77. int sloombatch = 0;
  78. const char* cdp_version = "6.1.0";
  79. /**************************** SYNTHESIS STAGE ****************************/
  80. #define SC_SYN_TABSIZE 4096
  81. static int generate_all_tones(double *frq,int frqcnt,int *duration,double **harm,double **amp, dataptr dz);
  82. static int gentable(double *tab,int tabsize,dataptr dz);
  83. static int gen_sound(double frq, double *tab,int sampdur,double sr,double *harm,double *amp, int harmcnt,dataptr dz);
  84. static double getval(double *tab,int i,double fracstep,double amp);
  85. static void advance_in_table(double frq,int *i,double convertor,double *step,double *fracstep,double dtabsize);
  86. static int read_srate(char *str,dataptr dz);
  87. static int setup_newscales_application(dataptr dz);
  88. static int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz);
  89. static int read_spectrum_data(char **cmdline,double ***harm,double ***amp,double maxfrq,dataptr dz);
  90. static int read_newscales_data(char **cmdline,double **frq,int **duration,double *maxfrq,dataptr dz);
  91. static int establish_application(dataptr dz);
  92. /*
  93. * Params must be a special data file containing
  94. * (1) A list of frequencies to synthesize (each required frq synthd only ONCE
  95. * (2) A list of their durations (these are > maximum duration used by any frequency in the original input melody)
  96. * (3) A list of harmonics
  97. * (4) A list of harmonic amplitudes
  98. */
  99. /**************************************** MAIN *********************************************/
  100. int main(int argc,char *argv[])
  101. {
  102. int exit_status;
  103. dataptr dz = NULL;
  104. char **cmdline;
  105. int cmdlinecnt;
  106. int n;
  107. int is_launched = FALSE;
  108. double *frq, **harm, **amp, maxfrq;
  109. int *duration;
  110. if(argc==2 && (strcmp(argv[1],"--version") == 0)) {
  111. fprintf(stdout,"%s\n",cdp_version);
  112. fflush(stdout);
  113. return 0;
  114. }
  115. /* CHECK FOR SOUNDLOOM */
  116. // if((sloom = sound_loom_in_use(&argc,&argv)) > 1) {
  117. // sloom = 0;
  118. // sloombatch = 1;
  119. // }
  120. if(sflinit("cdp")){
  121. sfperror("cdp: initialisation\n");
  122. return(FAILED);
  123. }
  124. /* SET UP THE PRINCIPLE DATASTRUCTURE */
  125. if((exit_status = establish_datastructure(&dz))<0) { // CDP LIB
  126. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  127. return(FAILED);
  128. }
  129. if(argc < 4 || argc > 5) {
  130. usage2("dummy");
  131. return(FAILED);
  132. }
  133. if(argc == 5){
  134. if((exit_status = read_srate(argv[4],dz))<0) {
  135. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  136. return(FAILED);
  137. }
  138. } else
  139. dz->infile->srate = 44100;
  140. dz->nyquist = dz->infile->srate/2.0;
  141. cmdline = argv;
  142. cmdlinecnt = argc;
  143. if((exit_status = setup_newscales_application(dz))<0) {
  144. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  145. return(FAILED);
  146. }
  147. cmdline++;
  148. cmdlinecnt--;
  149. if((exit_status = handle_the_outfile(&cmdlinecnt,&cmdline,dz))<0) {
  150. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  151. return(FAILED);
  152. }
  153. if((exit_status = read_newscales_data(cmdline,&frq,&duration,&maxfrq,dz))<0) {
  154. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  155. return(FAILED);
  156. }
  157. cmdline++;
  158. cmdlinecnt--;
  159. if((exit_status = read_spectrum_data(cmdline,&harm,&amp,maxfrq,dz))<0) {
  160. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  161. return(FAILED);
  162. }
  163. dz->infile->channels = 1;
  164. is_launched = TRUE;
  165. dz->bufcnt = 1;
  166. if((dz->sampbuf = (float **)malloc(sizeof(float *) * (dz->bufcnt+1)))==NULL) {
  167. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffers.\n");
  168. return(MEMORY_ERROR);
  169. }
  170. if((dz->sbufptr = (float **)malloc(sizeof(float *) * dz->bufcnt))==NULL) {
  171. sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffer pointers.\n");
  172. return(MEMORY_ERROR);
  173. }
  174. for(n = 0;n <dz->bufcnt; n++)
  175. dz->sampbuf[n] = dz->sbufptr[n] = (float *)0;
  176. dz->sampbuf[n] = (float *)0;
  177. if((exit_status = create_sndbufs(dz))<0) { // CDP LIB
  178. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  179. return(FAILED);
  180. }
  181. if((exit_status = generate_all_tones(frq,dz->itemcnt,duration,harm,amp,dz))<0) {
  182. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  183. return(FAILED);
  184. }
  185. if((exit_status = complete_output(dz))<0) { // CDP LIB
  186. print_messages_and_close_sndfiles(exit_status,is_launched,dz);
  187. return(FAILED);
  188. }
  189. exit_status = print_messages_and_close_sndfiles(FINISHED,is_launched,dz); // CDP LIB
  190. free(dz);
  191. return(SUCCEEDED);
  192. }
  193. int generate_all_tones(double *frq,int frqcnt,int *duration,double **harm,double **amp,dataptr dz)
  194. {
  195. int exit_status;
  196. double *tab;
  197. int n, sampdur;
  198. double sr = (double)dz->infile->srate;
  199. char outfilename[200], temp[4];
  200. if((dz->insams = (int *)malloc(1 * sizeof(int)))==NULL) {
  201. sprintf(errstr,"Insufficient memory for insams arrays.\n");
  202. return(MEMORY_ERROR);
  203. }
  204. if((tab = (double *)malloc((SC_SYN_TABSIZE+1) * sizeof(double)))==NULL) {
  205. sprintf(errstr,"Insufficient memory for wave table.\n");
  206. return(MEMORY_ERROR);
  207. }
  208. if((exit_status = gentable(tab,SC_SYN_TABSIZE,dz))<0)
  209. return(exit_status);
  210. n = 0;
  211. while(n < frqcnt) {
  212. strcpy(outfilename,dz->outfilename);
  213. sprintf(temp,"%d",n);
  214. strcat(outfilename,temp);
  215. strcat(outfilename,".wav");
  216. sampdur = duration[n];
  217. dz->insams[0] = duration[n];
  218. dz->process_type = EQUAL_SNDFILE; /* allow sndfile to be created */
  219. if((exit_status = create_sized_outfile(outfilename,dz))<0) {
  220. sprintf(errstr, "Failed to open file %s\n",outfilename);
  221. /*free(outfilename);*/
  222. dz->ofd = -1;
  223. dz->process_type = OTHER_PROCESS;
  224. return(GOAL_FAILED);
  225. }
  226. reset_filedata_counters(dz);
  227. //HEREH, DEPENDING ON WHICH NOTE IT IS, WE GET THE HARMONIC COUNT FROM wordcnt[n],
  228. if((exit_status = gen_sound(frq[n],tab,sampdur,sr,harm[n],amp[n],dz->wordcnt[n],dz))<0) {
  229. fprintf(stdout,"Synthesis %d failed.\n",n+1);
  230. fflush(stdout);
  231. return(GOAL_FAILED);
  232. }
  233. if((exit_status = headwrite(dz->ofd,dz))<0) {
  234. fprintf(stdout,"Failed to write header to synthed output %d.\n",n+1);
  235. fflush(stdout);
  236. return(exit_status);
  237. }
  238. n++;
  239. if((exit_status = reset_peak_finder(dz))<0) {
  240. if(n < frqcnt) {
  241. fprintf(stdout,"Failed to reset peakfinder for synthesis %d.\n",n+1);
  242. fflush(stdout);
  243. return(exit_status);
  244. }
  245. }
  246. if(sndcloseEx(dz->ofd)<0) {
  247. sprintf(errstr,"Failed to close output soundfile for synthesis %d.\n",n);
  248. return(SYSTEM_ERROR);
  249. }
  250. dz->ofd = -1;
  251. }
  252. return(FINISHED);
  253. }
  254. /******************************* GENTABLE ******************************/
  255. int gentable(double *tab,int tabsize,dataptr dz)
  256. {
  257. int n;
  258. double step;
  259. step = (2.0 * PI)/(double)tabsize;
  260. for(n=0;n<tabsize;n++)
  261. tab[n] = sin(step * (double)n) * F_MAXSAMP;
  262. tab[tabsize] = 0.0;
  263. return(FINISHED);
  264. }
  265. /****************************** GEN_SOUND *************************/
  266. int gen_sound(double frq, double *tab,int sampdur,double sr,double *harm,double *amp, int harmcnt,dataptr dz)
  267. {
  268. int exit_status;
  269. double inverse_sr = 1.0/sr;
  270. double *step;
  271. double dtabsize = (double)SC_SYN_TABSIZE;
  272. double convertor = dtabsize * inverse_sr, maxsamp, normaliser;
  273. int n, m, *i;
  274. int chans = dz->infile->channels;
  275. double harmfrq, harmamp;
  276. double *fracstep, val;
  277. int do_start = 1;
  278. int synth_splicelen = SYNTH_SPLICELEN * chans;
  279. int total_samps = 0;
  280. int startj = 0, endj = SYNTH_SPLICELEN;
  281. int total_samps_left = sampdur;
  282. int endsplicestart = sampdur - synth_splicelen;
  283. int todo;
  284. if((step = (double *)malloc(harmcnt * sizeof(double)))==NULL) {
  285. sprintf(errstr,"Insufficient memory all harmonic wave table step counters.\n");
  286. return(MEMORY_ERROR);
  287. }
  288. if((fracstep = (double *)malloc(harmcnt * sizeof(double)))==NULL) {
  289. sprintf(errstr,"Insufficient memory all harmonic wave table step counters.\n");
  290. return(MEMORY_ERROR);
  291. }
  292. if((i = (int *)malloc(harmcnt * sizeof(int)))==NULL) {
  293. sprintf(errstr,"Insufficient memory all harmonic wave table position indicators.\n");
  294. return(MEMORY_ERROR);
  295. }
  296. for(n = 0;n < harmcnt;n++) {
  297. step[n] = 0.0;
  298. fracstep[n] = 0.0;
  299. i[n] = 0;
  300. }
  301. if(sampdur < (synth_splicelen * 2) + chans) {
  302. fprintf(stdout,"ERROR: Specified output duration is less then available splicing length.\n");
  303. return(DATA_ERROR);
  304. }
  305. maxsamp = 0.0;
  306. /* FIRST PASS: ADD UP ALL HARMONICS, AND GET MAX OUTPUT LEVEL */
  307. while(total_samps_left > 0) {
  308. memset((char *)dz->bigbuf,0,dz->buflen * sizeof(float));
  309. if(total_samps_left/dz->buflen <= 0)
  310. todo = total_samps_left;
  311. else
  312. todo = dz->buflen;
  313. for(n = 0;n < harmcnt;n++) {
  314. harmfrq = frq * harm[n];
  315. harmamp = amp[n];
  316. m = 0;
  317. while(m < todo) {
  318. val = getval(tab,i[n],fracstep[n],harmamp);
  319. dz->bigbuf[m] = (float)(dz->bigbuf[m] + val);
  320. m++;
  321. advance_in_table(harmfrq,&(i[n]),convertor,&(step[n]),&(fracstep[n]),dtabsize);
  322. }
  323. }
  324. m = 0;
  325. while(m < todo) {
  326. if(fabs(dz->bigbuf[m]) > maxsamp)
  327. maxsamp = fabs(dz->bigbuf[m]);
  328. m++;
  329. }
  330. total_samps_left -= dz->buflen;
  331. }
  332. normaliser = 1.0;
  333. if(maxsamp > MAXLEVEL)
  334. normaliser = MAXLEVEL/maxsamp;
  335. total_samps_left = sampdur;
  336. while(total_samps_left > 0) {
  337. memset((char *)dz->bigbuf,0,dz->buflen * sizeof(float));
  338. if(total_samps_left/dz->buflen <= 0)
  339. todo = total_samps_left;
  340. else
  341. todo = dz->buflen;
  342. for(n = 0;n < harmcnt;n++) {
  343. harmfrq = frq * harm[n];
  344. harmamp = amp[n];
  345. m = 0;
  346. while(m < todo) {
  347. val = getval(tab,i[n],fracstep[n],harmamp);
  348. dz->bigbuf[m] = dz->bigbuf[m] + (float)val;
  349. m++;
  350. advance_in_table(harmfrq,&(i[n]),convertor,&(step[n]),&(fracstep[n]),dtabsize);
  351. }
  352. }
  353. m = 0;
  354. while(m < todo) {
  355. dz->bigbuf[m] = (float)(dz->bigbuf[m] * normaliser);
  356. if(do_start) {
  357. dz->bigbuf[m] = (float)(dz->bigbuf[m] * (startj++/(double)SYNTH_SPLICELEN));
  358. if(startj >= SYNTH_SPLICELEN)
  359. do_start = 0;
  360. }
  361. if(total_samps >= endsplicestart)
  362. dz->bigbuf[m] = (float)(dz->bigbuf[m] * (endj--/(double)SYNTH_SPLICELEN));
  363. total_samps++;
  364. m++;
  365. }
  366. if(todo) {
  367. if((exit_status = write_samps(dz->bigbuf,todo,dz))<0)
  368. return(exit_status);
  369. }
  370. total_samps_left -= dz->buflen;
  371. }
  372. return(FINISHED);
  373. }
  374. /****************************** GETVAL *************************/
  375. double getval(double *tab,int i,double fracstep,double amp)
  376. {
  377. double diff, val = tab[i];
  378. diff = tab[i+1] - val;
  379. val += diff * fracstep;
  380. val *= amp;
  381. return(val);
  382. }
  383. /****************************** ADVANCE_IN_TABLE *************************/
  384. static void advance_in_table(double frq,int *i,double convertor,double *step,double *fracstep,double dtabsize)
  385. {
  386. *step += frq * convertor;
  387. while(*step >= dtabsize)
  388. *step -= dtabsize;
  389. *i = (int)(*step); /* TRUNCATE */
  390. *fracstep = *step - (double)(*i);
  391. }
  392. /************************ HANDLE_THE_OUTFILE *********************/
  393. int handle_the_outfile(int *cmdlinecnt,char ***cmdline,dataptr dz)
  394. {
  395. int len;
  396. char *filename = (*cmdline)[0], *p, *q, *full_filename;
  397. if(filename[0]=='-' && filename[1]=='f') {
  398. dz->floatsam_output = 1;
  399. dz->true_outfile_stype = SAMP_FLOAT;
  400. filename+= 2;
  401. }
  402. full_filename = filename;
  403. len = strlen(filename);
  404. q = filename;
  405. p = filename + len;
  406. p--;
  407. while(p >= q) { /* Sesparate off path */
  408. if(*p == '/' || *p == '\\') {
  409. filename = p+1;
  410. break;
  411. }
  412. p--;
  413. }
  414. if((len = strlen(filename)) <= 0) {
  415. sprintf(errstr,"Invalid outfilename (path only).\n");
  416. return(MEMORY_ERROR);
  417. }
  418. q = filename;
  419. len = strlen(filename);
  420. p = filename + len;
  421. p--;
  422. while(p >= q) {
  423. if(*p == '.') { /* Snip off file extension */
  424. *p = ENDOFSTR;
  425. break;
  426. }
  427. p--;
  428. }
  429. if((len = strlen(filename)) <= 0) {
  430. sprintf(errstr,"Invalid outfilename.\n");
  431. return(MEMORY_ERROR);
  432. }
  433. p = filename + len;
  434. p--;
  435. if(isdigit(*p)) {
  436. sprintf(errstr,"Invalid outfilename (ends in number).\n");
  437. return(MEMORY_ERROR);
  438. }
  439. filename = full_filename;
  440. len = strlen(filename);
  441. len++;
  442. if((dz->outfilename = (char *)malloc(len * sizeof(char)))==NULL) {
  443. sprintf(errstr,"INSUFFICIENT MEMORY to store output filename.\n");
  444. return(MEMORY_ERROR);
  445. }
  446. strcpy(dz->outfilename,filename);
  447. (*cmdline)++;
  448. (*cmdlinecnt)--;
  449. return(FINISHED);
  450. }
  451. /************************* SETUP_NEWSCALES_APPLICATION *******************/
  452. int setup_newscales_application(dataptr dz)
  453. {
  454. int exit_status;
  455. // aplptr ap;
  456. if((exit_status = establish_application(dz))<0) // GLOBAL
  457. return(FAILED);
  458. // ap = dz->application;
  459. // set_legal_infile_structure -->
  460. dz->has_otherfile = FALSE;
  461. // assign_process_logic -->
  462. dz->input_data_type = NO_FILE_AT_ALL;
  463. dz->process_type = UNEQUAL_SNDFILE;
  464. dz->outfiletype = SNDFILE_OUT;
  465. return(FINISHED);
  466. }
  467. /************************* READ_SRATE *******************/
  468. int read_srate(char *str,dataptr dz)
  469. {
  470. int dummy;
  471. if(sscanf(str,"%d",&dummy) != 1) {
  472. sprintf(errstr,"Failed to read output sample rate.\n");
  473. return(DATA_ERROR);
  474. }
  475. if(BAD_SR(dummy)) {
  476. sprintf(errstr,"Invalid sample rate.\n");
  477. return(DATA_ERROR);
  478. }
  479. dz->infile->srate = dummy;
  480. return(FINISHED);
  481. }
  482. /************************* READ_NEWSCALES_DATA *******************/
  483. int read_newscales_data(char **cmdline,double **frq,int **duration,double *maxfrq,dataptr dz)
  484. {
  485. double *f, dummy;
  486. int n = 0, dur, *d;
  487. char temp[200], *q;
  488. int isfrq;
  489. FILE *fp;
  490. if((fp = fopen(cmdline[0],"r"))==NULL) {
  491. sprintf(errstr, "Can't open datafile %s to read data.\n",cmdline[0]);
  492. return(DATA_ERROR);
  493. }
  494. n = 0;
  495. while(fgets(temp,200,fp)==temp) { /* READ AND TEST VALS */
  496. q = temp;
  497. if(*q == ';') // Allow comments in file
  498. continue;
  499. while(get_float_from_within_string(&q,&dummy)) {
  500. n++;
  501. }
  502. }
  503. if(n <= 0) {
  504. sprintf(errstr,"NO DATA Found in datafile.\n");
  505. return(DATA_ERROR);
  506. }
  507. if(ODD(n)) {
  508. sprintf(errstr,"DATA INCORRECTLY PAIRED in datafile %s.\n",cmdline[0]);
  509. return(DATA_ERROR);
  510. }
  511. n = n/2;
  512. dz->itemcnt = n;
  513. if((*frq = (double *)malloc(n * sizeof(double)))==NULL) {
  514. sprintf(errstr,"INSUFFICIENT MEMORY to store note frequencies.\n");
  515. return(MEMORY_ERROR);
  516. }
  517. if((*duration = (int *)malloc(n * sizeof(int)))==NULL) {
  518. sprintf(errstr,"INSUFFICIENT MEMORY to store note max-durations.\n");
  519. return(MEMORY_ERROR);
  520. }
  521. fseek(fp,0,0);
  522. f = *frq;
  523. d = *duration;
  524. n = 0;
  525. isfrq = 1;
  526. *maxfrq = 0.0;
  527. while(fgets(temp,200,fp)==temp) { /* READ AND STORE VALS */
  528. q = temp;
  529. if(*q == ';') // Allow comments in file
  530. continue;
  531. while(get_float_from_within_string(&q,&dummy)) {
  532. if(isfrq) {
  533. if(dummy <= 5) {
  534. sprintf(errstr,"Frq <= 5: too low for this application.\n");
  535. return(DATA_ERROR);
  536. }
  537. if(dummy > *maxfrq)
  538. *maxfrq = dummy;
  539. *f = dummy;
  540. f++;
  541. } else {
  542. if(dummy > 3600) {
  543. sprintf(errstr,"Duration greater than an hour: too long for this application.\n");
  544. return(DATA_ERROR);
  545. } else if (dummy <= 0.03) {
  546. sprintf(errstr,"Duration less than30 mS: too short for this application.\n");
  547. return(DATA_ERROR);
  548. }
  549. dur = (int)(round(dummy * dz->infile->srate));
  550. *d = dur;
  551. d++;
  552. }
  553. isfrq = !isfrq;
  554. }
  555. }
  556. return(FINISHED);
  557. }
  558. /************************* READ_SPECTRUM_DATA *******************/
  559. int read_spectrum_data(char **cmdline,double ***harm,double ***amp,double maxfrq,dataptr dz)
  560. {
  561. double *h, *a, dummy;
  562. int /*harmcnt,*/ linecnt, k;
  563. char temp[200], *q;
  564. int isharm;
  565. FILE *fp;
  566. if((fp = fopen(cmdline[0],"r"))==NULL) {
  567. sprintf(errstr, "Can't open datafile %s to read data.\n",cmdline[0]);
  568. return(DATA_ERROR);
  569. }
  570. // harmcnt = 0;
  571. linecnt = 0;
  572. while(fgets(temp,200,fp)==temp) { /* READ AND TEST VALS */
  573. q = temp;
  574. if(*q == ';') // Allow comments in file
  575. continue;
  576. k = 0;
  577. while(get_float_from_within_string(&q,&dummy)) {
  578. k++;
  579. }
  580. if(k == 0) {
  581. continue;
  582. }
  583. linecnt++;
  584. }
  585. if(linecnt != 1 && linecnt != dz->itemcnt) {
  586. sprintf(errstr,"No. of lines of spectral data (%d) does NOT = no. of notes entered (%d).\n",linecnt,dz->itemcnt);
  587. return(DATA_ERROR);
  588. }
  589. if((*harm = (double **)malloc(dz->itemcnt * sizeof(double *)))==NULL) {
  590. sprintf(errstr,"INSUFFICIENT MEMORY to store harmonics info.\n");
  591. return(MEMORY_ERROR);
  592. }
  593. if((*amp = (double **)malloc(dz->itemcnt * sizeof(double *)))==NULL) {
  594. sprintf(errstr,"INSUFFICIENT MEMORY to store amplitudes of harmonics.\n");
  595. return(MEMORY_ERROR);
  596. }
  597. if((dz->wordcnt = (int *)malloc(dz->itemcnt * sizeof(int)))==NULL) {
  598. sprintf(errstr,"INSUFFICIENT MEMORY to store count of harmonics for each note.\n");
  599. return(MEMORY_ERROR);
  600. }
  601. linecnt = 0;
  602. fseek(fp,0,0);
  603. while(fgets(temp,200,fp)==temp) { /* READ AND TEST VALS */
  604. q = temp;
  605. if(*q == ';') // Allow comments in file
  606. continue;
  607. k = 0;
  608. while(get_float_from_within_string(&q,&dummy)) {
  609. k++;
  610. }
  611. if(k == 0) {
  612. continue;
  613. }
  614. if(k == 0 || ODD(k)) {
  615. sprintf(errstr,"SPECTRAL DATA INCORRECTLY PAIRED in datafile %s line %d\n",cmdline[0],linecnt+1);
  616. return(DATA_ERROR);
  617. }
  618. k /= 2;
  619. if(((*harm)[linecnt] = (double *)malloc(k * sizeof(double)))==NULL) {
  620. sprintf(errstr,"INSUFFICIENT MEMORY to store harmonics info for note %d.\n",linecnt+1);
  621. return(MEMORY_ERROR);
  622. }
  623. if(((*amp)[linecnt] = (double *)malloc(k * sizeof(double)))==NULL) {
  624. sprintf(errstr,"INSUFFICIENT MEMORY to store amplitudes of harmonics for note %d.\n",linecnt+1);
  625. return(MEMORY_ERROR);
  626. }
  627. dz->wordcnt[linecnt] = k;
  628. linecnt++;
  629. } /* IF ONLY ONE SPECTRAL DATA LINE, ASSIGN SAME SPECTRUM TO ALL INPUT NOTES */
  630. fseek(fp,0,0);
  631. isharm = 1;
  632. linecnt = 0;
  633. while(fgets(temp,200,fp)==temp) { /* READ AND STORE VALS */
  634. h = (*harm)[linecnt];
  635. a = (*amp)[linecnt];
  636. q = temp;
  637. if(*q == ';') // Allow comments in file
  638. continue;
  639. k = 0;
  640. while(get_float_from_within_string(&q,&dummy)) {
  641. if(isharm) {
  642. if(dummy < 1) {
  643. sprintf(errstr,"Invalid harmonic value (< 1).\n");
  644. return(DATA_ERROR);
  645. } else if(dummy * maxfrq > dz->nyquist) {
  646. sprintf(errstr,"Harmonic value (%lf) too high for max frequency (%lf) being used\n",dummy,maxfrq);
  647. return(DATA_ERROR);
  648. }
  649. *h = dummy;
  650. h++;
  651. } else {
  652. if(dummy > 1 || dummy <= 0) {
  653. sprintf(errstr,"Harmonic amplitude out of range (>0 - 1).\n");
  654. return(DATA_ERROR);
  655. }
  656. *a = dummy;
  657. a++;
  658. }
  659. isharm = !isharm;
  660. }
  661. linecnt++;
  662. }
  663. if(linecnt == 1) {
  664. while(linecnt < dz->itemcnt) {
  665. (*harm)[linecnt] = (*harm)[0];
  666. (*amp)[linecnt] = (*amp)[0];
  667. dz->wordcnt[linecnt] = dz->wordcnt[0];
  668. linecnt++;
  669. }
  670. }
  671. return(FINISHED);
  672. }
  673. int usage2(char *dummy)
  674. {
  675. fprintf(stderr,"USAGE: newscales outfile datafile spectrumfile [srate]\n");
  676. fprintf(stderr,"outfile Generic name for output soundfiles (must not end with a number)\n");
  677. fprintf(stderr,"datafile Frq-amp pairs defining note-events in output\n");
  678. fprintf(stderr,"spectrumfile Harmonicnumber-amplitude pairs, define spectrum of note.\n");
  679. fprintf(stderr," One line for all notes\n");
  680. fprintf(stderr," OR\n");
  681. fprintf(stderr," One line for each note in the frq-list.\n");
  682. fprintf(stderr," (First line corresponds to lowest note, etc.)\n");
  683. return(FAILED);
  684. }
  685. /****************************** ESTABLISH_APPLICATION *******************************/
  686. int establish_application(dataptr dz)
  687. {
  688. aplptr ap;
  689. if((dz->application = (aplptr)malloc(sizeof (struct applic)))==NULL) {
  690. sprintf(errstr,"establish_application()\n");
  691. return(MEMORY_ERROR);
  692. }
  693. ap = dz->application;
  694. memset((char *)ap,0,sizeof(struct applic));
  695. return(FINISHED);
  696. }
  697. int assign_process_logic(dataptr dz)
  698. {
  699. return(FINISHED);
  700. }
  701. void set_legal_infile_structure(dataptr dz)
  702. {
  703. }
  704. int set_legal_internalparam_structure(int process,int mode,aplptr ap)
  705. {
  706. return(FINISHED);
  707. }
  708. int setup_internal_arrays_and_array_pointers(dataptr dz)
  709. {
  710. return(FINISHED);
  711. }
  712. int establish_bufptrs_and_extra_buffers(dataptr dz)
  713. {
  714. return(FINISHED);
  715. }
  716. int inner_loop(int *peakscore,int *descnt,int *in_start_portion,int *least,int *pitchcnt,int windows_in_buf,dataptr dz)
  717. {
  718. return(FINISHED);
  719. }
  720. int get_process_no(char *str,dataptr dz)
  721. {
  722. return(FINISHED);
  723. }
  724. int usage3(char *str1,char *str2)
  725. {
  726. return(FINISHED);
  727. }
  728. int usage1(void)
  729. {
  730. return(FINISHED);
  731. }
  732. int read_special_data(char *str,dataptr dz)
  733. {
  734. return(FINISHED);
  735. }
  736. //***************************** APPLICATION_INIT **************************/
  737. //
  738. //int application_init(dataptr dz)
  739. //{
  740. // int exit_status;
  741. // int storage_cnt;
  742. // int tipc, brkcnt;
  743. // aplptr ap = dz->application;
  744. // if(ap->vflag_cnt>0)
  745. // initialise_vflags(dz);
  746. // tipc = ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt;
  747. // ap->total_input_param_cnt = (char)tipc;
  748. // if(tipc>0) {
  749. // if((exit_status = setup_input_param_range_stores(tipc,ap))<0)
  750. // return(exit_status);
  751. // if((exit_status = setup_input_param_defaultval_stores(tipc,ap))<0)
  752. // return(exit_status);
  753. // if((exit_status = setup_and_init_input_param_activity(dz,tipc))<0)
  754. // return(exit_status);
  755. // }
  756. // brkcnt = tipc;
  757. //
  758. // if(dz->input_data_type==BRKFILES_ONLY
  759. // || dz->input_data_type==UNRANGED_BRKFILE_ONLY
  760. // || dz->input_data_type==DB_BRKFILES_ONLY
  761. // || dz->input_data_type==SNDFILE_AND_BRKFILE
  762. // || dz->input_data_type==SNDFILE_AND_UNRANGED_BRKFILE
  763. // || dz->input_data_type==SNDFILE_AND_DB_BRKFILE
  764. // || dz->input_data_type==ALL_FILES
  765. // || dz->input_data_type==ANY_NUMBER_OF_ANY_FILES
  766. // || dz->outfiletype==BRKFILE_OUT) {
  767. // dz->extrabrkno = brkcnt;
  768. // brkcnt++; /* extra brktable for input or output brkpntfile data */
  769. // }
  770. // if(brkcnt>0) {
  771. // if((exit_status = setup_and_init_input_brktable_constants(dz,brkcnt))<0)
  772. // return(exit_status);
  773. // }
  774. //
  775. // if((storage_cnt = tipc + ap->internal_param_cnt)>0) {
  776. // if((exit_status = setup_parameter_storage_and_constants(storage_cnt,dz))<0)
  777. // return(exit_status);
  778. // if((exit_status = initialise_is_int_and_no_brk_constants(storage_cnt,dz))<0)
  779. // return(exit_status);
  780. // }
  781. // if((exit_status = mark_parameter_types(dz,ap))<0)
  782. // return(exit_status);
  783. //
  784. // if((exit_status = establish_infile_constants(dz))<0)
  785. // return(exit_status);
  786. // if((exit_status = establish_bufptrs_and_extra_buffers(dz))<0)
  787. // return(exit_status);
  788. // if((exit_status = setup_internal_arrays_and_array_pointers(dz))<0)
  789. // return(exit_status);
  790. // return(FINISHED);
  791. //}