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 __OAML_H__ 24 #define __OAML_H__ 25 26 #include <stddef.h> 27 28 // 29 // Definitions 30 // 31 32 #define OAML_VOLUME_MIN 0.f 33 #define OAML_VOLUME_MAX 1.f 34 35 #define OAML_VOLUME_DEFAULT 0.5f 36 37 // 38 typedef enum { 39 OAML_CONDTYPE_EQUAL = 0, // x == value 40 OAML_CONDTYPE_GREATER = 1, // x > value 41 OAML_CONDTYPE_LESS = 2, // x < value 42 OAML_CONDTYPE_RANGE = 3 // x >= value AND x <= value2 43 } oamlCondType; 44 45 // Condition id's 1-9 are reserved for oaml core 46 typedef enum { 47 OAML_CONDID_TENSION = 1, 48 OAML_CONDID_MAIN_LOOP = 2, 49 OAML_CONDID_USER = 10 50 } oamlCondId; 51 52 // Return codes 53 typedef enum { 54 OAML_OK = 0, 55 OAML_ERROR = -1, 56 OAML_NOT_FOUND = -2 57 } oamlRC; 58 59 typedef struct { 60 void* (*open) (const char *filename); 61 size_t (*read) (void *ptr, size_t size, size_t nitems, void *fd); 62 int (*seek) (void *fd, long offset, int whence); 63 long (*tell) (void *fd); 64 int (*close) (void *fd); 65 } oamlFileCallbacks; 66 67 68 #ifndef __cplusplus 69 70 #ifdef _MSC_VER 71 typedef int bool; 72 #define false 0 73 #define true 1 74 #else 75 #include <stdbool.h> 76 #endif 77 78 const char* oamlGetVersion(); 79 oamlRC oamlInitAudioDevice(int sampleRate, int channels); 80 oamlRC oamlInit(const char *defsFilename); 81 oamlRC oamlReadDefsFile(const char *defsFilename); 82 oamlRC oamlInitString(const char *defs); 83 void oamlSetAudioFormat(int sampleRate, int channels, int bytesPerSample, bool floatBuffer); 84 oamlRC oamlPlayTrack(const char *name); 85 oamlRC oamlPlayTrackWithStringRandom(const char *str); 86 oamlRC oamlPlayTrackByGroupRandom(const char *group); 87 oamlRC oamlPlayTrackByGroupAndSubgroupRandom(const char *group, const char *subgroup); 88 oamlRC oamlPlaySfx(const char *name); 89 oamlRC oamlPlaySfxEx(const char *name, float vol, float pan); 90 oamlRC oamlPlaySfx2d(const char *name, int x, int y, int width, int height); 91 bool oamlIsTrackPlaying(const char *name); 92 bool oamlIsPlaying(); 93 void oamlStopPlaying(); 94 void oamlPause(); 95 void oamlResume(); 96 void oamlPauseToggle(); 97 bool oamlIsPaused(); 98 void oamlMixToBuffer(void *buffer, int size); 99 void oamlSetCondition(int id, int value); 100 void oamlSetVolume(float vol); 101 float oamlGetVolume(); 102 void oamlAddTension(int value); 103 void oamlSetTension(int value); 104 void oamlSetMainLoopCondition(int value); 105 void oamlUpdate(); 106 void SetDebugClipping(bool option); 107 void SetWriteAudioAtShutdown(bool option); 108 void oamlSetFileCallbacks(oamlFileCallbacks *cbs); 109 void oamlEnableDynamicCompressor(bool enable, double threshold, double ratio); 110 const char* oamlGetDefsFile(); 111 const char* oamlGetPlayingInfo(); 112 void oamlShutdown(); 113 114 #else 115 116 #include <algorithm> 117 #include <string> 118 #include <vector> 119 120 typedef struct { 121 std::string filename; 122 std::string layer; 123 int randomChance; 124 } oamlAudioFileInfo; 125 126 typedef struct { 127 std::string name; 128 int type; 129 float volume; 130 float bpm; 131 int beatsPerBar; 132 int bars; 133 int minMovementBars; 134 int randomChance; 135 int playOrder; 136 int fadeIn; 137 int fadeOut; 138 int xfadeIn; 139 int xfadeOut; 140 int condId; 141 int condType; 142 int condValue; 143 int condValue2; 144 std::vector<oamlAudioFileInfo> files; 145 } oamlAudioInfo; 146 147 typedef struct { 148 std::string name; 149 std::vector<std::string> groups; 150 std::vector<std::string> subgroups; 151 bool musicTrack; 152 bool sfxTrack; 153 int fadeIn; 154 int fadeOut; 155 int xfadeIn; 156 int xfadeOut; 157 float volume; 158 std::vector<oamlAudioInfo> audios; 159 } oamlTrackInfo; 160 161 typedef struct { 162 float bpm; 163 int beatsPerBar; 164 std::vector<oamlTrackInfo> tracks; 165 } oamlTracksInfo; 166 167 168 // 169 // Internal declarations 170 // 171 172 class oamlBase; 173 class oamlStudioApi; 174 175 // 176 // Main class 177 // 178 179 #if defined(oaml_shared_EXPORTS) || defined(OAML_EXPORTS) 180 class DLLEXPORT oamlApi { 181 #else 182 class oamlApi { 183 #endif 184 private: 185 oamlBase *oaml; 186 oamlStudioApi *oamlStudio; 187 188 public: 189 oamlApi(); 190 ~oamlApi(); 191 192 const char* GetVersion(); 193 194 /** Initilize the Open Adaptive Music Library with the path to 'oaml.defs' 195 * @return returns OAML_OK on success 196 */ 197 oamlRC Init(const char *defsFilename); 198 199 /** Read Open Adaptive Music Library definition file 200 * @return returns OAML_OK on success 201 */ 202 oamlRC ReadDefsFile(const char *defsFilename); 203 204 /** Initilize the Open Adaptive Music Library with xml definitions on value defs 205 * @return returns OAML_OK on success 206 */ 207 oamlRC InitString(const char *defs); 208 209 /** Initialize the audio device through RtAudio 210 * @return returns OAML_OK on success 211 */ 212 oamlRC InitAudioDevice(int sampleRate = 44100, int channels = 2); 213 214 /** Shutdown the library */ 215 void Shutdown(); 216 217 /** Set the audio format to be used by MixToBuffer */ 218 void SetAudioFormat(int sampleRate, int channels, int bytesPerSample, bool floatBuffer = false); 219 void SetVolume(float vol); 220 float GetVolume(); 221 222 /** Play a music track by name (recommended) or id 223 * @return returns OAML_OK on success 224 */ 225 oamlRC PlayTrack(const char *name); 226 227 /** Play a random music track that contains str in the name 228 * @return returns OAML_OK on success 229 */ 230 oamlRC PlayTrackWithStringRandom(const char *str); 231 232 /** Play a random music track that belongs to a certain group 233 * @return returns OAML_OK on success 234 */ 235 oamlRC PlayTrackByGroupRandom(const char *group); 236 237 /** Play a random music track that belongs to a certain group and subgroup 238 * @return returns OAML_OK on success 239 */ 240 oamlRC PlayTrackByGroupAndSubgroupRandom(const char *group, const char *subgroup); 241 242 /** Play a sound fx 243 * @return returns OAML_OK on success 244 */ 245 oamlRC PlaySfx(const char *name); 246 oamlRC PlaySfxEx(const char *name, float vol, float pan); 247 oamlRC PlaySfx2d(const char *name, int x, int y, int width, int height); 248 249 /** Load a track into memory cache (blocking) 250 */ 251 oamlRC LoadTrack(const char *name); 252 253 /** Load a track into memory cache (non-blocking) 254 * @return returns 0.f to 1.f or -1.f on error 255 */ 256 float LoadTrackProgress(const char *name); 257 258 /** Stop playing any track currently playing */ 259 void StopPlaying(); 260 261 /** Pause playback */ 262 void Pause(); 263 264 /** Resume playback */ 265 void Resume(); 266 267 /** Pause/resume playback */ 268 void PauseToggle(); 269 270 /** Are we in pause state? */ 271 bool IsPaused(); 272 273 /** Check if a track is playing */ 274 bool IsTrackPlaying(const char *name); 275 276 /** Check if any track is playing */ 277 bool IsPlaying(); 278 279 /** Add tension that triggers different aspects of the music */ 280 void AddTension(int value); 281 282 /** Set tension that triggers different aspects of the music */ 283 void SetTension(int value); 284 285 /** Get the current tension value */ 286 int GetTension(); 287 288 /** Sets a condition that affects the main loop */ 289 void SetMainLoopCondition(int value); 290 291 /** Set a condition */ 292 void SetCondition(int id, int value); 293 294 /** Clears current conditions */ 295 void ClearConditions(); 296 297 /** Set gain (0.f - 1.f) of a layer */ 298 void SetLayerGain(const char *layer, float gain); 299 300 /** Get gain (0.f - 1.f) of a layer */ 301 float GetLayerGain(const char *layer); 302 303 /** Set random chance (0 - 100) of a layer */ 304 void SetLayerRandomChance(const char *layer, int rhandomChance); 305 306 /** Get random chance (0 - 100) of a layer */ 307 int GetLayerRandomChance(const char *layer); 308 309 /** Main function to call form the internal game audio manager */ 310 void MixToBuffer(void *buffer, int size); 311 312 /** Update */ 313 void Update(); 314 315 /** Debugging functions */ 316 void SetDebugClipping(bool option); 317 void SetWriteAudioAtShutdown(bool option); 318 319 /** Enable dynamic compressor for music */ 320 void EnableDynamicCompressor(bool enable = true, double thresholdDb = -3, double ratio = 4.0); 321 322 /** Set file handling callbacks */ 323 void SetFileCallbacks(oamlFileCallbacks *cbs); 324 325 /** Returns the 'oaml.defs' filename that was used for initialization */ 326 const char* GetDefsFile(); 327 328 /** Returns a simple text showing the track and audios being played */ 329 const char* GetPlayingInfo(); 330 331 /** Returns a pointer to the tracks information */ 332 oamlTracksInfo *GetTracksInfo(); 333 334 /** Returns the current playing state as a string, this can be used to resume the exact music state with LoadState */ 335 std::string SaveState(); 336 337 /** Resume the exact music state that was saved using SaveState */ 338 void LoadState(std::string state); 339 340 /** Returns a pointer to the oamlStudioApi class */ 341 oamlStudioApi *GetStudioApi(); 342 }; 343 344 345 // 346 // oamlStudioApi, this api is used by the oamlStudio app 347 // 348 349 #if defined(oaml_shared_EXPORTS) || defined(OAML_EXPORTS) 350 class DLLEXPORT oamlStudioApi { 351 #else 352 class oamlStudioApi { 353 #endif 354 private: 355 oamlBase *oaml; 356 357 public: 358 oamlStudioApi(oamlBase *_oaml); 359 ~oamlStudioApi(); 360 361 void ProjectNew(); 362 void ProjectSetBPM(float bpm); 363 void ProjectSetBeatsPerBar(int beatsPerBar); 364 365 float ProjectGetBPM(); 366 int ProjectGetBeatsPerBar(); 367 368 oamlRC TrackNew(std::string name, bool sfxTrack = false); 369 oamlRC TrackRemove(std::string name); 370 void TrackRename(std::string name, std::string newName); 371 void TrackSetVolume(std::string name, float volume); 372 void TrackSetFadeIn(std::string name, int fadeIn); 373 void TrackSetFadeOut(std::string name, int fadeOut); 374 void TrackSetXFadeIn(std::string name, int xFadeIn); 375 void TrackSetXFadeOut(std::string name, int xFadeOut); 376 377 bool TrackExists(std::string name); 378 bool TrackIsSfxTrack(std::string name); 379 bool TrackIsMusicTrack(std::string name); 380 void TrackGetAudioList(std::string name, std::vector<std::string>& list); 381 float TrackGetVolume(std::string name); 382 int TrackGetFadeIn(std::string name); 383 int TrackGetFadeOut(std::string name); 384 int TrackGetXFadeIn(std::string name); 385 int TrackGetXFadeOut(std::string name); 386 387 oamlRC AudioNew(std::string trackName, std::string audioName, int type); 388 oamlRC AudioRemove(std::string trackName, std::string audioName); 389 void AudioAddAudioFile(std::string trackName, std::string audioName, std::string filename); 390 void AudioSetName(std::string trackName, std::string audioName, std::string name); 391 void AudioSetVolume(std::string trackName, std::string audioName, float volume); 392 void AudioSetBPM(std::string trackName, std::string audioName, float bpm); 393 void AudioSetBeatsPerBar(std::string trackName, std::string audioName, int beatsPerBar); 394 void AudioSetBars(std::string trackName, std::string audioName, int bars); 395 void AudioSetMinMovementBars(std::string trackName, std::string audioName, int minMovementBars); 396 void AudioSetRandomChance(std::string trackName, std::string audioName, int randomChance); 397 void AudioSetFadeIn(std::string trackName, std::string audioName, int fadeIn); 398 void AudioSetFadeOut(std::string trackName, std::string audioName, int fadeOut); 399 void AudioSetXFadeIn(std::string trackName, std::string audioName, int xFadeIn); 400 void AudioSetXFadeOut(std::string trackName, std::string audioName, int xFadeOut); 401 void AudioSetCondId(std::string trackName, std::string audioName, int condId); 402 void AudioSetCondType(std::string trackName, std::string audioName, int condType); 403 void AudioSetCondValue(std::string trackName, std::string audioName, int condValue); 404 void AudioSetCondValue2(std::string trackName, std::string audioName, int condValue2); 405 406 bool AudioExists(std::string trackName, std::string audioName); 407 void AudioGetAudioFileList(std::string trackName, std::string audioName, std::vector<std::string>& list); 408 int AudioGetType(std::string trackName, std::string audioName); 409 float AudioGetVolume(std::string trackName, std::string audioName); 410 float AudioGetBPM(std::string trackName, std::string audioName); 411 int AudioGetBeatsPerBar(std::string trackName, std::string audioName); 412 int AudioGetBars(std::string trackName, std::string audioName); 413 int AudioGetMinMovementBars(std::string trackName, std::string audioName); 414 int AudioGetRandomChance(std::string trackName, std::string audioName); 415 int AudioGetFadeIn(std::string trackName, std::string audioName); 416 int AudioGetFadeOut(std::string trackName, std::string audioName); 417 int AudioGetXFadeIn(std::string trackName, std::string audioName); 418 int AudioGetXFadeOut(std::string trackName, std::string audioName); 419 int AudioGetCondId(std::string trackName, std::string audioName); 420 int AudioGetCondType(std::string trackName, std::string audioName); 421 int AudioGetCondValue(std::string trackName, std::string audioName); 422 int AudioGetCondValue2(std::string trackName, std::string audioName); 423 424 void AudioFileRemove(std::string trackName, std::string audioName, std::string filename); 425 void AudioFileSetLayer(std::string trackName, std::string audioName, std::string filename, std::string layer); 426 void AudioFileSetRandomChance(std::string trackName, std::string audioName, std::string filename, int randomChance); 427 428 std::string AudioFileGetLayer(std::string trackName, std::string audioName, std::string filename); 429 int AudioFileGetRandomChance(std::string trackName, std::string audioName, std::string filename); 430 431 oamlRC LayerNew(std::string name); 432 void LayerList(std::vector<std::string>& list); 433 void LayerRename(std::string layerName, std::string name); 434 int LayerGetId(std::string layerName); 435 int LayerGetRandomChance(std::string layerName); 436 float LayerGetGain(std::string layerName); 437 }; 438 439 #endif 440 441 #endif /* __OAML_H__ */ 442