Nedko Arnaudov 2023-12-21 17:18:36 +02:00
parent 374a13403a
commit b8050e299d
1 changed files with 770 additions and 0 deletions

770
jack1-design.html Normal file
View File

@ -0,0 +1,770 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<!--Converted with jLaTeX2HTML 2002 (1.62) JA patch-1.4
patched version by: Kenshi Muto, Debian Project.
LaTeX2HTML 2002 (1.62),
original version by: Nikos Drakos, CBLU, University of Leeds
* revised and updated by: Marcus Hennecke, Ross Moore, Herb Swan
* with significant contributions from:
Jens Lippmann, Marek Rouchal, Martin Wilck and others -->
<html>
<head><script type="text/javascript" src="https://web-static.archive.org/_static/js/bundle-playback.js?v=t1Bf4PY_" charset="utf-8"></script>
<script type="text/javascript" src="https://web-static.archive.org/_static/js/wombat.js?v=txqj7nKC" charset="utf-8"></script>
<script>window.RufflePlayer=window.RufflePlayer||{};window.RufflePlayer.config={"autoplay":"on","unmuteOverlay":"hidden"};</script>
<script type="text/javascript" src="https://web-static.archive.org/_static/js/ruffle.js"></script>
<script type="text/javascript">
__wm.init("https://web.archive.org/web");
__wm.wombat("http://jackit.sourceforge.net:80/docs/design/","20080221160709","https://web.archive.org/","web","https://web-static.archive.org/_static/",
"1203610029");
</script>
<link rel="stylesheet" type="text/css" href="https://web-static.archive.org/_static/css/banner-styles.css?v=S1zqJCYt" />
<link rel="stylesheet" type="text/css" href="https://web-static.archive.org/_static/css/iconochive.css?v=qtvMKcIJ" />
<!-- End Wayback Rewrite JS Include -->
<title>JACK Design Documentation</title>
<meta name="description" content="JACK Design Documentation">
<meta name="keywords" content="design">
<meta name="resource-type" content="document">
<meta name="distribution" content="global">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Generator" content="jLaTeX2HTML v2002 JA patch-1.4">
<meta http-equiv="Content-Style-Type" content="text/css">
<link rel="STYLESHEET" href="/web/20080221160709cs_/http://jackit.sourceforge.net/docs/design/design.css">
</head>
<body>
<h1 align="CENTER">JACK Design Documentation</h1>
<p align="CENTER"><strong>Kai Vehmanen
<br>Andy Wingo
<br>Paul Davis</strong></p>
<p align="CENTER"><strong>27 August 2003</strong></p>
<p>
<br>
<h2><a name="SECTION00100000000000000000">
Contents</a>
</h2>
<!--Table of Contents-->
<ul>
<li><a name="tex2html54" href="design.html">General</a>
<ul>
<li><a name="tex2html55" href="design.html#SECTION00210000000000000000">Introduction</a>
<li><a name="tex2html56" href="design.html#SECTION00220000000000000000">Document Scope and Status</a>
<li><a name="tex2html57" href="design.html#SECTION00230000000000000000">What we're aiming at--an example use case</a>
<li><a name="tex2html58" href="design.html#SECTION00240000000000000000">Document history</a>
</ul><br>
<li><a name="tex2html59" href="design.html#SECTION00300000000000000000">Design aims</a>
<ul>
<li><a name="tex2html60" href="design.html#SECTION00310000000000000000">Constraints and requirements</a>
</ul><br>
<li><a name="tex2html61" href="design.html#SECTION00400000000000000000">Problem Description</a>
<ul>
<li><a name="tex2html62" href="design.html#SECTION00410000000000000000">Key Issues in Audio Application design</a>
<ul>
<li><a name="tex2html63" href="design.html#SECTION00411000000000000000">Realtime Requirements Imposed by Audio Hardware</a>
<li><a name="tex2html64" href="design.html#SECTION00412000000000000000">Keeping the Audio Device Buffers Full</a>
<li><a name="tex2html65" href="design.html#SECTION00413000000000000000">Scheduling and System Calls</a>
</ul>
<li><a name="tex2html66" href="design.html#SECTION00420000000000000000">Problems in Combining Audio Software Components</a>
<ul>
<li><a name="tex2html67" href="design.html#SECTION00421000000000000000">Overview</a>
<li><a name="tex2html68" href="design.html#SECTION00422000000000000000">Multi-Process Approach</a>
<li><a name="tex2html69" href="design.html#SECTION00423000000000000000">Scheduling of Clients in Multi-Process Scenario</a>
<li><a name="tex2html70" href="design.html#SECTION00424000000000000000">Single-Process Approach</a>
</ul>
</ul><br>
<li><a name="tex2html71" href="design.html#SECTION00500000000000000000">Architecture Description</a>
<ul>
<li><a name="tex2html72" href="design.html#SECTION00510000000000000000">Overview</a>
<li><a name="tex2html73" href="design.html#SECTION00520000000000000000">Modules</a>
<ul>
<li><a name="tex2html74" href="design.html#SECTION00521000000000000000">Jackd - the JACK Server</a>
<li><a name="tex2html75" href="design.html#SECTION00522000000000000000">Libjack - the JACK Client Interface</a>
</ul>
</ul><br>
<li><a name="tex2html76" href="design.html#SECTION00600000000000000000">Implementation Notes to Developers</a>
<ul>
<li><a name="tex2html77" href="design.html#SECTION00610000000000000000">Real-Time Considerations When Implementing JACK Clients</a>
<ul>
<li><a name="tex2html78" href="design.html#SECTION00611000000000000000">Implementing the Callbacks</a>
<li><a name="tex2html79" href="design.html#SECTION00612000000000000000">Communication Between Application Threads</a>
</ul>
<li><a name="tex2html80" href="design.html#SECTION00620000000000000000">JACK Graphs and Subgraphs</a>
</ul><br>
<li><a name="tex2html81" href="design.html#SECTION00700000000000000000">Bibliography</a>
<li><a name="tex2html82" href="design.html#SECTION00800000000000000000">Appendices</a>
<ul>
<li><a name="tex2html83" href="design.html#SECTION00810000000000000000">Source code</a>
</ul><br>
<li><a name="tex2html84" href="design.html#SECTION00900000000000000000">About this document ...</a>
</ul>
<!--End of Table of Contents-->
<p>
<p>
<h1><a name="SECTION00200000000000000000">
General</a>
</h1>
<p>
<h1><a name="SECTION00210000000000000000">
Introduction</a>
</h1>
<p>
In April 2001, people on the <tt>linux-audio-dev</tt>[<a href="design.html#lad">9</a>] mailing list began
to see the need for system that would allow high-bandwidth, low-latency,
sample-synchronized data transfer between independent audio applications. Such a
system would necessarily offer robust performance, even on highly stressed
systems. Discussions on the nature of the project, nicknamed LAAGA[<a href="design.html#laaga">8</a>]
(the ``Linux Audio Application Glue API''), continued until the fall. A sample
implementation, derived from the source code of Ardour[<a href="design.html#ardour">3</a>], came to be
known as Jack, an acronym for ``Jack Audio Connection Kit''. Jack has largely
achieved the goals of LAAGA, although it is still under development. This
document offers a retrospective look at the problems facing audio development on
Linux, and was initially written by Kai Vehmanen for LAAGA. It has been adapted
with his permission.
<p>
<h1><a name="SECTION00220000000000000000">
Document Scope and Status</a>
</h1>
<p>
It is important to note that this document is not complete nor it is
100% accurate description of JACK's design. For a complete view you
have to combine information from this document, source code, Doxygen
documentation embedded to the sources and jackit-devel mailing list
archives. This is not an optimal situation, but reflects the
distributed nature of JACK development. In any case, this document
still provides lots of valuable information for your use.
<p>
<h1><a name="SECTION00230000000000000000">
What we're aiming at--an example use case</a>
</h1>
<p>
Let's say you are using a multitrack recorder/mixer. It's working nicely on your
Linux box. You can record and mix without problems. But now you've found a
couple of interesting new apps, let's say a software synth and a virtual drum
machine. They seem to work great, so why not use them in your recordings? But
how to connect them to the multitrack recorder?
<p>
Now that's the big problem, because you can't. Or at least not in a easy,
reliable way. This is the problem JACK aims to resolve.
<p>
<h1><a name="SECTION00240000000000000000">
Document history</a>
</h1>
<p>
<ul>
<li>27.08.2003 - Added Paul's explanation of graphs and subgraphs to
the implementation notes chapter, link to J&#246;rn's
JACK schematic diagram and a few viewcvs weblinks.
Reorganized the problem description section a bit.
Added the ``Document Scope and Status'' note. <i>Kai Vehmanen</i>
</li>
<li>29.01.2003 - Added lots of entries to the bibliography. <i>Kai Vehmanen</i>
</li>
<li>29.01.2003 - Added the ``Architecture Description'' section. <i>Kai Vehmanen</i>
</li>
<li>29.01.2003 - Added the ``Implementation Notes'' section. <i>Kai Vehmanen</i>
</li>
<li>04.01.2002 - Various updates. <i>Andy Wingo</i>
</li>
<li>16.12.2001 - Typo fixes. <i>Andy Wingo</i>
</li>
<li>16.12.2001 - Initial version. <i>Kai Vehmanen</i>
</li>
</ul>
<p>
<h1><a name="SECTION00300000000000000000">
Design aims</a>
</h1>
<p>
<h1><a name="SECTION00310000000000000000">
Constraints and requirements</a>
</h1>
<p>
Following is a list of constraints and requirements that JACK aims to fulfill.
<p>
<ol>
<li>Jack should allow streaming of low-latency, high-bandwidth data between
independent applications.
</li>
<li>Although not a requirement, Jack should support any streaming data type,
not just audio.
</li>
<li>In an active Jack setup, there will be one server and one or more Jack
plugins. It will be possible to run multiple Jack servers, but each server will
form an independent Jack setup. Jack will not define any interfaces between Jack
servers.
</li>
<li>Applications connected using Jack may have their own graphical interfaces.
Jack will not make any specifications as to different GUI toolkits or
libraries. As a consequence of this requirement, different parts of a
running Jack setup may be spread across multiple processes.
</li>
<li>Jack should provide full, sample accurate synchronation (ie. totally
synchronous execution of all client plugins)
</li>
<li>To represent audio data, Jack should use 32 bit IEEE floats,
normalized to value range [-1,1].
</li>
<li>Only noninterleaved audio streams will be supported.
</li>
<li>One Jack client may consume or produce multiple data streams.
</li>
<li>The Jack API should be specified in ANSI C. There are no restrictions on
how servers and clients are to be implemented.
</li>
<li>It should be possible to connect already running applications.
</li>
<li>It should be possible to add or remove Jack clients while the server is
running.
</li>
</ol>
<p>
<h1><a name="SECTION00400000000000000000">
Problem Description</a>
</h1>
<p>
<h1><a name="SECTION00410000000000000000">
Key Issues in Audio Application design</a>
</h1>
<p>
<h2><a name="SECTION00411000000000000000">
Realtime Requirements Imposed by Audio Hardware</a>
</h2>
<p>
Basic constraints that affect audio application design come from the audio
hardware level. At some point in time, the soundcard is started. After this, the
audio application must transfer audio data to the device at a constant speed in
order to avoid buffer underruns and overflows. This behaviour is sometimes
described as running at real-time speed. Some headroom is available, as all
soundcards have room for at least a few audio blocks. Here the term block refers
to the amount of data processed per one hardware interrupt. The soundcard's
driver software usually implements another layer of buffering. But every time we
add buffering, independently from the implementation level, we are also adding
delays to the signal path.
<p>
<h2><a name="SECTION00412000000000000000">
Keeping the Audio Device Buffers Full</a>
</h2>
<p>
But this headroom is not necessarily enough. In modern, pre-emptive operating
systems, a normal user application doesn't have exclusive access to hardware
resources. This means that the application gets to run at certain, not
necessarily even, intervals. From audio application's point of view, it's
critical that it gets a chance to communicate with the audio device often
enough. Like all applications with real-time restrictions, audio applications
can't do much transfer in advance, and they can't lag much behind.
<p>
<h2><a name="SECTION00413000000000000000">
Scheduling and System Calls</a>
</h2>
<p>
Most operating systems that implement the POSIX [<a href="design.html#posix1003.1">11</a>] specification
provide means to run processes with so-called real-time scheduling. In practice
this means that once a process gets to run, it can keep the processor until
either it is blocked by an I/O request, it loses the processor to a higher
priority real-time process, a hardware interrupt occurs, or it willingly gives
the processor up.
<p>
One very efficient way of implementing audio applications is having one
real-time scheduled thread or a process that handles all soundcard I/O. But even
with this approach, there are a number of pitfalls. Allocating memory with
standard system services is not a deterministic operation. In other words it's
not predictable how much one allocation takes time as it's not a direct function
of the amount of requested memory.
<p>
The same applies to many system services such as accessing files, network
devices, and so on. Implementing the audio thread needs very careful planning.
When the audio thread needs to communicate with other software modules, various
nonblocking techniques like read-writer locks [<a href="design.html#readwriterlocks">12</a>] are
required. Most of these rely on atomic operations and shared memory.
<p>
<h1><a name="SECTION00420000000000000000">
Problems in Combining Audio Software Components</a>
</h1>
<p>
<h2><a name="SECTION00421000000000000000">
Overview</a>
</h2>
<p>
Modularization is a central concept in computer science. It's easier to handle
complex problems by dividing them first into smaller components. Small
components have also proved to be powerful building blocks. Good examples of
this are the standard UNIX text processing tools. They are simple, yet powerful.
<p>
The same approach should also be useful for processing audio data. In practice,
however, this has proved to be very difficult to implement. There are numerous
audio servers and application frameworks available, but nearly all them have
serious problems when it comes to latency and bandwidth considerations. The
basic problem is that all common mechanisms for process-to-process communication
(IPC) involve possibly blocking system calls. This is especially true for
network operations. These problems can be avoided to some degree by increasing
the buffersizes. But this will also increase the signal path delay. And the more
bandwidth is needed, the more restricting this limitation becomes.
<p>
For instance, if some client application offers its user a possiblity to
interact in real-time with the audio generation process, the delay in audio
output must not reach 5ms. After this limit, some people start noticing a delay
between actions and the resulting audio. If the processed signal is to be
combined with the original signal, a 'comb filter' effect will begin to be heard
at latencies above about 3 ms. In summary, the scheduling requirements for a
low-latency system are quite tight, which requires a solid design from the
beginning.
<p>
<h2><a name="SECTION00422000000000000000">
Multi-Process Approach</a>
</h2>
<p>
Now if we have multiple processes (programs) producing audio data, and one
process that is handling all communication with the audio hardware,
then we need some form of inter-process communication (IPC). There are
however two possible problems with this approach: process switching
overhead and performance problems in IPC mechanisms.
<p>
Let's say that we have 5 processes producing audio, and one of them handles the
audio hardware I/O. To avoid buffer underruns, during one hardware interrupt
cycle, all 5 processes must have enough processor time to produce the next block
of audio data. The more processes are involved, the higher the process switching
overhead becomes. It also becomes increasingly difficult to adjust the relative
priorities of different processes. If only one process fails to produce its
audio fragment, a buffer underrun can occur.
<p>
In the above it is assumed that transferring data between processes doesn't have
any extra cost. This is of course not true. All IPC mechanisms cause some
overhead, although some of them (especially shared memory) are very efficient.
Here the cost comes primarily from process synchronation.
<p>
One way to avoid the possible IPC troubles is to locate all audio producing code
into the audio engine process (audio engine refers to the process, or more
specifically the thread, responsible for audio hardware i/o). Clients could be
loaded as plugins into the engine. However, this approach has its own problems.
<p>
<h2><a name="SECTION00423000000000000000">
Scheduling of Clients in Multi-Process Scenario</a>
</h2>
<p>
If we choose to go with all the multi-process approach, where all
clients are out-of-process, we have another problem to contend with.
Each client will be told by the engine when it is time to operate on
its data. If the client then ``returns'' to the engine after every
process cycle, many context switches will occur, causing increased latency or
possible dropouts. Clients will have to be notified of shared memory locations,
but this is not a big problem. The largest problem is how to communicate between
the server and the client. There are two choices on a POSIX system, signals and
polling on UNIX sockets.
<p>
<h2><a name="SECTION00424000000000000000">
Single-Process Approach</a>
</h2>
<p>
The biggest problem of this approach is the increased client side complexity.
Client applications must be divided into realtime critical (audio
producing/consuming) and non-realtime parts (user interfaces, network and file
i/o, etc). The critical parts are loaded to the server process as plugins, while
the non-critical part run in a separate lower priority process. Some kind of IPC
is also needed between the realtime and non-realtime parts of the client. To
make things even more difficult, care must be taken that this communication
never blocks the realtime critical process.
<p>
Another interesting question is how different types of applications can take
advantage of this plugin-based approach.
<p>
<p>
<p>
<h1><a name="SECTION00500000000000000000">
Architecture Description</a>
</h1>
<p>
<h1><a name="SECTION00510000000000000000">
Overview</a>
</h1>
<p>
<img align="BOTTOM" border="0" src="https://web.archive.org/web/20080221160709im_/http://jackit.sourceforge.net/docs/diagram/JACK-Diagram-screensize.png" alt="JACK-Diagram.png">
<p>
<h1><a name="SECTION00520000000000000000">
Modules</a>
</h1>
<h2><a name="SECTION00521000000000000000">
Jackd - the JACK Server</a>
</h2>
<p>
<a name="tex2html1" href="https://web.archive.org/web/20080221160709/http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/jackit/jack/jackd/jackd.c?rev=HEAD&amp;content-type=text/vnd.viewcvs-markup">jackd.c</a>
<p>
<h3><a name="SECTION00521100000000000000">
Engine Core</a>
</h3>
<p>
<a name="tex2html2" href="https://web.archive.org/web/20080221160709/http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/jackit/jack/jackd/engine.c?rev=HEAD&amp;content-type=text/vnd.viewcvs-markup">engine.c</a>
<p>
<h3><a name="SECTION00521200000000000000">
Driver Interface</a>
</h3>
<p>
<a name="tex2html3" href="https://web.archive.org/web/20080221160709/http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/jackit/jack/jack/driver.h?rev=HEAD&amp;content-type=text/vnd.viewcvs-markup">driver.h</a>
<p>
<h2><a name="SECTION00522000000000000000">
Libjack - the JACK Client Interface</a>
</h2>
<p>
<a name="tex2html4" href="https://web.archive.org/web/20080221160709/http://jackit.sourceforge.net/docs/reference/html/jack_8h.html">jack.h</a>
<p>
<h1><a name="SECTION00600000000000000000">
Implementation Notes to Developers</a>
</h1>
<p>
<h1><a name="SECTION00610000000000000000">
Real-Time Considerations When Implementing JACK Clients</a>
</h1>
<p>
<h2><a name="SECTION00611000000000000000">
Implementing the Callbacks</a>
</h2>
<p>
The jack_process() callback provided by each client is required
to be real-time safe. In other words its code must be deterministic
and not involve functions that might block for a long time. These
functions are for example malloc, free, printf, pthread_mutex_lock,
sleep, wait, poll, select, pthread_join, and pthread_cond_wait.
<p>
<h2><a name="SECTION00612000000000000000">
Communication Between Application Threads</a>
</h2>
<p>
As the jack_process() must not contain any blocking
function calls or other non-deterministic code, you have to be
extra careful when implementing communication between your
jack_process() callback and other application threads.
<p>
For a practical example, see the the source file capture_client.c
that is distributed along with the JACK package. It contains
one example of non-blocking communication.
<p>
<h1><a name="SECTION00620000000000000000">
JACK Graphs and Subgraphs</a>
</h1>
<p>
<i>Graphs</i> are an idea/abstraction that is widely used in
DSP programming.
<p>
A graph is a set of connected "nodes", each of which must be
"executed" on a periodic basis. In the case of JACK, the graph is made
up of JACK clients, and we need each one to have its process()
function called in a specific order. The connections between each node
may take any configuration whatsoever. JACK has to serialize the
execution of each client so that the connections represented by the
graph are honored (e.g. client A sends data to client B, so client A
should execute before client B).
<p>
Subgraphs are a JACK specific term that cover portions of the overall
graph. Specifically, a part of the serialized execution order bounded
by either of (i) one end of the serialized order or (ii) an in-process
client. Subgraphs are important in JACK because they represent
out-of-process clients that will drive the execution of the next
client in the subgraph. rather than switch to a client, then back to
the server, and so on, we instead arrange the subgraph so that each
client drives the execution of the next client till the last one
returns control to the server. This is *much* more efficient than the
out-and-back-per-client design.
<p>
So, a moderately complex graph might look like:
<p>
<pre>
A(I)
B(O) | subgraph
C(O) | one
D(I)
E(O) |
F(O) | subgraph
G(O) | two
</pre>
<p>
The (I) or (O) designates whether client A-G is in- or
out-of-process. In this case, our execution pattern is like this:
<p>
<pre>
A-&gt;process(); // direct function call
start subgraph one by telling B to call its process function
B tells C
C returns to the server
D-&gt;process(); // direct function call
start subgraph two by telling E to call its process function
E tells F
F tells G
G returns to the server.
</pre>
<p>
<h2><a name="SECTION00700000000000000000">
Bibliography</a>
</h2><dl compact><dd>
<p>
<p></p><dt><a name="alsa">1</a>
<dd>
Advanced Linux Sound Architecture,
<tt><a name="tex2html5" href="https://web.archive.org/web/20080221160709/http://www.alsa-project.org/">http://www.alsa-project.org</a></tt>, Nov. 2002.
<p>
<p></p><dt><a name="anderson95">2</a>
<dd>
Anderson, James H., Srikanth Ramamurthy and Kevin Jeffay,
Real-time Computing with Lock-Free Shared Objects,
<i>ACM Transactions on Computer Systems</i>, Volume 15, Number 2, pp. 134-165, May 1997,
<tt><a name="tex2html6" href="https://web.archive.org/web/20080221160709/http://citeseer.nj.nec.com/anderson95realtime.html">http://citeseer.nj.nec.com/anderson95realtime.html</a></tt>.
<p>
<p></p><dt><a name="ardour">3</a>
<dd>
Ardour,
<tt><a name="tex2html7" href="https://web.archive.org/web/20080221160709/http://ardour.sourceforge.net/">http://ardour.sourceforge.net/</a></tt>.
<p>
<p></p><dt><a name="carstens00">4</a>
<dd>
Carstens, Matthias,
<i>Low Latency Background: Buffer and Latency Jitter</i>,
RME Technical Info, 2002,
<tt><a name="tex2html8" href="https://web.archive.org/web/20080221160709/http://www.rme-audio.com/english/techinfo/lola/latec.htm">http://www.rme-audio.com/english/techinfo/lola/latec.htm</a></tt>.
<p>
<p></p><dt><a name="cheshire96">5</a>
<dd>
Cheshire, Stuart,
<i>Latency and Quest for Interactivity</i>,
White paper commissioned by Volpe Welty Asset Management, L.L.C., for the Synchronous Person-to-Person Interactive Computing Environments Meeting, San Francisco, November 1996,
<tt><a name="tex2html9" href="https://web.archive.org/web/20080221160709/http://www.stuartcheshire.org/papers/LatencyQuest.ps">http://www.stuartcheshire.org/papers/LatencyQuest.ps</a></tt>.
<p>
<p></p><dt><a name="fober02b">6</a>
<dd>
Fober, D., S. Letz, Y. Orlarey,
<i>Lock-Free Techniques for Concurrent Access to Shared Objects</i>,
Actes des Journ&#233;es d'Informatique Musicale JIM2002, pp. 143-150, Marseille, 2002.
<p>
<p></p><dt><a name="jack">7</a>
<dd>
JACK Audio Connection Kit web site,
<tt><a name="tex2html10" href="https://web.archive.org/web/20080221160709/http://jackit.sourceforge.net/">http://jackit.sourceforge.net</a></tt>, Nov. 2002.
<p>
<p></p><dt><a name="laaga">8</a>
<dd>
Linux Audio Application Glue API, <tt><a name="tex2html11" href="https://web.archive.org/web/20080221160709/http://eca.cx/laaga/">http://eca.cx/laaga/</a></tt>
<p>
<p></p><dt><a name="lad">9</a>
<dd>
Linux Audio Developers' Mailing List,
<tt><a name="tex2html12" href="https://web.archive.org/web/20080221160709/http://www.linuxdj.com/audio/lad/archive.php3">http://www.linuxdj.com/audio/lad/archive.php3</a></tt>, Nov. 2002.
<p>
<p></p><dt><a name="macmillan01">10</a>
<dd>
Macmillan Karl, Michael Droettboom and Ichiro Fujinaga,
<i>Audio latency measurements of desktop operating systems</i>,
International Computer Music Conference, pp. 259-262, 2001, La Habana, Cuba,
<tt><a name="tex2html13" href="https://web.archive.org/web/20080221160709/http://gigue.peabody.jhu.edu/~mdboom/latency-icmc2001.pdf">http://gigue.peabody.jhu.edu/~mdboom/latency-icmc2001.pdf</a></tt>.
<p>
<p></p><dt><a name="posix1003.1">11</a>
<dd>
POSIX 1003.1 Standard for Information Technology - Portable Operating System Interface System Interfaces,
IEEE Std 1003.1-2001. System Interfaces, Issue 6, December 2001.
<p>
<p></p><dt><a name="readwriterlocks">12</a>
<dd>
Reader/writer locks,
<tt><a name="tex2html14" href="https://web.archive.org/web/20080221160709/http://www.google.com/search?q=reader-writer+locks&amp;btnG=Google+Search">http://www.google.com/search?q=reader-writer+locks&amp;btnG=Google+Search</a></tt>.
<p>
<p></p><dt><a name="valois94">13</a>
<dd>
Valois, John D,
<i>Implementing Lock-Free Queues</i>,
Proceedings of the 7th International Conference on Parallel and
Distributed Computing Systems, Las Vegas, NV, pp. 64-69, October 1994.
<p>
<p></p><dt><a name="sos99">14</a>
<dd>
Walker, Martin,
<i>Dealing with Computer Audio Latency</i>,
Sound on Sound Magazine, April, 1999,
<tt><a name="tex2html15" href="https://web.archive.org/web/20080221160709/http://www.sospubs.co.uk/sos/apr99/articles/letency.htm">http://www.sospubs.co.uk/sos/apr99/articles/letency.htm</a></tt>.
<p>
<p></p><dt><a name="williams02">15</a>
<dd>
Williams, Clark,
<i>Linux Scheduler Latency</i>,
Red Hat Inc., White paper, March 2002,
<tt><a name="tex2html16" href="https://web.archive.org/web/20080221160709/http://www.linuxdevices.com/files/article027/rh-rtpaper.pdf">http://www.linuxdevices.com/files/article027/rh-rtpaper.pdf</a></tt>.
<p>
</dl>
<p>
<h1><a name="SECTION00800000000000000000">
Appendices</a>
</h1>
<p>
<h1><a name="SECTION00810000000000000000">
Source code</a>
</h1>
<p>
Jack source is available online. Please see the Jack web site at
<tt><a name="tex2html17" href="https://web.archive.org/web/20080221160709/http://jackit.sourceforge.net/">http://jackit.sourceforge.net/</a></tt> or <a name="tex2html19" href="https://web.archive.org/web/20080221160709/http://jackit.sourceforge.net/cgi-bin/lxr/http/source">go directly to the
source browser</a>. The file
<tt><a name="tex2html18" href="https://web.archive.org/web/20080221160709/http://jackit.sourceforge.net/cgi-bin/lxr/http/source/jack/jack.h">jack.h</a></tt>
contains the public api.
<p>
<h1><a name="SECTION00900000000000000000">
About this document ...</a>
</h1>
<strong>JACK Design Documentation</strong><p>
This document was generated using the
<a href="https://web.archive.org/web/20080221160709/http://www.latex2html.org/"><strong>LaTeX</strong>2<tt>HTML</tt></a> translator Version 2002 (1.62)
<p>
Copyright &#169; 1993, 1994, 1995, 1996,
<a href="https://web.archive.org/web/20080221160709/http://cbl.leeds.ac.uk/nikos/personal.html">Nikos Drakos</a>,
Computer Based Learning Unit, University of Leeds.
<br>Copyright &#169; 1997, 1998, 1999,
<a href="https://web.archive.org/web/20080221160709/http://www.maths.mq.edu.au/~ross/">Ross Moore</a>,
Mathematics Department, Macquarie University, Sydney.
<p>
The command line arguments were: <br>
<strong>latex2html</strong> <tt>-dir ../design -split 1 -no_navigation design.tex</tt>
<p>
The translation was initiated by Kai Vehmanen on 2003-08-26<br><hr>
<address>
Kai Vehmanen
2003-08-26
</address>
</body>
</html>
<!--
FILE ARCHIVED ON 16:07:09 Feb 21, 2008 AND RETRIEVED FROM THE
INTERNET ARCHIVE ON 15:17:20 Dec 21, 2023.
JAVASCRIPT APPENDED BY WAYBACK MACHINE, COPYRIGHT INTERNET ARCHIVE.
ALL OTHER CONTENT MAY ALSO BE PROTECTED BY COPYRIGHT (17 U.S.C.
SECTION 108(a)(3)).
-->
<!--
playback timings (ms):
captures_list: 190.513
exclusion.robots: 0.12
exclusion.robots.policy: 0.112
cdx.remote: 0.057
esindex: 0.008
LoadShardBlock: 163.693 (3)
PetaboxLoader3.datanode: 85.0 (4)
load_resource: 153.995
PetaboxLoader3.resolve: 104.964
-->