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