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
|
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]">
<meta name="Author" content="Phil Burk">
<meta name="Description" content="Internal docs. How a stream is started or stopped.">
<meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
<title>PortAudio Implementation - Start/Stop</title>
</head>
<body>
<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
<tr>
<td>
<center>
<h1>
<a href="http://www.portaudio.com">PortAudio</a> Implementation Guide</h1></center>
</td>
</tr>
</table></center>
<p>This document describes how to implement the PortAudio API on a new
computer platform. Implementing PortAudio on a new platform, makes it possible
to port many existing audio applications to that platform.
<p>By Phil Burk
<br>Copyright 2000 Phil Burk and Ross Bencina
<p>Note that the license says: <b>"Any person wishing to distribute modifications
to the Software is requested to send the modifications to the original
developer so that they can be incorporated into the canonical version."</b>.
So when you have finished a new implementation, please send it back to
us at "<a href="http://www.portaudio.com">http://www.portaudio.com</a>"
so that we can make it available for other users. Thank you!
<h2>
Download the Latest PortAudio Implementation</h2>
Always start with the latest implementation available at "<a href="http://www.portaudio.com">http://www.portaudio.com</a>".
Look for the nightly snapshot under the CVS section.
<h2>
Select an Existing Implementation as a Basis</h2>
The fastest way to get started is to take an existing implementation and
translate it for your new platform. Choose an implementation whose architecture
is as close as possible to your target.
<ul>
<li>
DirectSound Implementation - pa_win_ds - Uses a timer callback for the
background "thread". Polls a circular buffer and writes blocks of data
to keep it full.</li>
<li>
Windows MME - pa_win_wmme - Spawns an actual Win32 thread. Writes blocks
of data to the HW device and waits for events that signal buffer completion.</li>
<li>
Linux OSS - pa_linux - Spawns a real thread that writes to the "/dev/dsp"
stream using blocking I/O calls.</li>
</ul>
When you write a new implementation, you will be using some code that is
in common with all implementations. This code is in the folder "pa_common".
It provides various functions such as parameter checking, error code to
text conversion, sample format conversion, clipping and dithering, etc.
<p>The code that you write will go into a separate folder called "pa_{os}_{api}".
For example, code specific to the DirectSound interface for Windows goes
in "pa_win_ds".
<h2>
Read Docs and Code</h2>
Famialiarize yourself with the system by reading the documentation provided.
here is a suggested order:
<ol>
<li>
User Programming <a href="pa_tutorial.html">Tutorial</a></li>
<li>
Header file "pa_common/portaudio.h" which defines API.</li>
<li>
Header file "pa_common/pa_host.h" for host dependant code. This definces
the routine you will need to provide.</li>
<li>
Shared code in "pa_common/pa_lib.c".</li>
<li>
Docs on Implementation of <a href="pa_impl_startstop.html">Start/Stop</a>
code.</li>
</ol>
<h2>
Implement Output to Default Device</h2>
Now we are ready to crank some code. For instant gratification, let's try
to play a sine wave.
<ol>
<li>
Link the test program "pa_tests/patest_sine.c" with the file "pa_lib.c"
and the implementation specific file you are creating.</li>
<li>
For now, just stub out the device query code and the audio input code.</li>
<li>
Modify PaHost_OpenStream() to open your default target device and get everything
setup.</li>
<li>
Modify PaHost_StartOutput() to start playing audio.</li>
<li>
Modify PaHost_StopOutput() to stop audio.</li>
<li>
Modify PaHost_CloseStream() to clean up. Free all memory that you allocated
in PaHost_OpenStream().</li>
<li>
Keep cranking until you can play a sine wave using "patest_sine.c".</li>
<li>
Once that works, try "patest_pink.c", "patest_clip.c", "patest_sine8.c".</li>
<li>
To test your Open and Close code, try "patest_many.c".</li>
<li>
Now test to make sure that the three modes of stopping are properly supported
by running "patest_stop.c".</li>
<li>
Test your implementation of time stamping with "patest_sync.c".</li>
</ol>
<h2>
Implement Device Queries</h2>
Now that output is working, lets implement the code for querying what devices
are available to the user. Run "pa_tests/pa_devs.c". It should print all
of the devices available and their characteristics.
<h2>
Implement Input</h2>
Implement audio input and test it with:
<ol>
<li>
patest_record.c - record in half duplex, play back as recorded.</li>
<li>
patest_wire.c - full duplex, copies input to output. Note that some HW
may not support full duplex.</li>
<li>
patest_fuzz.c - plug in your guitar and get a feel for why latency is an
important issue in computer music.</li>
<li>
paqa_devs.c - try to open every device and use it with every possible format</li>
</ol>
<h2>
Debugging Tools</h2>
You generally cannot use printf() calls to debug real-time processes because
they disturb the timing. Also calling printf() from your background thread
or interrupt could crash the machine. So PA includes a tool for capturing
events and storing the information while it is running. It then prints
the events when Pa_Terminate() is called.
<ol>
<li>
To enable trace mode, change TRACE_REALTIME_EVENTS in "pa_common/pa_trace.h"
from a (0) to a (1).</li>
<li>
Link with "pa_common/pa_trace.c".</li>
<li>
Add trace messages to your code by calling:</li>
<br><tt> void AddTraceMessage( char *msg, int data );</tt>
<br><tt>for example</tt>
<br><tt> AddTraceMessage("Pa_TimeSlice: past_NumCallbacks ",
past->past_NumCallbacks );</tt>
<li>
Run your program. You will get a dump of events at the end.</li>
<li>
You can leave the trace messages in your code. They will turn to NOOPs
when you change TRACE_REALTIME_EVENTS back to (0).</li>
</ol>
<h2>
Delivery</h2>
Please send your new code along with notes on the implementation back to
us at "<a href="http://www.portaudio.com">http://www.portaudio.com</a>".
We will review the implementation and post it with your name. If you had
to make any modifications to the code in "pa_common" or "pa_tests" <b>please</b>
send us those modifications and your notes. We will try to merge your changes
so that the "pa_common" code works with <b>all</b> implementations.
<p>If you have suggestions for how to make future implementations easier,
please let us know.
<br>THANKS!
<br>
</body>
</html>
|