mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-07-02 13:01:18 +12:00
Play portal audio via Cemu output
This commit is contained in:
parent
2f02fda9ea
commit
1f3b97216f
4 changed files with 64 additions and 12 deletions
|
@ -6,6 +6,8 @@
|
|||
#include "Backend.h"
|
||||
|
||||
#include "Common/FileStream.h"
|
||||
#include "audio/IAudioAPI.h"
|
||||
#include "config/CemuConfig.h"
|
||||
|
||||
namespace nsyshid
|
||||
{
|
||||
|
@ -558,6 +560,45 @@ namespace nsyshid
|
|||
|
||||
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;
|
||||
return Device::WriteResult::Success;
|
||||
}
|
||||
|
@ -604,20 +645,20 @@ namespace nsyshid
|
|||
*(uint16be*)(currentWritePtr + 7) = 0x001D; // wDescriptorLength
|
||||
currentWritePtr = currentWritePtr + 9;
|
||||
// endpoint descriptor 1
|
||||
*(uint8*)(currentWritePtr + 0) = 7; // bLength
|
||||
*(uint8*)(currentWritePtr + 1) = 0x05; // bDescriptorType
|
||||
*(uint8*)(currentWritePtr + 2) = 0x81; // bEndpointAddress
|
||||
*(uint8*)(currentWritePtr + 3) = 0x03; // bmAttributes
|
||||
*(uint8*)(currentWritePtr + 0) = 7; // bLength
|
||||
*(uint8*)(currentWritePtr + 1) = 0x05; // bDescriptorType
|
||||
*(uint8*)(currentWritePtr + 2) = 0x81; // bEndpointAddress
|
||||
*(uint8*)(currentWritePtr + 3) = 0x03; // bmAttributes
|
||||
*(uint16be*)(currentWritePtr + 4) = 0x0040; // wMaxPacketSize
|
||||
*(uint8*)(currentWritePtr + 6) = 0x01; // bInterval
|
||||
*(uint8*)(currentWritePtr + 6) = 0x01; // bInterval
|
||||
currentWritePtr = currentWritePtr + 7;
|
||||
// endpoint descriptor 2
|
||||
*(uint8*)(currentWritePtr + 0) = 7; // bLength
|
||||
*(uint8*)(currentWritePtr + 1) = 0x05; // bDescriptorType
|
||||
*(uint8*)(currentWritePtr + 2) = 0x02; // bEndpointAddress
|
||||
*(uint8*)(currentWritePtr + 3) = 0x03; // bmAttributes
|
||||
*(uint8*)(currentWritePtr + 0) = 7; // bLength
|
||||
*(uint8*)(currentWritePtr + 1) = 0x05; // bDescriptorType
|
||||
*(uint8*)(currentWritePtr + 2) = 0x02; // bEndpointAddress
|
||||
*(uint8*)(currentWritePtr + 3) = 0x03; // bmAttributes
|
||||
*(uint16be*)(currentWritePtr + 4) = 0x0040; // wMaxPacketSize
|
||||
*(uint8*)(currentWritePtr + 6) = 0x01; // bInterval
|
||||
*(uint8*)(currentWritePtr + 6) = 0x01; // bInterval
|
||||
currentWritePtr = currentWritePtr + 7;
|
||||
|
||||
cemu_assert_debug((currentWritePtr - configurationDescriptor) == 0x29);
|
||||
|
@ -628,8 +669,8 @@ namespace nsyshid
|
|||
}
|
||||
|
||||
bool SkylanderPortalDevice::SetIdle(uint8 ifIndex,
|
||||
uint8 reportId,
|
||||
uint8 duration)
|
||||
uint8 reportId,
|
||||
uint8 duration)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -462,6 +462,14 @@ namespace snd_core
|
|||
else
|
||||
g_padAudio->Stop();
|
||||
}
|
||||
|
||||
if (g_portalAudio)
|
||||
{
|
||||
if (isPlaying)
|
||||
g_portalAudio->Play();
|
||||
else
|
||||
g_portalAudio->Stop();
|
||||
}
|
||||
}
|
||||
|
||||
// called periodically to check for AX updates
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
std::shared_mutex g_audioMutex;
|
||||
AudioAPIPtr g_tvAudio;
|
||||
AudioAPIPtr g_padAudio;
|
||||
AudioAPIPtr g_portalAudio;
|
||||
std::atomic_int32_t g_padVolume = 0;
|
||||
|
||||
uint32 IAudioAPI::s_audioDelay = 2;
|
||||
|
|
|
@ -93,3 +93,5 @@ extern AudioAPIPtr g_tvAudio;
|
|||
|
||||
extern AudioAPIPtr g_padAudio;
|
||||
extern std::atomic_int32_t g_padVolume;
|
||||
|
||||
extern AudioAPIPtr g_portalAudio;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue