Skip to content

Commit

Permalink
Implement PS2 audio via SPU
Browse files Browse the repository at this point in the history
This give us 4MB of dedicated audio memory and support for compressed
audio at runtime which is a huge boost to the already limited system
memory
  • Loading branch information
AJenbo committed Feb 4, 2023
1 parent 0007217 commit 190499a
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 4 deletions.
7 changes: 6 additions & 1 deletion CMake/platforms/ps2.cmake
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
set(NONET ON)
set(NOSOUND ON)
set(DISABLE_DEMOMODE ON)
set(ASAN OFF)
set(UBSAN OFF)
Expand All @@ -14,4 +13,10 @@ set(NOEXIT ON)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/threads-stub")

set(BUILD_ASSETS_MPQ OFF)
set(UNPACKED_MPQS ON)

# -fmerge-all-constants saves ~4 KiB
set(_extra_flags "-fmerge-all-constants -fipa-pta")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${_extra_flags}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_extra_flags}")

10 changes: 8 additions & 2 deletions Source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,10 @@ else()
list(APPEND libdevilutionx_SRCS
effects.cpp
engine/sound.cpp
utils/push_aulib_decoder.cpp
utils/soundsample.cpp)
if(NOT PS2)
list(APPEND libdevilutionx_SRCS utils/push_aulib_decoder.cpp)
endif()
endif()

if(NOT NONET)
Expand Down Expand Up @@ -279,7 +281,11 @@ if(NOT NONET)
endif()

if(NOT NOSOUND)
target_link_libraries(libdevilutionx PUBLIC SDL_audiolib::SDL_audiolib)
if(PS2)
target_link_libraries(libdevilutionx PUBLIC audsrv)
else()
target_link_libraries(libdevilutionx PUBLIC SDL_audiolib::SDL_audiolib)
endif()
endif()

if(NOT NONET AND NOT DISABLE_ZERO_TIER)
Expand Down
23 changes: 23 additions & 0 deletions Source/engine/sound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,22 +38,37 @@ namespace {

SoundSample music;

#ifndef PS2
std::string GetMp3Path(const char *path)
{
std::string mp3Path = path;
const std::string::size_type dot = mp3Path.find_last_of('.');
mp3Path.replace(dot + 1, mp3Path.size() - (dot + 1), "mp3");
return mp3Path;
}
#else
std::string GetAdpPath(const char *path)
{
std::string adpPath = path;
const std::string::size_type dot = adpPath.find_last_of('.');
adpPath.replace(dot + 1, adpPath.size() - (dot + 1), "adp");
return adpPath;
}
#endif

bool LoadAudioFile(const char *path, bool stream, bool errorDialog, SoundSample &result)
{
#ifndef PS2
bool isMp3 = true;
AssetRef ref = FindAsset(GetMp3Path(path).c_str());
if (!ref.ok()) {
ref = FindAsset(path);
isMp3 = false;
}
#else
bool isMp3 = false;
AssetRef ref = FindAsset(GetAdpPath(path).c_str());
#endif
if (!ref.ok())
ErrDlg("Audio file not found", StrCat(path, "\n", SDL_GetError(), "\n"), __FILE__, __LINE__);

Expand Down Expand Up @@ -118,10 +133,12 @@ SoundSample *DuplicateSound(const SoundSample &sound)
it = duplicateSounds.end();
--it;
}
#ifndef PS2
result->SetFinishCallback([it]([[maybe_unused]] Aulib::Stream &stream) {
const std::lock_guard<SdlMutex> lock(*duplicateSoundsMutex);
duplicateSounds.erase(it);
});
#endif
return result;
}

Expand Down Expand Up @@ -209,6 +226,7 @@ void snd_init()
sgOptions.Audio.musicVolume.SetValue(CapVolume(*sgOptions.Audio.musicVolume));
gbMusicOn = *sgOptions.Audio.musicVolume > VOLUME_MIN;

