2024-07-04 17:30:40 +02:00
|
|
|
#include "SplashSoundPlayer.h"
|
|
|
|
#include "logger.h"
|
|
|
|
#include "utils.h"
|
|
|
|
#include <coreinit/transition.h>
|
|
|
|
#include <cstring>
|
|
|
|
#include <sndcore2/core.h>
|
|
|
|
#include <sndcore2/device.h>
|
|
|
|
#include <span>
|
|
|
|
#include <string>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <vector>
|
|
|
|
#include <whb/log.h>
|
|
|
|
|
|
|
|
SplashSoundPlayer::SplashSoundPlayer(std::string_view meta_dir) {
|
|
|
|
std::string bootSound = std::string(meta_dir).append("/bootSound.btsnd");
|
|
|
|
|
|
|
|
if (!LoadFileIntoBuffer(bootSound, mBuffer)) {
|
|
|
|
mBuffer.clear();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (mBuffer.size() < 8) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto target = ((uint32_t *) mBuffer.data())[0];
|
|
|
|
if (target <= 2) {
|
|
|
|
mOutputTarget = static_cast<TransitionAudioTarget>(target);
|
|
|
|
}
|
|
|
|
|
|
|
|
mLoopPoint = ((uint32_t *) mBuffer.data())[1];
|
|
|
|
}
|
|
|
|
|
|
|
|
void SplashSoundPlayer::Play() {
|
|
|
|
if (mBuffer.empty() || mBuffer.size() < 8) {
|
2024-07-14 11:58:15 +02:00
|
|
|
DEBUG_FUNCTION_LINE_WARN("mBuffer is empty or too small");
|
2024-07-04 17:30:40 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
AXTransitionAudioBuffer transitionAudioBuffer = {};
|
|
|
|
|
|
|
|
AXInit();
|
|
|
|
AXDeviceMode tvMode;
|
|
|
|
AXDeviceMode drcMode;
|
|
|
|
AXGetDeviceMode(0, &tvMode);
|
|
|
|
AXGetDeviceMode(1, &drcMode);
|
|
|
|
AXQuit();
|
|
|
|
|
2024-07-14 11:58:15 +02:00
|
|
|
WHBLogPrintf("TV mode before transition = %d", tvMode);
|
2024-07-04 17:30:40 +02:00
|
|
|
transitionAudioBuffer.tv.mode = tvMode;
|
|
|
|
|
2024-07-14 11:58:15 +02:00
|
|
|
WHBLogPrintf("DRC mode before transition = %d", drcMode);
|
2024-07-04 17:30:40 +02:00
|
|
|
transitionAudioBuffer.drc.mode = drcMode;
|
|
|
|
|
|
|
|
transitionAudioBuffer.unk1 = 1;
|
|
|
|
transitionAudioBuffer.unk2 = 0;
|
|
|
|
|
|
|
|
transitionAudioBuffer.tv.unk1 = 0.99987207655f;
|
|
|
|
transitionAudioBuffer.tv.unk2 = 600;
|
|
|
|
|
|
|
|
transitionAudioBuffer.drc.unk1 = transitionAudioBuffer.tv.unk1;
|
|
|
|
transitionAudioBuffer.tv.unk2 = transitionAudioBuffer.tv.unk2;
|
|
|
|
|
|
|
|
switch (mOutputTarget) {
|
|
|
|
case TV_ONLY:
|
|
|
|
transitionAudioBuffer.tv.enabled = true;
|
|
|
|
transitionAudioBuffer.drc.enabled = false;
|
|
|
|
break;
|
|
|
|
case DRC_ONLY:
|
|
|
|
transitionAudioBuffer.tv.enabled = false;
|
|
|
|
transitionAudioBuffer.drc.enabled = true;
|
|
|
|
break;
|
|
|
|
case BOTH:
|
|
|
|
transitionAudioBuffer.tv.enabled = true;
|
|
|
|
transitionAudioBuffer.drc.enabled = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
void *audioBuffer = (void *) nullptr;
|
|
|
|
uint32_t audioBufferLen = 0;
|
|
|
|
auto res = __OSGetTransitionAudioBuffer(&audioBuffer, &audioBufferLen);
|
|
|
|
if (res == 0) {
|
2024-07-14 11:58:15 +02:00
|
|
|
DEBUG_FUNCTION_LINE_ERR("Could not get access to audio buffer from foreground bucket");
|
2024-07-04 17:30:40 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::span<uint8_t> audioBufferIn(mBuffer.data() + 8, mBuffer.size() - 8);
|
|
|
|
|
2024-07-14 11:58:15 +02:00
|
|
|
DEBUG_FUNCTION_LINE("Got audio buffer from foreground bucket @ %8.8x len = %d", audioBuffer, audioBufferLen);
|
2024-07-04 17:30:40 +02:00
|
|
|
if (audioBufferLen < mBuffer.size()) {
|
|
|
|
DEBUG_FUNCTION_LINE_ERR("buffer not big enough");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(audioBuffer, audioBufferIn.data(), audioBufferIn.size());
|
|
|
|
__OSSetTransitionAudioSize(audioBufferIn.size());
|
|
|
|
|
|
|
|
transitionAudioBuffer.length = audioBufferIn.size();
|
|
|
|
transitionAudioBuffer.loopPoint = mLoopPoint;
|
|
|
|
transitionAudioBuffer.audioBuffer = audioBuffer;
|
|
|
|
transitionAudioBuffer.audioBufferLen = audioBufferLen;
|
|
|
|
AXSetUpTransitionAudio((AXTransitionAudioBuffer *) &transitionAudioBuffer);
|
|
|
|
AXStartTransitionAudio();
|
|
|
|
}
|