-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathAudio-subsystem.html
208 lines (208 loc) · 12.5 KB
/
Audio-subsystem.html
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>Audio-subsystem(7) - SerenityOS man pages</title>
<style>
html {
line-height: 1.5;
font-family: Georgia, serif;
font-size: 20px;
color: #1a1a1a;
background-color: #fdfdfd;
}
body {
margin: 0 auto;
max-width: 36em;
padding-left: 50px;
padding-right: 50px;
padding-top: 50px;
padding-bottom: 50px;
hyphens: auto;
word-wrap: break-word;
text-rendering: optimizeLegibility;
font-kerning: normal;
}
@media (max-width: 600px) {
body {
font-size: 0.9em;
padding: 1em;
}
}
@media print {
body {
background-color: transparent;
color: black;
font-size: 12pt;
}
p, h2, h3 {
orphans: 3;
widows: 3;
}
h2, h3, h4 {
page-break-after: avoid;
}
}
p {
margin: 1em 0;
}
a {
color: #1a1a1a;
}
a:visited {
color: #1a1a1a;
}
img {
max-width: 100%;
}
h1, h2, h3, h4, h5, h6 {
margin-top: 1.4em;
}
h5, h6 {
font-size: 1em;
font-style: italic;
}
h6 {
font-weight: normal;
}
ol, ul {
padding-left: 1.7em;
margin-top: 1em;
}
li > ol, li > ul {
margin-top: 0;
}
blockquote {
margin: 1em 0 1em 1.7em;
padding-left: 1em;
border-left: 2px solid #e6e6e6;
color: #606060;
}
code {
font-family: Menlo, Monaco, 'Lucida Console', Consolas, monospace;
font-size: 85%;
margin: 0;
}
pre {
margin: 1em 0;
overflow: auto;
}
pre code {
padding: 0;
overflow: visible;
}
.sourceCode {
background-color: transparent;
overflow: visible;
}
hr {
background-color: #1a1a1a;
border: none;
height: 1px;
margin: 1em 0;
}
table {
margin: 1em 0;
border-collapse: collapse;
width: 100%;
overflow-x: auto;
display: block;
font-variant-numeric: lining-nums tabular-nums;
}
table caption {
margin-bottom: 0.75em;
}
tbody {
margin-top: 0.5em;
border-top: 1px solid #1a1a1a;
border-bottom: 1px solid #1a1a1a;
}
th {
border-top: 1px solid #1a1a1a;
padding: 0.25em 0.5em 0.25em 0.5em;
}
td {
padding: 0.125em 0.5em 0.25em 0.5em;
}
header {
margin-bottom: 4em;
text-align: center;
}
#TOC li {
list-style: none;
}
#TOC a:not(:hover) {
text-decoration: none;
}
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
</style>
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
<![endif]-->
</head>
<body>
<img src="/banner.png" style="display: block; margin-left: auto; margin-right: auto; margin-bottom: 2em;">
<header id="title-block-header">
<h1 class="title">Audio-subsystem(7) - SerenityOS man pages</h1>
</header>
<h2 id="name"><a style="margin-right: 15px" href="#name">#</a>Name</h2>
<p>Overview of the SerenityOS audio subsystem, including a brief description of <a href="/man4/audio.html"><code>/dev/audio</code></a>, the AudioServer and their interfaces.</p>
<h2 id="description"><a style="margin-right: 15px" href="#description">#</a>Description</h2>
<p>(Note that familiarity with the basics of digitized audio, pulse code modulation (PCM), sample rate and bit depth is assumed.)</p>
<p>SerenityOS structures audio into three groups of responsibilities: The Kernel audio subsystem, including drivers that talk to hardware and expose (among others) the <code>/dev/audio</code> devices; the AudioServer that is responsible for talking to userland audio clients, mixing and processing audio, and controlling the hardware via the Kernel interfaces; the audio libraries LibAudio and LibDSP that facilitate easier handling of audio data for userland applications.</p>
<h3 id="sample-formats"><a style="margin-right: 15px" href="#sample-formats">#</a>Sample formats</h3>
<p>There are two primary sample formats used in SerenityOS. The <code>Sample</code> class in LibAudio provides the userland sample format. It contains 32-bit floating-point samples in multiple channels (currently 2; Stereo), which accurately represent mathematical audio signals between -1 and 1. The kernel audio interfaces use other audio formats described in <a href="/man4/audio.html">audio(4)</a> which userland need not worry about.</p>
<h3 id="audioserver"><a style="margin-right: 15px" href="#audioserver">#</a>AudioServer</h3>
<p>AudioServer is responsible for handling userland audio clients and talking to the hardware. For this reason, no userland application should ever need to write to a device in <code>/dev/audio</code> directly, except for special cases in which AudioServer is not present.</p>
<p>As with all system servers, AudioServer provides an IPC interface on <code>/tmp/session/%sid/portal/audio</code>, with <code>%sid</code> being the current login session id. For specifics on how to talk to AudioServer, the IPC interface specifications are the best source of information. For controlling mixer functionality, clients have the ability to obtain and change their own volume.</p>
<p>Userland audio transmission happens via the AudioQueue. This is a shared memory circular queue which supports concurrent lock-free writing and reading. The queue is created by the audio client and its shared memory file descriptor sent to the audio server. In order to use this queue, an audio application needs to split up its audio data into atomic chunks that can then be provided to the queue. The application might need to wait around until the queue is empty in order to write to it. For these reasons, there's a utility API in LibAudio which allows audio applications to send off a large chunk of samples which get progressively sent in the background.</p>
<p>On the server → client side, AudioServer has "event" calls that the client receives. These are various state changes relating to the client itself. Note that there are no "periodic" event calls relating to regular audio playback, such as a "buffer played" callback.</p>
<h4 id="audiomanagerserver"><a style="margin-right: 15px" href="#audiomanagerserver">#</a>AudioManagerServer</h4>
<p>AudioServer has a second IPC interface, the management interface. While the regular interface is intended for clients to be able to play audio and control the parameters of that playback, the management interface provides functionality to control AudioServer's internal behavior, such as output setup, global mixing control, as well as accessing other client's mixing properties like mute and volume. In most cases, a client needs to either access the client interface for playing audio, or the management interface for managing AudioServer itself; but not both at the same time.</p>
<h3 id="libraries"><a style="margin-right: 15px" href="#libraries">#</a>Libraries</h3>
<p>There are two complementary audio libraries.</p>
<h4 id="libaudio"><a style="margin-right: 15px" href="#libaudio">#</a>LibAudio</h4>
<p>LibAudio is the baseline audio library that provides common audio abstractions, such as audio buffers and samples. Additionally, an important feature of LibAudio are the Loaders and Writers. The Loader class provides a multitude of audio formats (for example: WAV, FLAC, and MP3), can auto-detect the format of a file or stream and abstracts away the low-level complications of parsing and reading these formats. The Encoder class provides an abstraction over exporting audio in specific formats (for example: WAV and FLAC) to disk.</p>
<h4 id="libdsp"><a style="margin-right: 15px" href="#libdsp">#</a>LibDSP</h4>
<p>LibDSP is the digital signal processing library. It provides structures for audio editing programs, such as tracks and clips, while both dealing with MIDI data and sample data. More important is the Processor system, which allows synthesizers, samplers, sequencers, effects, etc. to be written with a common interface and be combined into chains for unlimited DSP (and musical) potential. The ProcessorParameters provide an interface for changing processor parameters programmatically or through a UI.</p>
<p>The following class diagram outlines the structure of LibDSP pertaining to DAW-like applications:</p>
<p><img src="/LibDSP_classes.svg" alt="LibDSP class diagram" /></p>
<p>LibDSP was started to support development efforts in Piano, but it is intended as a general-purpose audio processing library, building on the groundwork from LibAudio. Therefore, users of LibDSP must be familiar with LibAudio classes and concepts, as they are used extensively in LibDSP.</p>
<p>LibDSP also contains a collection of general signal processing primitives, such as windowing functions and resamplers.</p>
<h3 id="applications"><a style="margin-right: 15px" href="#applications">#</a>Applications</h3>
<p>This is a non-exhaustive list of applications that use audio. Most of these follow the good practices laid out in this manual page and may serve as a template for new audio applications.</p>
<ul>
<li><strong>Piano</strong> is a sequencer/tracker and synthesizer.</li>
<li><a href="/man1/aplay.html"><strong>aplay</strong></a> is a command line audio file playback utility.</li>
<li><strong>SoundPlayer</strong> is a UI audio file player with extra features such as playlist support and audio visualizations.</li>
<li><a href="/man1/asctl.html"><strong>asctl</strong></a> is a command line audio server control utility.</li>
<li><strong>Applets/Audio</strong> (AudioApplet) is a taskbar applet for setting audio parameters through a UI.</li>
<li>The <a href="/man1/Applications/Browser.html">Browser</a> can play audio on websites.</li>
</ul>
<h3 id="volume"><a style="margin-right: 15px" href="#volume">#</a>Volume</h3>
<p>Audio volume is more complicated than just multiplying a (digital or analog) audio signal with a percentage volume value. As the human hearing is logarithmic, volume changes also need to be logarithmic. An excellent article on the topic can be found <a href="https://www.dr-lex.be/info-stuff/volumecontrols.html">here</a>.</p>
<p>For the SerenityOS audio system, the following applies: Userland applications and libraries that do their own volume changes need to be aware of the nature of volume. LibAudio provides utility functions for correctly handling volume, so these are to be used whenever applicable. For AudioServer, main and per-client volume is already handled correctly; to the outside, volume is linear between 0 and 1.</p>
<p>For example: A program may set its client volume to 0.5 and the audio will be perceived as half as loud by a human. However, if the program wishes to change the volume beforehand, it needs to use logarithmic scaling, for example with LibAudio's built-in functionality.</p>
<h3 id="sample-rate"><a style="margin-right: 15px" href="#sample-rate">#</a>Sample rate</h3>
<p>SerenityOS's audio system uses a variety of sample rates in different layers of the audio stack. For a client, one sample rate is relevant: The client's own sample rate. Audio samples passed to AudioServer are interpreted at the client sample rate, which may be changed at any time via a dedicated IPC API. The default sample rate is the current hardware sample rate, but clients are recommended to change the sample rate to whatever's most convenient for them, since this reduces the amount of resampling to be performed and therefore increases the audio quality. AudioServer uses independent hardware sample rates for audio devices, which may be configured via the management interface.</p>
<h2 id="files"><a style="margin-right: 15px" href="#files">#</a>Files</h2>
<ul>
<li><a href="/man4/audio.html">/dev/audio</a></li>
<li>AudioApplet and AudioServer have settings which are managed by ConfigServer.</li>
<li><code>/tmp/session/%sid/portal/audio</code>: AudioServer's client IPC socket</li>
</ul>
<h2 id="see-also"><a style="margin-right: 15px" href="#see-also">#</a>See also</h2>
<ul>
<li><a href="/man1/asctl.html">asctl</a></li>
<li><a href="/man1/aplay.html">aplay</a></li>
</ul>
</body>
</html>