Project Andio
This commit is contained in:
parent
6e36f4d230
commit
458da8a948
270 changed files with 33712 additions and 8445 deletions
100
src/audio_core/out/audio_out.cpp
Normal file
100
src/audio_core/out/audio_out.cpp
Normal file
|
@ -0,0 +1,100 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "audio_core/audio_out_manager.h"
|
||||
#include "audio_core/out/audio_out.h"
|
||||
#include "core/hle/kernel/k_event.h"
|
||||
|
||||
namespace AudioCore::AudioOut {
|
||||
|
||||
Out::Out(Core::System& system_, Manager& manager_, Kernel::KEvent* event_, size_t session_id_)
|
||||
: manager{manager_}, parent_mutex{manager.mutex}, event{event_}, system{system_, event,
|
||||
session_id_} {}
|
||||
|
||||
void Out::Free() {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
manager.ReleaseSessionId(system.GetSessionId());
|
||||
}
|
||||
|
||||
System& Out::GetSystem() {
|
||||
return system;
|
||||
}
|
||||
|
||||
AudioOut::State Out::GetState() {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
return system.GetState();
|
||||
}
|
||||
|
||||
Result Out::StartSystem() {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
return system.Start();
|
||||
}
|
||||
|
||||
void Out::StartSession() {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
system.StartSession();
|
||||
}
|
||||
|
||||
Result Out::StopSystem() {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
return system.Stop();
|
||||
}
|
||||
|
||||
Result Out::AppendBuffer(const AudioOutBuffer& buffer, const u64 tag) {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
|
||||
if (system.AppendBuffer(buffer, tag)) {
|
||||
return ResultSuccess;
|
||||
}
|
||||
return Service::Audio::ERR_BUFFER_COUNT_EXCEEDED;
|
||||
}
|
||||
|
||||
void Out::ReleaseAndRegisterBuffers() {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
if (system.GetState() == State::Started) {
|
||||
system.ReleaseBuffers();
|
||||
system.RegisterBuffers();
|
||||
}
|
||||
}
|
||||
|
||||
bool Out::FlushAudioOutBuffers() {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
return system.FlushAudioOutBuffers();
|
||||
}
|
||||
|
||||
u32 Out::GetReleasedBuffers(std::span<u64> tags) {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
return system.GetReleasedBuffers(tags);
|
||||
}
|
||||
|
||||
Kernel::KReadableEvent& Out::GetBufferEvent() {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
return event->GetReadableEvent();
|
||||
}
|
||||
|
||||
f32 Out::GetVolume() {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
return system.GetVolume();
|
||||
}
|
||||
|
||||
void Out::SetVolume(const f32 volume) {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
system.SetVolume(volume);
|
||||
}
|
||||
|
||||
bool Out::ContainsAudioBuffer(const u64 tag) {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
return system.ContainsAudioBuffer(tag);
|
||||
}
|
||||
|
||||
u32 Out::GetBufferCount() {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
return system.GetBufferCount();
|
||||
}
|
||||
|
||||
u64 Out::GetPlayedSampleCount() {
|
||||
std::scoped_lock l{parent_mutex};
|
||||
return system.GetPlayedSampleCount();
|
||||
}
|
||||
|
||||
} // namespace AudioCore::AudioOut
|
147
src/audio_core/out/audio_out.h
Normal file
147
src/audio_core/out/audio_out.h
Normal file
|
@ -0,0 +1,147 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include "audio_core/out/audio_out_system.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace Kernel {
|
||||
class KEvent;
|
||||
class KReadableEvent;
|
||||
} // namespace Kernel
|
||||
|
||||
namespace AudioCore::AudioOut {
|
||||
class Manager;
|
||||
|
||||
/**
|
||||
* Interface between the service and audio out system. Mainly responsible for forwarding service
|
||||
* calls to the system.
|
||||
*/
|
||||
class Out {
|
||||
public:
|
||||
explicit Out(Core::System& system, Manager& manager, Kernel::KEvent* event, size_t session_id);
|
||||
|
||||
/**
|
||||
* Free this audio out from the audio out manager.
|
||||
*/
|
||||
void Free();
|
||||
|
||||
/**
|
||||
* Get this audio out's system.
|
||||
*/
|
||||
System& GetSystem();
|
||||
|
||||
/**
|
||||
* Get the current state.
|
||||
*
|
||||
* @return Started or Stopped.
|
||||
*/
|
||||
AudioOut::State GetState();
|
||||
|
||||
/**
|
||||
* Start the system
|
||||
*
|
||||
* @return Result code
|
||||
*/
|
||||
Result StartSystem();
|
||||
|
||||
/**
|
||||
* Start the system's device session.
|
||||
*/
|
||||
void StartSession();
|
||||
|
||||
/**
|
||||
* Stop the system.
|
||||
*
|
||||
* @return Result code
|
||||
*/
|
||||
Result StopSystem();
|
||||
|
||||
/**
|
||||
* Append a new buffer to the system, the buffer event will be signalled when it is filled.
|
||||
*
|
||||
* @param buffer - The new buffer to append.
|
||||
* @param tag - Unique tag for this buffer.
|
||||
* @return Result code.
|
||||
*/
|
||||
Result AppendBuffer(const AudioOutBuffer& buffer, u64 tag);
|
||||
|
||||
/**
|
||||
* Release all completed buffers, and register any appended.
|
||||
*/
|
||||
void ReleaseAndRegisterBuffers();
|
||||
|
||||
/**
|
||||
* Flush all buffers.
|
||||
*/
|
||||
bool FlushAudioOutBuffers();
|
||||
|
||||
/**
|
||||
* Get all of the currently released buffers.
|
||||
*
|
||||
* @param tags - Output container for the buffer tags which were released.
|
||||
* @return The number of buffers released.
|
||||
*/
|
||||
u32 GetReleasedBuffers(std::span<u64> tags);
|
||||
|
||||
/**
|
||||
* Get the buffer event for this audio out, this event will be signalled when a buffer is
|
||||
* filled.
|
||||
* @return The buffer event.
|
||||
*/
|
||||
Kernel::KReadableEvent& GetBufferEvent();
|
||||
|
||||
/**
|
||||
* Get the current system volume.
|
||||
*
|
||||
* @return The current volume.
|
||||
*/
|
||||
f32 GetVolume();
|
||||
|
||||
/**
|
||||
* Set the system volume.
|
||||
*
|
||||
* @param volume - The volume to set.
|
||||
*/
|
||||
void SetVolume(f32 volume);
|
||||
|
||||
/**
|
||||
* Check if a buffer is in the system.
|
||||
*
|
||||
* @param tag - The tag to search for.
|
||||
* @return True if the buffer is in the system, otherwise false.
|
||||
*/
|
||||
bool ContainsAudioBuffer(u64 tag);
|
||||
|
||||
/**
|
||||
* Get the maximum number of buffers.
|
||||
*
|
||||
* @return The maximum number of buffers.
|
||||
*/
|
||||
u32 GetBufferCount();
|
||||
|
||||
/**
|
||||
* Get the total played sample count for this audio out.
|
||||
*
|
||||
* @return The played sample count.
|
||||
*/
|
||||
u64 GetPlayedSampleCount();
|
||||
|
||||
private:
|
||||
/// The AudioOut::Manager this audio out is registered with
|
||||
Manager& manager;
|
||||
/// Manager's mutex
|
||||
std::recursive_mutex& parent_mutex;
|
||||
/// Buffer event, signalled when buffers are ready to be released
|
||||
Kernel::KEvent* event;
|
||||
/// Main audio out system
|
||||
System system;
|
||||
};
|
||||
|
||||
} // namespace AudioCore::AudioOut
|
207
src/audio_core/out/audio_out_system.cpp
Normal file
207
src/audio_core/out/audio_out_system.cpp
Normal file
|
@ -0,0 +1,207 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include "audio_core/audio_event.h"
|
||||
#include "audio_core/audio_manager.h"
|
||||
#include "audio_core/out/audio_out_system.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/core.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/hle/kernel/k_event.h"
|
||||
|
||||
namespace AudioCore::AudioOut {
|
||||
|
||||
System::System(Core::System& system_, Kernel::KEvent* event_, size_t session_id_)
|
||||
: system{system_}, buffer_event{event_},
|
||||
session_id{session_id_}, session{std::make_unique<DeviceSession>(system_)} {}
|
||||
|
||||
System::~System() {
|
||||
Finalize();
|
||||
}
|
||||
|
||||
void System::Finalize() {
|
||||
Stop();
|
||||
session->Finalize();
|
||||
buffer_event->GetWritableEvent().Signal();
|
||||
}
|
||||
|
||||
std::string_view System::GetDefaultOutputDeviceName() {
|
||||
return "DeviceOut";
|
||||
}
|
||||
|
||||
Result System::IsConfigValid(std::string_view device_name, const AudioOutParameter& in_params) {
|
||||
if ((device_name.size() > 0) && (device_name != GetDefaultOutputDeviceName())) {
|
||||
return Service::Audio::ERR_INVALID_DEVICE_NAME;
|
||||
}
|
||||
|
||||
if (in_params.sample_rate != TargetSampleRate && in_params.sample_rate > 0) {
|
||||
return Service::Audio::ERR_INVALID_SAMPLE_RATE;
|
||||
}
|
||||
|
||||
if (in_params.channel_count == 0 || in_params.channel_count == 2 ||
|
||||
in_params.channel_count == 6) {
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
return Service::Audio::ERR_INVALID_CHANNEL_COUNT;
|
||||
}
|
||||
|
||||
Result System::Initialize(std::string& device_name, const AudioOutParameter& in_params, u32 handle_,
|
||||
u64& applet_resource_user_id_) {
|
||||
auto result = IsConfigValid(device_name, in_params);
|
||||
if (result.IsError()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
handle = handle_;
|
||||
applet_resource_user_id = applet_resource_user_id_;
|
||||
if (device_name.empty() || device_name[0] == '\0') {
|
||||
name = std::string(GetDefaultOutputDeviceName());
|
||||
} else {
|
||||
name = std::move(device_name);
|
||||
}
|
||||
|
||||
sample_rate = TargetSampleRate;
|
||||
sample_format = SampleFormat::PcmInt16;
|
||||
channel_count = in_params.channel_count <= 2 ? 2 : 6;
|
||||
volume = 1.0f;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
void System::StartSession() {
|
||||
session->Start();
|
||||
}
|
||||
|
||||
size_t System::GetSessionId() const {
|
||||
return session_id;
|
||||
}
|
||||
|
||||
Result System::Start() {
|
||||
if (state != State::Stopped) {
|
||||
return Service::Audio::ERR_OPERATION_FAILED;
|
||||
}
|
||||
|
||||
session->Initialize(name, sample_format, channel_count, session_id, handle,
|
||||
applet_resource_user_id, Sink::StreamType::Out);
|
||||
session->SetVolume(volume);
|
||||
session->Start();
|
||||
state = State::Started;
|
||||
|
||||
std::vector<AudioBuffer> buffers_to_flush{};
|
||||
buffers.RegisterBuffers(buffers_to_flush);
|
||||
session->AppendBuffers(buffers_to_flush);
|
||||
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Result System::Stop() {
|
||||
if (state == State::Started) {
|
||||
session->Stop();
|
||||
session->SetVolume(0.0f);
|
||||
state = State::Stopped;
|
||||
}
|
||||
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
bool System::AppendBuffer(const AudioOutBuffer& buffer, u64 tag) {
|
||||
if (buffers.GetTotalBufferCount() == BufferCount) {
|
||||
return false;
|
||||
}
|
||||
|
||||
AudioBuffer new_buffer{
|
||||
.played_timestamp = 0, .samples = buffer.samples, .tag = tag, .size = buffer.size};
|
||||
|
||||
buffers.AppendBuffer(new_buffer);
|
||||
RegisterBuffers();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void System::RegisterBuffers() {
|
||||
if (state == State::Started) {
|
||||
std::vector<AudioBuffer> registered_buffers{};
|
||||
buffers.RegisterBuffers(registered_buffers);
|
||||
session->AppendBuffers(registered_buffers);
|
||||
}
|
||||
}
|
||||
|
||||
void System::ReleaseBuffers() {
|
||||
bool signal{buffers.ReleaseBuffers(system.CoreTiming(), *session)};
|
||||
if (signal) {
|
||||
// Signal if any buffer was released, or if none are registered, we need more.
|
||||
buffer_event->GetWritableEvent().Signal();
|
||||
}
|
||||
}
|
||||
|
||||
u32 System::GetReleasedBuffers(std::span<u64> tags) {
|
||||
return buffers.GetReleasedBuffers(tags);
|
||||
}
|
||||
|
||||
bool System::FlushAudioOutBuffers() {
|
||||
if (state != State::Started) {
|
||||
return false;
|
||||
}
|
||||
|
||||
u32 buffers_released{};
|
||||
buffers.FlushBuffers(buffers_released);
|
||||
|
||||
if (buffers_released > 0) {
|
||||
buffer_event->GetWritableEvent().Signal();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
u16 System::GetChannelCount() const {
|
||||
return channel_count;
|
||||
}
|
||||
|
||||
u32 System::GetSampleRate() const {
|
||||
return sample_rate;
|
||||
}
|
||||
|
||||
SampleFormat System::GetSampleFormat() const {
|
||||
return sample_format;
|
||||
}
|
||||
|
||||
State System::GetState() {
|
||||
switch (state) {
|
||||
case State::Started:
|
||||
case State::Stopped:
|
||||
return state;
|
||||
default:
|
||||
LOG_ERROR(Service_Audio, "AudioOut invalid state!");
|
||||
state = State::Stopped;
|
||||
break;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
std::string System::GetName() const {
|
||||
return name;
|
||||
}
|
||||
|
||||
f32 System::GetVolume() const {
|
||||
return volume;
|
||||
}
|
||||
|
||||
void System::SetVolume(const f32 volume_) {
|
||||
volume = volume_;
|
||||
session->SetVolume(volume_);
|
||||
}
|
||||
|
||||
bool System::ContainsAudioBuffer(const u64 tag) {
|
||||
return buffers.ContainsBuffer(tag);
|
||||
}
|
||||
|
||||
u32 System::GetBufferCount() {
|
||||
return buffers.GetAppendedRegisteredCount();
|
||||
}
|
||||
|
||||
u64 System::GetPlayedSampleCount() const {
|
||||
return session->GetPlayedSampleCount();
|
||||
}
|
||||
|
||||
} // namespace AudioCore::AudioOut
|
257
src/audio_core/out/audio_out_system.h
Normal file
257
src/audio_core/out/audio_out_system.h
Normal file
|
@ -0,0 +1,257 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <span>
|
||||
#include <string>
|
||||
|
||||
#include "audio_core/common/common.h"
|
||||
#include "audio_core/device/audio_buffers.h"
|
||||
#include "audio_core/device/device_session.h"
|
||||
#include "core/hle/service/audio/errors.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace Kernel {
|
||||
class KEvent;
|
||||
}
|
||||
|
||||
namespace AudioCore::AudioOut {
|
||||
|
||||
constexpr SessionTypes SessionType = SessionTypes::AudioOut;
|
||||
|
||||
struct AudioOutParameter {
|
||||
/* 0x0 */ s32_le sample_rate;
|
||||
/* 0x4 */ u16_le channel_count;
|
||||
/* 0x6 */ u16_le reserved;
|
||||
};
|
||||
static_assert(sizeof(AudioOutParameter) == 0x8, "AudioOutParameter is an invalid size");
|
||||
|
||||
struct AudioOutParameterInternal {
|
||||
/* 0x0 */ u32_le sample_rate;
|
||||
/* 0x4 */ u32_le channel_count;
|
||||
/* 0x8 */ u32_le sample_format;
|
||||
/* 0xC */ u32_le state;
|
||||
};
|
||||
static_assert(sizeof(AudioOutParameterInternal) == 0x10,
|
||||
"AudioOutParameterInternal is an invalid size");
|
||||
|
||||
struct AudioOutBuffer {
|
||||
/* 0x00 */ AudioOutBuffer* next;
|
||||
/* 0x08 */ VAddr samples;
|
||||
/* 0x10 */ u64 capacity;
|
||||
/* 0x18 */ u64 size;
|
||||
/* 0x20 */ u64 offset;
|
||||
};
|
||||
static_assert(sizeof(AudioOutBuffer) == 0x28, "AudioOutBuffer is an invalid size");
|
||||
|
||||
enum class State {
|
||||
Started,
|
||||
Stopped,
|
||||
};
|
||||
|
||||
/**
|
||||
* Controls and drives audio output.
|
||||
*/
|
||||
class System {
|
||||
public:
|
||||
explicit System(Core::System& system, Kernel::KEvent* event, size_t session_id);
|
||||
~System();
|
||||
|
||||
/**
|
||||
* Get the default audio output device name.
|
||||
*
|
||||
* @return The default audio output device name.
|
||||
*/
|
||||
std::string_view GetDefaultOutputDeviceName();
|
||||
|
||||
/**
|
||||
* Is the given initialize config valid?
|
||||
*
|
||||
* @param device_name - The name of the requested output device.
|
||||
* @param in_params - Input parameters, see AudioOutParameter.
|
||||
* @return Result code.
|
||||
*/
|
||||
Result IsConfigValid(std::string_view device_name, const AudioOutParameter& in_params);
|
||||
|
||||
/**
|
||||
* Initialize this system.
|
||||
*
|
||||
* @param device_name - The name of the requested output device.
|
||||
* @param in_params - Input parameters, see AudioOutParameter.
|
||||
* @param handle - Unused.
|
||||
* @param applet_resource_user_id - Unused.
|
||||
* @return Result code.
|
||||
*/
|
||||
Result Initialize(std::string& device_name, const AudioOutParameter& in_params, u32 handle,
|
||||
u64& applet_resource_user_id);
|
||||
|
||||
/**
|
||||
* Start this system.
|
||||
*
|
||||
* @return Result code.
|
||||
*/
|
||||
Result Start();
|
||||
|
||||
/**
|
||||
* Stop this system.
|
||||
*
|
||||
* @return Result code.
|
||||
*/
|
||||
Result Stop();
|
||||
|
||||
/**
|
||||
* Finalize this system.
|
||||
*/
|
||||
void Finalize();
|
||||
|
||||
/**
|
||||
* Start this system's device session.
|
||||
*/
|
||||
void StartSession();
|
||||
|
||||
/**
|
||||
* Get this system's id.
|
||||
*/
|
||||
size_t GetSessionId() const;
|
||||
|
||||
/**
|
||||
* Append a new buffer to the device.
|
||||
*
|
||||
* @param buffer - New buffer to append.
|
||||
* @param tag - Unique tag of the buffer.
|
||||
* @return True if the buffer was appended, otherwise false.
|
||||
*/
|
||||
bool AppendBuffer(const AudioOutBuffer& buffer, u64 tag);
|
||||
|
||||
/**
|
||||
* Register all appended buffers.
|
||||
*/
|
||||
void RegisterBuffers();
|
||||
|
||||
/**
|
||||
* Release all registered buffers.
|
||||
*/
|
||||
void ReleaseBuffers();
|
||||
|
||||
/**
|
||||
* Get all released buffers.
|
||||
*
|
||||
* @param tags - Container to be filled with the released buffers' tags.
|
||||
* @return The number of buffers released.
|
||||
*/
|
||||
u32 GetReleasedBuffers(std::span<u64> tags);
|
||||
|
||||
/**
|
||||
* Flush all appended and registered buffers.
|
||||
*
|
||||
* @return True if buffers were successfully flushed, otherwise false.
|
||||
*/
|
||||
bool FlushAudioOutBuffers();
|
||||
|
||||
/**
|
||||
* Get this system's current channel count.
|
||||
*
|
||||
* @return The channel count.
|
||||
*/
|
||||
u16 GetChannelCount() const;
|
||||
|
||||
/**
|
||||
* Get this system's current sample rate.
|
||||
*
|
||||
* @return The sample rate.
|
||||
*/
|
||||
u32 GetSampleRate() const;
|
||||
|
||||
/**
|
||||
* Get this system's current sample format.
|
||||
*
|
||||
* @return The sample format.
|
||||
*/
|
||||
SampleFormat GetSampleFormat() const;
|
||||
|
||||
/**
|
||||
* Get this system's current state.
|
||||
*
|
||||
* @return The current state.
|
||||
*/
|
||||
State GetState();
|
||||
|
||||
/**
|
||||
* Get this system's name.
|
||||
*
|
||||
* @return The system's name.
|
||||
*/
|
||||
std::string GetName() const;
|
||||
|
||||
/**
|
||||
* Get this system's current volume.
|
||||
*
|
||||
* @return The system's current volume.
|
||||
*/
|
||||
f32 GetVolume() const;
|
||||
|
||||
/**
|
||||
* Set this system's current volume.
|
||||
*
|
||||
* @param The new volume.
|
||||
*/
|
||||
void SetVolume(f32 volume);
|
||||
|
||||
/**
|
||||
* Does the system contain this buffer?
|
||||
*
|
||||
* @param tag - Unique tag to search for.
|
||||
* @return True if the buffer is in the system, otherwise false.
|
||||
*/
|
||||
bool ContainsAudioBuffer(u64 tag);
|
||||
|
||||
/**
|
||||
* Get the maximum number of usable buffers (default 32).
|
||||
*
|
||||
* @return The number of buffers.
|
||||
*/
|
||||
u32 GetBufferCount();
|
||||
|
||||
/**
|
||||
* Get the total number of samples played by this system.
|
||||
*
|
||||
* @return The number of samples.
|
||||
*/
|
||||
u64 GetPlayedSampleCount() const;
|
||||
|
||||
private:
|
||||
/// Core system
|
||||
Core::System& system;
|
||||
/// (Unused)
|
||||
u32 handle{};
|
||||
/// (Unused)
|
||||
u64 applet_resource_user_id{};
|
||||
/// Buffer event, signalled when a buffer is ready
|
||||
Kernel::KEvent* buffer_event;
|
||||
/// Session id of this system
|
||||
size_t session_id{};
|
||||
/// Device session for this system
|
||||
std::unique_ptr<DeviceSession> session;
|
||||
/// Audio buffers in use by this system
|
||||
AudioBuffers<BufferCount> buffers{BufferCount};
|
||||
/// Sample rate of this system
|
||||
u32 sample_rate{};
|
||||
/// Sample format of this system
|
||||
SampleFormat sample_format{SampleFormat::PcmInt16};
|
||||
/// Channel count of this system
|
||||
u16 channel_count{};
|
||||
/// State of this system
|
||||
std::atomic<State> state{State::Stopped};
|
||||
/// Name of this system
|
||||
std::string name{};
|
||||
/// Volume of this system
|
||||
f32 volume{1.0f};
|
||||
};
|
||||
|
||||
} // namespace AudioCore::AudioOut
|
Loading…
Add table
Add a link
Reference in a new issue