Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1149 lines
36KB

  1. /*
  2. ZynAddSubFX - a software synthesizer
  3. Master.cpp - It sends Midi Messages to Parts, receives samples from parts,
  4. process them with system/insertion effects and mix them
  5. Copyright (C) 2002-2005 Nasca Octavian Paul
  6. Author: Nasca Octavian Paul
  7. This program is free software; you can redistribute it and/or
  8. modify it under the terms of the GNU General Public License
  9. as published by the Free Software Foundation; either version 2
  10. of the License, or (at your option) any later version.
  11. */
  12. #include "Master.h"
  13. #include "Part.h"
  14. #include "../Misc/Stereo.h"
  15. #include "../Misc/Util.h"
  16. #include "../Params/LFOParams.h"
  17. #include "../Effects/EffectMgr.h"
  18. #include "../DSP/FFTwrapper.h"
  19. #include "../Misc/Allocator.h"
  20. #include "../Nio/Nio.h"
  21. #include "PresetExtractor.h"
  22. #include <rtosc/ports.h>
  23. #include <rtosc/port-sugar.h>
  24. #include <rtosc/thread-link.h>
  25. #include <stdio.h>
  26. #include <sys/stat.h>
  27. #include <sys/types.h>
  28. #include <iostream>
  29. #include <algorithm>
  30. #include <cmath>
  31. #include <atomic>
  32. #include <unistd.h>
  33. using namespace std;
  34. using namespace rtosc;
  35. #define rObject Master
  36. static const Ports sysefxPort =
  37. {
  38. {"part#" STRINGIFY(NUM_MIDI_PARTS) "::i", rProp(parameter)
  39. rDoc("gain on part to sysefx routing"), 0,
  40. [](const char *m, RtData&d)
  41. {
  42. //ok, this is going to be an ugly workaround
  43. //we know that if we are here the message previously MUST have
  44. //matched Psysefxvol#/
  45. //and the number is one or two digits at most
  46. const char *index_1 = m;
  47. index_1 -=2;
  48. assert(isdigit(*index_1));
  49. if(isdigit(index_1[-1]))
  50. index_1--;
  51. int ind1 = atoi(index_1);
  52. //Now get the second index like normal
  53. while(!isdigit(*m)) m++;
  54. int ind2 = atoi(m);
  55. Master &mast = *(Master*)d.obj;
  56. if(rtosc_narguments(m)) {
  57. mast.setPsysefxvol(ind2, ind1, rtosc_argument(m,0).i);
  58. d.broadcast(d.loc, "i", mast.Psysefxvol[ind1][ind2]);
  59. } else
  60. d.reply(d.loc, "i", mast.Psysefxvol[ind1][ind2]);
  61. }}
  62. };
  63. static const Ports sysefsendto =
  64. {
  65. {"to#" STRINGIFY(NUM_SYS_EFX) "::i",
  66. rProp(parameter) rDoc("sysefx to sysefx routing gain"), 0, [](const char *m, RtData&d)
  67. {
  68. //same ugly workaround as before
  69. const char *index_1 = m;
  70. index_1 -=2;
  71. assert(isdigit(*index_1));
  72. if(isdigit(index_1[-1]))
  73. index_1--;
  74. int ind1 = atoi(index_1);
  75. //Now get the second index like normal
  76. while(!isdigit(*m)) m++;
  77. int ind2 = atoi(m);
  78. Master &master = *(Master*)d.obj;
  79. if(rtosc_narguments(m))
  80. master.setPsysefxsend(ind1, ind2, rtosc_argument(m,0).i);
  81. else
  82. d.reply(d.loc, "i", master.Psysefxsend[ind1][ind2]);
  83. }}
  84. };
  85. static const Ports master_ports = {
  86. rString(last_xmz, XMZ_PATH_MAX, "File name for last name loaded if any."),
  87. rRecursp(part, 16, "Part"),//NUM_MIDI_PARTS
  88. rRecursp(sysefx, 4, "System Effect"),//NUM_SYS_EFX
  89. rRecursp(insefx, 8, "Insertion Effect"),//NUM_INS_EFX
  90. rRecur(microtonal, "Micrtonal Mapping Functionality"),
  91. rRecur(ctl, "Controller"),
  92. rArrayI(Pinsparts, NUM_INS_EFX, "Part to insert part onto"),
  93. {"Pkeyshift::i", rProp(parameter) rLinear(0,127) rDoc("Global Key Shift"), 0, [](const char *m, RtData&d) {
  94. if(rtosc_narguments(m)==0) {
  95. d.reply(d.loc, "i", ((Master*)d.obj)->Pkeyshift);
  96. } else if(rtosc_narguments(m)==1 && rtosc_type(m,0)=='i') {
  97. ((Master*)d.obj)->setPkeyshift(limit<char>(rtosc_argument(m,0).i,0,127));
  98. d.broadcast(d.loc, "i", ((Master*)d.obj)->Pkeyshift);}}},
  99. {"echo", rDoc("Hidden port to echo messages"), 0, [](const char *m, RtData&d) {
  100. d.reply(m-1);}},
  101. {"get-vu:", rDoc("Grab VU Data"), 0, [](const char *, RtData &d) {
  102. Master *m = (Master*)d.obj;
  103. d.reply("/vu-meter", "bb", sizeof(m->vu), &m->vu, sizeof(float)*NUM_MIDI_PARTS, m->vuoutpeakpart);}},
  104. {"reset-vu:", rDoc("Grab VU Data"), 0, [](const char *, RtData &d) {
  105. Master *m = (Master*)d.obj;
  106. m->vuresetpeaks();}},
  107. {"load-part:ib", rProp(internal) rDoc("Load Part From Middleware"), 0, [](const char *msg, RtData &d) {
  108. Master *m = (Master*)d.obj;
  109. Part *p = *(Part**)rtosc_argument(msg, 1).b.data;
  110. int i = rtosc_argument(msg, 0).i;
  111. m->part[i]->cloneTraits(*p);
  112. m->part[i]->kill_rt();
  113. d.reply("/free", "sb", "Part", sizeof(void*), &m->part[i]);
  114. m->part[i] = p;
  115. p->initialize_rt();
  116. }},
  117. {"Pvolume::i", rProp(parameter) rLinear(0,127) rDoc("Master Volume"), 0,
  118. [](const char *m, rtosc::RtData &d) {
  119. if(rtosc_narguments(m)==0) {
  120. d.reply(d.loc, "i", ((Master*)d.obj)->Pvolume);
  121. } else if(rtosc_narguments(m)==1 && rtosc_type(m,0)=='i') {
  122. ((Master*)d.obj)->setPvolume(limit<char>(rtosc_argument(m,0).i,0,127));
  123. d.broadcast(d.loc, "i", ((Master*)d.obj)->Pvolume);}}},
  124. {"volume::i", rProp(parameter) rLinear(0,127) rDoc("Master Volume"), 0,
  125. [](const char *m, rtosc::RtData &d) {
  126. if(rtosc_narguments(m)==0) {
  127. d.reply(d.loc, "i", ((Master*)d.obj)->Pvolume);
  128. } else if(rtosc_narguments(m)==1 && rtosc_type(m,0)=='i') {
  129. ((Master*)d.obj)->setPvolume(limit<char>(rtosc_argument(m,0).i,0,127));
  130. d.broadcast(d.loc, "i", ((Master*)d.obj)->Pvolume);}}},
  131. {"Psysefxvol#" STRINGIFY(NUM_SYS_EFX) "/::i", 0, &sysefxPort,
  132. [](const char *msg, rtosc::RtData &d) {
  133. SNIP;
  134. sysefxPort.dispatch(msg, d);
  135. }},
  136. {"sysefxfrom#" STRINGIFY(NUM_SYS_EFX) "/", rDoc("Routing Between System Effects"), &sysefsendto,
  137. [](const char *msg, RtData&d) {
  138. SNIP;
  139. sysefsendto.dispatch(msg, d);
  140. }},
  141. {"noteOn:iii", rDoc("Noteon Event"), 0,
  142. [](const char *m,RtData &d){
  143. Master *M = (Master*)d.obj;
  144. M->noteOn(rtosc_argument(m,0).i,rtosc_argument(m,1).i,rtosc_argument(m,2).i);}},
  145. {"noteOff:ii", rDoc("Noteoff Event"), 0,
  146. [](const char *m,RtData &d){
  147. Master *M = (Master*)d.obj;
  148. M->noteOff(rtosc_argument(m,0).i,rtosc_argument(m,1).i);}},
  149. {"virtual_midi_cc:iii", rDoc("MIDI CC Event"), 0,
  150. [](const char *m,RtData &d){
  151. Master *M = (Master*)d.obj;
  152. M->setController(rtosc_argument(m,0).i,rtosc_argument(m,1).i,rtosc_argument(m,2).i);}},
  153. {"setController:iii", rDoc("MIDI CC Event"), 0,
  154. [](const char *m,RtData &d){
  155. Master *M = (Master*)d.obj;
  156. M->setController(rtosc_argument(m,0).i,rtosc_argument(m,1).i,rtosc_argument(m,2).i);}},
  157. {"Panic:", rDoc("Stop all sound"), 0,
  158. [](const char *, RtData &d) {
  159. Master &M = *(Master*)d.obj;
  160. M.ShutUp();
  161. }},
  162. {"freeze_state:", rProp(internal) rDoc("Disable OSC event handling\n"
  163. "This sets up a read-only mode from which it's safe for another"
  164. " thread to save parameters"), 0,
  165. [](const char *,RtData &d) {
  166. Master *M = (Master*)d.obj;
  167. std::atomic_thread_fence(std::memory_order_release);
  168. M->frozenState = true;
  169. d.reply("/state_frozen", "");}},
  170. {"thaw_state:", rProp(internal) rDoc("Resume handling OSC messages\n"
  171. "See /freeze_state for more information"), 0,
  172. [](const char *,RtData &d) {
  173. Master *M = (Master*)d.obj;
  174. M->frozenState = false;}},
  175. {"midi-learn/", 0, &rtosc::MidiMapperRT::ports,
  176. [](const char *msg, RtData &d) {
  177. Master *M = (Master*)d.obj;
  178. SNIP;
  179. printf("residue message = <%s>\n", msg);
  180. d.obj = &M->midi;
  181. rtosc::MidiMapperRT::ports.dispatch(msg,d);}},
  182. {"close-ui:", rDoc("Request to close any connection named \"GUI\""), 0,
  183. [](const char *, RtData &d) {
  184. d.reply("/close-ui", "");}},
  185. {"add-rt-memory:bi", rProp(internal) rDoc("Add Additional Memory To RT MemPool"), 0,
  186. [](const char *msg, RtData &d)
  187. {
  188. Master &m = *(Master*)d.obj;
  189. char *mem = *(char**)rtosc_argument(msg, 0).b.data;
  190. int i = rtosc_argument(msg, 1).i;
  191. m.memory->addMemory(mem, i);
  192. m.pendingMemory = false;
  193. }},
  194. {"samplerate:", rMap(unit, Hz) rDoc("Get synthesizer sample rate"), 0, [](const char *, RtData &d) {
  195. Master &m = *(Master*)d.obj;
  196. d.reply("/samplerate", "f", m.synth.samplerate_f);
  197. }},
  198. {"oscilsize:", rDoc("Get synthesizer oscillator size"), 0, [](const char *, RtData &d) {
  199. Master &m = *(Master*)d.obj;
  200. d.reply("/oscilsize", "f", m.synth.oscilsize_f);
  201. d.reply("/oscilsize", "i", m.synth.oscilsize);
  202. }},
  203. {"undo_pause:",rProp(internal) rDoc("pause undo event recording"),0,
  204. [](const char *, rtosc::RtData &d) {d.reply("/undo_pause", "");}},
  205. {"undo_resume:",rProp(internal) rDoc("resume undo event recording"),0,
  206. [](const char *, rtosc::RtData &d) {d.reply("/undo_resume", "");}},
  207. {"config/", rDoc("Top Level Application Configuration Parameters"), &Config::ports,
  208. [](const char *, rtosc::RtData &d){d.forward();}},
  209. {"presets/", rDoc("Parameter Presets"), &preset_ports, rBOIL_BEGIN
  210. SNIP
  211. preset_ports.dispatch(msg, data);
  212. rBOIL_END},
  213. {"HDDRecorder/preparefile:s", rDoc("Init WAV file"), 0, [](const char *msg, RtData &d) {
  214. Master *m = (Master*)d.obj;
  215. m->HDDRecorder.preparefile(rtosc_argument(msg, 0).s, 1);}},
  216. {"HDDRecorder/start:", rDoc("Start recording"), 0, [](const char *, RtData &d) {
  217. Master *m = (Master*)d.obj;
  218. m->HDDRecorder.start();}},
  219. {"HDDRecorder/stop:", rDoc("Stop recording"), 0, [](const char *, RtData &d) {
  220. Master *m = (Master*)d.obj;
  221. m->HDDRecorder.stop();}},
  222. {"HDDRecorder/pause:", rDoc("Pause recording"), 0, [](const char *, RtData &d) {
  223. Master *m = (Master*)d.obj;
  224. m->HDDRecorder.pause();}},
  225. };
  226. const Ports &Master::ports = master_ports;
  227. class DataObj:public rtosc::RtData
  228. {
  229. public:
  230. DataObj(char *loc_, size_t loc_size_, void *obj_, rtosc::ThreadLink *bToU_)
  231. {
  232. memset(loc_, 0, loc_size_);
  233. loc = loc_;
  234. loc_size = loc_size_;
  235. obj = obj_;
  236. bToU = bToU_;
  237. forwarded = false;
  238. }
  239. virtual void reply(const char *path, const char *args, ...) override
  240. {
  241. va_list va;
  242. va_start(va,args);
  243. char *buffer = bToU->buffer();
  244. rtosc_vmessage(buffer,bToU->buffer_size(),path,args,va);
  245. reply(buffer);
  246. va_end(va);
  247. }
  248. virtual void reply(const char *msg) override
  249. {
  250. if(rtosc_message_length(msg, -1) == 0)
  251. fprintf(stderr, "Warning: Invalid Rtosc message '%s'\n", msg);
  252. bToU->raw_write(msg);
  253. }
  254. virtual void broadcast(const char *path, const char *args, ...) override{
  255. va_list va;
  256. va_start(va,args);
  257. reply("/broadcast", "");
  258. char *buffer = bToU->buffer();
  259. rtosc_vmessage(buffer,bToU->buffer_size(),path,args,va);
  260. reply(buffer);
  261. va_end(va);
  262. }
  263. virtual void broadcast(const char *msg) override
  264. {
  265. reply("/broadcast", "");
  266. reply(msg);
  267. }
  268. virtual void forward(const char *reason) override
  269. {
  270. assert(message);
  271. reply("/forward", "");
  272. printf("forwarding '%s'\n", message);
  273. forwarded = true;
  274. }
  275. bool forwarded;
  276. private:
  277. rtosc::ThreadLink *bToU;
  278. };
  279. vuData::vuData(void)
  280. :outpeakl(0.0f), outpeakr(0.0f), maxoutpeakl(0.0f), maxoutpeakr(0.0f),
  281. rmspeakl(0.0f), rmspeakr(0.0f), clipped(0)
  282. {}
  283. Master::Master(const SYNTH_T &synth_, Config* config)
  284. :HDDRecorder(synth_), time(synth_), ctl(synth_, &time),
  285. microtonal(config->cfg.GzipCompression), bank(config),
  286. frozenState(false), pendingMemory(false),
  287. synth(synth_), gzip_compression(config->cfg.GzipCompression)
  288. {
  289. bToU = NULL;
  290. uToB = NULL;
  291. //Setup MIDI
  292. midi.frontend = [this](const char *msg) {bToU->raw_write(msg);};
  293. midi.backend = [this](const char *msg) {applyOscEvent(msg);};
  294. memory = new AllocatorClass();
  295. swaplr = 0;
  296. off = 0;
  297. smps = 0;
  298. bufl = new float[synth.buffersize];
  299. bufr = new float[synth.buffersize];
  300. last_xmz[0] = 0;
  301. fft = new FFTwrapper(synth.oscilsize);
  302. shutup = 0;
  303. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart) {
  304. vuoutpeakpart[npart] = 1e-9;
  305. fakepeakpart[npart] = 0;
  306. }
  307. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart)
  308. part[npart] = new Part(*memory, synth, time, config->cfg.GzipCompression,
  309. config->cfg.Interpolation, &microtonal, fft);
  310. //Insertion Effects init
  311. for(int nefx = 0; nefx < NUM_INS_EFX; ++nefx)
  312. insefx[nefx] = new EffectMgr(*memory, synth, 1, &time);
  313. //System Effects init
  314. for(int nefx = 0; nefx < NUM_SYS_EFX; ++nefx)
  315. sysefx[nefx] = new EffectMgr(*memory, synth, 0, &time);
  316. defaults();
  317. mastercb = 0;
  318. mastercb_ptr = 0;
  319. }
  320. void Master::applyOscEvent(const char *msg)
  321. {
  322. char loc_buf[1024];
  323. DataObj d{loc_buf, 1024, this, bToU};
  324. memset(loc_buf, 0, sizeof(loc_buf));
  325. d.matches = 0;
  326. if(strcmp(msg, "/get-vu") && false) {
  327. fprintf(stdout, "%c[%d;%d;%dm", 0x1B, 0, 5 + 30, 0 + 40);
  328. fprintf(stdout, "backend[*]: '%s'<%s>\n", msg,
  329. rtosc_argument_string(msg));
  330. fprintf(stdout, "%c[%d;%d;%dm", 0x1B, 0, 7 + 30, 0 + 40);
  331. }
  332. ports.dispatch(msg, d, true);
  333. if(d.matches == 0 && !d.forwarded)
  334. fprintf(stderr, "Unknown path '%s:%s'\n", msg, rtosc_argument_string(msg));
  335. if(d.forwarded)
  336. bToU->raw_write(msg);
  337. }
  338. void Master::defaults()
  339. {
  340. volume = 1.0f;
  341. setPvolume(80);
  342. setPkeyshift(64);
  343. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart) {
  344. part[npart]->defaults();
  345. part[npart]->Prcvchn = npart % NUM_MIDI_CHANNELS;
  346. }
  347. partonoff(0, 1); //enable the first part
  348. for(int nefx = 0; nefx < NUM_INS_EFX; ++nefx) {
  349. insefx[nefx]->defaults();
  350. Pinsparts[nefx] = -1;
  351. }
  352. //System Effects init
  353. for(int nefx = 0; nefx < NUM_SYS_EFX; ++nefx) {
  354. sysefx[nefx]->defaults();
  355. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart)
  356. setPsysefxvol(npart, nefx, 0);
  357. for(int nefxto = 0; nefxto < NUM_SYS_EFX; ++nefxto)
  358. setPsysefxsend(nefx, nefxto, 0);
  359. }
  360. microtonal.defaults();
  361. ShutUp();
  362. }
  363. /*
  364. * Note On Messages (velocity=0 for NoteOff)
  365. */
  366. void Master::noteOn(char chan, char note, char velocity)
  367. {
  368. if(velocity) {
  369. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart)
  370. if(chan == part[npart]->Prcvchn) {
  371. fakepeakpart[npart] = velocity * 2;
  372. if(part[npart]->Penabled)
  373. part[npart]->NoteOn(note, velocity, keyshift);
  374. }
  375. }
  376. else
  377. this->noteOff(chan, note);
  378. HDDRecorder.triggernow();
  379. }
  380. /*
  381. * Note Off Messages
  382. */
  383. void Master::noteOff(char chan, char note)
  384. {
  385. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart)
  386. if((chan == part[npart]->Prcvchn) && part[npart]->Penabled)
  387. part[npart]->NoteOff(note);
  388. }
  389. /*
  390. * Pressure Messages (velocity=0 for NoteOff)
  391. */
  392. void Master::polyphonicAftertouch(char chan, char note, char velocity)
  393. {
  394. if(velocity) {
  395. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart)
  396. if(chan == part[npart]->Prcvchn)
  397. if(part[npart]->Penabled)
  398. part[npart]->PolyphonicAftertouch(note, velocity, keyshift);
  399. }
  400. else
  401. this->noteOff(chan, note);
  402. }
  403. /*
  404. * Controllers
  405. */
  406. void Master::setController(char chan, int type, int par)
  407. {
  408. if(frozenState)
  409. return;
  410. //TODO add chan back
  411. midi.handleCC(type,par);
  412. if((type == C_dataentryhi) || (type == C_dataentrylo)
  413. || (type == C_nrpnhi) || (type == C_nrpnlo)) { //Process RPN and NRPN by the Master (ignore the chan)
  414. ctl.setparameternumber(type, par);
  415. int parhi = -1, parlo = -1, valhi = -1, vallo = -1;
  416. if(ctl.getnrpn(&parhi, &parlo, &valhi, &vallo) == 0) { //this is NRPN
  417. switch(parhi) {
  418. case 0x04: //System Effects
  419. if(parlo < NUM_SYS_EFX)
  420. sysefx[parlo]->seteffectparrt(valhi, vallo);
  421. break;
  422. case 0x08: //Insertion Effects
  423. if(parlo < NUM_INS_EFX)
  424. insefx[parlo]->seteffectparrt(valhi, vallo);
  425. break;
  426. }
  427. }
  428. } else { //other controllers
  429. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart) //Send the controller to all part assigned to the channel
  430. if((chan == part[npart]->Prcvchn) && (part[npart]->Penabled != 0))
  431. part[npart]->SetController(type, par);
  432. if(type == C_allsoundsoff) { //cleanup insertion/system FX
  433. for(int nefx = 0; nefx < NUM_SYS_EFX; ++nefx)
  434. sysefx[nefx]->cleanup();
  435. for(int nefx = 0; nefx < NUM_INS_EFX; ++nefx)
  436. insefx[nefx]->cleanup();
  437. }
  438. }
  439. }
  440. void Master::vuUpdate(const float *outl, const float *outr)
  441. {
  442. //Peak computation (for vumeters)
  443. vu.outpeakl = 1e-12;
  444. vu.outpeakr = 1e-12;
  445. for(int i = 0; i < synth.buffersize; ++i) {
  446. if(fabs(outl[i]) > vu.outpeakl)
  447. vu.outpeakl = fabs(outl[i]);
  448. if(fabs(outr[i]) > vu.outpeakr)
  449. vu.outpeakr = fabs(outr[i]);
  450. }
  451. if((vu.outpeakl > 1.0f) || (vu.outpeakr > 1.0f))
  452. vu.clipped = 1;
  453. if(vu.maxoutpeakl < vu.outpeakl)
  454. vu.maxoutpeakl = vu.outpeakl;
  455. if(vu.maxoutpeakr < vu.outpeakr)
  456. vu.maxoutpeakr = vu.outpeakr;
  457. //RMS Peak computation (for vumeters)
  458. vu.rmspeakl = 1e-12;
  459. vu.rmspeakr = 1e-12;
  460. for(int i = 0; i < synth.buffersize; ++i) {
  461. vu.rmspeakl += outl[i] * outl[i];
  462. vu.rmspeakr += outr[i] * outr[i];
  463. }
  464. vu.rmspeakl = sqrt(vu.rmspeakl / synth.buffersize_f);
  465. vu.rmspeakr = sqrt(vu.rmspeakr / synth.buffersize_f);
  466. //Part Peak computation (for Part vumeters or fake part vumeters)
  467. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart) {
  468. vuoutpeakpart[npart] = 1.0e-12f;
  469. if(part[npart]->Penabled != 0) {
  470. float *outl = part[npart]->partoutl,
  471. *outr = part[npart]->partoutr;
  472. for(int i = 0; i < synth.buffersize; ++i) {
  473. float tmp = fabs(outl[i] + outr[i]);
  474. if(tmp > vuoutpeakpart[npart])
  475. vuoutpeakpart[npart] = tmp;
  476. }
  477. vuoutpeakpart[npart] *= volume;
  478. }
  479. else
  480. if(fakepeakpart[npart] > 1)
  481. fakepeakpart[npart]--;
  482. }
  483. }
  484. /*
  485. * Enable/Disable a part
  486. */
  487. void Master::partonoff(int npart, int what)
  488. {
  489. if(npart >= NUM_MIDI_PARTS)
  490. return;
  491. if(what == 0) { //disable part
  492. fakepeakpart[npart] = 0;
  493. part[npart]->Penabled = 0;
  494. part[npart]->cleanup();
  495. for(int nefx = 0; nefx < NUM_INS_EFX; ++nefx) {
  496. if(Pinsparts[nefx] == npart)
  497. insefx[nefx]->cleanup();
  498. }
  499. }
  500. else { //enabled
  501. part[npart]->Penabled = 1;
  502. fakepeakpart[npart] = 0;
  503. }
  504. }
  505. void Master::setMasterChangedCallback(void(*cb)(void*,Master*), void *ptr)
  506. {
  507. mastercb = cb;
  508. mastercb_ptr = ptr;
  509. }
  510. #if 0
  511. template <class T>
  512. struct def_skip
  513. {
  514. static void skip(const char*& argptr) { argptr += sizeof(T); }
  515. };
  516. template <class T>
  517. struct str_skip
  518. {
  519. static void skip(const char*& argptr) { while(argptr++); /*TODO: 4 padding */ }
  520. };
  521. template<class T, class Display = T, template<class TMP> class SkipsizeFunc = def_skip>
  522. void _dump_prim_arg(const char*& argptr, std::ostream& os)
  523. {
  524. os << ' ' << (Display)*(const T*)argptr;
  525. SkipsizeFunc<T>::skip(argptr);
  526. }
  527. void dump_msg(const char* ptr, std::ostream& os = std::cerr)
  528. {
  529. assert(*ptr == '/');
  530. os << ptr;
  531. while(*++ptr) ; // skip address
  532. while(!*++ptr) ; // skip 0s
  533. assert(*ptr == ',');
  534. os << ' ' << (ptr + 1);
  535. const char* argptr = ptr;
  536. while(*++argptr) ; // skip type string
  537. while(!*++argptr) ; // skip 0s
  538. char c;
  539. while((c = *++ptr))
  540. {
  541. switch(c)
  542. {
  543. case 'i':
  544. _dump_prim_arg<int32_t>(argptr, os); break;
  545. case 'c':
  546. _dump_prim_arg<int32_t, char>(argptr, os); break;
  547. // case 's':
  548. // _dump_prim_arg<char, const char*>(argptr, os); break;
  549. default:
  550. exit(1);
  551. }
  552. }
  553. }
  554. #endif
  555. int msg_id=0;
  556. /*
  557. * Master audio out (the final sound)
  558. */
  559. bool Master::AudioOut(float *outr, float *outl)
  560. {
  561. //Danger Limits
  562. if(memory->lowMemory(2,1024*1024))
  563. printf("QUITE LOW MEMORY IN THE RT POOL BE PREPARED FOR WEIRD BEHAVIOR!!\n");
  564. //Normal Limits
  565. if(!pendingMemory && memory->lowMemory(4,1024*1024)) {
  566. printf("Requesting more memory\n");
  567. bToU->write("/request-memory", "");
  568. pendingMemory = true;
  569. }
  570. //Handle user events TODO move me to a proper location
  571. char loc_buf[1024];
  572. DataObj d{loc_buf, 1024, this, bToU};
  573. memset(loc_buf, 0, sizeof(loc_buf));
  574. int events = 0;
  575. while(uToB && uToB->hasNext() && events < 100) {
  576. const char *msg = uToB->read();
  577. if(!strcmp(msg, "/load-master")) {
  578. Master *this_master = this;
  579. Master *new_master = *(Master**)rtosc_argument(msg, 0).b.data;
  580. new_master->AudioOut(outl, outr);
  581. Nio::masterSwap(new_master);
  582. if (mastercb)
  583. mastercb(mastercb_ptr, new_master);
  584. bToU->write("/free", "sb", "Master", sizeof(Master*), &this_master);
  585. return false;
  586. }
  587. //XXX yes, this is not realtime safe, but it is useful...
  588. if(strcmp(msg, "/get-vu") && false) {
  589. fprintf(stdout, "%c[%d;%d;%dm", 0x1B, 0, 5 + 30, 0 + 40);
  590. fprintf(stdout, "backend[%d]: '%s'<%s>\n", msg_id++, msg,
  591. rtosc_argument_string(msg));
  592. fprintf(stdout, "%c[%d;%d;%dm", 0x1B, 0, 7 + 30, 0 + 40);
  593. }
  594. ports.dispatch(msg, d, true);
  595. events++;
  596. if(!d.matches) {// && !ports.apropos(msg)) {
  597. fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 1, 7 + 30, 0 + 40);
  598. fprintf(stderr, "Unknown address<BACKEND> '%s:%s'\n", uToB->peak(), rtosc_argument_string(uToB->peak()));
  599. #if 0
  600. if(strstr(msg, "PFMVelocity"))
  601. dump_msg(msg);
  602. if(ports.apropos(msg))
  603. fprintf(stderr, " -> best match: '%s'\n", ports.apropos(msg)->name);
  604. if(ports.apropos(msg+1))
  605. fprintf(stderr, " -> best match: '%s'\n", ports.apropos(msg+1)->name);
  606. #endif
  607. fprintf(stderr, "%c[%d;%d;%dm", 0x1B, 0, 7 + 30, 0 + 40);
  608. }
  609. }
  610. if(events>1 && false)
  611. fprintf(stderr, "backend: %d events per cycle\n",events);
  612. //Swaps the Left channel with Right Channel
  613. if(swaplr)
  614. swap(outl, outr);
  615. //clean up the output samples (should not be needed?)
  616. memset(outl, 0, synth.bufferbytes);
  617. memset(outr, 0, synth.bufferbytes);
  618. //Compute part samples and store them part[npart]->partoutl,partoutr
  619. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart)
  620. if(part[npart]->Penabled)
  621. part[npart]->ComputePartSmps();
  622. //Insertion effects
  623. for(int nefx = 0; nefx < NUM_INS_EFX; ++nefx)
  624. if(Pinsparts[nefx] >= 0) {
  625. int efxpart = Pinsparts[nefx];
  626. if(part[efxpart]->Penabled)
  627. insefx[nefx]->out(part[efxpart]->partoutl,
  628. part[efxpart]->partoutr);
  629. }
  630. //Apply the part volumes and pannings (after insertion effects)
  631. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart) {
  632. if(!part[npart]->Penabled)
  633. continue;
  634. Stereo<float> newvol(part[npart]->volume),
  635. oldvol(part[npart]->oldvolumel,
  636. part[npart]->oldvolumer);
  637. float pan = part[npart]->panning;
  638. if(pan < 0.5f)
  639. newvol.l *= pan * 2.0f;
  640. else
  641. newvol.r *= (1.0f - pan) * 2.0f;
  642. //if(npart==0)
  643. //printf("[%d]vol = %f->%f\n", npart, oldvol.l, newvol.l);
  644. //the volume or the panning has changed and needs interpolation
  645. if(ABOVE_AMPLITUDE_THRESHOLD(oldvol.l, newvol.l)
  646. || ABOVE_AMPLITUDE_THRESHOLD(oldvol.r, newvol.r)) {
  647. for(int i = 0; i < synth.buffersize; ++i) {
  648. Stereo<float> vol(INTERPOLATE_AMPLITUDE(oldvol.l, newvol.l,
  649. i, synth.buffersize),
  650. INTERPOLATE_AMPLITUDE(oldvol.r, newvol.r,
  651. i, synth.buffersize));
  652. part[npart]->partoutl[i] *= vol.l;
  653. part[npart]->partoutr[i] *= vol.r;
  654. }
  655. part[npart]->oldvolumel = newvol.l;
  656. part[npart]->oldvolumer = newvol.r;
  657. }
  658. else {
  659. for(int i = 0; i < synth.buffersize; ++i) { //the volume did not changed
  660. part[npart]->partoutl[i] *= newvol.l;
  661. part[npart]->partoutr[i] *= newvol.r;
  662. }
  663. }
  664. }
  665. //System effects
  666. for(int nefx = 0; nefx < NUM_SYS_EFX; ++nefx) {
  667. if(sysefx[nefx]->geteffect() == 0)
  668. continue; //the effect is disabled
  669. float tmpmixl[synth.buffersize];
  670. float tmpmixr[synth.buffersize];
  671. //Clean up the samples used by the system effects
  672. memset(tmpmixl, 0, synth.bufferbytes);
  673. memset(tmpmixr, 0, synth.bufferbytes);
  674. //Mix the channels according to the part settings about System Effect
  675. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart) {
  676. //skip if the part has no output to effect
  677. if(Psysefxvol[nefx][npart] == 0)
  678. continue;
  679. //skip if the part is disabled
  680. if(part[npart]->Penabled == 0)
  681. continue;
  682. //the output volume of each part to system effect
  683. const float vol = sysefxvol[nefx][npart];
  684. for(int i = 0; i < synth.buffersize; ++i) {
  685. tmpmixl[i] += part[npart]->partoutl[i] * vol;
  686. tmpmixr[i] += part[npart]->partoutr[i] * vol;
  687. }
  688. }
  689. // system effect send to next ones
  690. for(int nefxfrom = 0; nefxfrom < nefx; ++nefxfrom)
  691. if(Psysefxsend[nefxfrom][nefx] != 0) {
  692. const float vol = sysefxsend[nefxfrom][nefx];
  693. for(int i = 0; i < synth.buffersize; ++i) {
  694. tmpmixl[i] += sysefx[nefxfrom]->efxoutl[i] * vol;
  695. tmpmixr[i] += sysefx[nefxfrom]->efxoutr[i] * vol;
  696. }
  697. }
  698. sysefx[nefx]->out(tmpmixl, tmpmixr);
  699. //Add the System Effect to sound output
  700. const float outvol = sysefx[nefx]->sysefxgetvolume();
  701. for(int i = 0; i < synth.buffersize; ++i) {
  702. outl[i] += tmpmixl[i] * outvol;
  703. outr[i] += tmpmixr[i] * outvol;
  704. }
  705. }
  706. //Mix all parts
  707. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart)
  708. if(part[npart]->Penabled) //only mix active parts
  709. for(int i = 0; i < synth.buffersize; ++i) { //the volume did not changed
  710. outl[i] += part[npart]->partoutl[i];
  711. outr[i] += part[npart]->partoutr[i];
  712. }
  713. //Insertion effects for Master Out
  714. for(int nefx = 0; nefx < NUM_INS_EFX; ++nefx)
  715. if(Pinsparts[nefx] == -2)
  716. insefx[nefx]->out(outl, outr);
  717. //Master Volume
  718. for(int i = 0; i < synth.buffersize; ++i) {
  719. outl[i] *= volume;
  720. outr[i] *= volume;
  721. }
  722. vuUpdate(outl, outr);
  723. //Shutup if it is asked (with fade-out)
  724. if(shutup) {
  725. for(int i = 0; i < synth.buffersize; ++i) {
  726. float tmp = (synth.buffersize_f - i) / synth.buffersize_f;
  727. outl[i] *= tmp;
  728. outr[i] *= tmp;
  729. }
  730. ShutUp();
  731. }
  732. //update the global frame timer
  733. time++;
  734. return true;
  735. }
  736. //TODO review the respective code from yoshimi for this
  737. //If memory serves correctly, libsamplerate was used
  738. void Master::GetAudioOutSamples(size_t nsamples,
  739. unsigned samplerate,
  740. float *outl,
  741. float *outr)
  742. {
  743. off_t out_off = 0;
  744. //Fail when resampling rather than doing a poor job
  745. if(synth.samplerate != samplerate) {
  746. printf("darn it: %d vs %d\n", synth.samplerate, samplerate);
  747. return;
  748. }
  749. while(nsamples) {
  750. //use all available samples
  751. if(nsamples >= smps) {
  752. memcpy(outl + out_off, bufl + off, sizeof(float) * smps);
  753. memcpy(outr + out_off, bufr + off, sizeof(float) * smps);
  754. nsamples -= smps;
  755. //generate samples
  756. if (! AudioOut(bufl, bufr))
  757. return;
  758. off = 0;
  759. out_off += smps;
  760. smps = synth.buffersize;
  761. }
  762. else { //use some samples
  763. memcpy(outl + out_off, bufl + off, sizeof(float) * nsamples);
  764. memcpy(outr + out_off, bufr + off, sizeof(float) * nsamples);
  765. smps -= nsamples;
  766. off += nsamples;
  767. nsamples = 0;
  768. }
  769. }
  770. }
  771. Master::~Master()
  772. {
  773. delete []bufl;
  774. delete []bufr;
  775. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart)
  776. delete part[npart];
  777. for(int nefx = 0; nefx < NUM_INS_EFX; ++nefx)
  778. delete insefx[nefx];
  779. for(int nefx = 0; nefx < NUM_SYS_EFX; ++nefx)
  780. delete sysefx[nefx];
  781. delete fft;
  782. delete memory;
  783. }
  784. /*
  785. * Parameter control
  786. */
  787. void Master::setPvolume(char Pvolume_)
  788. {
  789. Pvolume = Pvolume_;
  790. volume = dB2rap((Pvolume - 96.0f) / 96.0f * 40.0f);
  791. }
  792. void Master::setPkeyshift(char Pkeyshift_)
  793. {
  794. Pkeyshift = Pkeyshift_;
  795. keyshift = (int)Pkeyshift - 64;
  796. }
  797. void Master::setPsysefxvol(int Ppart, int Pefx, char Pvol)
  798. {
  799. Psysefxvol[Pefx][Ppart] = Pvol;
  800. sysefxvol[Pefx][Ppart] = powf(0.1f, (1.0f - Pvol / 96.0f) * 2.0f);
  801. }
  802. void Master::setPsysefxsend(int Pefxfrom, int Pefxto, char Pvol)
  803. {
  804. Psysefxsend[Pefxfrom][Pefxto] = Pvol;
  805. sysefxsend[Pefxfrom][Pefxto] = powf(0.1f, (1.0f - Pvol / 96.0f) * 2.0f);
  806. }
  807. /*
  808. * Panic! (Clean up all parts and effects)
  809. */
  810. void Master::ShutUp()
  811. {
  812. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart) {
  813. part[npart]->cleanup();
  814. fakepeakpart[npart] = 0;
  815. }
  816. for(int nefx = 0; nefx < NUM_INS_EFX; ++nefx)
  817. insefx[nefx]->cleanup();
  818. for(int nefx = 0; nefx < NUM_SYS_EFX; ++nefx)
  819. sysefx[nefx]->cleanup();
  820. vuresetpeaks();
  821. shutup = 0;
  822. }
  823. /*
  824. * Reset peaks and clear the "cliped" flag (for VU-meter)
  825. */
  826. void Master::vuresetpeaks()
  827. {
  828. vu.outpeakl = 1e-9;
  829. vu.outpeakr = 1e-9;
  830. vu.maxoutpeakl = 1e-9;
  831. vu.maxoutpeakr = 1e-9;
  832. vu.clipped = 0;
  833. }
  834. void Master::applyparameters(void)
  835. {
  836. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart)
  837. part[npart]->applyparameters();
  838. }
  839. void Master::initialize_rt(void)
  840. {
  841. for(int i=0; i<NUM_SYS_EFX; ++i)
  842. sysefx[i]->init();
  843. for(int i=0; i<NUM_INS_EFX; ++i)
  844. insefx[i]->init();
  845. for(int i=0; i<NUM_MIDI_PARTS; ++i)
  846. part[i]->initialize_rt();
  847. }
  848. void Master::add2XML(XMLwrapper& xml)
  849. {
  850. xml.addpar("volume", Pvolume);
  851. xml.addpar("key_shift", Pkeyshift);
  852. xml.addparbool("nrpn_receive", ctl.NRPN.receive);
  853. xml.beginbranch("MICROTONAL");
  854. microtonal.add2XML(xml);
  855. xml.endbranch();
  856. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart) {
  857. xml.beginbranch("PART", npart);
  858. part[npart]->add2XML(xml);
  859. xml.endbranch();
  860. }
  861. xml.beginbranch("SYSTEM_EFFECTS");
  862. for(int nefx = 0; nefx < NUM_SYS_EFX; ++nefx) {
  863. xml.beginbranch("SYSTEM_EFFECT", nefx);
  864. xml.beginbranch("EFFECT");
  865. sysefx[nefx]->add2XML(xml);
  866. xml.endbranch();
  867. for(int pefx = 0; pefx < NUM_MIDI_PARTS; ++pefx) {
  868. xml.beginbranch("VOLUME", pefx);
  869. xml.addpar("vol", Psysefxvol[nefx][pefx]);
  870. xml.endbranch();
  871. }
  872. for(int tonefx = nefx + 1; tonefx < NUM_SYS_EFX; ++tonefx) {
  873. xml.beginbranch("SENDTO", tonefx);
  874. xml.addpar("send_vol", Psysefxsend[nefx][tonefx]);
  875. xml.endbranch();
  876. }
  877. xml.endbranch();
  878. }
  879. xml.endbranch();
  880. xml.beginbranch("INSERTION_EFFECTS");
  881. for(int nefx = 0; nefx < NUM_INS_EFX; ++nefx) {
  882. xml.beginbranch("INSERTION_EFFECT", nefx);
  883. xml.addpar("part", Pinsparts[nefx]);
  884. xml.beginbranch("EFFECT");
  885. insefx[nefx]->add2XML(xml);
  886. xml.endbranch();
  887. xml.endbranch();
  888. }
  889. xml.endbranch();
  890. }
  891. int Master::getalldata(char **data)
  892. {
  893. XMLwrapper xml;
  894. xml.beginbranch("MASTER");
  895. add2XML(xml);
  896. xml.endbranch();
  897. *data = xml.getXMLdata();
  898. return strlen(*data) + 1;
  899. }
  900. void Master::putalldata(const char *data)
  901. {
  902. XMLwrapper xml;
  903. if(!xml.putXMLdata(data)) {
  904. return;
  905. }
  906. if(xml.enterbranch("MASTER") == 0)
  907. return;
  908. getfromXML(xml);
  909. xml.exitbranch();
  910. }
  911. int Master::saveXML(const char *filename)
  912. {
  913. XMLwrapper xml;
  914. xml.beginbranch("MASTER");
  915. add2XML(xml);
  916. xml.endbranch();
  917. return xml.saveXMLfile(filename, gzip_compression);
  918. }
  919. int Master::loadXML(const char *filename)
  920. {
  921. XMLwrapper xml;
  922. if(xml.loadXMLfile(filename) < 0) {
  923. return -1;
  924. }
  925. if(xml.enterbranch("MASTER") == 0)
  926. return -10;
  927. getfromXML(xml);
  928. xml.exitbranch();
  929. initialize_rt();
  930. return 0;
  931. }
  932. void Master::getfromXML(XMLwrapper& xml)
  933. {
  934. setPvolume(xml.getpar127("volume", Pvolume));
  935. setPkeyshift(xml.getpar127("key_shift", Pkeyshift));
  936. ctl.NRPN.receive = xml.getparbool("nrpn_receive", ctl.NRPN.receive);
  937. part[0]->Penabled = 0;
  938. for(int npart = 0; npart < NUM_MIDI_PARTS; ++npart) {
  939. if(xml.enterbranch("PART", npart) == 0)
  940. continue;
  941. part[npart]->getfromXML(xml);
  942. xml.exitbranch();
  943. }
  944. if(xml.enterbranch("MICROTONAL")) {
  945. microtonal.getfromXML(xml);
  946. xml.exitbranch();
  947. }
  948. sysefx[0]->changeeffect(0);
  949. if(xml.enterbranch("SYSTEM_EFFECTS")) {
  950. for(int nefx = 0; nefx < NUM_SYS_EFX; ++nefx) {
  951. if(xml.enterbranch("SYSTEM_EFFECT", nefx) == 0)
  952. continue;
  953. if(xml.enterbranch("EFFECT")) {
  954. sysefx[nefx]->getfromXML(xml);
  955. xml.exitbranch();
  956. }
  957. for(int partefx = 0; partefx < NUM_MIDI_PARTS; ++partefx) {
  958. if(xml.enterbranch("VOLUME", partefx) == 0)
  959. continue;
  960. setPsysefxvol(partefx, nefx,
  961. xml.getpar127("vol", Psysefxvol[partefx][nefx]));
  962. xml.exitbranch();
  963. }
  964. for(int tonefx = nefx + 1; tonefx < NUM_SYS_EFX; ++tonefx) {
  965. if(xml.enterbranch("SENDTO", tonefx) == 0)
  966. continue;
  967. setPsysefxsend(nefx, tonefx,
  968. xml.getpar127("send_vol",
  969. Psysefxsend[nefx][tonefx]));
  970. xml.exitbranch();
  971. }
  972. xml.exitbranch();
  973. }
  974. xml.exitbranch();
  975. }
  976. if(xml.enterbranch("INSERTION_EFFECTS")) {
  977. for(int nefx = 0; nefx < NUM_INS_EFX; ++nefx) {
  978. if(xml.enterbranch("INSERTION_EFFECT", nefx) == 0)
  979. continue;
  980. Pinsparts[nefx] = xml.getpar("part",
  981. Pinsparts[nefx],
  982. -2,
  983. NUM_MIDI_PARTS);
  984. if(xml.enterbranch("EFFECT")) {
  985. insefx[nefx]->getfromXML(xml);
  986. xml.exitbranch();
  987. }
  988. xml.exitbranch();
  989. }
  990. xml.exitbranch();
  991. }
  992. }