添加一些关于midi播放的项目
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
/*! \page acknowledge Acknowledgements
|
||||
|
||||
Many thanks to the following people for providing bug fixes and improvements:
|
||||
<UL>
|
||||
<LI>Stephen Sinclair (major code and repository support!)</LI>
|
||||
<LI>Stefan Arisona</LI>
|
||||
<LI>bejuryu</LI>
|
||||
<LI>Vincent Bénony</LI>
|
||||
<LI>Francesco Bertolaccini</LI>
|
||||
<LI>Benjamin Brown</LI>
|
||||
<LI>Claudio Cabral</LI>
|
||||
<LI>JP Cimalando</LI>
|
||||
<LI>Rasmus Ekman</LI>
|
||||
<LI>Anders Ervik</LI>
|
||||
<LI>Robin Davies (Windows DS and ASIO)</LI>
|
||||
<LI>Marcelo Fernandez</LI>
|
||||
<LI>Taylor Holberton</LI>
|
||||
<LI>Martin Koegler</LI>
|
||||
<LI>Dmitry Kostjuchenko</LI>
|
||||
<LI>Oliver Larkin</LI>
|
||||
<LI>Jakob Leben</LI>
|
||||
<LI>Antoine Lefebvre</LI>
|
||||
<LI>Carlos Luna</LI>
|
||||
<LI>Connor MacDonald</LI>
|
||||
<LI>Jasper Mackenzie</LI>
|
||||
<LI>Dominic Mazzoni</LI>
|
||||
<LI>Tristan Matthews</LI>
|
||||
<LI>Peter Meerwald (PulseAudio)</LI>
|
||||
<LI>Jaromir Mikes</LI>
|
||||
<LI>rehans</LI>
|
||||
<LI>Sebastian Reimers</LI>
|
||||
<LI>Ryan Schmidt</LI>
|
||||
<LI>Benjamin Schroeder</LI>
|
||||
<LI>sonoro1234</LI>
|
||||
<LI>terminator356</LI>
|
||||
<LI>Marcus Tomlinson (WASAPI)</LI>
|
||||
<LI>Ryan Williams (Windows non-MS compiler ASIO support)</LI>
|
||||
<LI>Ed Wildgoose (Linux ALSA and Jack)</LI>
|
||||
<LI>Serge Zaitsev</LI>
|
||||
<LI>Iohannes Zmölnig</LI>
|
||||
|
||||
</UL>
|
||||
|
||||
The RtAudio API incorporates many of the concepts developed in the <A href="http://www.portaudio.com/">PortAudio</A> project by Phil Burk and Ross Bencina. Early development also incorporated ideas from Bill Schottstaedt's <A href="http://www-ccrma.stanford.edu/software/snd/sndlib/">sndlib</A>. The CCRMA <A href="http://www-ccrma.stanford.edu/groups/soundwire/">SoundWire group</A> provided valuable feedback during the API proposal stages.
|
||||
|
||||
The early 2.0 version of RtAudio was slowly developed over the course of many months while in residence at the <A href="http://www.iua.upf.es/">Institut Universitari de L'Audiovisual (IUA)</A> in Barcelona, Spain and the <A href="http://www.acoustics.hut.fi/">Laboratory of Acoustics and Audio Signal Processing</A> at the Helsinki University of Technology, Finland. Much subsequent development happened while working at the <A href="http://www-ccrma.stanford.edu/">Center for Computer Research in Music and Acoustics (CCRMA)</A> at <A href="http://www.stanford.edu/">Stanford University</A>. All recent versions of RtAudio have been completed while working as an assistant / associate professor of <a href="http://www.music.mcgill.ca/musictech/">Music Technology</a> at <a href="http://www.mcgill.ca/">McGill University</a>. This work was supported in part by the United States Air Force Office of Scientific Research (grant \#F49620-99-1-0293).
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,39 @@
|
||||
/*! \page apinotes API Notes
|
||||
|
||||
RtAudio is designed to provide a common API across the various supported operating systems and audio libraries. Despite that, some issues should be mentioned with regard to each.
|
||||
|
||||
\section linux Linux:
|
||||
|
||||
RtAudio for Linux was developed under Redhat distributions 7.0 - Fedora. Four different audio APIs are supported on Linux platforms: <A href="http://www.opensound.com/oss.html">OSS</A> (versions >= 4.0), <A href="http://www.alsa-project.org/">ALSA</A>, <A href="http://jackit.sourceforge.net/">Jack</A>, and <A href="http://www.freedesktop.org/wiki/Software/PulseAudio">PulseAudio</A>. Note that RtAudio now only supports the newer version 4.0 OSS API. The ALSA API is now part of the Linux kernel and offers significantly better functionality than the OSS API. RtAudio provides support for the 1.0 and higher versions of ALSA. Jack is a low-latency audio server written primarily for the GNU/Linux operating system. It can connect a number of different applications to an audio device, as well as allow them to share audio between themselves. Input/output latency on the order of 15 milliseconds can typically be achieved using any of the Linux APIs by fine-tuning the RtAudio buffer parameters (without kernel modifications). Latencies on the order of 5 milliseconds or less can be achieved using a low-latency kernel patch and increasing FIFO scheduling priority. The pthread library, which is used for callback functionality, is a standard component of all Linux distributions.
|
||||
|
||||
The ALSA library includes OSS emulation support. That means that you can run programs compiled for the OSS API even when using the ALSA drivers and library. It should be noted however that OSS emulation under ALSA is not perfect. Specifically, channel number queries seem to consistently produce invalid results. While OSS emulation is successful for the majority of RtAudio tests, it is recommended that the native ALSA implementation of RtAudio be used on systems which have ALSA drivers installed.
|
||||
|
||||
The ALSA implementation of RtAudio makes no use of the ALSA "plug" interface. All necessary data format conversions, channel compensation, de-interleaving, and byte-swapping is handled by internal RtAudio routines.
|
||||
|
||||
\section macosx Macintosh OS-X (CoreAudio and Jack):
|
||||
|
||||
The Apple CoreAudio API is designed to use a separate callback procedure for each of its audio devices. A single RtAudio duplex stream using two different devices is supported, though it cannot be guaranteed to always behave correctly because we cannot synchronize these two callbacks. The <I>numberOfBuffers</I> parameter to the RtAudio::openStream() function has no affect in this implementation.
|
||||
|
||||
It is not possible to have multiple instances of RtAudio accessing the same CoreAudio device.
|
||||
|
||||
The RtAudio Jack support can be compiled on Macintosh OS-X systems, as well as in Linux.
|
||||
|
||||
\section windowsds Windows (DirectSound):
|
||||
|
||||
The \c configure script provides support for the MinGW compiler. DirectSound support is specified with the "--with-ds" flag.
|
||||
|
||||
In order to compile RtAudio under Windows for the DirectSound API, you must have the header and source files for DirectSound version 5.0 or higher. As far as I know, there is no DirectSoundCapture support for Windows NT. Audio output latency with DirectSound can be reasonably good, especially since RtAudio version 3.0.2. Input audio latency still tends to be bad but better since version 3.0.2. RtAudio was originally developed with Visual C++ version 6.0 but has been tested with .NET.
|
||||
|
||||
The DirectSound version of RtAudio can be compiled with or without the UNICODE preprocessor definition.
|
||||
|
||||
\section windowsasio Windows (ASIO):
|
||||
|
||||
ASIO support using MinGW and the \c configure script is specified with the "--with-asio" flag.
|
||||
|
||||
The Steinberg ASIO audio API allows only a single device driver to be loaded and accessed at a time. ASIO device drivers must be supplied by audio hardware manufacturers, though ASIO emulation is possible on top of systems with DirectSound drivers. The <I>numberOfBuffers</I> parameter to the RtAudio::openStream() function has no affect in this implementation.
|
||||
|
||||
A number of ASIO source and header files are required for use with RtAudio. Specifically, an RtAudio project must include the following files: <TT>asio.h,cpp; asiodrivers.h,cpp; asiolist.h,cpp; asiodrvr.h; asiosys.h; ginclude.h; iasiodrv.h; iasiothiscallresolver.h,cpp</TT>. The Visual C++ projects found in <TT>/tests/Windows/</TT> compile both ASIO and DirectSound support.
|
||||
|
||||
The Steinberg provided <TT>asiolist</TT> class does not compile when the preprocessor definition UNICODE is defined. Note that this could be an issue when using RtAudio with Qt, though Qt programs appear to compile without the UNICODE definition (try <tt>DEFINES -= UNICODE</tt> in your .pro file). RtAudio with ASIO support has been tested using the MinGW compiler under Windows XP, as well as in the Visual Studio environment.
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,92 @@
|
||||
/*! \page compiling Debugging & Compiling
|
||||
|
||||
\section debug Debugging
|
||||
|
||||
If you are having problems getting RtAudio to run on your system, make sure to pass a value of \e true to the RtAudio::showWarnings() function (this is the default setting). A variety of warning messages will be displayed which may help in determining the problem. Also, try using the programs included in the <tt>tests</tt> directory. The program <tt>audioprobe</tt> displays the queried capabilities of all hardware devices found for all APIs compiled. When using the ALSA and JACK APIs, further information can be displayed by defining the preprocessor definition __RTAUDIO_DEBUG__.
|
||||
|
||||
\section compile Compiling
|
||||
|
||||
In order to compile RtAudio for a specific OS and audio API, it is necessary to supply the appropriate preprocessor definition and library within the compiler statement:
|
||||
<P>
|
||||
|
||||
<TABLE BORDER=2 COLS=5 WIDTH="100%">
|
||||
<TR BGCOLOR="beige">
|
||||
<TD WIDTH="5%"><B>OS:</B></TD>
|
||||
<TD WIDTH="5%"><B>Audio API:</B></TD>
|
||||
<TD WIDTH="5%"><B>C++ Class:</B></TD>
|
||||
<TD WIDTH="5%"><B>Preprocessor Definition:</B></TD>
|
||||
<TD WIDTH="5%"><B>Library or Framework:</B></TD>
|
||||
<TD><B>Example Compiler Statement:</B></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>Linux</TD>
|
||||
<TD>ALSA</TD>
|
||||
<TD>RtApiAlsa</TD>
|
||||
<TD>__LINUX_ALSA__</TD>
|
||||
<TD><TT>asound, pthread</TT></TD>
|
||||
<TD><TT>g++ -Wall -D__LINUX_ALSA__ -o audioprobe audioprobe.cpp RtAudio.cpp -lasound -lpthread</TT></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>Linux</TD>
|
||||
<TD>PulseAudio</TD>
|
||||
<TD>RtApiPulse</TD>
|
||||
<TD>__LINUX_PULSE__</TD>
|
||||
<TD><TT>pthread</TT></TD>
|
||||
<TD><TT>g++ -Wall -D__LINUX_PULSE__ -o audioprobe audioprobe.cpp RtAudio.cpp -lpthread -lpulse-simple -lpulse</TT></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>Linux</TD>
|
||||
<TD>OSS</TD>
|
||||
<TD>RtApiOss</TD>
|
||||
<TD>__LINUX_OSS__</TD>
|
||||
<TD><TT>pthread</TT></TD>
|
||||
<TD><TT>g++ -Wall -D__LINUX_OSS__ -o audioprobe audioprobe.cpp RtAudio.cpp -lpthread</TT></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>Linux or Macintosh OS-X</TD>
|
||||
<TD>Jack Audio Server</TD>
|
||||
<TD>RtApiJack</TD>
|
||||
<TD>__UNIX_JACK__</TD>
|
||||
<TD><TT>jack, pthread</TT></TD>
|
||||
<TD><TT>g++ -Wall -D__UNIX_JACK__ -o audioprobe audioprobe.cpp RtAudio.cpp $(pkg-config --cflags --libs jack) -lpthread</TT></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD>Macintosh OS-X</TD>
|
||||
<TD>CoreAudio</TD>
|
||||
<TD>RtApiCore</TD>
|
||||
<TD>__MACOSX_CORE__</TD>
|
||||
<TD><TT>pthread, CoreAudio</TT></TD>
|
||||
<TD><TT>g++ -Wall -D__MACOSX_CORE__ -o audioprobe audioprobe.cpp RtAudio.cpp -framework CoreAudio -framework CoreFoundation -lpthread</TT></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>Windows</TD>
|
||||
<TD>DirectSound</TD>
|
||||
<TD>RtApiDs</TD>
|
||||
<TD>__WINDOWS_DS__</TD>
|
||||
<TD><TT>dsound.lib (ver. 5.0 or higher), multithreaded</TT></TD>
|
||||
<TD>MinGW: <TT>g++ -Wall -D__WINDOWS_DS__ -o audioprobe audioprobe.cpp RtAudio.cpp -lole32 -lwinmm -ldsound</TT></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>Windows</TD>
|
||||
<TD>ASIO</TD>
|
||||
<TD>RtApiAsio</TD>
|
||||
<TD>__WINDOWS_ASIO__</TD>
|
||||
<TD><I>various ASIO header and source files</I></TD>
|
||||
<TD>MinGW: <TT>g++ -Wall -D__WINDOWS_ASIO__ -Iinclude -o audioprobe audioprobe.cpp RtAudio.cpp asio.cpp asiolist.cpp asiodrivers.cpp iasiothiscallresolver.cpp -lole32</TT></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>Windows</TD>
|
||||
<TD>WASAPI</TD>
|
||||
<TD>RtApiWasapi</TD>
|
||||
<TD>__WINDOWS_WASAPI__</TD>
|
||||
<TD>MinGW: <TT>FunctionDiscoveryKeys_devpkey.h, lksuser, lmfplat, lmfuuid, lwmcodecdspuuid, lwinmm, lole32</TT></TD>
|
||||
<TD>MinGW: <TT>g++ -Wall -D__WINDOWS_WASAPI__ -Iinclude -o audioprobe audioprobe.cpp RtAudio.cpp -lole32 -lwinmm -lksuser -lmfplat -lmfuuid -lwmcodecdspuuid</TT></TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
<P>
|
||||
|
||||
The example compiler statements above could be used to compile the <TT>audioprobe.cpp</TT> example file, assuming that <TT>audioprobe.cpp</TT>, <TT>RtAudio.h</TT>, <TT>RtAudio.cpp</TT> and any other necessary files all exist in the same directory or the include directory.
|
||||
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,76 @@
|
||||
/*! \page duplex Duplex Mode
|
||||
|
||||
Finally, it is easy to use RtAudio for simultaneous audio input/output, or duplex operation. In this example, we simply pass the input data back to the output.
|
||||
|
||||
\code
|
||||
#include "RtAudio.h"
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
// Pass-through function.
|
||||
int inout( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
|
||||
double streamTime, RtAudioStreamStatus status, void *data )
|
||||
{
|
||||
// Since the number of input and output channels is equal, we can do
|
||||
// a simple buffer copy operation here.
|
||||
if ( status ) std::cout << "Stream over/underflow detected." << std::endl;
|
||||
|
||||
unsigned int *bytes = (unsigned int *) data;
|
||||
memcpy( outputBuffer, inputBuffer, *bytes );
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
RtAudio adac;
|
||||
if ( adac.getDeviceCount() < 1 ) {
|
||||
std::cout << "\nNo audio devices found!\n";
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
// Set the same number of channels for both input and output.
|
||||
unsigned int bufferBytes, bufferFrames = 512;
|
||||
RtAudio::StreamParameters iParams, oParams;
|
||||
iParams.deviceId = 0; // first available device
|
||||
iParams.nChannels = 2;
|
||||
oParams.deviceId = 0; // first available device
|
||||
oParams.nChannels = 2;
|
||||
|
||||
try {
|
||||
adac.openStream( &oParams, &iParams, RTAUDIO_SINT32, 44100, &bufferFrames, &inout, (void *)&bufferBytes );
|
||||
}
|
||||
catch ( RtAudioError& e ) {
|
||||
e.printMessage();
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
bufferBytes = bufferFrames * 2 * 4;
|
||||
|
||||
try {
|
||||
adac.startStream();
|
||||
|
||||
char input;
|
||||
std::cout << "\nRunning ... press <enter> to quit.\n";
|
||||
std::cin.get(input);
|
||||
|
||||
// Stop the stream.
|
||||
adac.stopStream();
|
||||
}
|
||||
catch ( RtAudioError& e ) {
|
||||
e.printMessage();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if ( adac.isStreamOpen() ) adac.closeStream();
|
||||
|
||||
return 0;
|
||||
}
|
||||
\endcode
|
||||
|
||||
In this example, audio recorded by the stream input will be played out during the next round of audio processing.
|
||||
|
||||
Note that a duplex stream can make use of two different devices (except when using the Linux Jack and Windows ASIO APIs). However, this may cause timing problems due to possible device clock variations, unless a common external "sync" is provided.
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,5 @@
|
||||
/*! \page errors Error Handling
|
||||
|
||||
RtAudio makes restrained use of C++ exceptions. That is, exceptions are thrown only when system errors occur that prevent further class operation or when the user makes invalid function calls. In other cases, a warning message may be displayed and an appropriate value is returned. For example, if a system error occurs when processing the RtAudio::getDeviceCount() function, the return value is zero. In such a case, the user cannot expect to make use of most other RtAudio functions because no devices are available (and thus a stream cannot be opened). A client can call the function RtAudio::showWarnings() with a boolean argument to enable or disable the printing of warning messages to <tt>stderr</tt>. By default, warning messages are displayed. There is a protected RtAudio method, error(), that can be modified to globally control how these messages are handled and reported.
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,8 @@
|
||||
<HR>
|
||||
|
||||
<table><tr><td><img src="../images/mcgill.gif" width=165></td>
|
||||
<td>©2001-2021 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>
|
||||
</table>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
@@ -0,0 +1,10 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>The RtAudio Home Page</TITLE>
|
||||
<LINK HREF="doxygen.css" REL="stylesheet" TYPE="text/css">
|
||||
<LINK REL="SHORTCUT ICON" HREF="http://www.music.mcgill.ca/~gary/favicon.ico">
|
||||
</HEAD>
|
||||
<BODY BGCOLOR="#FFFFFF">
|
||||
<CENTER>
|
||||
<a class="qindex" href="index.html">Home</a> <a class="qindex" href="annotated.html">Class/Enum List</a> <a class="qindex" href="files.html">File List</a> <a class="qindex" href="functions.html">Compound Members</a> <a class="qindex" href="group__C-interface.html">C interface</a> </CENTER>
|
||||
<HR>
|
||||
@@ -0,0 +1,30 @@
|
||||
/*! \page license License
|
||||
|
||||
RtAudio: a set of realtime audio i/o C++ classes<BR>
|
||||
Copyright (c) 2001-2021 Gary P. Scavone
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation files
|
||||
(the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
Any person wishing to distribute modifications to the Software is
|
||||
asked to send the modifications to the original developer so that
|
||||
they can be incorporated into the canonical version. This is,
|
||||
however, not a binding provision of this license.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,7 @@
|
||||
/*! \page multi Using Simultaneous Multiple APIs
|
||||
|
||||
Because support for each audio API is encapsulated in a specific RtApi subclass, it is possible to compile and instantiate multiple API-specific subclasses on a given operating system. For example, one can compile both the RtApiDs and RtApiAsio classes on Windows operating systems by providing the appropriate preprocessor definitions, include files, and libraries for each. In a run-time situation, one might first attempt to determine whether any ASIO device drivers exist. This can be done by specifying the api argument RtAudio::WINDOWS_ASIO when attempting to create an instance of RtAudio. If no available devices are found, then an instance of RtAudio with the api argument RtAudio::WINDOWS_DS can be created. Alternately, if no api argument is specified, RtAudio will first look for an ASIO instance and then a DirectSound instance (on Linux systems, the default API search order is Jack, Alsa, and finally OSS). In theory, it should also be possible to have separate instances of RtAudio open at the same time with different underlying audio API support, though this has not been tested. It is difficult to know how well different audio APIs can simultaneously coexist on a given operating system. In particular, it is unlikely that the same device could be simultaneously controlled with two different audio APIs.
|
||||
|
||||
The static function RtAudio::getCompiledApi() is provided to determine the available compiled API support. The function RtAudio::getCurrentApi() indicates the API selected for a given RtAudio instance.
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,82 @@
|
||||
/*! \page playback Playback
|
||||
|
||||
In this example, we provide a complete program that demonstrates the use of RtAudio for audio playback. Our program produces a two-channel sawtooth waveform for output.
|
||||
|
||||
\code
|
||||
#include "RtAudio.h"
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
|
||||
// Two-channel sawtooth wave generator.
|
||||
int saw( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
|
||||
double streamTime, RtAudioStreamStatus status, void *userData )
|
||||
{
|
||||
unsigned int i, j;
|
||||
double *buffer = (double *) outputBuffer;
|
||||
double *lastValues = (double *) userData;
|
||||
|
||||
if ( status )
|
||||
std::cout << "Stream underflow detected!" << std::endl;
|
||||
|
||||
// Write interleaved audio data.
|
||||
for ( i=0; i<nBufferFrames; i++ ) {
|
||||
for ( j=0; j<2; j++ ) {
|
||||
*buffer++ = lastValues[j];
|
||||
|
||||
lastValues[j] += 0.005 * (j+1+(j*0.1));
|
||||
if ( lastValues[j] >= 1.0 ) lastValues[j] -= 2.0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
RtAudio dac;
|
||||
if ( dac.getDeviceCount() < 1 ) {
|
||||
std::cout << "\nNo audio devices found!\n";
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
RtAudio::StreamParameters parameters;
|
||||
parameters.deviceId = dac.getDefaultOutputDevice();
|
||||
parameters.nChannels = 2;
|
||||
parameters.firstChannel = 0;
|
||||
unsigned int sampleRate = 44100;
|
||||
unsigned int bufferFrames = 256; // 256 sample frames
|
||||
double data[2] = {0, 0};
|
||||
|
||||
try {
|
||||
dac.openStream( ¶meters, NULL, RTAUDIO_FLOAT64,
|
||||
sampleRate, &bufferFrames, &saw, (void *)&data );
|
||||
dac.startStream();
|
||||
}
|
||||
catch ( RtAudioError& e ) {
|
||||
e.printMessage();
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
char input;
|
||||
std::cout << "\nPlaying ... press <enter> to quit.\n";
|
||||
std::cin.get( input );
|
||||
|
||||
try {
|
||||
// Stop the stream
|
||||
dac.stopStream();
|
||||
}
|
||||
catch (RtAudioError& e) {
|
||||
e.printMessage();
|
||||
}
|
||||
|
||||
if ( dac.isStreamOpen() ) dac.closeStream();
|
||||
|
||||
return 0;
|
||||
}
|
||||
\endcode
|
||||
|
||||
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 \e "saw()". 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 RtAudio::startStream() and RtAudio::stopStream() functions). We can also pass a pointer value to the RtAudio::openStream() function that is made available in the callback function. In this way, it is possible to gain access to arbitrary data created in our \e main() function from within the globally defined callback function.
|
||||
|
||||
In this example, we stop the stream with an explicit call to RtAudio::stopStream(). 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 RtAudio::stopStream() function). A return value of 2 will cause the stream to stop immediately (equivalent to calling the RtAudio::abortStream() function).
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,73 @@
|
||||
/*! \page probe Probing Device Capabilities
|
||||
|
||||
A programmer may wish to query the available audio device capabilities before deciding which to use. The following example outlines how this can be done.
|
||||
|
||||
\code
|
||||
|
||||
// audioprobe.cpp
|
||||
|
||||
#include <iostream>
|
||||
#include "RtAudio.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
RtAudio audio;
|
||||
|
||||
// Determine the number of devices available
|
||||
unsigned int devices = audio.getDeviceCount();
|
||||
|
||||
// Scan through devices for various capabilities
|
||||
RtAudio::DeviceInfo info;
|
||||
for ( unsigned int i=0; i<devices; i++ ) {
|
||||
|
||||
info = audio.getDeviceInfo( i );
|
||||
|
||||
if ( info.probed == true ) {
|
||||
// Print, for example, the maximum number of output channels for each device
|
||||
std::cout << "device = " << i;
|
||||
std::cout << ": maximum output channels = " << info.outputChannels << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
\endcode
|
||||
|
||||
The RtAudio::DeviceInfo structure is defined in RtAudio.h and provides a variety of information useful in assessing the capabilities of a device:
|
||||
|
||||
\code
|
||||
typedef struct RtAudio::DeviceInfo {
|
||||
bool probed; // true if the device capabilities were successfully probed.
|
||||
std::string name; // Character string device identifier.
|
||||
unsigned int outputChannels; // Maximum output channels supported by device.
|
||||
unsigned int inputChannels; // Maximum input channels supported by device.
|
||||
unsigned int duplexChannels; // Maximum simultaneous input/output channels supported by device.
|
||||
bool isDefaultOutput; // true if this is the default output device.
|
||||
bool isDefaultInput; // true if this is the default input device.
|
||||
std::vector<unsigned int> sampleRates; // Supported sample rates.
|
||||
unsigned int preferredSampleRate; // Preferred sample rate, e.g. for WASAPI the system sample rate.
|
||||
RtAudioFormat nativeFormats; // Bit mask of supported data formats.
|
||||
};
|
||||
\endcode
|
||||
|
||||
The following data formats are defined and fully supported by RtAudio:
|
||||
|
||||
\code
|
||||
typedef unsigned long RtAudioFormat;
|
||||
static const RtAudioFormat RTAUDIO_SINT8 = 0x1; // 8-bit signed integer.
|
||||
static const RtAudioFormat RTAUDIO_SINT16 = 0x2; // 16-bit signed integer.
|
||||
static const RtAudioFormat RTAUDIO_SINT24 = 0x4; // 24-bit signed integer.
|
||||
static const RtAudioFormat RTAUDIO_SINT32 = 0x8; // 32-bit signed integer.
|
||||
static const RtAudioFormat RTAUDIO_FLOAT32 = 0x10; // Normalized between plus/minus 1.0.
|
||||
static const RtAudioFormat RTAUDIO_FLOAT64 = 0x20; // Normalized between plus/minus 1.0.
|
||||
\endcode
|
||||
|
||||
The \c nativeFormats member of the RtAudio::DeviceInfo structure is a bit mask of the above formats which are natively supported by the device. However, RtAudio will automatically provide format conversion if a particular format is not natively supported. When the \c probed member of the RtAudio::DeviceInfo structure is false, the remaining structure members are undefined and the device is probably unusable.
|
||||
|
||||
Some audio devices may require a minimum channel value greater than one. RtAudio will provide automatic channel number compensation when the number of channels set by the user is less than that required by the device. Channel compensation is <I>NOT</I> possible when the number of channels set by the user is greater than that supported by the device.
|
||||
|
||||
Note that the device enumeration is system specific and will change if any devices are plugged or unplugged by the user. Thus, the device numbers should be verified immediately before opening a stream. As well, if a user unplugs a device while an open stream is using that device, the resulting stream behaviour will be undefined (a system error will likely be generated).
|
||||
|
||||
Also, the capabilities reported by a device driver or underlying audio API are not always accurate and/or may be dependent on a combination of device settings. For this reason, RtAudio does not rely on the queried values when attempting to open a stream.
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,68 @@
|
||||
/*! \page recording Recording
|
||||
|
||||
|
||||
Using RtAudio for audio input is almost identical to the way it is used for playback. Here's the blocking playback example rewritten for recording:
|
||||
|
||||
\code
|
||||
#include "RtAudio.h"
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
int record( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames,
|
||||
double streamTime, RtAudioStreamStatus status, void *userData )
|
||||
{
|
||||
if ( status )
|
||||
std::cout << "Stream overflow detected!" << std::endl;
|
||||
|
||||
// Do something with the data in the "inputBuffer" buffer.
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
RtAudio adc;
|
||||
if ( adc.getDeviceCount() < 1 ) {
|
||||
std::cout << "\nNo audio devices found!\n";
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
RtAudio::StreamParameters parameters;
|
||||
parameters.deviceId = adc.getDefaultInputDevice();
|
||||
parameters.nChannels = 2;
|
||||
parameters.firstChannel = 0;
|
||||
unsigned int sampleRate = 44100;
|
||||
unsigned int bufferFrames = 256; // 256 sample frames
|
||||
|
||||
try {
|
||||
adc.openStream( NULL, ¶meters, RTAUDIO_SINT16,
|
||||
sampleRate, &bufferFrames, &record );
|
||||
adc.startStream();
|
||||
}
|
||||
catch ( RtAudioError& e ) {
|
||||
e.printMessage();
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
char input;
|
||||
std::cout << "\nRecording ... press <enter> to quit.\n";
|
||||
std::cin.get( input );
|
||||
|
||||
try {
|
||||
// Stop the stream
|
||||
adc.stopStream();
|
||||
}
|
||||
catch (RtAudioError& e) {
|
||||
e.printMessage();
|
||||
}
|
||||
|
||||
if ( adc.isStreamOpen() ) adc.closeStream();
|
||||
|
||||
return 0;
|
||||
}
|
||||
\endcode
|
||||
|
||||
In this example, we pass the address of the stream parameter structure as the second argument of the RtAudio::openStream() function and pass a NULL value for the output stream parameters. In this example, the \e record() callback function performs no specific operations.
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,48 @@
|
||||
/*! \page settings Device Settings
|
||||
|
||||
The next step in using RtAudio is to open a stream with particular device and parameter settings.
|
||||
|
||||
\code
|
||||
|
||||
#include "RtAudio.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
RtAudio dac;
|
||||
if ( dac.getDeviceCount() == 0 ) exit( 0 );
|
||||
|
||||
RtAudio::StreamParameters parameters;
|
||||
parameters.deviceId = dac.getDefaultOutputDevice();
|
||||
parameters.nChannels = 2;
|
||||
unsigned int sampleRate = 44100;
|
||||
unsigned int bufferFrames = 256; // 256 sample frames
|
||||
|
||||
RtAudio::StreamOptions options;
|
||||
options.flags = RTAUDIO_NONINTERLEAVED;
|
||||
|
||||
try {
|
||||
dac.openStream( ¶meters, NULL, RTAUDIO_FLOAT32,
|
||||
sampleRate, &bufferFrames, &myCallback, NULL, &options );
|
||||
}
|
||||
catch ( RtAudioError& e ) {
|
||||
std::cout << '\n' << e.getMessage() << '\n' << std::endl;
|
||||
exit( 0 );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
\endcode
|
||||
|
||||
The RtAudio::openStream() function attempts to open a stream with a specified set of parameter values. In the above example, we attempt to open a two channel playback stream using the default output device, 32-bit floating point data, a sample rate of 44100 Hz, and a frame rate of 256 sample frames per output buffer. If the user specifies an invalid parameter value (such as a device id greater than or equal to the number of enumerated devices), an RtAudioError is thrown of type = INVALID_USE. If a system error occurs or the device does not support the specified parameter values, an RtAudioError of type = SYSTEM_ERROR is thrown. In either case, a descriptive error message is bundled with the exception and can be queried with the RtAudioError::getMessage() or RtAudioError::what() functions.
|
||||
|
||||
RtAudio provides four signed integer and two floating point data formats which can be specified using the RtAudioFormat parameter values mentioned earlier. If the opened device does not natively support the given format, RtAudio will automatically perform the necessary data format conversion.
|
||||
|
||||
The \c bufferFrames parameter specifies the desired number of sample frames that will be written to and/or read from a device per write/read operation. This parameter can be used to control stream latency though there is no guarantee that the passed value will be that used by a device. In general, a lower \c bufferFrames value will produce less latency but perhaps less robust performance. A value of zero can be specified, in which case the smallest allowable value will be used. The \c bufferFrames parameter is passed as a pointer and the actual value used by the stream is set during the device setup procedure. \c bufferFrames values should be a power of two. Optimal and allowable buffer values tend to vary between systems and devices. Stream latency can also be controlled via the optional RtAudio::StreamOptions member \c numberOfBuffers (not used in the example above), though this tends to be more system dependent. In particular, the \c numberOfBuffers parameter is ignored when using the OS-X Core Audio, Jack, and the Windows ASIO APIs.
|
||||
|
||||
As noted earlier, the device capabilities reported by a driver or underlying audio API are not always accurate and/or may be dependent on a combination of device settings. Because of this, RtAudio does not attempt to query a device's capabilities or use previously reported values when opening a device. Instead, RtAudio simply attempts to set the given parameters on a specified device and then checks whether the setup is successful or not.
|
||||
|
||||
The RtAudioCallback parameter above is a pointer to a user-defined function that will be called whenever the audio system is ready for new output data or has new input data to be read. Further details on the use of a callback function are provided in the next section.
|
||||
|
||||
Several stream options are available to fine-tune the behavior of an audio stream. In the example above, we specify that data will be written by the user in a \e non-interleaved format via the RtAudio::StreamOptions member \c flags. That is, all \c bufferFrames of the first channel should be written consecutively, followed by all \c bufferFrames of the second channel. By default (when no option is specified), RtAudio expects data to be written in an \e interleaved format.
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,48 @@
|
||||
/*! \mainpage The RtAudio Home Page
|
||||
|
||||
RtAudio is a set of C++ classes that provide a common API (Application Programming Interface) for realtime audio input/output across Linux, Macintosh OS-X and Windows operating systems. RtAudio significantly simplifies the process of interacting with computer audio hardware. It was designed with the following objectives:
|
||||
|
||||
- object-oriented C++ design
|
||||
- simple, common API across all supported platforms
|
||||
- only one source and one header file for easy inclusion in programming projects
|
||||
- allow simultaneous multi-api support
|
||||
- support dynamic connection of devices
|
||||
- provide extensive audio device parameter control
|
||||
- allow audio device capability probing
|
||||
- automatic internal conversion for data format, channel number compensation, (de)interleaving, and byte-swapping
|
||||
|
||||
RtAudio incorporates the concept of audio streams, which represent audio output (playback) and/or input (recording). Available audio devices and their capabilities can be enumerated and then specified when opening a stream. Where applicable, multiple API support can be compiled and a particular API specified when creating an RtAudio instance. See the \ref apinotes section for information specific to each of the supported audio APIs.
|
||||
|
||||
\section whatsnew Latest Updates (Version 5.2.0)
|
||||
|
||||
Changes in this release include:
|
||||
|
||||
- update to audioprobe.cpp to list devices for all APIs
|
||||
- miscellaneous build system updates
|
||||
- PulseAudio device detection fixes
|
||||
- various WASAPI updates (thanks to Marcus Tomlinson)
|
||||
- see git history for complete list of changes
|
||||
|
||||
\section download Download
|
||||
|
||||
Latest Release (15 November 2021): <A href="http://www.music.mcgill.ca/~gary/rtaudio/release/rtaudio-5.2.0.tar.gz">Version 5.2.0</A>
|
||||
|
||||
\section documentation Documentation Links
|
||||
|
||||
-# \ref errors
|
||||
-# \ref probe
|
||||
-# \ref settings
|
||||
-# \ref playback
|
||||
-# \ref recording
|
||||
-# \ref duplex
|
||||
-# \ref multi
|
||||
-# \ref compiling
|
||||
-# \ref apinotes
|
||||
-# \ref acknowledge
|
||||
-# \ref license
|
||||
-# <A href="http://github.com/thestk/rtaudio">RtAudio on GitHub</A>
|
||||
|
||||
*/
|
||||
|
||||
-# <A href="bugs.html">Bug Tracker (out of date)</A>
|
||||
-# <A href="updates.html">Possible Updates (out of date)</A>
|
||||
Reference in New Issue
Block a user