summaryrefslogtreecommitdiffstats
path: root/src/audio_core/out/audio_out.h
blob: 946f345c6196a2eb0f8e67f920dc7aca211da6c1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
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() const;

    /**
     * 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) const;

    /**
     * Get the maximum number of buffers.
     *
     * @return The maximum number of buffers.
     */
    u32 GetBufferCount() const;

    /**
     * Get the total played sample count for this audio out.
     *
     * @return The played sample count.
     */
    u64 GetPlayedSampleCount() const;

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