The open source repository for the action RPG game in development by Sig Productions titled 'Adventures in Lestoria'!
https://forums.lestoria.net
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.
153 lines
5.9 KiB
153 lines
5.9 KiB
#pragma region License
|
|
/*
|
|
License (OLC-3)
|
|
~~~~~~~~~~~~~~~
|
|
|
|
Copyright 2024 Joshua Sigona <sigonasr2@gmail.com>
|
|
|
|
Redistribution and use in source and binary forms, with or without modification,
|
|
are permitted provided that the following conditions are met:
|
|
|
|
1. Redistributions or derivations of source code must retain the above copyright
|
|
notice, this list of conditions and the following disclaimer.
|
|
|
|
2. Redistributions or derivative works in binary form must reproduce the above
|
|
copyright notice. This list of conditions and the following disclaimer must be
|
|
reproduced in the documentation and/or other materials provided with the distribution.
|
|
|
|
3. Neither the name of the copyright holder nor the names of its contributors may
|
|
be used to endorse or promote products derived from this software without specific
|
|
prior written permission.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
|
SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
|
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
SUCH DAMAGE.
|
|
|
|
Portions of this software are copyright © 2024 The FreeType
|
|
Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
|
|
All rights reserved.
|
|
*/
|
|
#pragma endregion
|
|
#pragma once
|
|
#include "olcPGEX_MiniAudio.h"
|
|
#include "config.h"
|
|
#include <set>
|
|
#include "safemap.h"
|
|
|
|
using SongName=std::string;
|
|
using Event=std::string;
|
|
using ChannelName=std::string;
|
|
using ChannelID=int;
|
|
using ChannelIDList=std::vector<ChannelID>;
|
|
using Volume=float;
|
|
using VolumeList=std::vector<Volume>;
|
|
|
|
class SoundEffect;
|
|
|
|
class Audio{
|
|
friend class AiL;
|
|
public:
|
|
static Audio&Self();
|
|
static MiniAudio&Engine();
|
|
static void Initialize();
|
|
static void Update();
|
|
static void UpdateLoop();
|
|
static void Play(const std::string_view sound);
|
|
[[nodiscard]]
|
|
static const size_t LoadAndPlaySFX(const std::string_view sound,const bool loop=true);
|
|
//Prepares a BGM for loading. This means we call UpdateLoop() repeatedly until the loading of the music is complete. Names are found in bgm.txt configuration file.
|
|
static void PrepareBGM(const std::string_view sound,const bool loop=true);
|
|
//Play immediately a BGM given a name found in bgm.txt configuration file.
|
|
static void PlayBGM(const std::string_view sound,const bool loop=true);
|
|
static void StopBGM();
|
|
static const Event&GetAudioEvent();
|
|
static const SongName&GetTrackName();
|
|
static void SetAudioEvent(const Event&eventName);
|
|
static const bool BGMIsPlaying();
|
|
static const bool BGMFullyLoaded(); //Fully loaded means when the audio buffer has finished filling up, which means sound is now playing.
|
|
static void SetBGMPitch(float pitch);
|
|
static void SetBGMVolume(float vol);
|
|
static void UpdateBGMVolume();
|
|
static void SetSFXVolume(float vol);
|
|
static float&GetBGMVolume();
|
|
static float&GetSFXVolume();
|
|
static float GetMuteMult();
|
|
//This will get a prepared BGM loop iteration count which is useful for loading stages.
|
|
static int GetPrepareBGMLoopIterations(std::string_view sound);
|
|
static float GetCalculatedBGMVolume(const float channelVol);
|
|
static float GetCalculatedSFXVolume(const SoundEffect&sfx);
|
|
static float GetCalculatedSFXVolume(const float sfxVol); //NOTE: This is a more manually invoked function! If you are trying to play a specific sound effect from an event, use the SoundEffect version instead!! This accounts for any additional flags related to volume.
|
|
private:
|
|
bool trackLoadStarted=false;
|
|
bool trackLoadComplete=false;
|
|
bool channelPlayingStarted=false;
|
|
bool channelPlayingComplete=false;
|
|
int currentLoopIndex=0;
|
|
//Set to false by PrepareBGM(). If PlayBGM() is called instead, it will set the state of this variable to true, such that the loading is performed in Audio::Update()!
|
|
bool immediatelyLoadAudio=false;
|
|
|
|
struct BGMPlayParams{
|
|
std::string sound;
|
|
bool loop=false;
|
|
};
|
|
class EventData{
|
|
public:
|
|
void AddEventInfo(const Event&eventName,const VolumeList&volumes);
|
|
const VolumeList&GetVolumes(const Event&event)const;
|
|
private:
|
|
std::map<Event,VolumeList>eventInfo;
|
|
};
|
|
static float bgmVol;
|
|
static float sfxVol;
|
|
class BGM{
|
|
public:
|
|
void Load();
|
|
const size_t GetChannelCount()const;
|
|
const std::vector<ChannelName>&GetChannels()const;
|
|
const SongName&GetName()const;
|
|
const Volume&GetVolume(const Event&eventName,const int&index)const;
|
|
void SetName(std::string_view name);
|
|
void SetFileName(std::string_view name);
|
|
void AddChannel(const ChannelName&name);
|
|
void AddEventVolumes(const Event&eventName,const VolumeList&volumes);
|
|
void SetFadeTime(const float fadeTime);
|
|
const ChannelID&GetChannelID(const int index);
|
|
const ChannelIDList&GetChannelIDs()const;
|
|
const float&GetFadeTime()const;
|
|
const float&GetLoopStartTime()const;
|
|
void SetLoopStartTime(const float loopStartTime);
|
|
private:
|
|
std::string songName; //Name of the track.
|
|
std::string songFileName; //Name of the key in bgm.
|
|
ChannelIDList channels;
|
|
std::vector<ChannelName>channelNames;
|
|
EventData eventVolumes;
|
|
float loopStartTime{0.f};
|
|
float fadeTime="BGM.Default Fade Time"_F;
|
|
void Unload();
|
|
};
|
|
private:
|
|
MiniAudio audioEngine;
|
|
SongName currentBGM="";
|
|
safemap<SongName,BGM>bgm;
|
|
std::set<Event>events;
|
|
static float defaultFadeTime;
|
|
Event currentAudioEvent="Default Volume";
|
|
std::vector<float>prevVolumes;
|
|
std::vector<float>targetVolumes;
|
|
float fadeToTargetVolumeTime=0.f;
|
|
bool fullyLoaded=true;
|
|
float playBGMWaitTime=0.0f;
|
|
BGMPlayParams playParams;
|
|
static bool muted;
|
|
float lastTimestamp{0.f};
|
|
};
|
|
|
|
std::string operator""_SFX(const char*key,size_t length); |