audout_u: Add support for multiple IAudioOut streams.
- Used by Undertale.
This commit is contained in:
parent
bb175ab430
commit
5a6dc4d041
|
@ -44,8 +44,10 @@ enum class AudioState : u32 {
|
||||||
|
|
||||||
class IAudioOut final : public ServiceFramework<IAudioOut> {
|
class IAudioOut final : public ServiceFramework<IAudioOut> {
|
||||||
public:
|
public:
|
||||||
IAudioOut(AudoutParams audio_params, AudioCore::AudioOut& audio_core)
|
IAudioOut(AudoutParams audio_params, AudioCore::AudioOut& audio_core, std::string&& device_name,
|
||||||
: ServiceFramework("IAudioOut"), audio_core(audio_core), audio_params(audio_params) {
|
std::string&& unique_name)
|
||||||
|
: ServiceFramework("IAudioOut"), audio_core(audio_core), audio_params(audio_params),
|
||||||
|
device_name(std::move(device_name)) {
|
||||||
|
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, &IAudioOut::GetAudioOutState, "GetAudioOutState"},
|
{0, &IAudioOut::GetAudioOutState, "GetAudioOutState"},
|
||||||
|
@ -69,7 +71,7 @@ public:
|
||||||
Kernel::Event::Create(kernel, Kernel::ResetType::Sticky, "IAudioOutBufferReleased");
|
Kernel::Event::Create(kernel, Kernel::ResetType::Sticky, "IAudioOutBufferReleased");
|
||||||
|
|
||||||
stream = audio_core.OpenStream(audio_params.sample_rate, audio_params.channel_count,
|
stream = audio_core.OpenStream(audio_params.sample_rate, audio_params.channel_count,
|
||||||
"IAudioOut", [=]() { buffer_event->Signal(); });
|
std::move(unique_name), [=]() { buffer_event->Signal(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -177,6 +179,7 @@ private:
|
||||||
|
|
||||||
AudioCore::AudioOut& audio_core;
|
AudioCore::AudioOut& audio_core;
|
||||||
AudioCore::StreamPtr stream;
|
AudioCore::StreamPtr stream;
|
||||||
|
std::string device_name;
|
||||||
|
|
||||||
AudoutParams audio_params{};
|
AudoutParams audio_params{};
|
||||||
|
|
||||||
|
@ -199,7 +202,15 @@ void AudOutU::ListAudioOutsImpl(Kernel::HLERequestContext& ctx) {
|
||||||
void AudOutU::OpenAudioOutImpl(Kernel::HLERequestContext& ctx) {
|
void AudOutU::OpenAudioOutImpl(Kernel::HLERequestContext& ctx) {
|
||||||
LOG_DEBUG(Service_Audio, "called");
|
LOG_DEBUG(Service_Audio, "called");
|
||||||
|
|
||||||
ctx.WriteBuffer(DefaultDevice);
|
const auto device_name_data{ctx.ReadBuffer()};
|
||||||
|
std::string device_name;
|
||||||
|
if (device_name_data[0] != '\0') {
|
||||||
|
device_name.assign(device_name_data.begin(), device_name_data.end());
|
||||||
|
} else {
|
||||||
|
device_name.assign(DefaultDevice.begin(), DefaultDevice.end());
|
||||||
|
}
|
||||||
|
ctx.WriteBuffer(device_name);
|
||||||
|
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
auto params{rp.PopRaw<AudoutParams>()};
|
auto params{rp.PopRaw<AudoutParams>()};
|
||||||
if (params.channel_count <= 2) {
|
if (params.channel_count <= 2) {
|
||||||
|
@ -212,10 +223,9 @@ void AudOutU::OpenAudioOutImpl(Kernel::HLERequestContext& ctx) {
|
||||||
params.sample_rate = DefaultSampleRate;
|
params.sample_rate = DefaultSampleRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(bunnei): Support more than one IAudioOut interface. When we add this, ListAudioOutsImpl
|
std::string unique_name{fmt::format("{}-{}", device_name, audio_out_interfaces.size())};
|
||||||
// will likely need to be updated as well.
|
auto audio_out_interface = std::make_shared<IAudioOut>(
|
||||||
ASSERT_MSG(!audio_out_interface, "Unimplemented");
|
params, *audio_core, std::move(device_name), std::move(unique_name));
|
||||||
audio_out_interface = std::make_shared<IAudioOut>(params, *audio_core);
|
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 6, 0, 1};
|
IPC::ResponseBuilder rb{ctx, 6, 0, 1};
|
||||||
rb.Push(RESULT_SUCCESS);
|
rb.Push(RESULT_SUCCESS);
|
||||||
|
@ -224,6 +234,8 @@ void AudOutU::OpenAudioOutImpl(Kernel::HLERequestContext& ctx) {
|
||||||
rb.Push<u32>(static_cast<u32>(AudioCore::Codec::PcmFormat::Int16));
|
rb.Push<u32>(static_cast<u32>(AudioCore::Codec::PcmFormat::Int16));
|
||||||
rb.Push<u32>(static_cast<u32>(AudioState::Stopped));
|
rb.Push<u32>(static_cast<u32>(AudioState::Stopped));
|
||||||
rb.PushIpcInterface<Audio::IAudioOut>(audio_out_interface);
|
rb.PushIpcInterface<Audio::IAudioOut>(audio_out_interface);
|
||||||
|
|
||||||
|
audio_out_interfaces.push_back(std::move(audio_out_interface));
|
||||||
}
|
}
|
||||||
|
|
||||||
AudOutU::AudOutU() : ServiceFramework("audout:u") {
|
AudOutU::AudOutU() : ServiceFramework("audout:u") {
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
|
|
||||||
namespace AudioCore {
|
namespace AudioCore {
|
||||||
|
@ -24,7 +25,7 @@ public:
|
||||||
~AudOutU() override;
|
~AudOutU() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<IAudioOut> audio_out_interface;
|
std::vector<std::shared_ptr<IAudioOut>> audio_out_interfaces;
|
||||||
std::unique_ptr<AudioCore::AudioOut> audio_core;
|
std::unique_ptr<AudioCore::AudioOut> audio_core;
|
||||||
|
|
||||||
void ListAudioOutsImpl(Kernel::HLERequestContext& ctx);
|
void ListAudioOutsImpl(Kernel::HLERequestContext& ctx);
|
||||||
|
|
Loading…
Reference in a new issue