Merge 4.0.4 into releases
[rtaudio.git] / doc / html / playback.html
1 <HTML>
2 <HEAD>
3 <TITLE>The RtAudio Home Page</TITLE>
4 <LINK HREF="doxygen.css" REL="stylesheet" TYPE="text/css">
5 <LINK REL="SHORTCUT ICON" HREF="http://www.music.mcgill.ca/~gary/favicon.ico">
6 </HEAD>
7 <BODY BGCOLOR="#FFFFFF">
8 <CENTER>
9 <a class="qindex" href="index.html">Home</a> &nbsp; <a class="qindex" href="annotated.html">Class/Enum List</a> &nbsp; <a class="qindex" href="files.html">File List</a> &nbsp; <a class="qindex" href="functions.html">Compound Members</a> &nbsp; </CENTER>
10 <HR>
11 <!-- Generated by Doxygen 1.4.4 -->
12 <h1><a class="anchor" name="playback">Playback</a></h1>In this example, we provide a complete program that demonstrates the use of <a class="el" href="classRtAudio.html">RtAudio</a> for audio playback. Our program produces a two-channel sawtooth waveform for output.<p>
13 <div class="fragment"><pre class="fragment"><span class="preprocessor">#include "<a class="code" href="RtAudio_8h.html">RtAudio.h</a>"</span>
14 <span class="preprocessor">#include &lt;iostream&gt;</span>
15
16 <span class="comment">// Two-channel sawtooth wave generator.</span>
17 <span class="keywordtype">int</span> saw( <span class="keywordtype">void</span> *outputBuffer, <span class="keywordtype">void</span> *inputBuffer, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nBufferFrames,
18          <span class="keywordtype">double</span> streamTime, <a class="code" href="RtAudio_8h.html#a12">RtAudioStreamStatus</a> status, <span class="keywordtype">void</span> *userData )
19 {
20   <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i, j;
21   <span class="keywordtype">double</span> *buffer = (<span class="keywordtype">double</span> *) outputBuffer;
22   <span class="keywordtype">double</span> *lastValues = (<span class="keywordtype">double</span> *) userData;
23
24   <span class="keywordflow">if</span> ( status )
25     std::cout &lt;&lt; <span class="stringliteral">"Stream underflow detected!"</span> &lt;&lt; std::endl;
26
27   <span class="comment">// Write interleaved audio data.</span>
28   <span class="keywordflow">for</span> ( i=0; i&lt;nBufferFrames; i++ ) {
29     <span class="keywordflow">for</span> ( j=0; j&lt;2; j++ ) {
30       *buffer++ = lastValues[j];
31
32       lastValues[j] += 0.005 * (j+1+(j*0.1));
33       <span class="keywordflow">if</span> ( lastValues[j] &gt;= 1.0 ) lastValues[j] -= 2.0;
34     }
35   }
36
37   <span class="keywordflow">return</span> 0;
38 }
39
40 <span class="keywordtype">int</span> main()
41 {
42   <a class="code" href="classRtAudio.html">RtAudio</a> dac;
43   <span class="keywordflow">if</span> ( dac.<a class="code" href="classRtAudio.html#a3">getDeviceCount</a>() &lt; 1 ) {
44     std::cout &lt;&lt; <span class="stringliteral">"\nNo audio devices found!\n"</span>;
45     exit( 0 );
46   }
47
48   <a class="code" href="structRtAudio_1_1StreamParameters.html">RtAudio::StreamParameters</a> parameters;
49   parameters.<a class="code" href="structRtAudio_1_1StreamParameters.html#o0">deviceId</a> = dac.<a class="code" href="classRtAudio.html#a5">getDefaultOutputDevice</a>();
50   parameters.<a class="code" href="structRtAudio_1_1StreamParameters.html#o1">nChannels</a> = 2;
51   parameters.<a class="code" href="structRtAudio_1_1StreamParameters.html#o2">firstChannel</a> = 0;
52   <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> sampleRate = 44100;
53   <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> bufferFrames = 256; <span class="comment">// 256 sample frames</span>
54   <span class="keywordtype">double</span> data[2];
55
56   <span class="keywordflow">try</span> {
57     dac.<a class="code" href="classRtAudio.html#a7">openStream</a>( &amp;parameters, NULL, RTAUDIO_FLOAT64,
58                     sampleRate, &amp;bufferFrames, &amp;saw, (<span class="keywordtype">void</span> *)&amp;data );
59     dac.<a class="code" href="classRtAudio.html#a9">startStream</a>();
60   }
61   <span class="keywordflow">catch</span> ( <a class="code" href="classRtError.html">RtError</a>&amp; e ) {
62     e.<a class="code" href="classRtError.html#a2">printMessage</a>();
63     exit( 0 );
64   }
65   
66   <span class="keywordtype">char</span> input;
67   std::cout &lt;&lt; <span class="stringliteral">"\nPlaying ... press &lt;enter&gt; to quit.\n"</span>;
68   std::cin.get( input );
69
70   <span class="keywordflow">try</span> {
71     <span class="comment">// Stop the stream</span>
72     dac.<a class="code" href="classRtAudio.html#a10">stopStream</a>();
73   }
74   <span class="keywordflow">catch</span> (<a class="code" href="classRtError.html">RtError</a>&amp; e) {
75     e.<a class="code" href="classRtError.html#a2">printMessage</a>();
76   }
77
78   <span class="keywordflow">if</span> ( dac.<a class="code" href="classRtAudio.html#a12">isStreamOpen</a>() ) dac.<a class="code" href="classRtAudio.html#a8">closeStream</a>();
79
80   <span class="keywordflow">return</span> 0;
81 }
82 </pre></div><p>
83 We open the stream in exactly the same way as the previous example (except with a data format change) and specify the address of our callback function <em>"saw()"</em>. The callback function will automatically be invoked when the underlying audio system needs data for output. Note that the callback function is called only when the stream is "running" (between calls to the <a class="el" href="classRtAudio.html#a9">RtAudio::startStream()</a> and <a class="el" href="classRtAudio.html#a10">RtAudio::stopStream()</a> functions). We can also pass a pointer value to the <a class="el" href="classRtAudio.html#a7">RtAudio::openStream()</a> function that is made available in the callback function. In this way, it is possible to gain access to arbitrary data created in our <em>main()</em> function from within the globally defined callback function.<p>
84 In this example, we stop the stream with an explicit call to <a class="el" href="classRtAudio.html#a10">RtAudio::stopStream()</a>. It is also possible to stop a stream by returning a non-zero value from the callback function. A return value of 1 will cause the stream to finish draining its internal buffers and then halt (equivalent to calling the <a class="el" href="classRtAudio.html#a10">RtAudio::stopStream()</a> function). A return value of 2 will cause the stream to stop immediately (equivalent to calling the <a class="el" href="classRtAudio.html#a11">RtAudio::abortStream()</a> function). <HR>
85
86 <table><tr><td><img src="../images/mcgill.gif" width=165></td>
87   <td>&copy;2001-2007 Gary P. Scavone, McGill University. All Rights Reserved.<br>Maintained by <a href="http://www.music.mcgill.ca/~gary/">Gary P. Scavone</a>.</td></tr>
88 </table>
89
90 </BODY>
91 </HTML>