musunit.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668
  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 <pnames.h>
  26. #include <sndinfo.h>
  27. #include <globcon.h>
  28. #include <modeno.h>
  29. #include <math.h>
  30. #include <string.h>
  31. #include <ctype.h>
  32. #include <sfsys.h>
  33. #if defined unix || defined __GNUC__
  34. #define round(x) lround((x))
  35. #endif
  36. #define NOTEMIN ("A-4")
  37. #define NOTEMAX ("G5")
  38. #define FRQMAX (12543) /* Approx frequency at MIDI 127 */
  39. #define CONVERT_LOG10_TO_LOG2 (3.321928)
  40. #define my_LOG2(x) (log10(x) * CONVERT_LOG10_TO_LOG2)
  41. #define my_ANTILOG2(x) (pow(2.0,x))
  42. #define LOG_SEMITONE_INTERVAL (0.0250858329719984)
  43. #define QTONE_PER_OCT (24)
  44. //static double readnote(char *note,dataptr dz);
  45. static int midi_to_frq(double midi);
  46. static int frq_to_midi(double frq);
  47. static void note_to_frq(double midi);
  48. //static void note_to_midi(int argc,char *argv[]);
  49. static int ratio_to_semitones(double ratio);
  50. static int ratio_to_interval(double ratio);
  51. static int r_to_i(double ratio);
  52. static void semitones_to_ratio(double semitone_cnt);
  53. //static int interval_to_semitones(char *str,double *semitiones);
  54. static void semitones_to_oct(double semitone_cnt);
  55. static void oct_to_semitones(double oct);
  56. static void oct_to_ratio(double oct);
  57. static int ratio_to_oct(double ratio);
  58. static int do_fraction(double val);
  59. static int ratio_to_time(double ratio);
  60. static int time_to_ratio(double timestr);
  61. static void semitones_to_time(double timestr);
  62. static void oct_to_time(double oct);
  63. static int time_to_semitones(double timestr);
  64. static int time_to_intervals(double timestr);
  65. static int time_to_oct(double timestr);
  66. static int semitones_to_interval(double sc);
  67. static void gain_to_db(double gain);
  68. static void db_to_gain(double dbgain);
  69. static int midi_to_note(double val,dataptr dz);
  70. static void delay_to_frq(double val);
  71. static int delay_to_midi(double val);
  72. static void frq_to_delay(double val);
  73. static int midi_to_delay(double val);
  74. static int tempo_to_delay(double val);
  75. static int delay_to_tempo(double val);
  76. /************************ DO_MUSUNITS *************************/
  77. int do_musunits(dataptr dz)
  78. {
  79. int exit_status = FINISHED, k;
  80. switch(dz->mode) {
  81. case(MU_MIDI_TO_FRQ): exit_status = midi_to_frq(dz->param[MUSUNIT]); break;
  82. case(MU_FRQ_TO_MIDI): exit_status = frq_to_midi(dz->param[MUSUNIT]); break;
  83. case(MU_NOTE_TO_FRQ): note_to_frq(dz->scalefact); break;
  84. case(MU_NOTE_TO_MIDI):
  85. k = round(dz->scalefact);
  86. if(!flteq((double)k,dz->scalefact))
  87. sprintf(errstr,"MIDI value = %lf or approx %d\n",dz->scalefact,k);
  88. else
  89. sprintf(errstr,"MIDI value = %d\n",k);
  90. break;
  91. case(MU_FRQ_TO_NOTE):
  92. case(MU_MIDI_TO_NOTE): midi_to_note(dz->param[MUSUNIT],dz); break;
  93. case(MU_FRQRATIO_TO_SEMIT): exit_status = ratio_to_semitones(dz->param[MUSUNIT]); break;
  94. case(MU_FRQRATIO_TO_INTVL): exit_status = ratio_to_interval(dz->param[MUSUNIT]); break;
  95. case(MU_INTVL_TO_FRQRATIO): semitones_to_ratio(dz->scalefact); break;
  96. case(MU_SEMIT_TO_FRQRATIO): semitones_to_ratio(dz->param[MUSUNIT]); break;
  97. case(MU_OCTS_TO_FRQRATIO): oct_to_ratio(dz->param[MUSUNIT]); break;
  98. case(MU_OCTS_TO_SEMIT): oct_to_semitones(dz->param[MUSUNIT]); break;
  99. case(MU_FRQRATIO_TO_OCTS): exit_status = ratio_to_oct(dz->param[MUSUNIT]); break;
  100. case(MU_SEMIT_TO_OCTS): semitones_to_oct(dz->param[MUSUNIT]); break;
  101. case(MU_SEMIT_TO_INTVL): exit_status = semitones_to_interval(dz->param[MUSUNIT]); break;
  102. case(MU_FRQRATIO_TO_TSTRETH): exit_status = ratio_to_time(dz->param[MUSUNIT]); break;
  103. case(MU_SEMIT_TO_TSTRETCH): semitones_to_time(dz->param[MUSUNIT]); break;
  104. case(MU_OCTS_TO_TSTRETCH): oct_to_time(dz->param[MUSUNIT]); break;
  105. case(MU_INTVL_TO_TSTRETCH): semitones_to_time(dz->scalefact); break;
  106. case(MU_TSTRETCH_TO_FRQRATIO): exit_status = time_to_ratio(dz->param[MUSUNIT]); break;
  107. case(MU_TSTRETCH_TO_SEMIT): exit_status = time_to_semitones(dz->param[MUSUNIT]); break;
  108. case(MU_TSTRETCH_TO_OCTS): exit_status = time_to_oct(dz->param[MUSUNIT]); break;
  109. case(MU_TSTRETCH_TO_INTVL): exit_status = time_to_intervals(dz->param[MUSUNIT]); break;
  110. case(MU_GAIN_TO_DB): gain_to_db(dz->param[MUSUNIT]); break;
  111. case(MU_DB_TO_GAIN): db_to_gain(dz->param[MUSUNIT]); break;
  112. case(MU_DELAY_TO_FRQ): delay_to_frq(dz->param[MUSUNIT]); break;
  113. case(MU_DELAY_TO_MIDI): exit_status = delay_to_midi(dz->param[MUSUNIT]); break;
  114. case(MU_FRQ_TO_DELAY): frq_to_delay(dz->param[MUSUNIT]); break;
  115. case(MU_MIDI_TO_DELAY): exit_status = midi_to_delay(dz->param[MUSUNIT]); break;
  116. case(MU_NOTE_TO_DELAY): exit_status = midi_to_delay(dz->scalefact); break;
  117. case(MU_TEMPO_TO_DELAY): exit_status = tempo_to_delay(dz->param[MUSUNIT]); break;
  118. case(MU_DELAY_TO_TEMPO): exit_status = delay_to_tempo(dz->param[MUSUNIT]); break;
  119. default:
  120. sprintf(errstr,"Unknown mode in do_musunits()\n");
  121. return(PROGRAM_ERROR);
  122. }
  123. sprintf(errstr,"%s",errstr);
  124. print_outmessage_flush(errstr);
  125. return(exit_status);
  126. }
  127. /**************************** MIDI_TO_FRQ **************************/
  128. int midi_to_frq(double midi)
  129. {
  130. double frq;
  131. if(midi<(double)MIDIMIN || midi >(double)MIDIMAX) {
  132. sprintf(errstr,"MIDI value out of range %d - %d\n",MIDIMIN,MIDIMAX);
  133. return(GOAL_FAILED);
  134. }
  135. frq = midi;
  136. frq += 3.0;
  137. frq /= SEMITONES_PER_OCTAVE;
  138. frq = pow((double)2,frq);
  139. frq *= LOW_A;
  140. sprintf(errstr,"frequency = %lf\n",frq);
  141. return(FINISHED);
  142. }
  143. /************************ FRQ_TO_MIDI *****************/
  144. int frq_to_midi(double frq)
  145. {
  146. double midi;
  147. if(frq<MINPITCH || frq >(double)FRQMAX) {
  148. sprintf(errstr,"Frq value out of range %ld - %d\n",round(MINPITCH),FRQMAX);
  149. return(GOAL_FAILED);
  150. }
  151. midi = frq;
  152. midi /= LOW_A;
  153. midi = my_LOG2(midi);
  154. midi *= SEMITONES_PER_OCTAVE;
  155. midi -= 3.0;
  156. sprintf(errstr,"MIDI value = %lf or approx %ld\n",midi,round(midi));
  157. return(FINISHED);
  158. }
  159. /************************** NOTE_TO_FRQ *************************/
  160. void note_to_frq(double midi)
  161. {
  162. double frq;
  163. frq = midi;
  164. frq += 3.0;
  165. frq /= SEMITONES_PER_OCTAVE;
  166. frq = pow((double)2,frq);
  167. frq *= LOW_A;
  168. sprintf(errstr,"Frequency = %lf\n",frq);
  169. }
  170. /************************* RATIO_TO_SEMITONES **********************/
  171. int ratio_to_semitones(double ratio)
  172. {
  173. double semitone_cnt;
  174. if(ratio <= 0.0) {
  175. sprintf(errstr,"Freq ratio <= 0.0 : impossible.\n");
  176. return(GOAL_FAILED);
  177. }
  178. semitone_cnt = fabs(log10(ratio)/(double)LOG_SEMITONE_INTERVAL);
  179. //TW UPDATE
  180. if(ratio < 1.0)
  181. semitone_cnt = -semitone_cnt;
  182. sprintf(errstr,"%lf semitones\n",semitone_cnt);
  183. return(FINISHED);
  184. }
  185. /************************* RATIO_TO_SEMITONES **********************/
  186. int ratio_to_interval(double ratio)
  187. {
  188. if(ratio <= 0.0) {
  189. sprintf(errstr,"Freq ratio <= 0.0 : impossible.\n");
  190. return(GOAL_FAILED);
  191. }
  192. return r_to_i(ratio);
  193. }
  194. /************************* R_TO_I **********************/
  195. int r_to_i(double ratio)
  196. {
  197. double semitone_cnt;
  198. int oct_cnt, qtone_cnt;
  199. semitone_cnt = fabs(log10(ratio)/(double)LOG_SEMITONE_INTERVAL);
  200. qtone_cnt = round(semitone_cnt * 2);
  201. oct_cnt = qtone_cnt/QTONE_PER_OCT;
  202. qtone_cnt -= oct_cnt * QTONE_PER_OCT;
  203. switch(oct_cnt) {
  204. case(1): sprintf(errstr,"1 octave"); break;
  205. case(0): break;
  206. default:
  207. sprintf(errstr,"%d octaves",oct_cnt);
  208. break;
  209. }
  210. if(qtone_cnt && oct_cnt)
  211. strcat(errstr," and a ");
  212. switch(qtone_cnt) {
  213. case(0):
  214. if(oct_cnt==0) {
  215. sprintf(errstr,"Unison.\n");
  216. return(FINISHED);
  217. }
  218. break;
  219. case(1): strcat(errstr,"minor 2nd-\n"); break;
  220. case(2): strcat(errstr,"minor 2nd\n"); break;
  221. case(3): strcat(errstr,"minor 2nd+\n"); break;
  222. case(4): strcat(errstr,"major 2nd\n"); break;
  223. case(5): strcat(errstr,"major 2nd+\n"); break;
  224. case(6): strcat(errstr,"minor 3rd\n"); break;
  225. case(7): strcat(errstr,"minor 3rd+\n"); break;
  226. case(8): strcat(errstr,"major 3rd\n"); break;
  227. case(9): strcat(errstr,"major 3rd+\n"); break;
  228. case(10): strcat(errstr,"4th\n"); break;
  229. case(11): strcat(errstr,"4th+\n"); break;
  230. case(12): strcat(errstr,"augmented 4th\n"); break;
  231. case(13): strcat(errstr,"augmented 4th+\n"); break;
  232. case(14): strcat(errstr,"5th\n"); break;
  233. case(15): strcat(errstr,"5th+\n"); break;
  234. case(16): strcat(errstr,"minor 6th\n"); break;
  235. case(17): strcat(errstr,"minor 6th+\n"); break;
  236. case(18): strcat(errstr,"major 6th\n"); break;
  237. case(19): strcat(errstr,"major 6th+\n"); break;
  238. case(20): strcat(errstr,"minor 7th\n"); break;
  239. case(21): strcat(errstr,"minor 7th+\n"); break;
  240. case(22): strcat(errstr,"major 7th\n"); break;
  241. case(23): strcat(errstr,"major 7th+\n"); break;
  242. }
  243. return(FINISHED);
  244. }
  245. /************************ SEMITONES_TO_RATIO *******************/
  246. void semitones_to_ratio(double semitone_cnt)
  247. {
  248. double ratio;
  249. ratio = pow((double)SEMITONE_INTERVAL,semitone_cnt);
  250. sprintf(errstr,"frequency ratio is %.8lf\n",ratio);
  251. }
  252. /******************************** SEMITONES_TO_OCT ***********************/
  253. void semitones_to_oct(double semitone_cnt)
  254. {
  255. double oct;
  256. oct = (double)semitone_cnt/SEMITONES_PER_OCTAVE;
  257. sprintf(errstr,"octave_distance is %.8lf\n",oct);
  258. }
  259. /******************************** OCT_TO_SEMITONES ***********************/
  260. void oct_to_semitones(double oct)
  261. {
  262. double semitone_cnt;
  263. semitone_cnt = oct * SEMITONES_PER_OCTAVE;
  264. sprintf(errstr,"semitone count is %.8lf\n",semitone_cnt);
  265. }
  266. /******************************** OCT_TO_RATIO ***********************/
  267. void oct_to_ratio(double oct)
  268. {
  269. double ratio = my_ANTILOG2(oct);
  270. sprintf(errstr,"Frequency ratio is %.8lf\n",ratio);
  271. }
  272. /******************************** RATIO_TO_OCT ***********************/
  273. int ratio_to_oct(double ratio)
  274. {
  275. int exit_status;
  276. double oct;
  277. if(ratio <= FLTERR) {
  278. sprintf(errstr,"Interval ratio too small or negative (Impossible).\n");
  279. return(GOAL_FAILED);
  280. }
  281. oct = my_LOG2(ratio);
  282. sprintf(errstr,"Octave distance is ");
  283. if((exit_status = do_fraction(oct))<0)
  284. return(exit_status);
  285. strcat(errstr,"\n");
  286. return(FINISHED);
  287. }
  288. /*********************************** DO_FRACTION ******************************/
  289. int do_fraction(double val)
  290. {
  291. int n, m, k = 0;
  292. int is_neg = 0;
  293. double d, test, thisval = val;
  294. char temp[64];
  295. if(val <0.0) {
  296. thisval = -thisval;
  297. is_neg = 1;
  298. }
  299. for(n=1;n<5;n*=2) {
  300. d = 1.0/(double)n;
  301. if((test = fmod(thisval,d))< FLTERR || d - test < FLTERR) {
  302. m = (int)(thisval/d); /* truncate */
  303. if(!flteq((double)m * d,thisval))
  304. m++;
  305. if(!flteq((double)m * d,thisval)) {
  306. m-=2;
  307. if(!flteq((double)m * d,thisval)) {
  308. sprintf(errstr,"Problem in fractions\n");
  309. return(PROGRAM_ERROR);
  310. }
  311. }
  312. k = 0L;
  313. if(m >= n) {
  314. k = m/n; /* truncate */
  315. m -= k * n;
  316. }
  317. if(is_neg)
  318. strcat(errstr,"-");
  319. if(k) {
  320. sprintf(temp,"%d",k);
  321. strcat(errstr,temp);
  322. }
  323. switch(n) {
  324. case(2):
  325. if(m) strcat(errstr,".5");
  326. break;
  327. case(4):
  328. switch(m) {
  329. case(1): strcat(errstr,".25"); break;
  330. case(2): strcat(errstr,".5"); break;
  331. case(3): strcat(errstr,".75"); break;
  332. }
  333. }
  334. return(FINISHED);
  335. }
  336. }
  337. sprintf(temp,"%lf",val);
  338. strcat(errstr,temp);
  339. return(FINISHED);
  340. }
  341. /******************************** RATIO_TO_TIME ********************************/
  342. int ratio_to_time(double ratio)
  343. {
  344. if(ratio <= 0.0) {
  345. sprintf(errstr,"Freq ratio <= 0.0 : impossible.\n");
  346. return(GOAL_FAILED);
  347. }
  348. sprintf(errstr,"Timestretch is %lf\n",1.0/ratio);
  349. return(FINISHED);
  350. }
  351. /******************************** TIME_TO_RATIO ********************************/
  352. int time_to_ratio(double timestr)
  353. {
  354. if(timestr <= 0.0) {
  355. sprintf(errstr,"timestretch <= 0.0 : impossible.\n");
  356. return(GOAL_FAILED);
  357. }
  358. sprintf(errstr,"Timestretch is %lf\n",1.0/timestr);
  359. return(FINISHED);
  360. }
  361. /******************************** SEMITONES_TO_TIME ********************************/
  362. void semitones_to_time(double semitone_cnt)
  363. {
  364. double ratio;
  365. ratio = pow((double)SEMITONE_INTERVAL,semitone_cnt);
  366. sprintf(errstr,"Timestretch is %lf\n",1.0/ratio);
  367. }
  368. /******************************** OCT_TO_TIME ********************************/
  369. void oct_to_time(double oct)
  370. {
  371. double ratio;
  372. ratio = my_ANTILOG2(oct);
  373. sprintf(errstr,"Timestretch is %lf\n",1.0/ratio);
  374. }
  375. /******************************** TIME_TO_SEMITONES ********************************/
  376. int time_to_semitones(double timestr)
  377. {
  378. double semitone_cnt;
  379. double ratio;
  380. if(timestr <= 0.0) {
  381. sprintf(errstr,"timestretch <= 0.0 : impossible.\n");
  382. return(GOAL_FAILED);
  383. }
  384. ratio = 1.0/timestr;
  385. semitone_cnt = log10(ratio)/(double)LOG_SEMITONE_INTERVAL;
  386. sprintf(errstr,"%lf semitones\n",semitone_cnt);
  387. return(FINISHED);
  388. }
  389. /******************************** TIME_TO_INTERVALS ********************************/
  390. int time_to_intervals(double timestr)
  391. {
  392. int exit_status;
  393. double ratio;
  394. char *p;
  395. if(timestr <= 0.0) {
  396. sprintf(errstr,"timestretch <= 0.0 : impossible.\n");
  397. return(GOAL_FAILED);
  398. }
  399. ratio = 1.0/timestr;
  400. if((exit_status = r_to_i(ratio))<0)
  401. return(exit_status);
  402. if(ratio<1.0) {
  403. p = errstr;
  404. while(*p != ENDOFSTR) {
  405. if(*p == NEWLINE) {
  406. *p = ENDOFSTR;
  407. break;
  408. }
  409. p++;
  410. }
  411. strcat(errstr," Downwards.\n");
  412. }
  413. return(FINISHED);
  414. }
  415. /******************************** TIME_TO_OCT ********************************/
  416. int time_to_oct(double timestr)
  417. {
  418. int exit_status;
  419. double oct;
  420. if(timestr <= 0.0) {
  421. sprintf(errstr,"timestretch <= 0.0 : impossible.\n");
  422. return(GOAL_FAILED);
  423. }
  424. //TW UPDATE
  425. if(flteq((oct = my_LOG2(1.0/timestr)),0.0)) {
  426. sprintf(errstr,"Octave distance is 0\n");
  427. return(FINISHED);
  428. }
  429. sprintf(errstr,"Octave distance is ");
  430. if((exit_status = do_fraction(oct))<0)
  431. return(exit_status);
  432. strcat(errstr,"\n");
  433. return(FINISHED);
  434. }
  435. /********************** SEMITONES_TO_INTERVAL **********************/
  436. int semitones_to_interval(double sc)
  437. {
  438. int ocnt = 0, qcnt, scnt, neg = 0;
  439. char temp[200];
  440. errstr[0] = ENDOFSTR;
  441. if(sc < 0.0)
  442. neg = 1;
  443. sc = fabs(sc);
  444. ocnt = round(floor(sc/SEMITONES_PER_OCTAVE));
  445. sc = fmod(sc,SEMITONES_PER_OCTAVE);
  446. qcnt = round(sc * 2.0);
  447. scnt = qcnt/2;
  448. if(scnt*2 != qcnt)
  449. qcnt = 1;
  450. else
  451. qcnt = 0;
  452. switch(scnt) {
  453. case(0): break;
  454. case(1): sprintf(errstr,"minor 2nd"); break;
  455. case(2): sprintf(errstr,"2ns"); break;
  456. case(3): sprintf(errstr,"minor 3rd"); break;
  457. case(4): sprintf(errstr,"3rd"); break;
  458. case(5): sprintf(errstr,"4th"); break;
  459. case(6): sprintf(errstr,"#4th"); break;
  460. case(7): sprintf(errstr,"5th"); break;
  461. case(8): sprintf(errstr,"minor 6th"); break;
  462. case(9): sprintf(errstr,"6th"); break;
  463. case(10): sprintf(errstr,"minor 7th"); break;
  464. case(11): sprintf(errstr,"7th"); break;
  465. default:
  466. sprintf(errstr,"Unknown interval.\n");
  467. exit(PROGRAM_ERROR);
  468. }
  469. if(qcnt) {
  470. if(scnt==0)
  471. strcat(errstr,"1 quartertone ");
  472. else
  473. strcat(errstr," + quartertone");
  474. }
  475. if(ocnt) {
  476. if(scnt > 0 || qcnt > 0) {
  477. sprintf(temp," plus %d octave",ocnt);
  478. strcat(errstr,temp);
  479. } else {
  480. sprintf(temp,"%d octave",ocnt);
  481. strcat(errstr,temp);
  482. }
  483. if(ocnt > 1) {
  484. sprintf(temp,"s");
  485. strcat(errstr,temp);
  486. }
  487. }
  488. if(strlen(errstr) <= 0)
  489. sprintf(errstr,"Less than a quarter-tone");
  490. if(neg)
  491. strcat(errstr," down");
  492. strcat(errstr,"\n");
  493. return(FINISHED);
  494. }
  495. /********************** GAIN_TO_DB **********************/
  496. void gain_to_db(double gain)
  497. {
  498. double dbgain = log10(gain) * 20.0;
  499. if(dbgain <= MIN_DB_ON_16_BIT)
  500. sprintf(errstr,"-96dB: i.e. zero level\n");
  501. else
  502. sprintf(errstr,"%.3lfdB\n",dbgain);
  503. }
  504. /********************** DB_TO_GAIN **********************/
  505. void db_to_gain(double dbgain)
  506. {
  507. double gain = dbtogain(dbgain);
  508. sprintf(errstr,"Gain = %lf\n",gain);
  509. }
  510. /************************ MIDI_TO_NOTE *************************/
  511. int midi_to_note(double val,dataptr dz)
  512. {
  513. int oct, imidi, midinote, is_qtone = FALSE, is_approx = FALSE;
  514. char temp[6];
  515. double midival;
  516. if(dz->mode==MU_FRQ_TO_NOTE) {
  517. if(val<MINPITCH || val >(double)FRQMAX) {
  518. sprintf(errstr,"Frq value out of range %ld - %d\n",round(MINPITCH),FRQMAX);
  519. return(GOAL_FAILED);
  520. }
  521. midival = val;
  522. midival /= LOW_A;
  523. midival = my_LOG2(midival);
  524. midival *= SEMITONES_PER_OCTAVE;
  525. midival -= 3.0;
  526. } else
  527. midival = val;
  528. midival *= 2.0;
  529. imidi = round(midival);
  530. if(!flteq((double)imidi,midival))
  531. is_approx = TRUE;
  532. if(ODD(imidi))
  533. is_qtone = TRUE;
  534. imidi /= 2;
  535. midinote = imidi%12;
  536. oct = imidi/12;
  537. oct -= 5;
  538. sprintf(errstr,"Note is ");
  539. if(is_approx)
  540. strcat(errstr,"(approx) ");
  541. switch(midinote) {
  542. case(0): strcat(errstr,"C"); break;
  543. case(1): strcat(errstr,"C#"); break;
  544. case(2): strcat(errstr,"D"); break;
  545. case(3): strcat(errstr,"Eb"); break;
  546. case(4): strcat(errstr,"E"); break;
  547. case(5): strcat(errstr,"F"); break;
  548. case(6): strcat(errstr,"F#"); break;
  549. case(7): strcat(errstr,"G"); break;
  550. case(8): strcat(errstr,"Ab"); break;
  551. case(9): strcat(errstr,"A"); break;
  552. case(10): strcat(errstr,"Bb"); break;
  553. case(11): strcat(errstr,"B"); break;
  554. }
  555. if(is_qtone)
  556. strcat(errstr,"u");
  557. sprintf(temp,"%d",oct);
  558. strcat(errstr,temp);
  559. strcat(errstr,"\n");
  560. return(FINISHED);
  561. }
  562. void delay_to_frq(double val) {
  563. sprintf(errstr,"Frequency is %.5lf Hz\n",SECS_TO_MS/val);
  564. }
  565. int delay_to_midi(double val) {
  566. int exit_status = FINISHED;
  567. val = SECS_TO_MS/val;
  568. exit_status = frq_to_midi(val);
  569. return(exit_status);
  570. }
  571. void frq_to_delay(double frq) {
  572. sprintf(errstr,"Delay is %.5lf milliseconds\n",SECS_TO_MS/frq);
  573. }
  574. int midi_to_delay(double midi) {
  575. double frq, del;
  576. if(midi<(double)MIDIMIN || midi >(double)MIDIMAX) {
  577. sprintf(errstr,"MIDI value out of range %d - %d\n",MIDIMIN,MIDIMAX);
  578. return(GOAL_FAILED);
  579. }
  580. frq = midi;
  581. frq += 3.0;
  582. frq /= SEMITONES_PER_OCTAVE;
  583. frq = pow((double)2,frq);
  584. frq *= LOW_A;
  585. del = SECS_TO_MS/frq;
  586. sprintf(errstr,"Delay is %lf milliseconds\n",del);
  587. return(FINISHED);
  588. }
  589. int tempo_to_delay(double tempo) {
  590. double del = (60 * SECS_TO_MS)/(double)tempo;
  591. sprintf(errstr,"Delay is %lf milliseconds\n",del);
  592. return(FINISHED);
  593. }
  594. int delay_to_tempo(double del) {
  595. double tempo = (60 * SECS_TO_MS)/(double)del;
  596. sprintf(errstr,"Tempo : crotchet = %lf\n",tempo);
  597. return(FINISHED);
  598. }