1 #ifndef _Synth_Synth_h 2 #define _Synth_Synth_h 3 4 #include <Core/Core.h> 5 6 using namespace Upp; 7 8 enum FORMS { 9 WAVEFORM_SIN = 0, 10 WAVEFORM_SQUARE = 1, 11 WAVEFORM_TRIANGLE = 2, 12 WAVEFORM_SAWTOOTH = 3, 13 14 WAVEFORM_FIRSTSAMPLE = 4, 15 WAVEFORM_SAXOPHONE = WAVEFORM_FIRSTSAMPLE, 16 WAVEFORM_VIOLIN = 5, 17 WAVEFORM_DOUBLEBASS = 6, 18 WAVEFORM_BANJO = 7, 19 WAVEFORM_TRUMPET = 8, 20 WAVEFORM_LASTSAMPLE = 8, 21 22 WAVEFORM_BROWN = 100, 23 WAVEFORM_WHITE = 101, 24 }; 25 26 struct FMOP { 27 double duration = 99000; 28 double volume = 0; 29 30 double f = 1; 31 double fdrift = 0; 32 33 double attack = 100; 34 double decay = 100; 35 double sustain = 100; 36 double release = 100; 37 38 int waveform = WAVEFORM_SIN; 39 40 String Save() const; 41 const char *Load(const char *s); 42 }; 43 44 #define OPCOUNT 5 45 46 struct Sound { 47 double f = 440; 48 FMOP op[OPCOUNT]; 49 double pan = 0.5; 50 51 String Save() const; 52 void Load(const char *s); 53 54 Sound(); 55 }; 56 57 struct SoundGen { 58 struct FMOPGen : FMOP { 59 int p; 60 double v; 61 double n; 62 double *wave_tab; 63 StartSoundGen::FMOPGen64 void Start() { v = 1e-3; p = 0; n = 0; } 65 void Comp(); 66 String ToString() const; 67 68 double Evaluate(int t, double mf, double mod, double& current_volume); 69 }; 70 71 int serial; 72 int param_serial; 73 int id; 74 int priority; 75 double f = 440; 76 float lpan = 0.5f; 77 float rpan = 0.5f; 78 int t; 79 int delay; 80 FMOPGen op[OPCOUNT]; 81 float feedback[8192]; 82 double current_volume = 0; 83 double lfo_mod = 0; 84 85 void Start(const Sound& s); 86 float Get(); 87 String ToString() const; 88 }; 89 90 #define CHUNK_SIZE 512 91 #define NUM_CHANNELS 20 92 93 void InitSoundSynth(bool initsdl = true); 94 void CloseSoundSynth(bool exitsdl = true); 95 96 void SetChannel(int chi, const Sound& c, int priority = INT_MAX, int id = 0); 97 void SetChannelVolume(int chi, double volume); 98 void StopChannelById(int id); 99 int FindChannel(int priority, int from, double new_volume); 100 void StopChannels(int id); 101 102 void SetGlobalVolume(float vol); 103 104 struct SoundEvent : Moveable<SoundEvent> { 105 Sound *snd; 106 float duration; 107 float frequency; 108 float volume; 109 }; 110 111 struct SoundSequence { 112 mutable int at = 0; 113 int cursor = 0; 114 int loop = Null; 115 ArrayMap<String, Sound> bank; 116 Vector<Vector<SoundEvent>> event; 117 GetAtSoundSequence118 int GetAt(double at) { return (int)(at * 44100 / 512); } AtSoundSequence119 Vector<SoundEvent>& At(double at) { return event.At(GetAt(at)); } LoopAtSoundSequence120 void LoopAt(double at) { loop = GetAt(at); } 121 int SoundIndex(const String& s); 122 void Put(double at, int i, 123 double volume, double freqency, double duration, bool direct = false); 124 void Put(double at, const String& snd, 125 double volume, double freqency, double duration, bool direct = false); 126 }; 127 128 void PlaySequence(const SoundSequence& s); 129 void PlayTempSequence(SoundSequence&& s); 130 131 void StopSequencer(); 132 bool IsPlayingSequence(); 133 134 SoundSequence ParseQSF(const String& data); 135 136 #endif 137