ap_hfperm.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944
  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 <cdpmain.h>
  25. #include <tkglobals.h>
  26. #include <pnames.h>
  27. #include <synth.h>
  28. #include <processno.h>
  29. #include <modeno.h>
  30. #include <globcon.h>
  31. #include <logic.h>
  32. #include <filetype.h>
  33. #include <mixxcon.h>
  34. #include <speccon.h>
  35. #include <flags.h>
  36. #include <arrays.h>
  37. #include <special.h>
  38. #include <formants.h>
  39. #include <sfsys.h>
  40. #include <osbind.h>
  41. #include <string.h>
  42. #include <hfperm.h>
  43. #include <math.h>
  44. #include <srates.h>
  45. //#ifdef unix
  46. #define round(x) lround((x))
  47. //#endif
  48. static int eliminate_octave_duplications(dataptr dz);
  49. static int check_for_invalid_data(int k,dataptr dz);
  50. static void transpose_to_lowest_oct(dataptr dz);
  51. static void bublsort_hf(dataptr dz);
  52. static void elim_dupls(dataptr dz);
  53. static int create_hfpermbufs(dataptr dz);
  54. static void establish_waveform(dataptr dz);
  55. static int read_delperm_data(char *filename,dataptr dz);
  56. static int read_delperm2_data(char *filename,dataptr dz);
  57. char warnstr[2400];
  58. /***************************** ESTABLISH_BUFPTRS_AND_EXTRA_BUFFERS **************************/
  59. int establish_bufptrs_and_extra_buffers(dataptr dz)
  60. {
  61. // int is_spec = FALSE;
  62. dz->extra_bufcnt = -1; /* ENSURE EVERY CASE HAS A PAIR OF ENTRIES !! */
  63. dz->bptrcnt = 0;
  64. dz->bufcnt = 0;
  65. switch(dz->process) {
  66. case(HF_PERM1): case(HF_PERM2):
  67. dz->extra_bufcnt = 0;
  68. dz->bufcnt = 3;
  69. break;
  70. case(DEL_PERM):
  71. case(DEL_PERM2):
  72. dz->extra_bufcnt = 0;
  73. dz->bufcnt = 4;
  74. break;
  75. default:
  76. sprintf(errstr,"Unknown program type [%d] in establish_bufptrs_and_extra_buffers()\n",dz->process);
  77. return(PROGRAM_ERROR);
  78. }
  79. if(dz->extra_bufcnt < 0) {
  80. sprintf(errstr,"bufcnts have not been set: establish_bufptrs_and_extra_buffers()\n");
  81. return(PROGRAM_ERROR);
  82. }
  83. return establish_groucho_bufptrs_and_extra_buffers(dz);
  84. }
  85. /***************************** SETUP_INTERNAL_ARRAYS_AND_ARRAY_POINTERS **************************/
  86. int setup_internal_arrays_and_array_pointers(dataptr dz)
  87. {
  88. int n;
  89. dz->ptr_cnt = -1; /* base constructor...process */
  90. dz->array_cnt = -1;
  91. dz->iarray_cnt = -1;
  92. dz->larray_cnt = -1;
  93. switch(dz->process) {
  94. case(HF_PERM1):
  95. case(HF_PERM2):
  96. dz->array_cnt=1; dz->iarray_cnt=0; dz->larray_cnt=0; dz->ptr_cnt= 0; dz->fptr_cnt = 0; break;
  97. case(DEL_PERM):
  98. case(DEL_PERM2):
  99. dz->array_cnt=3; dz->iarray_cnt=0; dz->larray_cnt=0; dz->ptr_cnt= 0; dz->fptr_cnt = 0; break;
  100. }
  101. /*** WARNING ***
  102. ANY APPLICATION DEALING WITH A NUMLIST INPUT: MUST establish AT LEAST 1 double array: i.e. dz->array_cnt = at least 1
  103. **** WARNING ***/
  104. if(dz->array_cnt < 0 || dz->iarray_cnt < 0 || dz->larray_cnt < 0 || dz->ptr_cnt < 0 || dz->fptr_cnt < 0) {
  105. sprintf(errstr,"array_cnt not set in setup_internal_arrays_and_array_pointers()\n");
  106. return(PROGRAM_ERROR);
  107. }
  108. if(dz->array_cnt > 0) {
  109. if((dz->parray = (double **)malloc(dz->array_cnt * sizeof(double *)))==NULL) {
  110. sprintf(errstr,"INSUFFICIENT MEMORY for internal double arrays.\n");
  111. return(MEMORY_ERROR);
  112. }
  113. for(n=0;n<dz->array_cnt;n++)
  114. dz->parray[n] = NULL;
  115. }
  116. if(dz->iarray_cnt > 0) {
  117. if((dz->iparray = (int **)malloc(dz->iarray_cnt * sizeof(int *)))==NULL) {
  118. sprintf(errstr,"INSUFFICIENT MEMORY for internal int arrays.\n");
  119. return(MEMORY_ERROR);
  120. }
  121. for(n=0;n<dz->iarray_cnt;n++)
  122. dz->iparray[n] = NULL;
  123. }
  124. if(dz->larray_cnt > 0) {
  125. if((dz->lparray = (int **)malloc(dz->larray_cnt * sizeof(int *)))==NULL) {
  126. sprintf(errstr,"INSUFFICIENT MEMORY for internal long arrays.\n");
  127. return(MEMORY_ERROR);
  128. }
  129. for(n=0;n<dz->larray_cnt;n++)
  130. dz->lparray[n] = NULL;
  131. }
  132. if(dz->ptr_cnt > 0) {
  133. if((dz->ptr = (double **)malloc(dz->ptr_cnt * sizeof(double *)))==NULL) {
  134. sprintf(errstr,"INSUFFICIENT MEMORY for internal pointer arrays.\n");
  135. return(MEMORY_ERROR);
  136. }
  137. for(n=0;n<dz->ptr_cnt;n++)
  138. dz->ptr[n] = NULL;
  139. }
  140. if(dz->fptr_cnt > 0) {
  141. if((dz->fptr = (float **)malloc(dz->fptr_cnt * sizeof(float *)))==NULL) {
  142. sprintf(errstr,"INSUFFICIENT MEMORY for internal float-pointer arrays.\n");
  143. return(MEMORY_ERROR);
  144. }
  145. for(n=0;n<dz->fptr_cnt;n++)
  146. dz->fptr[n] = NULL;
  147. }
  148. return(FINISHED);
  149. }
  150. /****************************** ASSIGN_PROCESS_LOGIC *********************************/
  151. int assign_process_logic(dataptr dz)
  152. {
  153. switch(dz->process) {
  154. case(HF_PERM1):
  155. case(HF_PERM2):
  156. switch(dz->mode) {
  157. case(HFP_SNDOUT): setup_process_logic(WORDLIST_ONLY,UNEQUAL_SNDFILE,SNDFILE_OUT,dz); break;
  158. case(HFP_SNDSOUT): setup_process_logic(WORDLIST_ONLY,OTHER_PROCESS, NO_OUTPUTFILE,dz); break;
  159. case(HFP_TEXTOUT): setup_process_logic(WORDLIST_ONLY,TO_TEXTFILE, TEXTFILE_OUT,dz); break;
  160. case(HFP_MIDIOUT): setup_process_logic(WORDLIST_ONLY,TO_TEXTFILE, TEXTFILE_OUT,dz); break;
  161. default:
  162. sprintf(errstr,"Unknown mode: assign_process_logic()\n");
  163. return(PROGRAM_ERROR);
  164. }
  165. break;
  166. case(DEL_PERM): setup_process_logic(WORDLIST_ONLY,UNEQUAL_SNDFILE,SNDFILE_OUT,dz); break;
  167. case(DEL_PERM2): setup_process_logic(SNDFILES_ONLY,UNEQUAL_SNDFILE,SNDFILE_OUT,dz); break;
  168. default:
  169. sprintf(errstr,"Unknown process: assign_process_logic()\n");
  170. return(PROGRAM_ERROR);
  171. break;
  172. }
  173. return(FINISHED);
  174. }
  175. /***************************** SET_LEGAL_INFILE_STRUCTURE **************************
  176. *
  177. * Allows 2nd infile to have different props to first infile.
  178. */
  179. void set_legal_infile_structure(dataptr dz)
  180. {
  181. switch(dz->process) {
  182. default:
  183. dz->has_otherfile = FALSE;
  184. break;
  185. }
  186. }
  187. /****************************** FORMERLY IN internal.c *********************************/
  188. /***************************************************************************************/
  189. /****************************** SET_LEGAL_INTERNALPARAM_STRUCTURE *********************************/
  190. int set_legal_internalparam_structure(int process,int mode,aplptr ap)
  191. {
  192. int exit_status = FINISHED;
  193. mode = 0;
  194. switch(process) {
  195. case(HF_PERM1):
  196. case(HF_PERM2):
  197. exit_status = set_internalparam_data("i",ap);
  198. break;
  199. case(DEL_PERM):
  200. case(DEL_PERM2):
  201. exit_status = set_internalparam_data("ii",ap);
  202. break;
  203. default:
  204. sprintf(errstr,"Unknown process in set_legal_internalparam_structure()\n");
  205. return(PROGRAM_ERROR);
  206. }
  207. return(exit_status);
  208. }
  209. /********************************************************************************************/
  210. /********************************** FORMERLY IN specialin.c *********************************/
  211. /********************************************************************************************/
  212. /********************** READ_SPECIAL_DATA ************************/
  213. int read_special_data(char *str,dataptr dz)
  214. {
  215. // int exit_status = FINISHED;
  216. aplptr ap = dz->application;
  217. switch(ap->special_data) {
  218. case(DELPERM): return read_delperm_data(str,dz);
  219. case(DELPERM2): return read_delperm2_data(str,dz);
  220. default:
  221. sprintf(errstr,"Unknown special_data type: read_special_data()\n");
  222. return(PROGRAM_ERROR);
  223. }
  224. return(FINISHED); /* NOTREACHED */
  225. }
  226. /********************************************************************************************/
  227. /********************************** FORMERLY IN preprocess.c ********************************/
  228. /********************************************************************************************/
  229. /****************************** PARAM_PREPROCESS *********************************/
  230. int param_preprocess(dataptr dz)
  231. {
  232. int exit_status = FINISHED;
  233. int octaves_eliminated;
  234. double *hf = dz->parray[0];
  235. switch(dz->process) {
  236. case(HF_PERM1):
  237. dz->iparam[HP1_HFCNT] = dz->numsize;
  238. if((exit_status = check_for_invalid_data(HP1_HFCNT,dz))<0)
  239. return(exit_status);
  240. octaves_eliminated = eliminate_octave_duplications(dz);
  241. if(dz->iparam[HP1_HFCNT] < dz->iparam[HP1_MINSET]) {
  242. sprintf(errstr,"Minimum size of note set (%d)",dz->iparam[HP1_HFCNT]);
  243. if(octaves_eliminated) {
  244. sprintf(warnstr," (after octave duplication elimination)");
  245. strcat(errstr,warnstr);
  246. }
  247. sprintf(warnstr,"\nis less than minimum size specified for chords (%d): cannot proceed.\n",dz->iparam[HP1_MINSET]);
  248. strcat(errstr,warnstr);
  249. return(DATA_ERROR);
  250. }
  251. transpose_to_lowest_oct(dz);
  252. bublsort_hf(dz);
  253. if(hf[dz->iparam[HP1_HFCNT]-1] > (double)dz->iparam[HP1_TOPNOTE]) {
  254. sprintf(errstr,"Entered range does not span the given harmonic field\n");
  255. return(DATA_ERROR);
  256. }
  257. break;
  258. case(HF_PERM2):
  259. dz->iparam[HP1_HFCNT] = dz->numsize;
  260. if((exit_status = check_for_invalid_data(HP1_HFCNT,dz))<0)
  261. return(exit_status);
  262. elim_dupls(dz);
  263. if(dz->iparam[HP1_HFCNT] < dz->iparam[HP1_MINSET]) {
  264. sprintf(errstr,"Minimum size of note set (%d)",dz->iparam[HP1_HFCNT]);
  265. sprintf(warnstr,"\nis less than minimum size specified for chords (%d): cannot proceed.\n",dz->iparam[HP1_MINSET]);
  266. strcat(errstr,warnstr);
  267. return(DATA_ERROR);
  268. }
  269. bublsort_hf(dz);
  270. break;
  271. case(DEL_PERM2):
  272. if((dz->ssampsread = fgetfbufEx(dz->sampbuf[1],dz->insams[0],dz->ifd[0],0)) < 0) {
  273. sprintf(errstr,"Can't read samps from input soundfile.\n");
  274. return(SYSTEM_ERROR);
  275. }
  276. if((exit_status = check_for_invalid_data(DP_NOTECNT,dz))<0)
  277. return(exit_status);
  278. break;
  279. case(DEL_PERM):
  280. dz->iparam[DP_NOTECNT] = dz->numsize;
  281. if((exit_status = check_for_invalid_data(DP_NOTECNT,dz))<0)
  282. return(exit_status);
  283. break;
  284. default:
  285. sprintf(errstr,"Unknown process in param_preprocess()\n");
  286. return(PROGRAM_ERROR);
  287. }
  288. return(FINISHED);
  289. }
  290. /********************************************************************************************/
  291. /********************************** FORMERLY IN procgrou.c **********************************/
  292. /********************************************************************************************/
  293. /**************************** GROUCHO_PROCESS_FILE ****************************/
  294. int groucho_process_file(dataptr dz) /* FUNCTIONS FOUND IN PROCESS.C */
  295. {
  296. // int exit_status = FINISHED;
  297. switch(dz->process) {
  298. case(HF_PERM1):
  299. case(HF_PERM2):
  300. return do_hfperm(dz);
  301. case(DEL_PERM):
  302. case(DEL_PERM2):
  303. return gen_dp_output(dz);
  304. default:
  305. sprintf(errstr,"Unknown case in process_file()\n");
  306. return(PROGRAM_ERROR);
  307. }
  308. return(FINISHED); /* NOTREACHED */
  309. }
  310. /********************************************************************************************/
  311. /********************************** FORMERLY IN pconsistency.c ******************************/
  312. /********************************************************************************************/
  313. /****************************** CHECK_PARAM_VALIDITY_AND_CONSISTENCY *********************************/
  314. int check_param_validity_and_consistency(dataptr dz)
  315. {
  316. int exit_status = FINISHED;
  317. int temp;
  318. switch(dz->process) {
  319. case(HF_PERM1):
  320. dz->iparam[HP1_BOTNOTE] += MIDDLE_C_MIDI + (dz->iparam[HP1_BOTOCT] * 12);
  321. dz->iparam[HP1_TOPNOTE] += MIDDLE_C_MIDI + (dz->iparam[HP1_TOPOCT] * 12);
  322. if(dz->iparam[HP1_TOPNOTE] < dz->iparam[HP1_BOTNOTE]) {
  323. temp = dz->iparam[HP1_TOPNOTE];
  324. dz->iparam[HP1_TOPNOTE] = dz->iparam[HP1_BOTNOTE];
  325. dz->iparam[HP1_BOTNOTE] = temp;
  326. }
  327. /* fall thro */
  328. case(HF_PERM2):
  329. if(dz->mode == HFP_SNDOUT || dz->mode == HFP_SNDSOUT) {
  330. if(BAD_SR(dz->iparam[HP1_SRATE])) {
  331. sprintf(errstr,"Invalid sample rate.\n");
  332. return(DATA_ERROR);
  333. }
  334. dz->infile->channels = 1;
  335. dz->infile->srate = dz->iparam[HP1_SRATE];
  336. dz->infile->stype = SAMP_SHORT;
  337. dz->iparam[HP1_ELEMENT_SIZE] = (int)round(dz->param[HP1_ELEMENT_SIZE] * dz->infile->srate);
  338. dz->iparam[HP1_GAP_SIZE] = (int)round(dz->param[HP1_GAP_SIZE] * dz->infile->srate);
  339. dz->iparam[HP1_GGAP_SIZE] = (int)round(dz->param[HP1_GGAP_SIZE] * dz->infile->srate);
  340. }
  341. if(dz->mode == HFP_SNDOUT) {
  342. if((exit_status = create_sized_outfile(dz->outfilename,dz))<0)
  343. return(exit_status);
  344. }
  345. break;
  346. case(DEL_PERM):
  347. if(BAD_SR(dz->iparam[DP_SRATE])) {
  348. sprintf(errstr,"Invalid sample rate.\n");
  349. return(DATA_ERROR);
  350. }
  351. dz->infile->channels = 1;
  352. dz->infile->srate = dz->iparam[DP_SRATE];
  353. dz->infile->stype = SAMP_SHORT;
  354. dz->iparam[DP_DUR] = (int)round(dz->param[DP_DUR] * dz->infile->srate);
  355. if((exit_status = create_sized_outfile(dz->outfilename,dz))<0)
  356. return(exit_status);
  357. break;
  358. case(DEL_PERM2):
  359. dz->iparam[DP_DUR] = (int)(dz->insams[0]);
  360. break;
  361. }
  362. return(FINISHED);
  363. }
  364. /****************************** HFPERM_CONSISTENCY *********************************/
  365. int hfperm_consistency(dataptr dz)
  366. {
  367. return(FINISHED);
  368. }
  369. /********************************************************************************************/
  370. /********************************** FORMERLY IN buffers.c ***********************************/
  371. /********************************************************************************************/
  372. /**************************** ALLOCATE_LARGE_BUFFERS ******************************/
  373. int allocate_large_buffers(dataptr dz)
  374. {
  375. switch(dz->process) {
  376. case(HF_PERM1):
  377. case(HF_PERM2):
  378. if(dz->mode == HFP_SNDOUT || dz->mode == HFP_SNDSOUT)
  379. return create_hfpermbufs(dz);
  380. break;
  381. case(DEL_PERM):
  382. case(DEL_PERM2):
  383. return create_hfpermbufs(dz);
  384. default:
  385. sprintf(errstr,"Unknown program no. in allocate_large_buffers()\n");
  386. return(PROGRAM_ERROR);
  387. }
  388. return(FINISHED);
  389. }
  390. /********************************************************************************************/
  391. /********************************** FORMERLY IN cmdline.c ***********************************/
  392. /********************************************************************************************/
  393. int get_process_no(char *prog_identifier_from_cmdline,dataptr dz)
  394. {
  395. if (!strcmp(prog_identifier_from_cmdline,"hfchords")) dz->process = HF_PERM1;
  396. else if(!strcmp(prog_identifier_from_cmdline,"hfchords2")) dz->process = HF_PERM2;
  397. else if(!strcmp(prog_identifier_from_cmdline,"delperm")) dz->process = DEL_PERM;
  398. else if(!strcmp(prog_identifier_from_cmdline,"delperm2")) dz->process = DEL_PERM2;
  399. else {
  400. sprintf(errstr,"Unknown program identification string '%s'\n",prog_identifier_from_cmdline);
  401. return(USAGE_ONLY);
  402. }
  403. return(FINISHED);
  404. }
  405. /********************************************************************************************/
  406. /********************************** FORMERLY IN usage.c *************************************/
  407. /********************************************************************************************/
  408. /******************************** USAGE1 ********************************/
  409. int usage1(void)
  410. {
  411. sprintf(errstr,
  412. "USAGE: hfperm NAME (mode) outfile parameters\n"
  413. "\n"
  414. "where NAME can be any one of\n"
  415. "\n"
  416. "hfchords hfchords2 delperm\n"
  417. "\n"
  418. "OR: hfperm NAME (mode) infile outfile parameters\n"
  419. "\n"
  420. "where NAME can be any one of\n"
  421. "\n"
  422. "delperm2\n"
  423. "\n"
  424. "Type 'hfperm hfchords' for more info on hfperm hfchords option... ETC.\n");
  425. return(USAGE_ONLY);
  426. }
  427. /******************************** USAGE2 ********************************/
  428. int usage2(char *str)
  429. {
  430. if(!strcmp(str,"hfchords")) {
  431. fprintf(stdout,
  432. "GENERATE ALL CHORDS POSSIBLE FROM NOTES IN GIVEN SET, WITHIN GIVEN PITCH RANGE\n"
  433. "USING EACH NOTE (OR ITS OCTAVE TRANSPOSITION) ONCE ONLY IN ANY ONE CHORD.\n\n"
  434. "USAGE: hfperm hfchords 1 ifil ofil sr nd gd pd min bn bo tn to srt [-m -s -a -o]\n"
  435. "OR: hfperm hfchords 2 ifil ofil sr nd gd min bn bo tn to srt [-m -s -a -o]\n"
  436. "OR: hfperm hfchords 3-4 ifil ofil sr min bn bo tn to srt [-m -s -a -o]\n"
  437. "IFIL text input file of midi note values\n"
  438. "MODES: 1 SOUND OUT...Outputs 1 soundfile of all chords.\n"
  439. " 2 SOUNDS OUT..Outputs several sndfiles, chords grouped by sort specified\n"
  440. " 3 TEXT OUT ...Outputs textfile listing chords described by note names.\n"
  441. " 4 MIDI OUT ...Outputs list of chords described by MIDI values.\n"
  442. "PARAMETERS: OFIL output filename SR sample rate sound output\n"
  443. " ND duration each chord (secs) GD gap btwn chords (secs)\n"
  444. " PD gap btwn chord-groups MIN min no. notes to combine\n"
  445. "BN bottom note pitchrange, for derived chords (0-11 for C-C#....Bb-B)\n"
  446. "BO octave of bottom note (0 = octave upwards from middle C)\n"
  447. " TN top note of pitchrange TO octave of top note\n"
  448. "SRT 0 root: 1 topnote: 2 pitchclass: 3 chordtype: 4 chordtype(keep 1 of each)\n"
  449. " -m generate only chords of min number of notes specified\n"
  450. " -s in each group, put smallest span chord first (otherwise it goes last).\n"
  451. "-a do final sort by a method other than by chord density\n"
  452. " For ROOT or TOP NOTE sort, sort by way intervals stacked inside chord.\n"
  453. " For PITCHCLASS SET, sort by size of containing interval, then by density.\n"
  454. "-o eliminate chords duplicating-as-a-whole any chord 1 or more 8vas distant.\n");
  455. } else if(!strcmp(str,"hfchords2")) {
  456. fprintf(stdout,
  457. "GENERATE ALL CHORDS POSSIBLE FROM NOTES IN GIVEN SET.\n\n"
  458. "USAGE: hfperm hfchords2 1 ifil ofil sr nd gd pd min srt [-m -s -a -o]\n"
  459. "OR: hfperm hfchords2 2 ifil ofil sr nd gd min srt [-m -s -a -o]\n"
  460. "OR: hfperm hfchords2 3-4 ifil ofil sr min srt [-m -s -a -o]\n"
  461. "IFIL text input file of midi note values\n"
  462. "MODES: 1 SOUND OUT...Outputs 1 soundfile of the chords.\n"
  463. " 2 SOUNDS OUT..Outputs several sndfiles, chords grouped by sort specified\n"
  464. " 3 TEXT OUT ...Outputs textfile listing chords described by note names.\n"
  465. " 4 MIDI OUT ...Outputs list of chords described by MIDI values.\n"
  466. "PARAMETERS ARE\n"
  467. "SRATE sample rate of the sound output\n"
  468. "NOTE-DUR duration of each chord generated (secs)\n"
  469. "GAP-DUR duration of pauses between chords (secs)\n"
  470. "PAUSE-DUR duration of pauses between groups of chords (secs)\n"
  471. "MINSET minimum number of input notes to combine\n"
  472. "SORT BY 0 root: 1 topnote: 2 pitchclass set:\n"
  473. " 3 chord type: 4 chord type (keep 1 of each).\n"
  474. "-m generate only chords of min number of notes specified\n"
  475. "-s in each group, put smallest span chord first (otherwise it goes last).\n"
  476. "-a do final sort by a method other than by chord density\n"
  477. " For ROOT or TOP NOTE sort, sort by way intervals stacked inside chord.\n"
  478. " For PITCHCLASS SET, sort by size of containing interval, then by density\n"
  479. " -o eliminate chords duplicating-as-a-whole any chord 1 or more 8vas distant\n");
  480. } else if(!strcmp(str,"delperm")) {
  481. fprintf(stdout,
  482. "DELAY AND TRANSFORM EACH INPUT NOTE, CUMULATIVELY.\n\n"
  483. "USAGE: hfperm delperm 0 \n"
  484. " infile outfile permfile srate initial-notelen cycles-of-perm\n"
  485. "PARAMETERS ARE\n"
  486. " INFILE text input file of midi note values\n"
  487. " PERMFILE pairs of vals: 1st a semitone transpos, 2nd a time multiplier\n"
  488. " Sum of all time-multipliers must be 1.0\n"
  489. " SRATE sample rate of the sound output\n"
  490. " INITIAL-NOTELEN length of each input note, before it is transformed\n"
  491. " CYCLES-OF-PERM Number of times the permutation is recursively applied.\n");
  492. } else if(!strcmp(str,"delperm2")) {
  493. fprintf(stdout,
  494. "DELAY AND TRANSFORM EACH INPUT NOTE, CUMULATIVELY.\n\n"
  495. "USAGE: hfperm delperm2 0 \n"
  496. " infile outfile permfile cycles-of-perm\n"
  497. "PARAMETERS ARE\n"
  498. " PERMFILE pairs of vals: 1st a semitone transpos, 2nd a time multiplier\n"
  499. " Sum of all time-multipliers must be 1.0\n"
  500. " CYCLES-OF-PERM Number of times the permutation is recursively applied.\n");
  501. } else
  502. fprintf(stdout,"Unknown option '%s'\n",str);
  503. return(USAGE_ONLY);
  504. }
  505. /******************************** USAGE3 ********************************/
  506. int usage3(char *str1,char *str2)
  507. {
  508. sprintf(errstr,"Insufficient parameters on command line.\n");
  509. return(USAGE_ONLY);
  510. }
  511. /************************** ELIMINATE_OCTAVE_DUPLICATIONS **************************/
  512. int eliminate_octave_duplications(dataptr dz)
  513. {
  514. double *hf = dz->parray[0];
  515. int n, m, k, octaves_eliminated = 0;
  516. for(n=0;n< dz->iparam[HP1_HFCNT]-1;n++) {
  517. for(m=n+1;m< dz->iparam[HP1_HFCNT];m++) {
  518. if(flteq(fmod(hf[n],12.0),fmod(hf[m],12.0))) {
  519. octaves_eliminated = 1;
  520. k = m;
  521. dz->iparam[HP1_HFCNT]--;
  522. while(k < dz->iparam[HP1_HFCNT]) {
  523. hf[k] = hf[k+1];
  524. k++;
  525. }
  526. m--;
  527. }
  528. }
  529. }
  530. return octaves_eliminated;
  531. }
  532. /************************** CHECK_FOR_INVALID_DATA **************************/
  533. int check_for_invalid_data(int k,dataptr dz)
  534. {
  535. double *hf = dz->parray[0];
  536. int *bad, badcnt = 0;
  537. int n;
  538. if((bad = (int *)malloc(dz->iparam[k] * sizeof(int)))==NULL)
  539. return(MEMORY_ERROR);
  540. for(n=0;n< dz->iparam[k];n++) {
  541. if(hf[n] < MIDIMIN || hf[n] > MIDIMAX)
  542. bad[badcnt++] = n;
  543. }
  544. if(badcnt) {
  545. print_outmessage_flush("Invalid midi data in input.....\n");
  546. for(n=0;n < badcnt;n++) {
  547. sprintf(errstr,"item %d : value %ld\n",bad[n], round(hf[bad[n]]));
  548. print_outmessage_flush(errstr);
  549. }
  550. sprintf(errstr,"Cannot proceed\n");
  551. return(DATA_ERROR);
  552. }
  553. return FINISHED;
  554. }
  555. /**************************** TRANSPOSE_TO_LOWEST_OCT *******************************/
  556. void transpose_to_lowest_oct(dataptr dz)
  557. {
  558. int n;
  559. double *hf = dz->parray[0];
  560. for(n=0;n<dz->iparam[HP1_HFCNT];n++) {
  561. while(hf[n] < (double)dz->iparam[HP1_BOTNOTE])
  562. hf[n] += 12.0;
  563. while(hf[n] >= (double)dz->iparam[HP1_BOTNOTE])
  564. hf[n] -= 12.0;
  565. hf[n] += 12.0;
  566. }
  567. }
  568. /**************************** BUBLSORT_HF *******************************/
  569. void bublsort_hf(dataptr dz)
  570. {
  571. int n, m;
  572. double temp;
  573. double *hf = dz->parray[0];
  574. for(n=0;n<dz->iparam[HP1_HFCNT]-1;n++) {
  575. for(m = n; m<dz->iparam[HP1_HFCNT]; m++) {
  576. if(hf[m] < hf[n]) {
  577. temp = hf[n];
  578. hf[n] = hf[m];
  579. hf[m] = temp;
  580. }
  581. }
  582. }
  583. }
  584. /**************************** ELIM_DUPLS *******************************/
  585. void elim_dupls(dataptr dz)
  586. {
  587. int n, m, k;
  588. double *hf = dz->parray[0];
  589. for(n=0;n<dz->iparam[HP1_HFCNT]-1;n++) {
  590. for(m = n+1; m<dz->iparam[HP1_HFCNT]; m++) {
  591. if(hf[m] == hf[n]) {
  592. for(k = m+1; k < dz->iparam[HP1_HFCNT];k++)
  593. hf[k-1] = hf[k];
  594. dz->iparam[HP1_HFCNT]--;
  595. m--;
  596. }
  597. }
  598. }
  599. }
  600. /******************************** INNER_LOOP (redundant) ********************************/
  601. int inner_loop
  602. (int *peakscore,int *descnt,int *in_start_portion,int *least,int *pitchcnt,int windows_in_buf,dataptr dz)
  603. {
  604. return(FINISHED);
  605. }
  606. /*************************** CREATE_HFPERMBUFS **************************/
  607. int create_hfpermbufs(dataptr dz)
  608. {
  609. unsigned int presize = 0;
  610. //TW ADDED
  611. size_t bigbufsize;
  612. int fbytesector = F_SECSIZE * sizeof(float);
  613. int max_jitter = (int)round((double)HFP_MAXJITTER * (double)MS_TO_SECS * (double)dz->infile->srate);
  614. int k = 0;
  615. switch(dz->process) {
  616. case(HF_PERM1):
  617. case(HF_PERM2):
  618. k = HP1_ELEMENT_SIZE;
  619. break;
  620. case(DEL_PERM):
  621. case(DEL_PERM2):
  622. k = DP_DUR;
  623. break;
  624. }
  625. if(dz->sbufptr == 0 || dz->sampbuf==0) {
  626. sprintf(errstr,"buffer pointers not allocated: create_hfpermbufs()\n");
  627. return(PROGRAM_ERROR);
  628. }
  629. switch(dz->process) {
  630. case(HF_PERM1):
  631. case(HF_PERM2):
  632. presize = (dz->iparam[k] + max_jitter + HFP_TABSIZE + 1) * sizeof(double);
  633. break;
  634. case(DEL_PERM):
  635. presize = ((dz->iparam[k] * 2) + max_jitter + HFP_TABSIZE + 1) * sizeof(double);
  636. break;
  637. case(DEL_PERM2):
  638. presize = ((dz->iparam[k] * 2) + max_jitter) * sizeof(double)
  639. + dz->iparam[k] * sizeof(float);
  640. break;
  641. }
  642. //TW CHANGED FOR FLOATS
  643. bigbufsize = (size_t) Malloc(-1);
  644. if((bigbufsize = (bigbufsize/fbytesector) * fbytesector)<=0)
  645. bigbufsize = fbytesector;
  646. while((dz->bigbuf = (float *)malloc((size_t)(bigbufsize + presize))) == NULL) {
  647. if((bigbufsize -= fbytesector) <= 0) {
  648. sprintf(errstr,"INSUFFICIENT MEMORY to create sound buffers.\n");
  649. return(PROGRAM_ERROR);
  650. }
  651. }
  652. dz->buflen = (int)(bigbufsize/sizeof(float));
  653. memset(dz->bigbuf,0,bigbufsize + presize);
  654. switch(dz->process) {
  655. case(HF_PERM1):
  656. case(HF_PERM2):
  657. case(DEL_PERM):
  658. dz->sbufptr[0] = dz->sampbuf[0] = dz->bigbuf;
  659. dz->sbufptr[1] = dz->sampbuf[1] = dz->bigbuf + dz->buflen;
  660. dz->sampbuf[2] = (float *)((double *)dz->sampbuf[1] + HFP_TABSIZE + 1);
  661. dz->sampbuf[3] = (float *)((double *)dz->sampbuf[2] + dz->iparam[k] + max_jitter);
  662. if(dz->process == DEL_PERM)
  663. dz->sampbuf[4] = (float *)((double *)dz->sampbuf[3] + dz->iparam[k]);
  664. establish_waveform(dz);
  665. break;
  666. case(DEL_PERM2):
  667. dz->sbufptr[0] = dz->sampbuf[0] = dz->bigbuf;
  668. dz->sbufptr[1] = dz->sampbuf[1] = dz->bigbuf + dz->buflen;
  669. dz->sampbuf[2] = dz->sampbuf[1] + dz->insams[0];
  670. dz->sampbuf[3] = (float *)((double *)dz->sampbuf[2] + dz->iparam[k] + max_jitter);
  671. dz->sampbuf[4] = (float *)((double *)dz->sampbuf[3] + dz->iparam[k]);
  672. break;
  673. }
  674. return(FINISHED);
  675. }
  676. /*************************** ESTABLISH_WAVEFORM **************************
  677. *
  678. * Odd harmonics, declining in amplitude 1, 1/2. 1.3, 1/4 etc...
  679. */
  680. void establish_waveform(dataptr dz)
  681. {
  682. int n, partialno, ampdivide;
  683. double j, maxval = 0.0, normaliser;
  684. double *sintab = (double *)dz->sampbuf[1];
  685. memset((char *)sintab,0,HFP_TABSIZE * sizeof(double));
  686. for(partialno=1,ampdivide=1;partialno<12;partialno+=2,ampdivide++) {
  687. for(n=0;n < HFP_TABSIZE; n++) {
  688. j = sin(TWOPI * partialno * (double)n/(double)HFP_TABSIZE)/(double)ampdivide;
  689. *sintab += j;
  690. maxval = max(maxval,fabs(*sintab));
  691. sintab++;
  692. }
  693. j = sin(TWOPI * partialno * (double)n/(double)HFP_TABSIZE)/(double)ampdivide;
  694. *sintab += j;
  695. maxval = max(maxval,fabs(*sintab));
  696. sintab = (double *)dz->sampbuf[1];
  697. }
  698. normaliser = 1.0/maxval;
  699. for(n=0;n < HFP_TABSIZE; n++)
  700. *sintab++ *= normaliser;
  701. }
  702. /************************** READ_DELPERM_DATA ********************************/
  703. int read_delperm_data(char *filename,dataptr dz)
  704. {
  705. int n = 0, k, valcnt = 0;
  706. char temp[200], *p;
  707. double *val;
  708. // int is_transpos = TRUE;
  709. double dursum = 0.0;
  710. int arraysize = BIGARRAY;
  711. if((dz->fp = fopen(filename,"r"))==NULL) {
  712. sprintf(errstr,"Cannot open datafile %s\n",filename);
  713. return(DATA_ERROR);
  714. }
  715. if((val = (double *)malloc(arraysize * sizeof(double)))==NULL) {
  716. sprintf(errstr,"No memory for permutation data.\n");
  717. return(MEMORY_ERROR);
  718. }
  719. while(fgets(temp,200,dz->fp)!=NULL) {
  720. p = temp;
  721. while(strgetfloat(&p,&(val[valcnt]))) {
  722. if(++valcnt > arraysize) {
  723. arraysize += BIGARRAY;
  724. if((val = (double *)realloc((char *)val,arraysize * sizeof(double)))==NULL) {
  725. sprintf(errstr,"Out of memory loading permutation data.\n");
  726. return(MEMORY_ERROR);
  727. }
  728. }
  729. }
  730. }
  731. if(valcnt < arraysize) {
  732. if((val = (double *)realloc((char *)val,valcnt * sizeof(double)))==NULL) {
  733. sprintf(errstr,"Squeezing permutation data.\n");
  734. return(MEMORY_ERROR);
  735. }
  736. }
  737. if(ODD(valcnt)) {
  738. sprintf(errstr,"Permutation data incorrectly paired.\n");
  739. return(DATA_ERROR);
  740. }
  741. valcnt /= 2;
  742. if((dz->parray[1] = (double *)malloc(valcnt * sizeof(double)))==NULL) {
  743. sprintf(errstr,"No memory for transposition data.\n");
  744. return(MEMORY_ERROR);
  745. }
  746. if((dz->parray[2] = (double *)malloc(valcnt * sizeof(double)))==NULL) {
  747. sprintf(errstr,"No memory for transposition data.\n");
  748. return(MEMORY_ERROR);
  749. }
  750. for(n=0,k=0;n<valcnt;n++) {
  751. if((dz->parray[1][n] = val[k++]) < dz->application->min_special
  752. || dz->parray[1][n] > dz->application->max_special) {
  753. sprintf(errstr,"Transposition value %lf out of range, in permutation data.\n",dz->parray[1][n]);
  754. return(DATA_ERROR);
  755. }
  756. if((dz->parray[2][n] = val[k++]) < dz->application->min_special2
  757. || dz->parray[2][n] > dz->application->max_special2) {
  758. sprintf(errstr,"Duration multiplier value %lf out of range, in permutation data.\n",dz->parray[2][n]);
  759. return(DATA_ERROR);
  760. }
  761. dursum += dz->parray[2][n];
  762. }
  763. if(!flteq(dursum,1.0)) {
  764. sprintf(errstr,"Duration multipliers in permutation data do not sum to 1.0.\n");
  765. return(DATA_ERROR);
  766. }
  767. free(val);
  768. if(fclose(dz->fp)<0) {
  769. fprintf(stdout,"WARNING: Failed to close input textfile %s.\n",filename);
  770. fflush(stdout);
  771. }
  772. dz->iparam[DP_PERMCNT] = valcnt;
  773. return(FINISHED);
  774. }
  775. /************************** READ_DELPERM2_DATA ********************************/
  776. int read_delperm2_data(char *filename,dataptr dz)
  777. {
  778. int n = 0, k, valcnt = 0/*, linecnt = 0*/;
  779. char temp[200], *p;
  780. double *val;
  781. // int is_transpos = TRUE;
  782. double dursum = 0.0;
  783. int arraysize = BIGARRAY;
  784. if((dz->fp = fopen(filename,"r"))==NULL) {
  785. sprintf(errstr,"Cannot open datafile %s\n",filename);
  786. return(DATA_ERROR);
  787. }
  788. if((val = (double *)malloc(arraysize * sizeof(double)))==NULL) {
  789. sprintf(errstr,"No memory for permutation data.\n");
  790. return(MEMORY_ERROR);
  791. }
  792. while(fgets(temp,200,dz->fp)!=NULL) {
  793. p = temp;
  794. while(strgetfloat(&p,&(val[valcnt]))) {
  795. if(++valcnt > arraysize) {
  796. arraysize += BIGARRAY;
  797. if((val = (double *)realloc((char *)val,arraysize * sizeof(double)))==NULL) {
  798. sprintf(errstr,"Out of memory loading permutation data.\n");
  799. return(MEMORY_ERROR);
  800. }
  801. }
  802. }
  803. /* if(!linecnt) {
  804. if((dz->parray[0] = (double *)malloc(valcnt * sizeof(double)))==NULL) {
  805. sprintf(errstr,"No memory for midi transposition data data.\n");
  806. return(MEMORY_ERROR);
  807. }
  808. dz->iparam[DP_NOTECNT] = valcnt;
  809. memcpy((char *)dz->parray[0],(char *)val,valcnt * sizeof(double));
  810. linecnt++;
  811. valcnt = 0;
  812. continue;
  813. }
  814. */
  815. }
  816. if(valcnt < arraysize) {
  817. if((val = (double *)realloc((char *)val,valcnt * sizeof(double)))==NULL) {
  818. sprintf(errstr,"Squeezing permutation data.\n");
  819. return(MEMORY_ERROR);
  820. }
  821. }
  822. if(ODD(valcnt)) {
  823. sprintf(errstr,"Permutation data incorrectly paired.\n");
  824. return(DATA_ERROR);
  825. }
  826. valcnt /= 2;
  827. if((dz->parray[1] = (double *)malloc(valcnt * sizeof(double)))==NULL) {
  828. sprintf(errstr,"No memory for transposition data.\n");
  829. return(MEMORY_ERROR);
  830. }
  831. if((dz->parray[2] = (double *)malloc(valcnt * sizeof(double)))==NULL) {
  832. sprintf(errstr,"No memory for duration multiplier data.\n");
  833. return(MEMORY_ERROR);
  834. }
  835. for(n=0,k=0;n<valcnt;n++) {
  836. if((dz->parray[1][n] = val[k++]) < dz->application->min_special
  837. || dz->parray[1][n] > dz->application->max_special) {
  838. sprintf(errstr,"Transposition value %lf out of range, in permutation data.\n",dz->parray[1][n]);
  839. return(DATA_ERROR);
  840. }
  841. if((dz->parray[2][n] = val[k++]) < dz->application->min_special2
  842. || dz->parray[2][n] > dz->application->max_special2) {
  843. sprintf(errstr,"Duration multiplier value %lf out of range, in permutation data.\n",dz->parray[2][n]);
  844. return(DATA_ERROR);
  845. }
  846. dursum += dz->parray[2][n];
  847. }
  848. if(!flteq(dursum,1.0)) {
  849. sprintf(errstr,"Duration multipliers in permutation data do not sum to 1.0. (%lf)\n",dursum);
  850. return(DATA_ERROR);
  851. }
  852. free(val);
  853. if(fclose(dz->fp)<0) {
  854. fprintf(stdout,"WARNING: Failed to close input textfile %s.\n",filename);
  855. fflush(stdout);
  856. }
  857. dz->iparam[DP_PERMCNT] = valcnt;
  858. return(FINISHED);
  859. }