Collection of tools useful for audio production
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.

358 lines
10KB

  1. /*
  2. * Carla Native Plugins
  3. * Copyright (C) 2012 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the COPYING file
  16. */
  17. #include "carla_midi.h"
  18. #include "carla_native.hpp"
  19. #include <climits>
  20. #include "zynaddsubfx/Misc/Master.h"
  21. #include "zynaddsubfx/Misc/Util.h"
  22. //Dummy variables and functions for linking purposes
  23. class WavFile;
  24. namespace Nio {
  25. bool start(void){return 1;}
  26. void stop(void){}
  27. void waveNew(WavFile*){}
  28. void waveStart(void){}
  29. void waveStop(void){}
  30. void waveEnd(void){}
  31. }
  32. SYNTH_T* synth = nullptr;
  33. class ZynAddSubFxPlugin : public PluginDescriptorClass
  34. {
  35. public:
  36. enum Parameters {
  37. PARAMETER_MASTER,
  38. PARAMETER_MAX
  39. };
  40. ZynAddSubFxPlugin(const HostDescriptor* host)
  41. : PluginDescriptorClass(host)
  42. {
  43. qDebug("ZynAddSubFxPlugin::ZynAddSubFxPlugin(), s_instanceCount=%i", s_instanceCount);
  44. m_master = new Master;
  45. // refresh banks
  46. m_master->bank.rescanforbanks();
  47. for (size_t i=0, size = m_master->bank.banks.size(); i < size; i++)
  48. {
  49. if (m_master->bank.banks[i].dir.empty())
  50. continue;
  51. m_master->bank.loadbank(m_master->bank.banks[i].dir);
  52. for (unsigned int instrument = 0; instrument < BANK_SIZE; instrument++)
  53. {
  54. const std::string insName = m_master->bank.getname(instrument);
  55. if (insName.empty() || insName[0] == '\0' || insName[0] == ' ')
  56. continue;
  57. ProgramInfo pInfo;
  58. pInfo.bank = i;
  59. pInfo.prog = instrument;
  60. pInfo.name = insName;
  61. m_programs.push_back(pInfo);
  62. }
  63. }
  64. }
  65. ~ZynAddSubFxPlugin()
  66. {
  67. qDebug("ZynAddSubFxPlugin::~ZynAddSubFxPlugin(), s_instanceCount=%i", s_instanceCount);
  68. //ensure that everything has stopped with the mutex wait
  69. pthread_mutex_lock(&m_master->mutex);
  70. pthread_mutex_unlock(&m_master->mutex);
  71. m_programs.clear();
  72. delete m_master;
  73. }
  74. protected:
  75. // -------------------------------------------------------------------
  76. // Plugin parameter calls
  77. uint32_t getParameterCount()
  78. {
  79. return PARAMETER_MAX;
  80. }
  81. const Parameter* getParameterInfo(uint32_t index)
  82. {
  83. CARLA_ASSERT(index < getParameterCount());
  84. if (index >= PARAMETER_MAX)
  85. return nullptr;
  86. static Parameter param;
  87. param.ranges.step = PARAMETER_RANGES_DEFAULT_STEP;
  88. param.ranges.stepSmall = PARAMETER_RANGES_DEFAULT_STEP_SMALL;
  89. param.ranges.stepLarge = PARAMETER_RANGES_DEFAULT_STEP_LARGE;
  90. param.scalePointCount = 0;
  91. param.scalePoints = nullptr;
  92. switch (index)
  93. {
  94. case PARAMETER_MASTER:
  95. param.hints = PARAMETER_IS_ENABLED | PARAMETER_IS_AUTOMABLE;
  96. param.name = "Master Volume";
  97. param.unit = nullptr;
  98. param.ranges.min = 0.0f;
  99. param.ranges.max = 100.0f;
  100. param.ranges.def = 100.0f;
  101. break;
  102. }
  103. return &param;
  104. }
  105. float getParameterValue(uint32_t index)
  106. {
  107. switch (index)
  108. {
  109. case PARAMETER_MASTER:
  110. return m_master->Pvolume;
  111. default:
  112. return 0.0f;
  113. }
  114. }
  115. // -------------------------------------------------------------------
  116. // Plugin midi-program calls
  117. uint32_t getMidiProgramCount()
  118. {
  119. return m_programs.size();
  120. }
  121. const MidiProgram* getMidiProgramInfo(uint32_t index)
  122. {
  123. CARLA_ASSERT(index < getMidiProgramCount());
  124. if (index >= m_programs.size())
  125. return nullptr;
  126. const ProgramInfo pInfo(m_programs[index]);
  127. static MidiProgram midiProgram;
  128. midiProgram.bank = pInfo.bank;
  129. midiProgram.program = pInfo.prog;
  130. midiProgram.name = pInfo.name.c_str();
  131. return &midiProgram;
  132. }
  133. // -------------------------------------------------------------------
  134. // Plugin state calls
  135. void setParameterValue(uint32_t index, float value)
  136. {
  137. switch (index)
  138. {
  139. case PARAMETER_MASTER:
  140. m_master->setPvolume((char)rint(value));
  141. break;
  142. }
  143. }
  144. void setMidiProgram(uint32_t bank, uint32_t program)
  145. {
  146. if (bank >= m_master->bank.banks.size())
  147. return;
  148. if (program >= BANK_SIZE)
  149. return;
  150. const std::string bankdir = m_master->bank.banks[bank].dir;
  151. if (! bankdir.empty())
  152. {
  153. pthread_mutex_lock(&m_master->mutex);
  154. m_master->bank.loadbank(bankdir);
  155. m_master->bank.loadfromslot(program, m_master->part[0]);
  156. pthread_mutex_unlock(&m_master->mutex);
  157. }
  158. }
  159. // -------------------------------------------------------------------
  160. // Plugin process calls
  161. void activate()
  162. {
  163. m_master->setController(0, MIDI_CONTROL_ALL_SOUND_OFF, 0);
  164. }
  165. void process(float**, float** outBuffer, uint32_t frames, uint32_t midiEventCount, MidiEvent* midiEvents)
  166. {
  167. unsigned long from_frame = 0;
  168. unsigned long event_index = 0;
  169. unsigned long next_event_frame = 0;
  170. unsigned long to_frame = 0;
  171. pthread_mutex_lock(&m_master->mutex);
  172. do {
  173. /* Find the time of the next event, if any */
  174. if (event_index >= midiEventCount)
  175. next_event_frame = ULONG_MAX;
  176. else
  177. next_event_frame = midiEvents[event_index].time;
  178. /* find the end of the sub-sample to be processed this time round... */
  179. /* if the next event falls within the desired sample interval... */
  180. if ((next_event_frame < frames) && (next_event_frame >= to_frame))
  181. /* set the end to be at that event */
  182. to_frame = next_event_frame;
  183. else
  184. /* ...else go for the whole remaining sample */
  185. to_frame = frames;
  186. if (from_frame < to_frame)
  187. {
  188. // call master to fill from `from_frame` to `to_frame`:
  189. m_master->GetAudioOutSamples(to_frame - from_frame, (int)getSampleRate(), &outBuffer[0][from_frame], &outBuffer[1][from_frame]);
  190. // next sub-sample please...
  191. from_frame = to_frame;
  192. }
  193. // Now process any event(s) at the current timing point
  194. while (event_index < midiEventCount && midiEvents[event_index].time == to_frame)
  195. {
  196. uint8_t status = midiEvents[event_index].data[0];
  197. uint8_t channel = status & 0x0F;
  198. if (MIDI_IS_STATUS_NOTE_OFF(status))
  199. {
  200. uint8_t note = midiEvents[event_index].data[1];
  201. m_master->noteOff(channel, note);
  202. }
  203. else if (MIDI_IS_STATUS_NOTE_ON(status))
  204. {
  205. uint8_t note = midiEvents[event_index].data[1];
  206. uint8_t velo = midiEvents[event_index].data[2];
  207. m_master->noteOn(channel, note, velo);
  208. }
  209. else if (MIDI_IS_STATUS_POLYPHONIC_AFTERTOUCH(status))
  210. {
  211. uint8_t note = midiEvents[event_index].data[1];
  212. uint8_t pressure = midiEvents[event_index].data[2];
  213. m_master->polyphonicAftertouch(channel, note, pressure);
  214. }
  215. event_index++;
  216. }
  217. // Keep going until we have the desired total length of sample...
  218. } while (to_frame < frames);
  219. pthread_mutex_unlock(&m_master->mutex);
  220. }
  221. // -------------------------------------------------------------------
  222. private:
  223. struct ProgramInfo {
  224. uint32_t bank;
  225. uint32_t prog;
  226. std::string name;
  227. };
  228. std::vector<ProgramInfo> m_programs;
  229. Master* m_master;
  230. public:
  231. static int s_instanceCount;
  232. static PluginHandle _instantiate(const PluginDescriptor*, HostDescriptor* host)
  233. {
  234. if (s_instanceCount++ == 0)
  235. {
  236. synth = new SYNTH_T;
  237. synth->buffersize = host->get_buffer_size(host->handle);
  238. synth->samplerate = host->get_sample_rate(host->handle);
  239. synth->alias();
  240. config.init();
  241. config.cfg.SoundBufferSize = synth->buffersize;
  242. config.cfg.SampleRate = synth->samplerate;
  243. config.cfg.GzipCompression = 0;
  244. sprng(time(NULL));
  245. denormalkillbuf = new float [synth->buffersize];
  246. for (int i=0; i < synth->buffersize; i++)
  247. denormalkillbuf[i] = (RND - 0.5f) * 1e-16;
  248. }
  249. return new ZynAddSubFxPlugin(host);
  250. }
  251. static void _cleanup(PluginHandle handle)
  252. {
  253. delete (ZynAddSubFxPlugin*)handle;
  254. if (--s_instanceCount == 0)
  255. {
  256. delete[] denormalkillbuf;
  257. denormalkillbuf = nullptr;
  258. delete synth;
  259. synth = nullptr;
  260. }
  261. }
  262. };
  263. int ZynAddSubFxPlugin::s_instanceCount = 0;
  264. // -----------------------------------------------------------------------
  265. static PluginDescriptor zynAddSubFxDesc = {
  266. /* category */ PLUGIN_CATEGORY_SYNTH,
  267. /* hints */ PLUGIN_IS_SYNTH | PLUGIN_USES_SINGLE_THREAD,
  268. /* audioIns */ 2,
  269. /* audioOuts */ 2,
  270. /* midiIns */ 1,
  271. /* midiOuts */ 0,
  272. /* paramIns */ ZynAddSubFxPlugin::PARAMETER_MAX,
  273. /* paramOuts */ 0,
  274. /* name */ "ZynAddSubFX",
  275. /* label */ "zynaddsubfx",
  276. /* maker */ "falkTX",
  277. /* copyright */ "GNU GPL v2+",
  278. PluginDescriptorFILL(ZynAddSubFxPlugin)
  279. };
  280. // -----------------------------------------------------------------------
  281. void carla_register_native_plugin_zynaddsubfx()
  282. {
  283. carla_register_native_plugin(&zynAddSubFxDesc);
  284. }
  285. // -----------------------------------------------------------------------