Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
stenzek
GitHub Repository: stenzek/duckstation
Path: blob/master/src/util/audio_stream.cpp
7361 views
1
// SPDX-FileCopyrightText: 2019-2025 Connor McLaughlin <[email protected]>
2
// SPDX-License-Identifier: CC-BY-NC-ND-4.0
3
4
#include "audio_stream.h"
5
#include "translation.h"
6
7
#include "common/error.h"
8
9
AudioStream::AudioStream() = default;
10
11
AudioStream::~AudioStream() = default;
12
13
AudioStream::DeviceInfo::DeviceInfo(std::string name_, std::string display_name_, u32 minimum_latency_)
14
: name(std::move(name_)), display_name(std::move(display_name_)), minimum_latency_frames(minimum_latency_)
15
{
16
}
17
18
AudioStream::DeviceInfo::~DeviceInfo() = default;
19
20
static constexpr const std::array s_backend_names = {
21
"Null",
22
#ifndef __ANDROID__
23
"Cubeb",
24
"SDL",
25
#else
26
"AAudio",
27
"OpenSLES",
28
#endif
29
};
30
static constexpr const std::array s_backend_display_names = {
31
TRANSLATE_DISAMBIG_NOOP("Settings", "Null (No Output)", "AudioBackend"),
32
#ifndef __ANDROID__
33
TRANSLATE_DISAMBIG_NOOP("Settings", "Cubeb", "AudioBackend"),
34
TRANSLATE_DISAMBIG_NOOP("Settings", "SDL", "AudioBackend"),
35
#else
36
"AAudio",
37
"OpenSL ES",
38
#endif
39
};
40
41
std::optional<AudioBackend> AudioStream::ParseBackendName(const char* str)
42
{
43
int index = 0;
44
for (const char* name : s_backend_names)
45
{
46
if (std::strcmp(name, str) == 0)
47
return static_cast<AudioBackend>(index);
48
49
index++;
50
}
51
52
return std::nullopt;
53
}
54
55
const char* AudioStream::GetBackendName(AudioBackend backend)
56
{
57
return s_backend_names[static_cast<int>(backend)];
58
}
59
60
const char* AudioStream::GetBackendDisplayName(AudioBackend backend)
61
{
62
return Host::TranslateToCString("AudioStream", s_backend_display_names[static_cast<int>(backend)]);
63
}
64
65
u32 AudioStream::FramesToMS(u32 sample_rate, u32 frames)
66
{
67
return (frames * 1000) / sample_rate;
68
}
69
70
std::vector<std::pair<std::string, std::string>> AudioStream::GetDriverNames(AudioBackend backend)
71
{
72
std::vector<std::pair<std::string, std::string>> ret;
73
switch (backend)
74
{
75
#ifndef __ANDROID__
76
case AudioBackend::Cubeb:
77
ret = GetCubebDriverNames();
78
break;
79
#endif
80
81
default:
82
break;
83
}
84
85
return ret;
86
}
87
88
std::vector<AudioStream::DeviceInfo> AudioStream::GetOutputDevices(AudioBackend backend, std::string_view driver,
89
u32 sample_rate)
90
{
91
std::vector<AudioStream::DeviceInfo> ret;
92
switch (backend)
93
{
94
#ifndef __ANDROID__
95
case AudioBackend::Cubeb:
96
ret = GetCubebOutputDevices(driver, sample_rate);
97
break;
98
#endif
99
100
default:
101
break;
102
}
103
104
return ret;
105
}
106
107
std::unique_ptr<AudioStream> AudioStream::CreateStream(AudioBackend backend, u32 sample_rate, u32 channels,
108
u32 output_latency_frames, bool output_latency_minimal,
109
std::string_view driver_name, std::string_view device_name,
110
AudioStreamSource* source, bool auto_start, Error* error)
111
{
112
switch (backend)
113
{
114
#ifndef __ANDROID__
115
case AudioBackend::Cubeb:
116
return CreateCubebAudioStream(sample_rate, channels, output_latency_frames, output_latency_minimal, driver_name,
117
device_name, source, auto_start, error);
118
119
case AudioBackend::SDL:
120
return CreateSDLAudioStream(sample_rate, channels, output_latency_frames, output_latency_minimal, source,
121
auto_start, error);
122
#else
123
case AudioBackend::AAudio:
124
return CreateAAudioAudioStream(sample_rate, channels, output_latency_frames, output_latency_minimal, source,
125
auto_start, error);
126
127
case AudioBackend::OpenSLES:
128
return CreateOpenSLESAudioStream(sample_rate, channels, output_latency_frames, output_latency_minimal, source,
129
auto_start, error);
130
#endif
131
132
default:
133
Error::SetStringView(error, "Unknown audio backend.");
134
return nullptr;
135
}
136
}
137
138