#ifndef PS2
// Initialize the SDL_audiolib library. Set the output sample rate to
// 22kHz, the audio format to 16-bit signed, use 2 output channels
// (stereo), and a 2KiB output buffer.
Expand All @@ -220,14 +238,19 @@ void snd_init()
Aulib::sampleRate(), Aulib::channelCount(), Aulib::frameSize(), Aulib::sampleFormat());

duplicateSoundsMutex.emplace();
#else
audsrv_set_volume(MAX_VOLUME);
#endif
gbSndInited = true;
}

void snd_deinit()
{
if (gbSndInited) {
#ifndef PS2
Aulib::quit();
duplicateSoundsMutex = std::nullopt;
#endif
}

gbSndInited = false;
Expand Down
18 changes: 18 additions & 0 deletions Source/storm/storm_svid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,19 @@

#include <SmackerDecoder.h>

#ifndef PS2
#ifndef NOSOUND
#include "utils/push_aulib_decoder.h"
#endif
#endif

#include "engine/assets.hpp"
#include "engine/dx.h"
#include "engine/palette.h"
#include "options.h"
#ifndef PS2
#include "utils/aulib.hpp"
#endif
#include "utils/display.h"
#include "utils/log.hpp"
#include "utils/sdl_compat.h"
Expand All @@ -24,12 +28,14 @@
namespace devilution {
namespace {

#ifndef PS2
#ifndef NOSOUND
std::optional<Aulib::Stream> SVidAudioStream;
PushAulibDecoder *SVidAudioDecoder;
std::uint8_t SVidAudioDepth;
std::unique_ptr<int16_t[]> SVidAudioBuffer;
#endif
#endif

uint32_t SVidWidth, SVidHeight;
double SVidFrameEnd;
Expand Down Expand Up @@ -109,12 +115,14 @@ void TrySetVideoModeToSVidForSDL1()
}
#endif

#ifndef PS2
#ifndef NOSOUND
bool HasAudio()
{
return SVidAudioStream && SVidAudioStream->isPlaying();
}
#endif
#endif

bool SVidLoadNextFrame()
{
Expand Down Expand Up @@ -247,6 +255,7 @@ bool SVidPlayBegin(const char *filename, int flags)
return false;
}

#ifndef PS2
#ifndef NOSOUND
const bool enableAudio = (flags & 0x1000000) == 0;

Expand Down Expand Up @@ -276,6 +285,7 @@ bool SVidPlayBegin(const char *filename, int flags)
SVidAudioDecoder = nullptr;
}
}
#endif
#endif

SVidFrameLength = 1000000.0 / Smacker_GetFrameRate(SVidHandle);
Expand Down Expand Up @@ -333,6 +343,7 @@ bool SVidPlayContinue()
return SVidLoadNextFrame(); // Skip video and audio if the system is to slow
}

#ifndef PS2
#ifndef NOSOUND
if (HasAudio()) {
std::int16_t *buf = SVidAudioBuffer.get();
Expand All @@ -343,6 +354,7 @@ bool SVidPlayContinue()
SVidAudioDecoder->PushSamples(reinterpret_cast<const std::uint8_t *>(buf), len);
}
}
#endif
#endif

if (SDL_GetTicks() * 1000.0 >= SVidFrameEnd) {
Expand All @@ -362,12 +374,14 @@ bool SVidPlayContinue()

void SVidPlayEnd()
{
#ifndef PS2
#ifndef NOSOUND
if (HasAudio()) {
SVidAudioStream = std::nullopt;
SVidAudioDecoder = nullptr;
SVidAudioBuffer = nullptr;
}
#endif
#endif

if (SVidHandle.isValid)
Expand All @@ -394,18 +408,22 @@ void SVidPlayEnd()

void SVidMute()
{
#ifndef PS2
#ifndef NOSOUND
if (SVidAudioStream)
SVidAudioStream->mute();
#endif
#endif
}

void SVidUnmute()
{
#ifndef PS2
#ifndef NOSOUND
if (SVidAudioStream)
SVidAudioStream->unmute();
#endif
#endif
}

} // namespace devilution
Loading

0 comments on commit 190499a

Please sign in to comment.