2020-04-19 23:04:05 +02:00
|
|
|
// SPDX-License-Identifier: MPL-2.0
|
2020-03-27 20:36:02 +01:00
|
|
|
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
|
|
|
|
2020-01-24 23:04:16 +01:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <services/serviceman.h>
|
2020-02-17 20:11:59 +01:00
|
|
|
#include <audio.h>
|
2020-03-26 15:20:08 +01:00
|
|
|
#include "memory_pool.h"
|
2020-01-24 23:04:16 +01:00
|
|
|
#include "effect.h"
|
|
|
|
#include "voice.h"
|
2020-03-26 15:20:08 +01:00
|
|
|
#include "revision_info.h"
|
2020-01-24 23:04:16 +01:00
|
|
|
|
2020-03-25 18:59:37 +01:00
|
|
|
namespace skyline {
|
2020-01-24 23:04:16 +01:00
|
|
|
namespace constant {
|
2020-09-26 07:17:57 +02:00
|
|
|
constexpr u8 BufferAlignment{0x40}; //!< The alignment for all audren buffers
|
2020-01-24 23:04:16 +01:00
|
|
|
}
|
|
|
|
|
2020-03-25 18:59:37 +01:00
|
|
|
namespace service::audio::IAudioRenderer {
|
2020-01-24 23:04:16 +01:00
|
|
|
/**
|
2020-03-25 18:59:37 +01:00
|
|
|
* @brief The parameters used to configure an IAudioRenderer
|
2020-01-24 23:04:16 +01:00
|
|
|
*/
|
2020-04-17 23:35:31 +02:00
|
|
|
struct AudioRendererParameters {
|
2020-08-21 15:28:47 +02:00
|
|
|
u32 sampleRate;
|
|
|
|
u32 sampleCount;
|
|
|
|
u32 mixBufferCount;
|
|
|
|
u32 subMixCount;
|
|
|
|
u32 voiceCount;
|
|
|
|
u32 sinkCount;
|
|
|
|
u32 effectCount;
|
|
|
|
u32 performanceManagerCount;
|
|
|
|
u32 voiceDropEnable;
|
|
|
|
u32 splitterCount;
|
|
|
|
u32 splitterDestinationDataCount;
|
2020-03-25 18:59:37 +01:00
|
|
|
u32 _unk0_;
|
2020-08-21 15:28:47 +02:00
|
|
|
u32 revision;
|
2020-03-25 18:59:37 +01:00
|
|
|
};
|
2020-04-17 23:35:31 +02:00
|
|
|
static_assert(sizeof(AudioRendererParameters) == 0x34);
|
2020-01-24 23:04:16 +01:00
|
|
|
|
|
|
|
/**
|
2020-08-21 15:28:47 +02:00
|
|
|
* @brief Header containing information about the software side audren implementation and the sizes of all input data
|
2020-01-24 23:04:16 +01:00
|
|
|
*/
|
2020-03-25 18:59:37 +01:00
|
|
|
struct UpdateDataHeader {
|
2020-08-21 15:28:47 +02:00
|
|
|
u32 revision;
|
|
|
|
u32 behaviorSize;
|
|
|
|
u32 memoryPoolSize;
|
|
|
|
u32 voiceSize;
|
|
|
|
u32 voiceResourceSize;
|
|
|
|
u32 effectSize;
|
|
|
|
u32 mixSize;
|
|
|
|
u32 sinkSize;
|
|
|
|
u32 performanceManagerSize;
|
2020-03-25 18:59:37 +01:00
|
|
|
u32 _unk0_;
|
2020-08-21 15:28:47 +02:00
|
|
|
u32 elapsedFrameCountInfoSize;
|
2020-03-25 18:59:37 +01:00
|
|
|
u32 _unk1_[4];
|
2020-08-21 15:28:47 +02:00
|
|
|
u32 totalSize;
|
2020-03-25 18:59:37 +01:00
|
|
|
};
|
|
|
|
static_assert(sizeof(UpdateDataHeader) == 0x40);
|
2020-01-24 23:04:16 +01:00
|
|
|
|
|
|
|
/**
|
2020-09-28 12:05:17 +02:00
|
|
|
* @brief IAudioRenderer is used to control an audio renderer output
|
|
|
|
* @url https://switchbrew.org/wiki/Audio_services#IAudioRenderer
|
2020-01-24 23:04:16 +01:00
|
|
|
*/
|
2020-03-25 18:59:37 +01:00
|
|
|
class IAudioRenderer : public BaseService {
|
|
|
|
private:
|
2020-08-21 15:28:47 +02:00
|
|
|
AudioRendererParameters parameters;
|
2020-03-25 18:59:37 +01:00
|
|
|
RevisionInfo revisionInfo{}; //!< Stores info about supported features for the audren revision used
|
|
|
|
std::shared_ptr<skyline::audio::AudioTrack> track; //!< The audio track associated with the audio renderer
|
2020-07-05 14:51:15 +02:00
|
|
|
std::shared_ptr<type::KEvent> systemEvent; //!< The KEvent that is signalled when the DSP has processed all the commands
|
2020-08-21 15:28:47 +02:00
|
|
|
std::vector<MemoryPool> memoryPools;
|
|
|
|
std::vector<Effect> effects;
|
|
|
|
std::vector<Voice> voices;
|
2022-01-22 22:42:38 +01:00
|
|
|
std::array<i16, constant::MixBufferSize * constant::StereoChannelCount> sampleBuffer{}; //!< The final output data that is appended to the stream
|
2020-08-21 15:28:47 +02:00
|
|
|
skyline::audio::AudioOutState playbackState{skyline::audio::AudioOutState::Stopped};
|
2020-03-25 18:59:37 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Obtains new sample data from voices and mixes it together into the sample buffer
|
2020-04-17 23:35:31 +02:00
|
|
|
* @return The amount of samples present in the buffer
|
2020-03-25 18:59:37 +01:00
|
|
|
*/
|
|
|
|
void MixFinalBuffer();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Appends all released buffers with new mixed sample data
|
|
|
|
*/
|
|
|
|
void UpdateAudio();
|
|
|
|
|
|
|
|
public:
|
|
|
|
/**
|
2020-04-17 23:35:31 +02:00
|
|
|
* @param parameters The parameters to use for rendering
|
2020-03-25 18:59:37 +01:00
|
|
|
*/
|
2020-04-17 23:35:31 +02:00
|
|
|
IAudioRenderer(const DeviceState &state, ServiceManager &manager, AudioRendererParameters ¶meters);
|
2020-03-25 18:59:37 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Closes the audio track
|
|
|
|
*/
|
|
|
|
~IAudioRenderer();
|
|
|
|
|
|
|
|
/**
|
2020-09-28 12:05:17 +02:00
|
|
|
* @brief Returns the sample rate
|
|
|
|
* @url https://switchbrew.org/wiki/Audio_services#GetSampleRate
|
2020-03-25 18:59:37 +01:00
|
|
|
*/
|
2020-09-03 20:43:52 +02:00
|
|
|
Result GetSampleRate(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
2020-03-25 18:59:37 +01:00
|
|
|
|
|
|
|
/**
|
2020-09-28 12:05:17 +02:00
|
|
|
* @brief Returns the sample count
|
|
|
|
* @url https://switchbrew.org/wiki/Audio_services#GetSampleCount
|
2020-03-25 18:59:37 +01:00
|
|
|
*/
|
2020-09-03 20:43:52 +02:00
|
|
|
Result GetSampleCount(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
2020-03-25 18:59:37 +01:00
|
|
|
|
|
|
|
/**
|
2020-09-28 12:05:17 +02:00
|
|
|
* @brief Returns the number of mix buffers
|
|
|
|
* @url https://switchbrew.org/wiki/Audio_services#GetMixBufferCount
|
2020-03-25 18:59:37 +01:00
|
|
|
*/
|
2020-09-03 20:43:52 +02:00
|
|
|
Result GetMixBufferCount(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
2020-03-25 18:59:37 +01:00
|
|
|
|
|
|
|
/**
|
2020-09-28 12:05:17 +02:00
|
|
|
* @brief Returns the state of the renderer
|
|
|
|
* @url https://switchbrew.org/wiki/Audio_services#GetAudioRendererState (stubbed)?
|
2020-03-25 18:59:37 +01:00
|
|
|
*/
|
2020-09-03 20:43:52 +02:00
|
|
|
Result GetState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
2020-03-25 18:59:37 +01:00
|
|
|
|
|
|
|
/**
|
2020-09-28 12:05:17 +02:00
|
|
|
* @brief Updates the audio renderer state and appends new data to playback buffers
|
|
|
|
*/
|
2020-09-03 20:43:52 +02:00
|
|
|
Result RequestUpdate(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
2020-03-25 18:59:37 +01:00
|
|
|
|
|
|
|
/**
|
2020-09-28 12:05:17 +02:00
|
|
|
* @brief Start the audio stream from the renderer
|
|
|
|
*/
|
2020-09-03 20:43:52 +02:00
|
|
|
Result Start(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
2020-03-25 18:59:37 +01:00
|
|
|
|
|
|
|
/**
|
2020-09-28 12:05:17 +02:00
|
|
|
* @brief Stop the audio stream from the renderer
|
|
|
|
*/
|
2020-09-03 20:43:52 +02:00
|
|
|
Result Stop(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
2020-03-25 18:59:37 +01:00
|
|
|
|
|
|
|
/**
|
2020-09-28 12:05:17 +02:00
|
|
|
* @brief Returns a handle to the sample release KEvent
|
|
|
|
*/
|
2020-09-03 20:43:52 +02:00
|
|
|
Result QuerySystemEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
|
2020-09-21 12:04:26 +02:00
|
|
|
|
|
|
|
SERVICE_DECL(
|
|
|
|
SFUNC(0x0, IAudioRenderer, GetSampleRate),
|
|
|
|
SFUNC(0x1, IAudioRenderer, GetSampleCount),
|
|
|
|
SFUNC(0x2, IAudioRenderer, GetMixBufferCount),
|
|
|
|
SFUNC(0x3, IAudioRenderer, GetState),
|
|
|
|
SFUNC(0x4, IAudioRenderer, RequestUpdate),
|
|
|
|
SFUNC(0x5, IAudioRenderer, Start),
|
|
|
|
SFUNC(0x6, IAudioRenderer, Stop),
|
|
|
|
SFUNC(0x7, IAudioRenderer, QuerySystemEvent),
|
|
|
|
SFUNC(0xA, IAudioRenderer, RequestUpdate)
|
|
|
|
)
|
2020-03-25 18:59:37 +01:00
|
|
|
};
|
|
|
|
}
|
2020-01-24 23:04:16 +01:00
|
|
|
}
|