Release 4.4.0 tarball

This commit is contained in:
Gary Scavone
2013-09-29 23:44:33 +02:00
committed by Stephen Sinclair
parent 3706458166
commit d2ed001eb5
1427 changed files with 44061 additions and 39976 deletions

View File

@@ -8,25 +8,27 @@
<img src="princeton.gif"> &nbsp; <img src="ccrma.gif"> &nbsp; <img src="mcgill.gif"><P>
<a class="qindex" href="index.html">Home</a> &nbsp; <a class="qindex" href="information.html">Information</a> &nbsp; <a class="qindex" href="classes.html">Classes</a> &nbsp; <a class="qindex" href="download.html">Download</a> &nbsp; <a class="qindex" href="usage.html">Usage</a> &nbsp; <a class="qindex" href="maillist.html">Mail List</a> &nbsp; <a class="qindex" href="system.html">Requirements</a> &nbsp; <a class="qindex" href="links.html">Links</a> &nbsp; <a class="qindex" href="faq.html">FAQ</a> &nbsp; <a class="qindex" href="tutorial.html">Tutorial</a></CENTER>
<HR>
<!-- Generated by Doxygen 1.4.4 -->
<h1><a class="anchor" name="crealtime">Realtime Audio (callback)</a></h1>An alternative scheme for audio input/output is to define a specific function in which audio computations are performed and to let the audio system call this function when more input/output data can be accepted by the hardware (referred to as a callback scheme). In this section, we show how the previous <code>rtsine.cpp</code> program can be modified to work in a callback scenario. There is no "single-sample" interface for this functionality. The callback function will be invoked automatically by the audio system controller (<a class="el" href="classRtAudio.html">RtAudio</a>) when new data is needed and it is necessary to compute a full audio buffer of samples at that time (see <a class="el" href="crealtime.html#callback">Blocking vs. Callbacks</a> for further information).<p>
The previous section described the use of the <a class="el" href="classRtWvOut.html">RtWvOut</a> class for realtime audio output. The <a class="el" href="classWvOut.html#a6">RtWvOut::tick()</a> function writes data to a large ring-buffer, from which data is periodically written to the computer's audio hardware via an underlying callback routine.<p>
<!-- Generated by Doxygen 1.5.8 -->
<div class="contents">
<h1><a class="anchor" name="crealtime">Realtime Audio (callback) </a></h1>An alternative scheme for audio input/output is to define a specific function in which audio computations are performed and to let the audio system call this function when more input/output data can be accepted by the hardware (referred to as a callback scheme). In this section, we show how the previous <code>rtsine.cpp</code> program can be modified to work in a callback scenario. There is no "single-sample" interface for this functionality. The callback function will be invoked automatically by the audio system controller (<a class="el" href="classRtAudio.html" title="Realtime audio i/o C++ classes.">RtAudio</a>) when new data is needed and it is necessary to compute a full audio buffer of samples at that time (see <a class="el" href="crealtime.html#callback">Blocking vs. Callbacks</a> for further information).<p>
The previous section described the use of the <a class="el" href="classstk_1_1RtWvOut.html" title="STK realtime audio (blocking) output class.">stk::RtWvOut</a> class for realtime audio output. The <a class="el" href="classstk_1_1RtWvOut.html#02adabdc987f3b9ac4dc4e02ea20962d" title="Output a single sample to all channels in a sample frame.">stk::RtWvOut::tick()</a> function writes data to a large ring-buffer, from which data is periodically written to the computer's audio hardware via an underlying callback routine.<p>
<div class="fragment"><pre class="fragment"><span class="comment">// crtsine.cpp STK tutorial program</span>
<span class="preprocessor">#include "SineWave.h"</span>
<span class="preprocessor">#include "<a class="code" href="RtAudio_8h.html">RtAudio.h</a>"</span>
<span class="keyword">using namespace </span>stk;
<span class="comment">// This tick() function handles sample computation only. It will be</span>
<span class="comment">// called automatically when the system needs a new buffer of audio</span>
<span class="comment">// samples.</span>
<span class="keywordtype">int</span> tick( <span class="keywordtype">void</span> *outputBuffer, <span class="keywordtype">void</span> *inputBuffer, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> nBufferFrames,
<span class="keywordtype">double</span> streamTime, <a class="code" href="RtAudio_8h.html#a11">RtAudioStreamStatus</a> status, <span class="keywordtype">void</span> *dataPointer )
<span class="keywordtype">double</span> streamTime, <a class="code" href="RtAudio_8h.html#80e306d363583da3b0a1b65d9b57c806" title="RtAudio stream status (over- or underflow) flags.">RtAudioStreamStatus</a> status, <span class="keywordtype">void</span> *dataPointer )
{
<a class="code" href="classSineWave.html">SineWave</a> *sine = (<a class="code" href="classSineWave.html">SineWave</a> *) dataPointer;
SineWave *sine = (SineWave *) dataPointer;
<span class="keyword">register</span> StkFloat *samples = (StkFloat *) outputBuffer;
<span class="keywordflow">for</span> ( <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i=0; i&lt;nBufferFrames; i++ )
*samples++ = sine-&gt;<a class="code" href="classGenerator.html#a3">tick</a>();
*samples++ = sine-&gt;tick();
<span class="keywordflow">return</span> 0;
}
@@ -34,32 +36,32 @@ The previous section described the use of the <a class="el" href="classRtWvOut.h
<span class="keywordtype">int</span> main()
{
<span class="comment">// Set the global sample rate before creating class instances.</span>
<a class="code" href="classStk.html#e1">Stk::setSampleRate</a>( 44100.0 );
Stk::setSampleRate( 44100.0 );
<a class="code" href="classSineWave.html">SineWave</a> sine;
<a class="code" href="classRtAudio.html">RtAudio</a> dac;
SineWave sine;
<a class="code" href="classRtAudio.html" title="Realtime audio i/o C++ classes.">RtAudio</a> dac;
<span class="comment">// Figure out how many bytes in an StkFloat and setup the RtAudio stream.</span>
<a class="code" href="structRtAudio_1_1StreamParameters.html">RtAudio::StreamParameters</a> parameters;
parameters.<a class="code" href="structRtAudio_1_1StreamParameters.html#o0">deviceId</a> = dac.<a class="code" href="classRtAudio.html#a5">getDefaultOutputDevice</a>();
parameters.<a class="code" href="structRtAudio_1_1StreamParameters.html#o1">nChannels</a> = 1;
<a class="code" href="RtAudio_8h.html#a0">RtAudioFormat</a> format = ( <span class="keyword">sizeof</span>(StkFloat) == 8 ) ? RTAUDIO_FLOAT64 : RTAUDIO_FLOAT32;
<a class="code" href="structRtAudio_1_1StreamParameters.html" title="The structure for specifying input or ouput stream parameters.">RtAudio::StreamParameters</a> parameters;
parameters.<a class="code" href="structRtAudio_1_1StreamParameters.html#ffd27496c70c0986522056234c64e28e">deviceId</a> = dac.<a class="code" href="classRtAudio.html#3a3f3dbe13ea696b521e49cdaaa357bc" title="A function that returns the index of the default output device.">getDefaultOutputDevice</a>();
parameters.<a class="code" href="structRtAudio_1_1StreamParameters.html#78798b65fada7941e1a7e47c11c9e627">nChannels</a> = 1;
<a class="code" href="RtAudio_8h.html#afca92882d25915560018873221e44b8" title="RtAudio data format type.">RtAudioFormat</a> format = ( <span class="keyword">sizeof</span>(StkFloat) == 8 ) ? RTAUDIO_FLOAT64 : RTAUDIO_FLOAT32;
<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> bufferFrames = RT_BUFFER_SIZE;
<span class="keywordflow">try</span> {
dac.<a class="code" href="classRtAudio.html#a7">openStream</a>( &amp;parameters, NULL, format, (<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span>)Stk::sampleRate(), &amp;bufferFrames, &amp;tick, (<span class="keywordtype">void</span> *)&amp;sine );
dac.<a class="code" href="classRtAudio.html#facc99740fa4c5606fb35467cdea6da8" title="A public function for opening a stream with the specified parameters.">openStream</a>( &amp;parameters, NULL, format, (<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span>)Stk::sampleRate(), &amp;bufferFrames, &amp;tick, (<span class="keywordtype">void</span> *)&amp;sine );
}
<span class="keywordflow">catch</span> ( <a class="code" href="classRtError.html">RtError</a> &amp;error ) {
error.<a class="code" href="classRtError.html#a2">printMessage</a>();
<span class="keywordflow">catch</span> ( <a class="code" href="classRtError.html" title="Exception handling class for RtAudio &amp;amp; RtMidi.">RtError</a> &amp;error ) {
error.<a class="code" href="classRtError.html#da41f7472122f45bc5b4677f066e0943" title="Prints thrown error message to stderr.">printMessage</a>();
<span class="keywordflow">goto</span> cleanup;
}
sine.<a class="code" href="classSineWave.html#a4">setFrequency</a>(440.0);
sine.setFrequency(440.0);
<span class="keywordflow">try</span> {
dac.<a class="code" href="classRtAudio.html#a9">startStream</a>();
dac.<a class="code" href="classRtAudio.html#ec017a89629ccef66a90b60be22a2f80" title="A function that starts a stream.">startStream</a>();
}
<span class="keywordflow">catch</span> ( <a class="code" href="classRtError.html">RtError</a> &amp;error ) {
error.<a class="code" href="classRtError.html#a2">printMessage</a>();
<span class="keywordflow">catch</span> ( <a class="code" href="classRtError.html" title="Exception handling class for RtAudio &amp;amp; RtMidi.">RtError</a> &amp;error ) {
error.<a class="code" href="classRtError.html#da41f7472122f45bc5b4677f066e0943" title="Prints thrown error message to stderr.">printMessage</a>();
<span class="keywordflow">goto</span> cleanup;
}
@@ -70,10 +72,10 @@ The previous section described the use of the <a class="el" href="classRtWvOut.h
<span class="comment">// Shut down the output stream.</span>
<span class="keywordflow">try</span> {
dac.<a class="code" href="classRtAudio.html#a8">closeStream</a>();
dac.<a class="code" href="classRtAudio.html#90d599002ad32cf250a4cb866f2cc93a" title="A function that closes a stream and frees any associated stream memory.">closeStream</a>();
}
<span class="keywordflow">catch</span> ( <a class="code" href="classRtError.html">RtError</a> &amp;error ) {
error.<a class="code" href="classRtError.html#a2">printMessage</a>();
<span class="keywordflow">catch</span> ( <a class="code" href="classRtError.html" title="Exception handling class for RtAudio &amp;amp; RtMidi.">RtError</a> &amp;error ) {
error.<a class="code" href="classRtError.html#da41f7472122f45bc5b4677f066e0943" title="Prints thrown error message to stderr.">printMessage</a>();
}
cleanup:
@@ -81,18 +83,19 @@ The previous section described the use of the <a class="el" href="classRtWvOut.h
<span class="keywordflow">return</span> 0;
}
</pre></div><p>
The sinusoidal oscillator is created as before. The instantiation of <a class="el" href="classRtAudio.html">RtAudio</a> requires quite a few more parameters, including output/input device and channel specifiers, the data format, and the desired buffer length (in frames). In this example, we request a single output channel using the default output device, zero channels of input, the <a class="el" href="classRtAudio.html">RtAudio</a> data format which corresponds to an <code>StkFloat</code>, and the RT_BUFFER_SIZE defined in <a class="el" href="Stk_8h-source.html">Stk.h</a>. The <code>bufferFrames</code> argument is an API-dependent buffering parameter (see <a class="el" href="classRtAudio.html">RtAudio</a> for further information).<p>
The sinusoidal oscillator is created as before. The instantiation of <a class="el" href="classRtAudio.html" title="Realtime audio i/o C++ classes.">RtAudio</a> requires quite a few more parameters, including output/input device and channel specifiers, the data format, and the desired buffer length (in frames). In this example, we request a single output channel using the default output device, zero channels of input, the <a class="el" href="classRtAudio.html" title="Realtime audio i/o C++ classes.">RtAudio</a> data format which corresponds to an <code>StkFloat</code>, and the RT_BUFFER_SIZE defined in <a class="el" href="Stk_8h-source.html">Stk.h</a>. The <code>bufferFrames</code> argument is an API-dependent buffering parameter (see <a class="el" href="classRtAudio.html" title="Realtime audio i/o C++ classes.">RtAudio</a> for further information).<p>
We also provide the audio system controller with a pointer to our callback function and an optional pointer to data that will be made available in the callback. In this example, we need to pass only the pointer to the oscillator. In more complex programs, it is typically necessary to put all shared data in a <code>struct</code> (see the next tutorial program for an example) or make use of global variables.<p>
Our callback routine is the <code>tick()</code> function. <a class="el" href="classFunction.html">Function</a> arguments include pointers to the audio input and output data buffers, the buffer size (in frames), a stream time argument, a status argument to test for over/underruns, and the data pointer passed in the openStream() function (if it exists). It is necessary to cast these pointers to their corresponding data types before use. Our tick() routine simply "ticks" the oscillator for <code>nBufferFrames</code> counts and writes the result into the audio data buffer before returning.<p>
Our callback routine is the <code>tick()</code> function. Function arguments include pointers to the audio input and output data buffers, the buffer size (in frames), a stream time argument, a status argument to test for over/underruns, and the data pointer passed in the openStream() function (if it exists). It is necessary to cast these pointers to their corresponding data types before use. Our tick() routine simply "ticks" the oscillator for <code>nBufferFrames</code> counts and writes the result into the audio data buffer before returning.<p>
The <code>main()</code> function blocks at the std::cin.get() call until the user hits the "enter" key, after which the audio controller is shut down and program execution ends.<h2><a class="anchor" name="callback">
Blocking vs. Callbacks</a></h2>
Prior to version 4.2.0, all STK example projects and programs used blocking audio input/output functionality (typically with the <a class="el" href="classRtWvIn.html">RtWvIn</a>, <a class="el" href="classRtWvOut.html">RtWvOut</a>, or RtDuplex classes). In many instances, a blocking scheme results in a clearer and more straight-forward program structure. Within a graphical user interface (GUI) programming context, however, callback routines are often more natural.<p>
Prior to version 4.2.0, all STK example projects and programs used blocking audio input/output functionality (typically with the RtWvIn, RtWvOut, or RtDuplex classes). In many instances, a blocking scheme results in a clearer and more straight-forward program structure. Within a graphical user interface (GUI) programming context, however, callback routines are often more natural.<p>
In order to allow all STK programs to function with equal proficiency on all supported computer platforms, a decision was made to modify the example projects to use audio callback routines. The result is a more complicated code structure, which is unfortunate given that we generally strive to make STK code as clear as possible for educational purposes. This was especially an issue with the demo program because it is designed to function in both realtime and non-realtime contexts. The use of global variables has been avoided by defining data structures to hold all variables that must be accessible to the callback routine and other functions. Alternative schemes for making control updates could be designed depending on particular program needs and constraints.<p>
[<a href="tutorial.html">Main tutorial page</a>] &nbsp; [<a href="instruments.html">Next tutorial</a>] <HR>
[<a href="tutorial.html">Main tutorial page</a>] &nbsp; [<a href="instruments.html">Next tutorial</a>] </div>
<HR>
<table>
<tr><td><A HREF="http://ccrma.stanford.edu/software/stk/"><I>The Synthesis ToolKit in C++ (STK)</I></A></td></tr>
<tr><td>&copy;1995-2007 Perry R. Cook and Gary P. Scavone. All Rights Reserved.</td></tr>
<tr><td>&copy;1995-2009 Perry R. Cook and Gary P. Scavone. All Rights Reserved.</td></tr>
</table>
</BODY>