Play portal audio via Cemu output

This commit is contained in:
Joshua de Reeper 2025-01-21 19:11:39 +01:00
parent 2f02fda9ea
commit 1f3b97216f
4 changed files with 64 additions and 12 deletions

View file

@ -6,6 +6,8 @@
#include "Backend.h" #include "Backend.h"
#include "Common/FileStream.h" #include "Common/FileStream.h"
#include "audio/IAudioAPI.h"
#include "config/CemuConfig.h"
namespace nsyshid namespace nsyshid
{ {
@ -558,6 +560,45 @@ namespace nsyshid
Device::WriteResult SkylanderPortalDevice::Write(WriteMessage* message) Device::WriteResult SkylanderPortalDevice::Write(WriteMessage* message)
{ {
if (message->length != 64) {
cemu_assert_error();
}
if (!g_portalAudio)
{
auto& config = GetConfig();
auto& selectedDevice = L"default";
const auto audio_api = (IAudioAPI::AudioAPI)config.audio_api;
IAudioAPI::DeviceDescriptionPtr device_description;
if (IAudioAPI::IsAudioAPIAvailable(audio_api))
{
auto devices = IAudioAPI::GetDevices(audio_api);
const auto it = std::find_if(devices.begin(), devices.end(), [&selectedDevice](const auto& d) {
return d->GetIdentifier() == selectedDevice;
});
if (it != devices.end())
{
device_description = *it;
}
}
if (!device_description)
throw std::runtime_error("failed to find selected device while trying to create audio device");
// Portal audio is mono channel, 16 bit audio.
// Audio is unsigned 16 bit, supplied as 64 bytes which is 32 samples per block
g_portalAudio = IAudioAPI::CreateDevice((IAudioAPI::AudioAPI)GetConfig().audio_api, device_description, 8000, 1, 32, 16);
}
std::array<sint16, 32> mono_samples;
for (unsigned int i = 0; i < mono_samples.size(); ++i)
{
sint16 sample = static_cast<uint16>(message->data[i * 2 + 1]) << 8 | static_cast<uint16>(message->data[i * 2]);
mono_samples[i] = sample;
}
if (g_portalAudio)
{
g_portalAudio->FeedBlock(mono_samples.data());
}
message->bytesWritten = message->length; message->bytesWritten = message->length;
return Device::WriteResult::Success; return Device::WriteResult::Success;
} }

View file

@ -462,6 +462,14 @@ namespace snd_core
else else
g_padAudio->Stop(); g_padAudio->Stop();
} }
if (g_portalAudio)
{
if (isPlaying)
g_portalAudio->Play();
else
g_portalAudio->Stop();
}
} }
// called periodically to check for AX updates // called periodically to check for AX updates

View file

@ -13,6 +13,7 @@
std::shared_mutex g_audioMutex; std::shared_mutex g_audioMutex;
AudioAPIPtr g_tvAudio; AudioAPIPtr g_tvAudio;
AudioAPIPtr g_padAudio; AudioAPIPtr g_padAudio;
AudioAPIPtr g_portalAudio;
std::atomic_int32_t g_padVolume = 0; std::atomic_int32_t g_padVolume = 0;
uint32 IAudioAPI::s_audioDelay = 2; uint32 IAudioAPI::s_audioDelay = 2;

View file

@ -93,3 +93,5 @@ extern AudioAPIPtr g_tvAudio;
extern AudioAPIPtr g_padAudio; extern AudioAPIPtr g_padAudio;
extern std::atomic_int32_t g_padVolume; extern std::atomic_int32_t g_padVolume;
extern AudioAPIPtr g_portalAudio;