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-02 21:19:34 +01:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <kernel/types/KEvent.h>
|
|
|
|
#include "common.h"
|
|
|
|
|
|
|
|
namespace skyline::audio {
|
|
|
|
/**
|
|
|
|
* @brief The AudioTrack class manages the buffers for an audio stream
|
|
|
|
*/
|
|
|
|
class AudioTrack {
|
|
|
|
private:
|
2020-04-22 19:02:27 +02:00
|
|
|
std::function<void()> releaseCallback; //!< Callback called when a buffer has been played
|
2020-04-17 23:23:38 +02:00
|
|
|
std::deque<BufferIdentifier> identifiers; //!< Queue of all appended buffer identifiers
|
2020-01-02 21:19:34 +01:00
|
|
|
|
2020-08-21 15:28:47 +02:00
|
|
|
u8 channelCount;
|
|
|
|
u32 sampleRate;
|
2020-01-02 21:19:34 +01:00
|
|
|
|
|
|
|
public:
|
2020-08-21 15:28:47 +02:00
|
|
|
CircularBuffer<i16, constant::SampleRate * constant::ChannelCount * 10> samples; //!< A circular buffer with all appended audio samples
|
2020-10-28 17:00:39 +01:00
|
|
|
std::mutex bufferLock; //!< Synchronizes appending to audio buffers
|
2020-01-02 21:19:34 +01:00
|
|
|
|
|
|
|
AudioOutState playbackState{AudioOutState::Stopped}; //!< The current state of playback
|
2020-08-21 15:28:47 +02:00
|
|
|
u64 sampleCounter{}; //!< A counter used for tracking when buffers have been played and can be released
|
2020-01-02 21:19:34 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @param channelCount The amount channels that will be present in the track
|
|
|
|
* @param sampleRate The sample rate to use for the track
|
|
|
|
* @param releaseCallback A callback to call when a buffer has been played
|
|
|
|
*/
|
2020-04-22 19:02:27 +02:00
|
|
|
AudioTrack(u8 channelCount, u32 sampleRate, const std::function<void()> &releaseCallback);
|
2020-01-02 21:19:34 +01:00
|
|
|
|
|
|
|
/**
|
2020-04-18 23:40:18 +02:00
|
|
|
* @brief Starts audio playback using data from appended buffers
|
2020-01-02 21:19:34 +01:00
|
|
|
*/
|
|
|
|
inline void Start() {
|
|
|
|
playbackState = AudioOutState::Started;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-09-28 12:05:17 +02:00
|
|
|
* @brief Stops audio playback, this waits for audio playback to finish before returning
|
2020-01-02 21:19:34 +01:00
|
|
|
*/
|
|
|
|
void Stop();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Checks if a buffer has been released
|
|
|
|
* @param tag The tag of the buffer to check
|
|
|
|
* @return True if the given buffer hasn't been released
|
|
|
|
*/
|
|
|
|
bool ContainsBuffer(u64 tag);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Gets the IDs of all newly released buffers
|
|
|
|
* @param max The maximum amount of buffers to return
|
|
|
|
* @return A vector containing the identifiers of the buffers
|
|
|
|
*/
|
|
|
|
std::vector<u64> GetReleasedBuffers(u32 max);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Appends audio samples to the output buffer
|
|
|
|
* @param tag The tag of the buffer
|
2020-08-21 15:28:47 +02:00
|
|
|
* @param buffer A span containing the source sample buffer
|
2020-01-02 21:19:34 +01:00
|
|
|
*/
|
2020-09-25 02:05:12 +02:00
|
|
|
void AppendBuffer(u64 tag, span<i16> buffer = {});
|
2020-01-02 21:19:34 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Checks if any buffers have been released and calls the appropriate callback for them
|
2020-08-21 15:28:47 +02:00
|
|
|
* @note bufferLock MUST be locked when calling this
|
2020-01-02 21:19:34 +01:00
|
|
|
*/
|
|
|
|
void CheckReleasedBuffers();
|
|
|
|
};
|
|
|
|
}
|