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.

522 lines
15KB

  1. #ifndef SYNTH_H
  2. #define SYNTH_H
  3. #include <stdint.h>
  4. #include <vector>
  5. #include "juce_PluginHeaders.h"
  6. #include "filters.h"
  7. #include "ADSRenv.h"
  8. #include "simd.h"
  9. template<typename T> T sqr(T v) { return v*v; }
  10. class wolpSound: public SynthesiserSound
  11. {
  12. public:
  13. bool appliesToNote(const int midiNoteNumber) override { return true; }
  14. bool appliesToChannel(const int midiChannel) override { return true; }
  15. };
  16. class chebyshev_7pole_generated
  17. {
  18. /* Digital filter designed by mkfilter/mkshape/gencode A.J. Fisher
  19. Command line: /www/usr/fisher/helpers/mkfilter -Ch -5.0000000000e-02 -Lp -o 7 -a 2.2786458333e-02 0.0000000000e+00 -l */
  20. #define NZEROS 7
  21. #define NPOLES 7
  22. #define GAIN 8.185223519e+08
  23. public:
  24. chebyshev_7pole_generated() { memset(xv, 0, sizeof(xv)); memset(yv, 0, sizeof(yv)); }
  25. double xv[NZEROS+1], yv[NPOLES+1];
  26. double run(double nextvalue)
  27. {
  28. xv[0] = xv[1]; xv[1] = xv[2]; xv[2] = xv[3]; xv[3] = xv[4]; xv[4] = xv[5]; xv[5] = xv[6]; xv[6] = xv[7];
  29. xv[7] = nextvalue / GAIN;
  30. yv[0] = yv[1]; yv[1] = yv[2]; yv[2] = yv[3]; yv[3] = yv[4]; yv[4] = yv[5]; yv[5] = yv[6]; yv[6] = yv[7];
  31. yv[7] = (xv[0] + xv[7]) + 7 * (xv[1] + xv[6]) + 21 * (xv[2] + xv[5])
  32. + 35 * (xv[3] + xv[4])
  33. + ( 0.7582559865 * yv[0]) + ( -5.4896632588 * yv[1])
  34. + ( 17.0657116090 * yv[2]) + (-29.5302444680 * yv[3])
  35. + ( 30.7191651920 * yv[4]) + (-19.2116577140 * yv[5])
  36. + ( 6.6884324971 * yv[6]);
  37. return yv[7];
  38. }
  39. #undef NZEROS
  40. #undef NPOLES
  41. #undef GAIN
  42. };
  43. class chebyshev_7pole
  44. {
  45. /* Digital filter designed by mkfilter/mkshape/gencode A.J. Fisher
  46. Command line: /www/usr/fisher/helpers/mkfilter -Ch -5.0000000000e-02 -Lp -o 7 -a 2.2786458333e-02 0.0000000000e+00 -l */
  47. #define NZEROS 7
  48. #define NPOLES 7
  49. #define GAIN 3.749197811e+07 //8.185223519e+08
  50. #define IGAIN (1.0/GAIN)
  51. public:
  52. uint32_t index;
  53. chebyshev_7pole(): index(0) { memset(xv, 0, sizeof(xv)); memset(yv, 0, sizeof(yv)); }
  54. double xv[NZEROS+1], yv[NPOLES+1];
  55. double run(double nextvalue)
  56. {
  57. #if 0
  58. index++;
  59. xv[index+7&7]= nextvalue*IGAIN;
  60. yv[index+7&7]= (xv[index+0&7] + xv[index+7&7]) + 7 * (xv[index+1&7] + xv[index+6&7]) + 21 * (xv[index+2&7] + xv[index+5&7])
  61. + 35 * (xv[index+3&7] + xv[index+4&7])
  62. + ( 0.7582559865 * yv[index+0&7]) + ( -5.4896632588 * yv[index+1&7])
  63. + ( 17.0657116090 * yv[index+2&7]) + (-29.5302444680 * yv[index+3&7])
  64. + ( 30.7191651920 * yv[index+4&7]) + (-19.2116577140 * yv[index+5&7])
  65. + ( 6.6884324971 * yv[index+6&7]);
  66. return yv[index+7&7];
  67. #else
  68. xv[0] = xv[1]; xv[1] = xv[2]; xv[2] = xv[3]; xv[3] = xv[4]; xv[4] = xv[5]; xv[5] = xv[6]; xv[6] = xv[7];
  69. xv[7] = nextvalue * IGAIN;
  70. yv[0] = yv[1]; yv[1] = yv[2]; yv[2] = yv[3]; yv[3] = yv[4]; yv[4] = yv[5]; yv[5] = yv[6]; yv[6] = yv[7];
  71. yv[7] = (xv[0] + xv[7]) + 7 * (xv[1] + xv[6]) + 21 * (xv[2] + xv[5])
  72. + 35 * (xv[3] + xv[4])
  73. + ( 0.5583379245 * yv[0]) + ( -4.2029878877 * yv[1])
  74. + ( 13.6048706560 * yv[2]) + (-24.5500454730 * yv[3])
  75. + ( 26.6748933120 * yv[4]) + (-17.4541474870 * yv[5])
  76. + ( 6.3690755413 * yv[6]);
  77. // yv[7] = (xv[0] + xv[7]) + 7 * (xv[1] + xv[6]) + 21 * (xv[2] + xv[5])
  78. // + 35 * (xv[3] + xv[4])
  79. // + ( 0.7582559865 * yv[0]) + ( -5.4896632588 * yv[1])
  80. // + ( 17.0657116090 * yv[2]) + (-29.5302444680 * yv[3])
  81. // + ( 30.7191651920 * yv[4]) + (-19.2116577140 * yv[5])
  82. // + ( 6.6884324971 * yv[6]);
  83. return yv[7];
  84. #endif
  85. }
  86. #undef NZEROS
  87. #undef NPOLES
  88. #undef GAIN
  89. };
  90. class chebyshev_3pole
  91. {
  92. /*
  93. Digital filter designed by mkfilter/mkshape/gencode A.J. Fisher
  94. parameters:
  95. filtertype = Chebyshev
  96. passtype = Lowpass
  97. ripple = -1
  98. order = 3
  99. samplerate = 768000
  100. corner1 = 18000
  101. corner2 =
  102. adzero =
  103. logmin =
  104. */
  105. #define NZEROS 3
  106. #define NPOLES 3
  107. #define GAIN 5.476029231e+03
  108. #define IGAIN (1.0/GAIN)
  109. public:
  110. double xv[NZEROS+1]; double yv[NPOLES+1];
  111. chebyshev_3pole() { memset(xv, 0, sizeof(xv)); memset(yv, 0, sizeof(yv)); }
  112. double run(double nextvalue)
  113. {
  114. xv[0] = xv[1]; xv[1] = xv[2]; xv[2] = xv[3];
  115. xv[3] = nextvalue * IGAIN;
  116. yv[0] = yv[1]; yv[1] = yv[2]; yv[2] = yv[3];
  117. yv[3] = (xv[0] + xv[3]) + 3 * (xv[1] + xv[2])
  118. + ( 0.8646065740 * yv[0]) + ( -2.7049827914 * yv[1])
  119. + ( 2.8389153049 * yv[2]);
  120. return yv[3];
  121. }
  122. #undef NZEROS
  123. #undef NPOLES
  124. #undef IGAIN
  125. };
  126. template<int oversampling>
  127. class chebyshev_downsampling_lp
  128. {
  129. public:
  130. double xv[3+1]; double yv[3+1];
  131. chebyshev_downsampling_lp() { memset(xv, 0, sizeof(xv)); memset(yv, 0, sizeof(yv)); }
  132. double run(double nextvalue);
  133. };
  134. template<>
  135. inline double chebyshev_downsampling_lp<16>::run(double nextvalue)
  136. {
  137. /*
  138. mkfilter/mkshape/gencode A.J. Fisher
  139. parameters:
  140. filtertype = Chebyshev
  141. passtype = Lowpass
  142. ripple = -1
  143. order = 3
  144. samplerate = 768000
  145. corner1 = 18000
  146. */
  147. xv[0] = xv[1]; xv[1] = xv[2]; xv[2] = xv[3];
  148. xv[3] = nextvalue * (1.0 / 5.476029231e+03);
  149. yv[0] = yv[1]; yv[1] = yv[2]; yv[2] = yv[3];
  150. yv[3] = (xv[0] + xv[3]) + 3 * (xv[1] + xv[2])
  151. + ( 0.8646065740 * yv[0]) + ( -2.7049827914 * yv[1])
  152. + ( 2.8389153049 * yv[2]);
  153. return yv[3];
  154. }
  155. template<>
  156. inline double chebyshev_downsampling_lp<8>::run(double nextvalue)
  157. {
  158. /*
  159. mkfilter/mkshape/gencode A.J. Fisher
  160. parameters:
  161. filtertype = Chebyshev
  162. passtype = Lowpass
  163. ripple = -1
  164. order = 3
  165. samplerate = 768000
  166. corner1 = 18000
  167. */
  168. xv[0] = xv[1]; xv[1] = xv[2]; xv[2] = xv[3];
  169. xv[3] = nextvalue * (1.0 / 7.330193589e+02);
  170. yv[0] = yv[1]; yv[1] = yv[2]; yv[2] = yv[3];
  171. yv[3] = (xv[0] + xv[3]) + 3 * (xv[1] + xv[2])
  172. + ( 0.7478260267 * yv[0]) + ( -2.4083812307 * yv[1])
  173. + ( 2.6496414404 * yv[2]);
  174. return yv[3];
  175. }
  176. template<>
  177. inline double chebyshev_downsampling_lp<1>::run(double nextvalue)
  178. {
  179. return nextvalue;
  180. }
  181. template<int oversampling> class WaveGenerator
  182. {
  183. public:
  184. WaveGenerator():
  185. phase(0.0), cyclecount(0)
  186. { }
  187. ~WaveGenerator()
  188. { }
  189. double getNextSample()
  190. {
  191. double s= 0;
  192. for(int i= 0; i<oversampling; i++)
  193. {
  194. if(oversampling>1)
  195. s= chebyshev_lp.run(getNextRawSample());
  196. else
  197. s= getNextRawSample();
  198. }
  199. return s;
  200. }
  201. void setFrequency(double sampleRate, double noteFrequency)
  202. {
  203. sampleStep= noteFrequency / (sampleRate*oversampling);
  204. }
  205. void setMultipliers(double mSaw, double mRect, double mTri)
  206. {
  207. float div= mSaw+mRect+mTri;
  208. if(div==0.0f) mSaw= div= 1.0;
  209. div= 1.0/div;
  210. sawFactor= mSaw*div;
  211. rectFactor= mRect*div;
  212. triFactor= mTri*div;
  213. }
  214. float *generateSamples(int nSamples)
  215. {
  216. if(int(sampleBuffer.size())<nSamples)
  217. sampleBuffer.resize(nSamples);
  218. double s;
  219. for(int i= 0; i<nSamples; i++)
  220. {
  221. for(int k= oversampling; k; k--)
  222. s= chebyshev_lp.run(getNextRawSample());
  223. sampleBuffer[i]= s;
  224. }
  225. return &sampleBuffer[0];
  226. }
  227. private:
  228. double sawFactor, rectFactor, triFactor, sampleStep, phase;
  229. int cyclecount;
  230. std::vector<float> rawSampleBuffer;
  231. std::vector<float> sampleBuffer;
  232. chebyshev_downsampling_lp<oversampling> chebyshev_lp;
  233. void generateRawSampleChunk(float *buffer, int nSamples)
  234. {
  235. double saw, rect, tri;
  236. for(int i= 0; i<nSamples; i++)
  237. {
  238. saw= phase;
  239. rect= (phase<0.5? -1: 1);
  240. tri= (cyclecount&1? 2-(phase+1)-1: phase);
  241. phase+= sampleStep;
  242. buffer[i]= saw*sawFactor + rect*rectFactor + tri*triFactor;
  243. }
  244. }
  245. void generateRawSamples(float *buffer, int nSamples)
  246. {
  247. while(phase>1.0) phase-= 2.0;
  248. for(int i= 0; i<nSamples; )
  249. {
  250. int chunkSize= (2 - (phase+1)) / sampleStep;
  251. if(chunkSize>nSamples-i) chunkSize= nSamples-i;
  252. generateRawSampleChunk(buffer+i, chunkSize);
  253. i+= chunkSize;
  254. if(i<nSamples) phase-= 2, cyclecount++;
  255. }
  256. }
  257. double getNextRawSample()
  258. {
  259. double saw= phase,
  260. rect= (phase<0.5? -1: 1),
  261. tri= (cyclecount&1? 2-(phase+1)-1: phase);
  262. double val= saw*sawFactor + rect*rectFactor + tri*triFactor;
  263. phase+= sampleStep;
  264. if (phase > 1)
  265. cyclecount++,
  266. phase -= 2;
  267. return val;
  268. }
  269. };
  270. template<int oversampling> class wolpVoice: public SynthesiserVoice
  271. {
  272. public:
  273. wolpVoice(class wolp *s);
  274. //==============================================================================
  275. bool canPlaySound (SynthesiserSound* sound) override { return true; }
  276. void startNote (const int midiNoteNumber,
  277. const float velocity,
  278. SynthesiserSound* sound,
  279. const int currentPitchWheelPosition) override;
  280. void stopNote (float, const bool allowTailOff) override;
  281. void pitchWheelMoved (const int newValue) override { }
  282. void controllerMoved (const int controllerNumber,
  283. const int newValue) override { }
  284. //==============================================================================
  285. void renderNextBlock (AudioSampleBuffer& outputBuffer, int startSample, int numSamples) override;
  286. void setvolume(double v) { vol= v; }
  287. void setfreq(double f) { freq= f; }
  288. protected:
  289. void process(float* p1, float* p2, int samples);
  290. double phase, low, band, high, vol, freq;
  291. bool playing;
  292. int cyclecount;
  293. unsigned long samples_synthesized;
  294. WaveGenerator<oversampling> generator;
  295. bandpass<8> filter;
  296. ADSRenv env;
  297. class wolp *synth;
  298. };
  299. class wolp: public AudioProcessor,
  300. public Synthesiser,
  301. public ChangeBroadcaster,
  302. public MidiKeyboardStateListener
  303. {
  304. public:
  305. enum params
  306. {
  307. gain= 0,
  308. clip,
  309. gsaw,
  310. grect,
  311. gtri,
  312. tune,
  313. cutoff,
  314. resonance,
  315. bandwidth,
  316. velocity,
  317. inertia,
  318. nfilters,
  319. curcutoff,
  320. attack,
  321. decay,
  322. sustain,
  323. release,
  324. filtermin,
  325. filtermax,
  326. oversampling,
  327. param_size
  328. };
  329. struct paraminfo
  330. {
  331. const char *internalname;
  332. const char *label;
  333. double min, max, defval;
  334. bool dirty; // parameter has changed, GUI must be updated
  335. };
  336. static paraminfo paraminfos[param_size];
  337. wolp();
  338. ~wolp() override;
  339. bool silenceInProducesSilenceOut() const override { return false; }
  340. double getTailLengthSeconds() const override { return 0.0; }
  341. const String getName() const override { return "Wolpertinger"; }
  342. void prepareToPlay (double sampleRate, int estimatedSamplesPerBlock) override
  343. {
  344. setCurrentPlaybackSampleRate(sampleRate);
  345. for(int i= 0; i<getNumVoices(); i++)
  346. getVoice(i)->setCurrentPlaybackSampleRate(sampleRate);
  347. }
  348. void releaseResources() override { }
  349. void processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages) override;
  350. const String getInputChannelName (const int channelIndex) const override { return String("In") + String(channelIndex); }
  351. const String getOutputChannelName (const int channelIndex) const override { return String("Out") + String(channelIndex); }
  352. bool isInputChannelStereoPair (int index) const override { return true; }
  353. bool isOutputChannelStereoPair (int index) const override { return true; }
  354. bool acceptsMidi() const override { return true; }
  355. bool producesMidi() const override { return false; }
  356. #if ! JUCE_AUDIOPROCESSOR_NO_GUI
  357. bool hasEditor() const override { return true; }
  358. AudioProcessorEditor* createEditor() override;
  359. #endif
  360. int getNumParameters() override { return param_size; }
  361. const String getParameterName (int idx) override { return String(paraminfos[idx].label); }
  362. float getParameter (int idx) override
  363. {
  364. return params[idx];
  365. }
  366. const String getParameterText (int idx) override
  367. {
  368. switch(idx)
  369. {
  370. default:
  371. return String(getparam(idx), 2);
  372. }
  373. }
  374. void setParameter (int idx, float value) override;
  375. //==============================================================================
  376. int getNumPrograms() override { return 1; };
  377. int getCurrentProgram() override { return 0; };
  378. void setCurrentProgram (int index) override { };
  379. const String getProgramName (int index) override { return "Default"; };
  380. void changeProgramName (int index, const String& newName) override {}
  381. //==============================================================================
  382. void getStateInformation (JUCE_NAMESPACE::MemoryBlock& destData) override;
  383. void setStateInformation (const void* data, int sizeInBytes) override;
  384. //==============================================================================
  385. double getnotefreq (int noteNumber)
  386. {
  387. noteNumber -= 12 * 6 + 9; // now 0 = A440
  388. return getparam(tune) * pow (2.0, noteNumber / 12.0);
  389. }
  390. float getparam(int idx);
  391. void loaddefaultparams();
  392. void renderNextBlock (AudioSampleBuffer& outputAudio,
  393. const MidiBuffer& inputMidi,
  394. int startSample,
  395. int numSamples);
  396. //==============================================================================
  397. /** Called when one of the MidiKeyboardState's keys is pressed.
  398. This will be called synchronously when the state is either processing a
  399. buffer in its MidiKeyboardState::processNextMidiBuffer() method, or
  400. when a note is being played with its MidiKeyboardState::noteOn() method.
  401. Note that this callback could happen from an audio callback thread, so be
  402. careful not to block, and avoid any UI activity in the callback.
  403. */
  404. virtual void handleNoteOn (MidiKeyboardState* source,
  405. int midiChannel, int midiNoteNumber, float velocity) override
  406. {
  407. // printf("MidiKeyboard noteOn isProcessing=%s\n", isProcessing? "true": "false");
  408. noteOn(midiChannel, midiNoteNumber, velocity);
  409. }
  410. /** Called when one of the MidiKeyboardState's keys is released.
  411. This will be called synchronously when the state is either processing a
  412. buffer in its MidiKeyboardState::processNextMidiBuffer() method, or
  413. when a note is being played with its MidiKeyboardState::noteOff() method.
  414. Note that this callback could happen from an audio callback thread, so be
  415. careful not to block, and avoid any UI activity in the callback.
  416. */
  417. virtual void handleNoteOff (MidiKeyboardState* source,
  418. int midiChannel, int midiNoteNumber, float velocity) override
  419. {
  420. // printf("MidiKeyboard noteOff isProcessing=%s\n", isProcessing? "true": "false");
  421. noteOff(midiChannel, midiNoteNumber, velocity, true);
  422. }
  423. protected:
  424. private:
  425. double params[param_size];
  426. velocityfilter <double> cutoff_filter;
  427. bool isProcessing; // whether we are in the processBlock callback
  428. friend class wolpVoice<1>;
  429. friend class wolpVoice<8>;
  430. friend class wolpVoice<16>;
  431. friend class editor;
  432. };
  433. #endif // SYNTH_H