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.

217 lines
8.4KB

  1. /* Copyright 2013-2019 Matt Tytel
  2. *
  3. * vital is free software: you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation, either version 3 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * vital is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with vital. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #pragma once
  17. #include "JuceHeader.h"
  18. #include "concurrentqueue/concurrentqueue.h"
  19. #include "line_generator.h"
  20. #include "synth_constants.h"
  21. #include "synth_types.h"
  22. #include "midi_manager.h"
  23. #include "tuning.h"
  24. #include "wavetable_creator.h"
  25. #include <set>
  26. #include <string>
  27. namespace vital {
  28. class SoundEngine;
  29. struct Output;
  30. class StatusOutput;
  31. class StereoMemory;
  32. class Sample;
  33. class WaveFrame;
  34. class Wavetable;
  35. }
  36. class SynthGuiInterface;
  37. class SynthBase : public MidiManager::Listener {
  38. public:
  39. static constexpr float kOutputWindowMinNote = 16.0f;
  40. static constexpr float kOutputWindowMaxNote = 128.0f;
  41. SynthBase();
  42. virtual ~SynthBase();
  43. void valueChanged(const std::string& name, vital::mono_float value);
  44. void valueChangedThroughMidi(const std::string& name, vital::mono_float value) override;
  45. #if ! JUCE_AUDIOPROCESSOR_NO_GUI
  46. void pitchWheelMidiChanged(vital::mono_float value) override;
  47. void modWheelMidiChanged(vital::mono_float value) override;
  48. #endif
  49. void pitchWheelGuiChanged(vital::mono_float value);
  50. void modWheelGuiChanged(vital::mono_float value);
  51. #if ! JUCE_AUDIOPROCESSOR_NO_GUI
  52. void presetChangedThroughMidi(File preset) override;
  53. #endif
  54. void valueChangedExternal(const std::string& name, vital::mono_float value);
  55. void valueChangedInternal(const std::string& name, vital::mono_float value);
  56. bool connectModulation(const std::string& source, const std::string& destination);
  57. void connectModulation(vital::ModulationConnection* connection);
  58. void disconnectModulation(const std::string& source, const std::string& destination);
  59. void disconnectModulation(vital::ModulationConnection* connection);
  60. void clearModulations();
  61. void forceShowModulation(const std::string& source, bool force);
  62. bool isModSourceEnabled(const std::string& source);
  63. int getNumModulations(const std::string& destination);
  64. int getConnectionIndex(const std::string& source, const std::string& destination);
  65. vital::CircularQueue<vital::ModulationConnection*> getModulationConnections() { return mod_connections_; }
  66. std::vector<vital::ModulationConnection*> getSourceConnections(const std::string& source);
  67. bool isSourceConnected(const std::string& source);
  68. std::vector<vital::ModulationConnection*> getDestinationConnections(const std::string& destination);
  69. const vital::StatusOutput* getStatusOutput(const std::string& name);
  70. vital::Wavetable* getWavetable(int index);
  71. WavetableCreator* getWavetableCreator(int index);
  72. vital::Sample* getSample();
  73. LineGenerator* getLfoSource(int index);
  74. int getSampleRate();
  75. void initEngine();
  76. void loadTuningFile(const File& file);
  77. void loadInitPreset();
  78. bool loadFromFile(File preset, std::string& error);
  79. void renderAudioToFile(File file, float seconds, float bpm, std::vector<int> notes, bool render_images);
  80. void renderAudioForResynthesis(float* data, int samples, int note);
  81. bool saveToFile(File preset);
  82. bool saveToActiveFile();
  83. void clearActiveFile() { active_file_ = File(); }
  84. File getActiveFile() { return active_file_; }
  85. void setMpeEnabled(bool enabled);
  86. virtual void beginChangeGesture(const std::string& name) { }
  87. virtual void endChangeGesture(const std::string& name) { }
  88. virtual void setValueNotifyHost(const std::string& name, vital::mono_float value) { }
  89. void setAuthor(const String& author);
  90. void setComments(const String& comments);
  91. void setStyle(const String& comments);
  92. void setPresetName(const String& preset_name);
  93. void setMacroName(int index, const String& macro_name);
  94. String getAuthor();
  95. String getComments();
  96. String getStyle();
  97. String getPresetName();
  98. String getMacroName(int index);
  99. vital::control_map& getControls() { return controls_; }
  100. vital::SoundEngine* getEngine() { return engine_.get(); }
  101. MidiKeyboardState* getKeyboardState() { return keyboard_state_.get(); }
  102. const vital::poly_float* getOscilloscopeMemory() { return oscilloscope_memory_; }
  103. const vital::StereoMemory* getAudioMemory() { return audio_memory_.get(); }
  104. const vital::StereoMemory* getEqualizerMemory();
  105. vital::ModulationConnectionBank& getModulationBank();
  106. void notifyOversamplingChanged();
  107. void checkOversampling();
  108. virtual const CriticalSection& getCriticalSection() = 0;
  109. virtual void pauseProcessing(bool pause) = 0;
  110. Tuning* getTuning() { return &tuning_; }
  111. #if ! JUCE_AUDIOPROCESSOR_NO_GUI
  112. struct ValueChangedCallback : public CallbackMessage {
  113. ValueChangedCallback(std::shared_ptr<SynthBase*> listener, std::string name, vital::mono_float val) :
  114. listener(listener), control_name(std::move(name)), value(val) { }
  115. void messageCallback() override;
  116. std::weak_ptr<SynthBase*> listener;
  117. std::string control_name;
  118. vital::mono_float value;
  119. };
  120. #endif
  121. protected:
  122. vital::modulation_change createModulationChange(vital::ModulationConnection* connection);
  123. bool isInvalidConnection(const vital::modulation_change& change);
  124. #if ! JUCE_AUDIOPROCESSOR_NO_GUI
  125. virtual SynthGuiInterface* getGuiInterface() = 0;
  126. #endif
  127. json saveToJson();
  128. bool loadFromJson(const json& state);
  129. vital::ModulationConnection* getConnection(const std::string& source, const std::string& destination);
  130. inline bool getNextModulationChange(vital::modulation_change& change) {
  131. return modulation_change_queue_.try_dequeue_non_interleaved(change);
  132. }
  133. inline void clearModulationQueue() {
  134. vital::modulation_change change;
  135. while (modulation_change_queue_.try_dequeue_non_interleaved(change))
  136. ;
  137. }
  138. void processAudio(AudioSampleBuffer* buffer, int channels, int samples, int offset);
  139. void processAudioWithInput(AudioSampleBuffer* buffer, const vital::poly_float* input_buffer,
  140. int channels, int samples, int offset);
  141. void writeAudio(AudioSampleBuffer* buffer, int channels, int samples, int offset);
  142. void processMidi(MidiBuffer& buffer, int start_sample = 0, int end_sample = 0);
  143. void processKeyboardEvents(MidiBuffer& buffer, int num_samples);
  144. void processModulationChanges();
  145. void updateMemoryOutput(int samples, const vital::poly_float* audio);
  146. std::unique_ptr<vital::SoundEngine> engine_;
  147. std::unique_ptr<MidiManager> midi_manager_;
  148. std::unique_ptr<MidiKeyboardState> keyboard_state_;
  149. std::unique_ptr<WavetableCreator> wavetable_creators_[vital::kNumOscillators];
  150. std::shared_ptr<SynthBase*> self_reference_;
  151. File active_file_;
  152. vital::poly_float oscilloscope_memory_[2 * vital::kOscilloscopeMemoryResolution];
  153. vital::poly_float oscilloscope_memory_write_[2 * vital::kOscilloscopeMemoryResolution];
  154. std::unique_ptr<vital::StereoMemory> audio_memory_;
  155. vital::mono_float last_played_note_;
  156. int last_num_pressed_;
  157. vital::mono_float memory_reset_period_;
  158. vital::mono_float memory_input_offset_;
  159. int memory_index_;
  160. bool expired_;
  161. std::map<std::string, String> save_info_;
  162. vital::control_map controls_;
  163. vital::CircularQueue<vital::ModulationConnection*> mod_connections_;
  164. moodycamel::ConcurrentQueue<vital::control_change> value_change_queue_;
  165. moodycamel::ConcurrentQueue<vital::modulation_change> modulation_change_queue_;
  166. Tuning tuning_;
  167. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(SynthBase)
  168. };
  169. class HeadlessSynth : public SynthBase {
  170. public:
  171. virtual const CriticalSection& getCriticalSection() override {
  172. return critical_section_;
  173. }
  174. virtual void pauseProcessing(bool pause) override {
  175. if (pause)
  176. critical_section_.enter();
  177. else
  178. critical_section_.exit();
  179. }
  180. #if ! JUCE_AUDIOPROCESSOR_NO_GUI
  181. protected:
  182. virtual SynthGuiInterface* getGuiInterface() override { return nullptr; }
  183. #endif
  184. private:
  185. CriticalSection critical_section_;
  186. };