ogg vorbis resource pack encoding/decoding implementation started (currently crashes during playback)

pull/65/head
sigonasr2 3 months ago
parent 3afeb7fa91
commit 9b69a4ebb3
  1. 7
      Adventures in Lestoria/AdventuresInLestoria.cpp
  2. 1
      Adventures in Lestoria/AdventuresInLestoria.h
  3. 7
      Adventures in Lestoria/Audio.cpp
  4. 2
      Adventures in Lestoria/Audio.h
  5. 2
      Adventures in Lestoria/EnvironmentalAudio.cpp
  6. 2
      Adventures in Lestoria/Player.cpp
  7. 2
      Adventures in Lestoria/SoundEffect.cpp
  8. 2
      Adventures in Lestoria/State_LevelComplete.cpp
  9. 5
      Adventures in Lestoria/TODO.txt
  10. 2
      Adventures in Lestoria/Version.h
  11. BIN
      Adventures in Lestoria/assets/gamepack.pak
  12. 46
      Adventures in Lestoria/olcPGEX_MiniAudio.h
  13. 4
      Adventures in Lestoria/pixelGameEngine.cpp
  14. BIN
      x64/Release/Adventures in Lestoria.exe

@ -4447,11 +4447,8 @@ void AiL::GlobalGameUpdates(){
Audio::Engine().SetVolume(GetPlayer()->cooldownSoundInstance,Audio::GetCalculatedSFXVolume("Audio.Casting Sound Volume"_F/100.f));
}
if(!GamePaused()){
GameState::STATE->OnUserUpdate(this);
}else{
ClearTimedOutGarbage();
}
if(!GamePaused())GameState::STATE->OnUserUpdate(this);
else ClearTimedOutGarbage();
}

@ -95,6 +95,7 @@ class AiL : public olc::PixelGameEngine
friend class sig::Animation;
friend class Audio;
friend class Minimap;
friend class MiniAudio;
std::unique_ptr<Player>player;
SplashScreen splash;
public:

