summaryrefslogtreecommitdiffstats
path: root/src/audio_core/adsp/apps/audio_renderer/audio_renderer.h
blob: 85874d88ac8d7f84c20956e4c939d46128950520 (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
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#include <array>
#include <memory>
#include <thread>

#include "audio_core/adsp/apps/audio_renderer/command_buffer.h"
#include "audio_core/adsp/apps/audio_renderer/command_list_processor.h"
#include "audio_core/adsp/mailbox.h"
#include "common/common_types.h"
#include "common/polyfill_thread.h"
#include "common/reader_writer_queue.h"
#include "common/thread.h"

namespace Core {
class System;
} // namespace Core

namespace AudioCore {
namespace Sink {
class Sink;
}

namespace ADSP::AudioRenderer {

enum Message : u32 {
    Invalid = 0,
    MapUnmap_Map = 1,
    MapUnmap_MapResponse = 2,
    MapUnmap_Unmap = 3,
    MapUnmap_UnmapResponse = 4,
    MapUnmap_InvalidateCache = 5,
    MapUnmap_InvalidateCacheResponse = 6,
    MapUnmap_Shutdown = 7,
    MapUnmap_ShutdownResponse = 8,
    InitializeOK = 22,
    RenderResponse = 32,
    Render = 42,
    Shutdown = 52,
};

/**
 * The AudioRenderer application running on the ADSP.
 */
class AudioRenderer {
public:
    explicit AudioRenderer(Core::System& system, Sink::Sink& sink);
    ~AudioRenderer();

    /**
     * Start the AudioRenderer.
     *
     * @param mailbox The mailbox to use for this session.
     */
    void Start();

    /**
     * Stop the AudioRenderer.
     */
    void Stop();

    void Signal();
    void Wait();

    void Send(Direction dir, u32 message);
    u32 Receive(Direction dir);

    void SetCommandBuffer(s32 session_id, CpuAddr buffer, u64 size, u64 time_limit,
                          u64 applet_resource_user_id, bool reset) noexcept;
    u32 GetRemainCommandCount(s32 session_id) const noexcept;
    void ClearRemainCommandCount(s32 session_id) noexcept;
    u64 GetRenderingStartTick(s32 session_id) const noexcept;

private:
    /**
     * Main AudioRenderer thread, responsible for processing the command lists.
     */
    void Main(std::stop_token stop_token);

    /**
     * Creates the streams which will receive the processed samples.
     */
    void CreateSinkStreams();

    /// Core system
    Core::System& system;
    /// The output sink the AudioRenderer will send samples to
    Sink::Sink& sink;
    /// The active mailbox
    Mailbox mailbox;
    /// Main thread
    std::jthread main_thread{};
    /// The current state
    std::atomic<bool> running{};
    /// Shared memory of input command buffers, set by host, read by DSP
    std::array<CommandBuffer, MaxRendererSessions> command_buffers{};
    /// The command lists to process
    std::array<CommandListProcessor, MaxRendererSessions> command_list_processors{};
    /// The streams which will receive the processed samples
    std::array<Sink::SinkStream*, MaxRendererSessions> streams{};
    /// CPU Tick when the DSP was signalled to process, uses time rather than tick
    u64 signalled_tick{0};
};

} // namespace ADSP::AudioRenderer
} // namespace AudioCore