1 //-----------------------------------------------------------------------------
2 // Copyright (c) 2015-2018 Marcelo Fernandez
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a copy
5 // of this software and associated documentation files (the "Software"), to
6 // deal in the Software without restriction, including without limitation the
7 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 // sell copies of the Software, and to permit persons to whom the Software is
9 // furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 // IN THE SOFTWARE.
21 //-----------------------------------------------------------------------------
22 
23 #ifndef __OAMLBASE_H__
24 #define __OAMLBASE_H__
25 
26 #include <thread>
27 #include <mutex>
28 
29 #include "tinyxml2.h"
30 #ifdef __HAVE_RTAUDIO
31 #include "RtAudio.h"
32 #endif
33 
34 
35 class oamlBase {
36 private:
37 	std::thread *bufferThread;
38 	std::mutex mutex;
39 
40 	std::string defsFile;
41 	std::string playingInfo;
42 
43 	bool verbose;
44 	bool debugClipping;
45 	bool writeAudioAtShutdown;
46 	bool useCompressor;
47 	bool updateTension;
48 	bool stopThread;
49 
50 	std::vector<oamlMusicTrack*> musicTracks;
51 	std::vector<oamlSfxTrack*> sfxTracks;
52 	std::vector<oamlLayer*> layers;
53 
54 	std::vector<std::pair<int, int>> conditions;
55 
56 	float bpm;
57 	int beatsPerBar;
58 
59 	int curTrack;
60 	int bufferFrames;
61 
62 	ByteBuffer *dataBuffer;
63 	ByteBuffer *fullBuffer;
64 
65 #ifdef __HAVE_RTAUDIO
66 	RtAudio *rtAudio;
67 #endif
68 
69 	int sampleRate;
70 	int channels;
71 	int bytesPerSample;
72 	bool floatBuffer;
73 
74 	int tension;
75 	uint64_t tensionMs;
76 	float volume;
77 	bool pause;
78 
79 	oamlFileCallbacks *fcbs;
80 
81 	uint64_t timeMs;
82 
83 	oamlCompressor compressor;
84 
85 	oamlTracksInfo tracksInfo;
86 
87 	void Clear();
88 
89 	oamlRC PlayTrackId(int id);
90 	bool IsTrackPlayingId(int id);
91 
92 	void ShowPlayingTracks();
93 	oamlRC ReadAudioDefs(tinyxml2::XMLElement *el, oamlTrack *track);
94 	oamlRC ReadTrackDefs(tinyxml2::XMLElement *el);
95 	oamlRC ReadDefs(const char *buf, int size);
96 	void ReadInternalDefs(const char *filaname);
97 
98 	void BufferData();
99 	static void BufferThreadFunc();
100 
101 	int ReadSample(void *buffer, int index);
102 	void WriteSample(void *buffer, int index, int sample);
103 
104 	bool IsAudioFormatSupported();
105 
106 	void AddLayer(std::string layer);
107 	int GetLayerId(std::string layer);
108 	oamlLayer *GetLayer(std::string layer);
109 
110 	void UpdateTension(uint64_t ms);
111 	void UpdateCondition();
112 
113 	oamlTrack* GetTrack(std::string name);
114 	oamlAudio* GetAudio(std::string trackName, std::string audioName);
115 	oamlAudioFile* GetAudioFile(std::string trackName, std::string audioName, std::string filename);
116 
117 public:
118 	oamlBase();
119 	~oamlBase();
120 
121 	const char* GetVersion();
122 
123 	oamlRC InitAudioDevice(int sampleRate, int channels);
124 	oamlRC Init(const char *defsFilename);
125 	oamlRC ReadDefsFile(const char *defsFilename);
126 	oamlRC InitString(const char *defs);
127 	void Shutdown();
128 
SetVerbose(bool option)129 	void SetVerbose(bool option) { verbose = option; }
SetDebugClipping(bool option)130 	void SetDebugClipping(bool option) { debugClipping = option; }
SetWriteAudioAtShutdown(bool option)131 	void SetWriteAudioAtShutdown(bool option) { writeAudioAtShutdown = option; }
132 
133 	void SetAudioFormat(int audioSampleRate, int audioChannels, int audioBytesPerSample, bool audioFloatBuffer);
134 	void SetVolume(float vol);
GetVolume()135 	float GetVolume() const { return volume; }
136 
137 	oamlRC PlayTrack(const char *name);
138 	oamlRC PlayTrackWithStringRandom(const char *str);
139 	oamlRC PlayTrackByGroupRandom(const char *group);
140 	oamlRC PlayTrackByGroupAndSubgroupRandom(const char *group, const char *subgroup);
141 	oamlRC PlaySfx(const char *name);
142 	oamlRC PlaySfxEx(const char *name, float vol, float pan);
143 	oamlRC PlaySfx2d(const char *name, int x, int y, int width, int height);
144 
145 	oamlRC LoadTrack(const char *name);
146 	float LoadTrackProgress(const char *name);
147 
148 	void StopPlaying();
149 	void Pause();
150 	void Resume();
151 	void PauseToggle();
152 
IsPaused()153 	bool IsPaused() const { return pause; }
154 
155 	bool IsTrackPlaying(const char *name);
156 	bool IsPlaying();
157 
158 	void AddTension(int value);
159 	void SetTension(int value);
160 	int GetTension();
161 
162 	void SetMainLoopCondition(int value);
163 
164 	void ClearConditions();
165 	void SetCondition(int id, int value);
166 
167 	void SetLayerGain(const char *layer, float gain);
168 	float GetLayerGain(const char *layer);
169 	void SetLayerRandomChance(const char *layer, int randomChance);
170 	int GetLayerRandomChance(const char *layer);
171 
172 	void MixToBuffer(void *buffer, int size);
173 
174 	void Update();
175 
176 	int SafeAdd(int sample1, int sample2);
177 
178 	void SetFileCallbacks(oamlFileCallbacks *cbs);
179 
180 	void EnableDynamicCompressor(bool enable, double thresholdDb, double ratio);
181 
182 	std::string SaveState();
183 	void LoadState(std::string state);
184 
185 	oamlTracksInfo *GetTracksInfo();
186 
187 	const char* GetDefsFile();
188 	const char* GetPlayingInfo();
189 
190 	void ProjectNew();
191 	void ProjectSetBPM(float bpm);
192 	void ProjectSetBeatsPerBar(int beatsPerBar);
193 	float ProjectGetBPM();
194 	int ProjectGetBeatsPerBar();
195 
196 	oamlRC TrackNew(std::string name, bool sfxTrack = false);
197 	oamlRC TrackRemove(std::string name);
198 	void TrackRename(std::string name, std::string newName);
199 	void TrackSetVolume(std::string name, float volume);
200 	void TrackSetFadeIn(std::string name, int fadeIn);
201 	void TrackSetFadeOut(std::string name, int fadeOut);
202 	void TrackSetXFadeIn(std::string name, int xFadeIn);
203 	void TrackSetXFadeOut(std::string name, int xFadeOut);
204 
205 	bool TrackExists(std::string name);
206 	bool TrackIsSfxTrack(std::string name);
207 	bool TrackIsMusicTrack(std::string name);
208 	void TrackGetAudioList(std::string name, std::vector<std::string>& list);
209 	float TrackGetVolume(std::string name);
210 	int TrackGetFadeIn(std::string name);
211 	int TrackGetFadeOut(std::string name);
212 	int TrackGetXFadeIn(std::string name);
213 	int TrackGetXFadeOut(std::string name);
214 
215 	oamlRC AudioNew(std::string trackName, std::string audioName, int type);
216 	oamlRC AudioRemove(std::string trackName, std::string audioName);
217 	void AudioAddAudioFile(std::string trackName, std::string audioName, std::string filename);
218 	void AudioSetName(std::string trackName, std::string audioName, std::string name);
219 	void AudioSetVolume(std::string trackName, std::string audioName, float volume);
220 	void AudioSetBPM(std::string trackName, std::string audioName, float bpm);
221 	void AudioSetBeatsPerBar(std::string trackName, std::string audioName, int beatsPerBar);
222 	void AudioSetBars(std::string trackName, std::string audioName, int bars);
223 	void AudioSetMinMovementBars(std::string trackName, std::string audioName, int minMovementBars);
224 	void AudioSetRandomChance(std::string trackName, std::string audioName, int randomChance);
225 	void AudioSetFadeIn(std::string trackName, std::string audioName, int fadeIn);
226 	void AudioSetFadeOut(std::string trackName, std::string audioName, int fadeOut);
227 	void AudioSetXFadeIn(std::string trackName, std::string audioName, int xFadeIn);
228 	void AudioSetXFadeOut(std::string trackName, std::string audioName, int xFadeOut);
229 	void AudioSetCondId(std::string trackName, std::string audioName, int condId);
230 	void AudioSetCondType(std::string trackName, std::string audioName, int condType);
231 	void AudioSetCondValue(std::string trackName, std::string audioName, int condValue);
232 	void AudioSetCondValue2(std::string trackName, std::string audioName, int condValue2);
233 
234 	bool AudioExists(std::string trackName, std::string audioName);
235 	void AudioGetAudioFileList(std::string trackName, std::string audioName, std::vector<std::string>& list);
236 	int AudioGetType(std::string trackName, std::string audioName);
237 	float AudioGetVolume(std::string trackName, std::string audioName);
238 	float AudioGetBPM(std::string trackName, std::string audioName);
239 	int AudioGetBeatsPerBar(std::string trackName, std::string audioName);
240 	int AudioGetBars(std::string trackName, std::string audioName);
241 	int AudioGetMinMovementBars(std::string trackName, std::string audioName);
242 	int AudioGetRandomChance(std::string trackName, std::string audioName);
243 	int AudioGetFadeIn(std::string trackName, std::string audioName);
244 	int AudioGetFadeOut(std::string trackName, std::string audioName);
245 	int AudioGetXFadeIn(std::string trackName, std::string audioName);
246 	int AudioGetXFadeOut(std::string trackName, std::string audioName);
247 	int AudioGetCondId(std::string trackName, std::string audioName);
248 	int AudioGetCondType(std::string trackName, std::string audioName);
249 	int AudioGetCondValue(std::string trackName, std::string audioName);
250 	int AudioGetCondValue2(std::string trackName, std::string audioName);
251 
252 	void AudioFileRemove(std::string trackName, std::string audioName, std::string filename);
253 	void AudioFileSetLayer(std::string trackName, std::string audioName, std::string filename, std::string layer);
254 	void AudioFileSetRandomChance(std::string trackName, std::string audioName, std::string filename, int randomChance);
255 
256 	std::string AudioFileGetLayer(std::string trackName, std::string audioName, std::string filename);
257 	int AudioFileGetRandomChance(std::string trackName, std::string audioName, std::string filename);
258 
259 	oamlRC LayerNew(std::string name);
260 	void LayerList(std::vector<std::string>& list);
261 	void LayerRename(std::string layerName, std::string name);
262 	int LayerGetId(std::string layerName);
263 	int LayerGetRandomChance(std::string layerName);
264 	float LayerGetGain(std::string layerName);
265 
GetSampleRate()266 	int GetSampleRate() const { return sampleRate; }
267 };
268 
269 #endif /* __OAMLBASE_H__ */
270