@ -71,6 +71,9 @@ void Audio::Initialize(){
while(data.HasProperty(std::format("channel[{}]",channelCounter))){
std::string channelName=data[std::format("channel[{}]",channelCounter)].GetString();
if(!std::filesystem::exists("bgm_directory"_S+channelName))ERR(std::format("WARNING! Could not load file {} for track {}",channelName,songFileName));
if(!game->gamepack.Loaded()&&"GENERATE_GAMEPACK"_B){
game->gamepack.AddFile("bgm_directory"_S+channelName);
}
bgm.AddChannel(channelName);
channelCounter++;
}
@ -121,8 +124,8 @@ MiniAudio&Audio::Engine(){
void Audio::Play(const std::string_view sound){
Engine().Play(std::string(sound));
};
const size_t Audio::LoadAndPlay(const std::string_view sound,const bool loop){
size_t soundID=Engine().LoadSound(std::string(sound));
const size_t Audio::LoadAndPlaySFX(const std::string_view sound,const bool loop){
size_t soundID=Engine().LoadSound(std::string(sound),MiniAudio::SFX);
Engine().Play(soundID,loop);
return soundID;
};

@ -59,7 +59,7 @@ public:
static void UpdateLoop();
static void Play(const std::string_view sound);
[[nodiscard]]
static const size_t LoadAndPlay(const std::string_view sound,const bool loop=true);
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.

@ -67,7 +67,7 @@ void EnvironmentalAudio::SetAudioName(const std::string_view audioName){
}
void EnvironmentalAudio::Activate(){
if(activated)return;
soundInstance=Audio::LoadAndPlay(operator""_SFX(SOUND_DATA[audioName].file.c_str(),SOUND_DATA[audioName].file.length()),true);
soundInstance=Audio::LoadAndPlaySFX(operator""_SFX(SOUND_DATA[audioName].file.c_str(),SOUND_DATA[audioName].file.length()),true);
activated=true;
}
void EnvironmentalAudio::Deactivate(){

@ -115,7 +115,7 @@ void Player::Initialize(){
SetBaseStat("HP Recovery %",0);
SetBaseStat("Damage Reduction",0);
SetBaseStat("Attack Spd",0);
cooldownSoundInstance=Audio::Engine().LoadSound("spell_cast.ogg"_SFX);
cooldownSoundInstance=Audio::Engine().LoadSound("spell_cast.ogg"_SFX,MiniAudio::SFX);
afterImage.Create(24,24);
for(Pixel&p:afterImage.Sprite()->pColData){
p.a=0;

@ -115,7 +115,7 @@ void SoundEffect::PlaySFX(const std::string&eventName,const vf2d&pos){
size_t SoundEffect::PlayLoopingSFX(const std::string&eventName,const vf2d&pos){
if(game->TestingModeEnabled()||eventName.length()==0)return 0U;
const SoundEffect&sfx=GetRandomSFXFromFile(eventName);
const size_t id=Audio::Engine().LoadSound(operator""_SFX(sfx.filename.c_str(),sfx.filename.length()));
const size_t id=Audio::Engine().LoadSound(operator""_SFX(sfx.filename.c_str(),sfx.filename.length()),MiniAudio::SFX);
RepeatingSoundEffect::playingSoundEffects.insert(id);
Audio::Engine().Play(id,true);
return id;

@ -51,7 +51,7 @@ INCLUDE_game
void State_LevelComplete::OnStateChange(GameState*prevState){
if(xpGainSound==std::numeric_limits<size_t>::max()){
xpGainSound=Audio::LoadAndPlay("xpgain.ogg"_SFX,true);
xpGainSound=Audio::LoadAndPlaySFX("xpgain.ogg"_SFX,true);
Audio::Engine().SetVolume(xpGainSound,0.f);
}
if(Menu::IsMenuOpen()){

@ -17,7 +17,10 @@ New Monster Sound Effects
Add a Helper Function: Change proximity knockback checks regardless of player/monster friendliness to be a function call instead.
Add rectangular hitbox posssibility to the game for monsters. (specifically for use with pillars)
Add rectangular hitbox possibility to the game for monsters. (specifically for use with pillars)
Fanfare -> Post boss song
DEMO
====

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 1
#define VERSION_MINOR 2
#define VERSION_PATCH 5
#define VERSION_BUILD 11508
#define VERSION_BUILD 11523
#define stringify(a) stringify_(a)
#define stringify_(a) #a

@ -82,7 +82,12 @@ namespace olc
void SetBackgroundPlay(bool state);
public: // LOADING ROUTINES
const size_t LoadSound(const std::string& path);
enum SoundEffectFlag{
SFX,
BGM,
};
const size_t LoadSound(const std::string& path,const SoundEffectFlag soundType=BGM); //Setting sound effect to true avoids loading it from a resource pack.
const size_t LoadResource(const std::string& path);
void UnloadSound(const int id);
public: // PLAYBACK CONTROLS
@ -153,6 +158,7 @@ namespace olc
// this is where the sounds are kept
std::vector<ma_sound*> vecSounds;
std::vector<ma_sound*> vecOneOffSounds;
std::vector<std::pair<size_t,ma_audio_buffer>>vecResourcePackBuffers;
};
/**
@ -200,6 +206,10 @@ namespace olc
#ifdef OLC_PGEX_MINIAUDIO
#undef OLC_PGEX_MINIAUDIO
#include "AdventuresInLestoria.h"
INCLUDE_game
namespace olc
{
bool MiniAudio::backgroundPlay = false;
@ -290,28 +300,45 @@ namespace olc
MiniAudio::backgroundPlay = state;
}
const size_t MiniAudio::LoadSound(const std::string& path)
const size_t MiniAudio::LoadSound(const std::string& path,const SoundEffectFlag soundType)
{
// create the sound
ma_sound* sound = new ma_sound();
// load it from the file and decode it
if(ma_sound_init_from_file(&engine, path.c_str(), MA_SOUND_FLAG_DECODE | MA_SOUND_FLAG_ASYNC, NULL, NULL, sound) != MA_SUCCESS)
throw MiniAudioSoundException();
// assume no empty slots...
size_t id = vecSounds.size();
bool foundSound{false};
// attempt to re-use an empty slot
for(int i = 0; i < vecSounds.size(); i++)
{
if(vecSounds.at(i) == nullptr)
{
vecSounds.at(i) = sound;
return i;
id=i;
foundSound=true;
break;
}
}
// no empty slots, make more room!
const size_t id = vecSounds.size();
vecSounds.push_back(sound);
if(!foundSound)vecSounds.emplace_back(sound);
if(soundType==BGM){
ma_audio_buffer newBuffer{};
ResourceBuffer rb{game->gamepack.GetFileBuffer(path)};
short*decodedOggFile;
int numSamples{stb_vorbis_decode_memory((const unsigned char*)(rb.vMemory.data()),rb.vMemory.size(),(int*)(&device.playback.channels),(int*)(&device.sampleRate),&decodedOggFile)};
if(numSamples==-1)ERR(std::format("Failed to decode Ogg Vorbis file! {}",path));
LOG(std::format("Samples: {}, Channels: {}, Sample Rate: {}",numSamples,device.playback.channels,device.sampleRate));
ma_audio_buffer_config config{ma_audio_buffer_config_init(device.playback.format,device.playback.channels,numSamples,decodedOggFile,nullptr)};
if(ma_audio_buffer_init(&config,&newBuffer)!=MA_SUCCESS)ERR(std::format("WARNING! Failed to load audio buffer~! {}",path));
if(ma_sound_init_from_data_source(&engine,&newBuffer,MA_SOUND_FLAG_DECODE|MA_SOUND_FLAG_ASYNC,nullptr,sound)!=MA_SUCCESS)ERR(std::format("Could not initialize sound! {}",path));
vecResourcePackBuffers.emplace_back(std::pair<size_t,ma_audio_buffer>{id,newBuffer});
}else{ //Sound effects
// load it from the file and decode it
if(ma_sound_init_from_file(&engine, path.c_str(), MA_SOUND_FLAG_DECODE | MA_SOUND_FLAG_ASYNC, NULL, NULL, sound) != MA_SUCCESS)
throw MiniAudioSoundException();
}
return id;
}
@ -321,6 +348,7 @@ namespace olc
ma_sound_uninit(vecSounds.at(id));
delete vecSounds.at(id);
vecSounds.at(id) = nullptr;
std::erase_if(vecResourcePackBuffers,[&id](const std::pair<size_t,ma_audio_buffer>&bufferData){return id==bufferData.first;});
}
void MiniAudio::Play(const int id, const bool loop)

@ -51,9 +51,9 @@ All rights reserved.
#include "TMXParser.h"
#define TSX_PARSER_SETUP
#include "TSXParser.h"
#define OLC_PGEX_MINIAUDIO
#include "olcPGEX_MiniAudio.h"
#define OLC_PGEX_SPLASHSCREEN
#include "olcPGEX_SplashScreen.h"
#define OLC_PGE_GAMEPAD
#include "olcPGEX_Gamepad.h"
#define OLC_PGEX_MINIAUDIO
#include "olcPGEX_MiniAudio.h"
Loading…
Cancel
Save