z_mirror/sdl-osu
git clone https://git.raiguard.me/z_mirror/sdl-osu
4bbec0e
trunk
1#include "audio.h" 2#include "defines.h" 3#include "hitobject.h" 4#include "hitsound.h" 5#include "util.h" 6#include <SDL3/SDL_properties.h> 7#include <SDL3_mixer/SDL_mixer.h> 8#include <stdio.h> 9#include <stdlib.h> 10 11struct Osu_Audio * Osu_CreateAudio (const char * dataPath ) { 12SDL_SAFECALL (MIX_Init ); 13 14struct Osu_Audio * audio = calloc (1 ,sizeof (struct Osu_Audio )); 15 16SDL_SAFEASSN (audio -> mixer ,MIX_CreateMixerDevice ,SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK ,NULL ); 17SDL_SAFEASSN (audio -> musicTrack ,MIX_CreateTrack ,audio -> mixer ); 18 19char path [512 ]; 20snprintf (path ,512 ,"%s" OSU_PATHSEP "skins" OSU_PATHSEP OSU_ACTIVE_SKIN OSU_PATHSEP "normal-hitnormal.wav" ,dataPath ); 21SDL_SAFEASSN (audio -> hitNormal ,MIX_LoadAudio ,audio -> mixer ,path , true); 22snprintf (path ,512 ,"%s" OSU_PATHSEP "skins" OSU_PATHSEP OSU_ACTIVE_SKIN OSU_PATHSEP "normal-hitwhistle.wav" ,dataPath ); 23SDL_SAFEASSN (audio -> hitWhistle ,MIX_LoadAudio ,audio -> mixer ,path , true); 24snprintf (path ,512 ,"%s" OSU_PATHSEP "skins" OSU_PATHSEP OSU_ACTIVE_SKIN OSU_PATHSEP "normal-hitfinish.wav" ,dataPath ); 25SDL_SAFEASSN (audio -> hitFinish ,MIX_LoadAudio ,audio -> mixer ,path , true); 26snprintf (path ,512 ,"%s" OSU_PATHSEP "skins" OSU_PATHSEP OSU_ACTIVE_SKIN OSU_PATHSEP "normal-hitclap.wav" ,dataPath ); 27SDL_SAFEASSN (audio -> hitClap ,MIX_LoadAudio ,audio -> mixer ,path , true); 28 29return audio ; 30} 31 32void Osu_DestroyAudio (struct Osu_Audio * audio ) { 33if (audio -> music ) { 34MIX_DestroyAudio (audio -> music ); 35 } 36MIX_DestroyTrack (audio -> musicTrack ); 37if (audio -> musicPath ) { 38free (audio -> musicPath ); 39 } 40 41MIX_DestroyAudio (audio -> hitNormal ); 42MIX_DestroyAudio (audio -> hitWhistle ); 43MIX_DestroyAudio (audio -> hitFinish ); 44MIX_DestroyAudio (audio -> hitClap ); 45 46MIX_Quit (); 47 48free (audio ); 49} 50 51void Osu_SetMusic (struct Osu_Audio * audio ,const char * path ,Sint32 offset ,bool repeat ) { 52if (audio -> music ) { 53MIX_StopTrack (audio -> musicTrack ,0 ); 54MIX_DestroyAudio (audio -> music ); 55audio -> music = NULL ; 56 } 57if (audio -> musicPath ) { 58free (audio -> musicPath ); 59audio -> musicPath = NULL ; 60 } 61if (!path ) { 62return ; 63 } 64audio -> music = MIX_LoadAudio (audio -> mixer ,path , false); 65if (!audio -> music ) { 66SDL_LogError (OSU_LOG_CATEGORY_AUDIO ,"Failed to open music: %s" ,SDL_GetError ()); 67return ; 68 } 69SDL_asprintf (& audio -> musicPath ,"%s" ,path ); 70 71MIX_SetTrackAudio (audio -> musicTrack ,audio -> music ); 72 73if (audio -> musicProps ) { 74SDL_DestroyProperties (audio -> musicProps ); 75 } 76SDL_SAFEASSN (audio -> musicProps ,SDL_CreateProperties ); 77 78SDL_SAFECALL (SDL_SetNumberProperty ,audio -> musicProps ,MIX_PROP_PLAY_START_MILLISECOND_NUMBER ,offset ); 79 80if (repeat ) { 81SDL_SAFECALL (SDL_SetNumberProperty ,audio -> musicProps ,MIX_PROP_PLAY_LOOPS_NUMBER ,-1 ); 82SDL_SAFECALL (SDL_SetNumberProperty ,audio -> musicProps ,MIX_PROP_PLAY_LOOP_START_MILLISECOND_NUMBER ,offset ); 83 } 84} 85 86void Osu_PlayMusic (struct Osu_Audio * audio ) { 87if (MIX_TrackPlaying (audio -> musicTrack )|| !audio -> music ) { 88return ; 89 } 90 91if (!MIX_PlayTrack (audio -> musicTrack ,audio -> musicProps )) { 92SDL_LogError (OSU_LOG_CATEGORY_AUDIO ,"Failed to play music: %s" ,SDL_GetError ()); 93return ; 94 } 95} 96 97void Osu_PlayHitSounds (struct Osu_Audio * audio ,struct Osu_HitObject * hitObject ) { 98// TODO: Read LayeredHitSounds property from skin instead of assuming it is true 99// if (Osu_ShouldPlayHitSound(hitObject->hitSounds, OSU_HITSOUND_NORMAL)) 100MIX_PlayAudio (audio -> mixer ,audio -> hitNormal ); 101if (Osu_ShouldPlayHitSound (hitObject -> hitSounds ,OSU_HITSOUND_WHISTLE )) { 102MIX_PlayAudio (audio -> mixer ,audio -> hitWhistle ); 103 } 104if (Osu_ShouldPlayHitSound (hitObject -> hitSounds ,OSU_HITSOUND_FINISH )) { 105MIX_PlayAudio (audio -> mixer ,audio -> hitFinish ); 106 } 107if (Osu_ShouldPlayHitSound (hitObject -> hitSounds ,OSU_HITSOUND_CLAP )) { 108MIX_PlayAudio (audio -> mixer ,audio -> hitClap ); 109 } 110}