Path: blob/main/RSDKv4/Audio.hpp
817 views
#ifndef AUDIO_H1#define AUDIO_H23#define TRACK_COUNT (0x10)4#define SFX_COUNT (0x100)5#if !RETRO_USE_ORIGINAL_CODE6#define CHANNEL_COUNT (0x10) // 4 in the original, 16 for convenience7#else8#define CHANNEL_COUNT (0x4)9#endif1011#define MAX_VOLUME (100)1213#define MUSBUFFER_SIZE (0x200000)14#define STREAMFILE_COUNT (2)1516#define MIX_BUFFER_SAMPLES (256)1718#if RETRO_USING_SDL1 || RETRO_USING_SDL21920#define LockAudioDevice() SDL_LockAudio()21#define UnlockAudioDevice() SDL_UnlockAudio()2223#else24#define LockAudioDevice() ;25#define UnlockAudioDevice() ;26#endif2728struct TrackInfo {29char fileName[0x40];30bool trackLoop;31uint loopPoint;32};3334struct StreamInfo {35OggVorbis_File vorbisFile;36int vorbBitstream;37#if RETRO_USING_SDL138SDL_AudioSpec spec;39#endif40#if RETRO_USING_SDL241SDL_AudioStream *stream;42#endif43Sint16 buffer[MIX_BUFFER_SAMPLES];44bool trackLoop;45uint loopPoint;46bool loaded;47};4849struct SFXInfo {50char name[0x40];51Sint16 *buffer;52size_t length;53bool loaded;54};5556struct ChannelInfo {57size_t sampleLength;58Sint16 *samplePtr;59int sfxID;60byte loopSFX;61sbyte pan;62};6364struct StreamFile {65byte buffer[MUSBUFFER_SIZE];66int fileSize;67int filePos;68};6970enum MusicStatuses {71MUSIC_STOPPED = 0,72MUSIC_PLAYING = 1,73MUSIC_PAUSED = 2,74MUSIC_LOADING = 3,75MUSIC_READY = 4,76};7778extern int globalSFXCount;79extern int stageSFXCount;8081extern int masterVolume;82extern int trackID;83extern int sfxVolume;84extern int bgmVolume;85extern bool audioEnabled;8687extern bool musicEnabled;88extern int musicStatus;89extern int musicStartPos;90extern int musicPosition;91extern int musicRatio;92extern TrackInfo musicTracks[TRACK_COUNT];9394extern int currentStreamIndex;95extern StreamFile streamFile[STREAMFILE_COUNT];96extern StreamInfo streamInfo[STREAMFILE_COUNT];97extern StreamFile *streamFilePtr;98extern StreamInfo *streamInfoPtr;99100extern SFXInfo sfxList[SFX_COUNT];101extern char sfxNames[SFX_COUNT][0x40];102103extern ChannelInfo sfxChannels[CHANNEL_COUNT];104105#if RETRO_USING_SDL1 || RETRO_USING_SDL2106extern SDL_AudioSpec audioDeviceFormat;107#endif108109int InitAudioPlayback();110void LoadGlobalSfx();111112#if RETRO_USING_SDL1 || RETRO_USING_SDL2113#if !RETRO_USE_ORIGINAL_CODE114// These functions did exist, but with different signatures115void ProcessMusicStream(Sint32 *stream, size_t bytes_wanted);116void ProcessAudioPlayback(void *data, Uint8 *stream, int len);117void ProcessAudioMixing(Sint32 *dst, const Sint16 *src, int len, int volume, sbyte pan);118#endif119120#if !RETRO_USE_ORIGINAL_CODE121inline void FreeMusInfo()122{123LockAudioDevice();124125#if RETRO_USING_SDL2126if (streamInfo[currentStreamIndex].stream)127SDL_FreeAudioStream(streamInfo[currentStreamIndex].stream);128streamInfo[currentStreamIndex].stream = NULL;129#endif130131ov_clear(&streamInfo[currentStreamIndex].vorbisFile);132133#if RETRO_USING_SDL2134streamInfo[currentStreamIndex].stream = nullptr;135#endif136137UnlockAudioDevice();138}139#endif140#else141void ProcessMusicStream() {}142void ProcessAudioPlayback() {}143void ProcessAudioMixing() {}144145#if !RETRO_USE_ORIGINAL_CODE146inline void FreeMusInfo() { ov_clear(&streamInfo[currentStreamIndex].vorbisFile); }147#endif148#endif149150void LoadMusic(void *userdata);151void SetMusicTrack(const char *filePath, byte trackID, bool loop, uint loopPoint);152void SwapMusicTrack(const char *filePath, byte trackID, uint loopPoint, uint ratio);153bool PlayMusic(int track, int musStartPos);154inline void StopMusic(bool setStatus)155{156if (setStatus)157musicStatus = MUSIC_STOPPED;158musicPosition = 0;159160#if !RETRO_USE_ORIGINAL_CODE161LockAudioDevice();162FreeMusInfo();163UnlockAudioDevice();164#endif165}166167void LoadSfx(char *filePath, byte sfxID);168void PlaySfx(int sfx, bool loop);169inline void StopSfx(int sfx)170{171for (int i = 0; i < CHANNEL_COUNT; ++i) {172if (sfxChannels[i].sfxID == sfx) {173MEM_ZERO(sfxChannels[i]);174sfxChannels[i].sfxID = -1;175}176}177}178void SetSfxAttributes(int sfx, int loopCount, sbyte pan);179180void SetSfxName(const char *sfxName, int sfxID);181182#if !RETRO_USE_ORIGINAL_CODE183// Helper Funcs184inline bool PlaySfxByName(const char *sfx, sbyte loopCnt)185{186char buffer[0x40];187int pos = 0;188while (*sfx) {189if (*sfx != ' ')190buffer[pos++] = *sfx;191sfx++;192}193buffer[pos] = 0;194195for (int s = 0; s < globalSFXCount + stageSFXCount; ++s) {196if (StrComp(sfxNames[s], buffer)) {197PlaySfx(s, loopCnt);198return true;199}200}201return false;202}203inline bool StopSFXByName(const char *sfx)204{205char buffer[0x40];206int pos = 0;207while (*sfx) {208if (*sfx != ' ')209buffer[pos++] = *sfx;210sfx++;211}212buffer[pos] = 0;213214for (int s = 0; s < globalSFXCount + stageSFXCount; ++s) {215if (StrComp(sfxNames[s], buffer)) {216StopSfx(s);217return true;218}219}220return false;221}222#endif223224inline void SetMusicVolume(int volume)225{226if (volume < 0)227volume = 0;228if (volume > MAX_VOLUME)229volume = MAX_VOLUME;230231masterVolume = volume;232}233234inline void SetGameVolumes(int bgmVol, int sfxVol)235{236bgmVolume = bgmVol;237sfxVolume = sfxVol;238239if (bgmVolume < 0)240bgmVolume = 0;241if (bgmVolume > MAX_VOLUME)242bgmVolume = MAX_VOLUME;243244if (sfxVolume < 0)245sfxVolume = 0;246if (sfxVolume > MAX_VOLUME)247sfxVolume = MAX_VOLUME;248}249250inline bool PauseSound()251{252if (musicStatus == MUSIC_PLAYING) {253musicStatus = MUSIC_PAUSED;254return true;255}256return false;257}258259inline void ResumeSound()260{261if (musicStatus == MUSIC_PAUSED)262musicStatus = MUSIC_PLAYING;263}264265inline void StopAllSfx()266{267#if !RETRO_USE_ORIGINAL_CODE268LockAudioDevice();269#endif270271for (int i = 0; i < CHANNEL_COUNT; ++i) sfxChannels[i].sfxID = -1;272273#if !RETRO_USE_ORIGINAL_CODE274UnlockAudioDevice();275#endif276}277inline void ReleaseGlobalSfx()278{279for (int i = globalSFXCount - 1; i >= 0; --i) {280if (sfxList[i].loaded) {281StrCopy(sfxList[i].name, "");282StrCopy(sfxNames[i], "");283if (sfxList[i].buffer)284free(sfxList[i].buffer);285286sfxList[i].buffer = NULL;287sfxList[i].length = 0;288sfxList[i].loaded = false;289}290}291292globalSFXCount = 0;293}294inline void ReleaseStageSfx()295{296for (int i = (stageSFXCount + globalSFXCount) - 1; i >= globalSFXCount; --i) {297if (sfxList[i].loaded) {298StrCopy(sfxList[i].name, "");299StrCopy(sfxNames[i], "");300if (sfxList[i].buffer)301free(sfxList[i].buffer);302303sfxList[i].buffer = NULL;304sfxList[i].length = 0;305sfxList[i].loaded = false;306}307}308309stageSFXCount = 0;310}311312inline void ReleaseAudioDevice()313{314StopMusic(true);315StopAllSfx();316ReleaseStageSfx();317ReleaseGlobalSfx();318}319320#endif // !AUDIO_H321322323