├── CMakeLists.txt ├── LICENSE ├── Makefile.am ├── README.md ├── RtAudio.cpp ├── RtAudio.h ├── autogen.sh ├── cmake └── RtAudioConfigUninstall.cmake.in ├── configure.ac ├── contrib ├── go │ └── rtaudio │ │ ├── rtaudio.go │ │ ├── rtaudio_stub.cpp │ │ ├── rtaudio_stub.h │ │ └── rtaudio_test.go └── python │ └── pyrtaudio │ ├── PyRtAudioTest.py │ ├── readme │ ├── rtaudiomodule.cpp │ └── setup.py ├── doc ├── Doxyfile.in ├── Makefile.am ├── doxygen │ ├── acknowledge.txt │ ├── apinotes.txt │ ├── compiling.txt │ ├── duplex.txt │ ├── error.txt │ ├── footer.html │ ├── header.html │ ├── license.txt │ ├── multi.txt │ ├── playback.txt │ ├── probe.txt │ ├── recording.txt │ ├── settings.txt │ └── tutorial.txt ├── images │ ├── ccrma.gif │ ├── mcgill.gif │ └── meson.build ├── meson.build └── release.txt ├── include ├── asio.cpp ├── asio.h ├── asiodrivers.cpp ├── asiodrivers.h ├── asiodrvr.h ├── asioinfo.txt ├── asiolist.cpp ├── asiolist.h ├── asiosys.h ├── dsound.h ├── functiondiscoverykeys_devpkey.h ├── ginclude.h ├── iasiodrv.h ├── iasiothiscallresolver.cpp ├── iasiothiscallresolver.h └── soundcard.h ├── install.txt ├── m4 └── ax_cxx_compile_stdcxx.m4 ├── meson.build ├── meson_options.txt ├── rtaudio.pc.in ├── rtaudio_c.cpp ├── rtaudio_c.h └── tests ├── CMakeLists.txt ├── Debug └── .placeholder ├── Makefile.am ├── Release └── .placeholder ├── Windows ├── Debug │ └── .placeholder ├── Release │ └── .placeholder ├── audioprobe.dsp ├── duplex.dsp ├── playraw.dsp ├── playsaw.dsp ├── record.dsp ├── rtaudio.dsw ├── testall.dsp └── teststops.dsp ├── apinames.cpp ├── audioprobe.cpp ├── duplex.cpp ├── meson.build ├── playraw.cpp ├── playsaw.cpp ├── record.cpp ├── testall.cpp └── teststops.cpp /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | RtAudio: a set of realtime audio i/o C++ classes 3 | Copyright (c) 2001-2023 Gary P. Scavone 4 | 5 | Permission is hereby granted, free of charge, to any person 6 | obtaining a copy of this software and associated documentation files 7 | (the "Software"), to deal in the Software without restriction, 8 | including without limitation the rights to use, copy, modify, merge, 9 | publish, distribute, sublicense, and/or sell copies of the Software, 10 | and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | Any person wishing to distribute modifications to the Software is 17 | asked to send the modifications to the original developer so that 18 | they can be incorporated into the canonical version. This is, 19 | however, not a binding provision of this license. 20 | 21 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 24 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 25 | ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 26 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 27 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = . tests 2 | if MAKE_DOC 3 | SUBDIRS += doc 4 | endif 5 | 6 | AM_CXXFLAGS = @visibility@ 7 | 8 | lib_LTLIBRARIES = %D%/librtaudio.la 9 | %C%_librtaudio_la_CXXFLAGS = -DRTAUDIO_EXPORT 10 | %C%_librtaudio_la_LDFLAGS = -no-undefined -export-dynamic -version-info @SO_VERSION@ 11 | %C%_librtaudio_la_SOURCES = \ 12 | %D%/RtAudio.cpp \ 13 | %D%/rtaudio_c.cpp 14 | 15 | if ASIO 16 | %C%_librtaudio_la_SOURCES += \ 17 | include/asio.cpp \ 18 | include/asiodrivers.cpp \ 19 | include/asiolist.cpp \ 20 | include/iasiothiscallresolver.cpp 21 | 22 | # due to warning in asiolist.cpp 23 | %C%_librtaudio_la_CXXFLAGS += -Wno-error=unused-but-set-variable 24 | endif 25 | 26 | rtaudio_incdir = $(includedir)/rtaudio 27 | rtaudio_inc_HEADERS = \ 28 | %D%/RtAudio.h \ 29 | %D%/rtaudio_c.h 30 | 31 | pkgconfigdatadir = $(libdir)/pkgconfig 32 | pkgconfigdata_DATA = rtaudio.pc 33 | 34 | EXTRA_DIST = autogen.sh README.md install.txt contrib include cmake CMakeLists.txt 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RtAudio 2 | 3 | ![Build Status](https://github.com/thestk/rtaudio/actions/workflows/ci.yml/badge.svg) 4 | 5 | A set of C++ classes that provide a common API for realtime audio input/output across Linux (native ALSA, JACK, PulseAudio and OSS), Macintosh OS X (CoreAudio and JACK), and Windows (DirectSound, ASIO and WASAPI) operating systems. 6 | 7 | By Gary P. Scavone, 2001-2023 (and many other developers!) 8 | 9 | This distribution of RtAudio contains the following: 10 | 11 | - doc: RtAudio documentation (see doc/html/index.html) 12 | - tests: example RtAudio programs 13 | - include: header and source files necessary for ASIO, DS & OSS compilation 14 | - tests/Windows: Visual C++ .net test program workspace and projects 15 | 16 | ## Overview 17 | 18 | RtAudio is a set of C++ classes that provides a common API (Application Programming Interface) for realtime audio input/output across Linux (native ALSA, JACK, PulseAudio and OSS), Macintosh OS X and Windows (DirectSound, ASIO and WASAPI) operating systems. RtAudio significantly simplifies the process of interacting with computer audio hardware. It was designed with the following objectives: 19 | 20 | - object-oriented C++ design 21 | - simple, common API across all supported platforms 22 | - only one source and one header file for easy inclusion in programming projects 23 | - allow simultaneous multi-api support 24 | - support dynamic connection of devices 25 | - provide extensive audio device parameter control 26 | - allow audio device capability probing 27 | - automatic internal conversion for data format, channel number compensation, (de)interleaving, and byte-swapping 28 | 29 | 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. 30 | 31 | ## Building 32 | 33 | Several build systems are available. These are: 34 | 35 | - autotools (`./autogen.sh; make` from git, or `./configure; make` from tarball release) 36 | - CMake (`mkdir build; cd build; ../cmake; make`) 37 | - meson (`meson build; cd build; ninja`) 38 | - vcpkg (`./bootstrap-vcpkg.sh; ./vcpkg integrate install; ./vcpkg install rtaudio`) 39 | 40 | See `install.txt` for more instructions about how to select the audio backend API. By 41 | default all detected APIs will be enabled. 42 | 43 | We recommend using the autotools-based build for packaging purposes. Please note that 44 | RtAudio is designed as a single `.cpp` and `.h` file so that it is easy to copy directly 45 | into a project. In that case you need to define the appropriate flags for the desired 46 | backend APIs. 47 | 48 | ## FAQ 49 | 50 | ### Why does audio only come to one ear when I choose 1-channel output? 51 | 52 | RtAudio doesn't automatically turn 1-channel output into stereo output with copied values to two channels, since there may be cases when a user truly wants 1-channel behaviour. If you want monophonic data to be projected to stereo output, open a 2-channel stream and copy the data to both channels in your audio stream callback. 53 | 54 | ## Further Reading 55 | 56 | For complete documentation on RtAudio, see the doc directory of the distribution or surf to http://www.music.mcgill.ca/~gary/rtaudio/. 57 | 58 | 59 | ## Legal and ethical: 60 | 61 | The RtAudio license is similar to the MIT License. Please see [LICENSE](LICENSE). 62 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Run this to generate all the initial makefiles, etc. 3 | 4 | srcdir=`dirname $0` 5 | test -z "$srcdir" && srcdir=. 6 | 7 | DIE=0 8 | 9 | if test -z "$*"; then 10 | echo "**Warning**: I am going to run \`configure' with arguments for" 11 | echo "developer/maintainer mode. If you wish to pass extra arguments," 12 | echo "(such as --prefix), please specify them on the \`$0'" 13 | echo "command line." 14 | echo "If you wish to run configure yourself, please specify --no-configure." 15 | echo 16 | fi 17 | 18 | (test -f $srcdir/configure.ac) || { 19 | echo -n "**Error**: Directory "\`$srcdir\'" does not look like the" 20 | echo " top-level package directory" 21 | exit 1 22 | } 23 | 24 | # Make some directories required by automake, if they don't exist 25 | if ! [ -d config ]; then mkdir -v config; fi 26 | if ! [ -d m4 ]; then mkdir -v m4; fi 27 | 28 | if ! autoreconf --version /dev/null 2>&1 29 | then 30 | 31 | (autoconf --version) < /dev/null > /dev/null 2>&1 || { 32 | echo 33 | echo "**Error**: You must have \`autoconf' installed." 34 | echo "Download the appropriate package for your distribution," 35 | echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/" 36 | DIE=1 37 | } 38 | 39 | (grep "^LT_INIT" $srcdir/configure.ac >/dev/null) && { 40 | (libtoolize --version) < /dev/null > /dev/null 2>&1 \ 41 | && LIBTOOLIZE=libtoolize || { 42 | (glibtoolize --version) < /dev/null > /dev/null 2>&1 \ 43 | && LIBTOOLIZE=glibtoolize || { 44 | echo 45 | echo "**Error**: You must have \`libtool' installed." 46 | echo "You can get it from: ftp://ftp.gnu.org/pub/gnu/" 47 | DIE=1 48 | } 49 | } 50 | } 51 | 52 | (automake --version) < /dev/null > /dev/null 2>&1 || { 53 | echo 54 | echo "**Error**: You must have \`automake' installed." 55 | echo "You can get it from: ftp://ftp.gnu.org/pub/gnu/" 56 | DIE=1 57 | NO_AUTOMAKE=yes 58 | } 59 | 60 | 61 | # if no automake, don't bother testing for aclocal 62 | test -n "$NO_AUTOMAKE" || (aclocal --version) < /dev/null > /dev/null 2>&1 || { 63 | echo 64 | echo "**Error**: Missing \`aclocal'. The version of \`automake'" 65 | echo "installed doesn't appear recent enough." 66 | echo "You can get automake from ftp://ftp.gnu.org/pub/gnu/" 67 | DIE=1 68 | } 69 | 70 | if test "$DIE" -eq 1; then 71 | exit 1 72 | fi 73 | 74 | case $CC in 75 | xlc ) 76 | am_opt=--include-deps;; 77 | esac 78 | 79 | echo "Running aclocal $aclocalinclude ..." 80 | aclocal $ACLOCAL_FLAGS || exit 1 81 | echo "Running $LIBTOOLIZE ..." 82 | $LIBTOOLIZE || exit 1 83 | echo "Running automake --gnu $am_opt ..." 84 | automake --add-missing --gnu $am_opt || exit 1 85 | echo "Running autoconf ..." 86 | autoconf || exit 1 87 | 88 | else # autoreconf instead 89 | 90 | echo "Running autoreconf --verbose --install ..." 91 | autoreconf --verbose --install || exit 1 92 | 93 | fi 94 | 95 | if ( echo "$@" | grep -q -e "--no-configure" ); then 96 | NOCONFIGURE=1 97 | fi 98 | 99 | conf_flags="--enable-maintainer-mode --enable-debug --disable-silent-rules" 100 | 101 | if test x$NOCONFIGURE = x; then 102 | echo Running $srcdir/configure $conf_flags "$@" ... 103 | $srcdir/configure $conf_flags "$@" \ 104 | && echo Now type \`make\' to compile. || exit 1 105 | else 106 | echo Skipping configure process. 107 | fi 108 | -------------------------------------------------------------------------------- /cmake/RtAudioConfigUninstall.cmake.in: -------------------------------------------------------------------------------- 1 | if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 2 | message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") 3 | endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") 4 | 5 | file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) 6 | string(REGEX REPLACE "\n" ";" files "${files}") 7 | foreach(file ${files}) 8 | message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") 9 | if(EXISTS "$ENV{DESTDIR}${file}") 10 | exec_program( 11 | "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" 12 | OUTPUT_VARIABLE rm_out 13 | RETURN_VALUE rm_retval 14 | ) 15 | if(NOT "${rm_retval}" STREQUAL 0) 16 | message(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") 17 | endif(NOT "${rm_retval}" STREQUAL 0) 18 | else(EXISTS "$ENV{DESTDIR}${file}") 19 | message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") 20 | endif(EXISTS "$ENV{DESTDIR}${file}") 21 | endforeach(file) 22 | -------------------------------------------------------------------------------- /contrib/go/rtaudio/rtaudio_stub.cpp: -------------------------------------------------------------------------------- 1 | #include "../../../RtAudio.h" 2 | 3 | #include "../../../RtAudio.cpp" 4 | #include "../../../rtaudio_c.cpp" 5 | -------------------------------------------------------------------------------- /contrib/go/rtaudio/rtaudio_stub.h: -------------------------------------------------------------------------------- 1 | #include "../../../rtaudio_c.h" 2 | -------------------------------------------------------------------------------- /contrib/go/rtaudio/rtaudio_test.go: -------------------------------------------------------------------------------- 1 | package rtaudio 2 | 3 | import ( 4 | "log" 5 | "math" 6 | "time" 7 | ) 8 | 9 | func ExampleCompiledAPI() { 10 | log.Println("RtAudio version: ", Version()) 11 | for _, api := range CompiledAPI() { 12 | log.Println("Compiled API: ", api) 13 | } 14 | } 15 | 16 | func ExampleRtAudio_Devices() { 17 | audio, err := Create(APIUnspecified) 18 | if err != nil { 19 | log.Fatal(err) 20 | } 21 | defer audio.Destroy() 22 | devices, err := audio.Devices() 23 | if err != nil { 24 | log.Fatal(err) 25 | } 26 | for _, d := range devices { 27 | log.Printf("Audio device: %#v\n", d) 28 | } 29 | } 30 | 31 | func ExampleRtAudio_Open() { 32 | const ( 33 | sampleRate = 44100 34 | bufSz = 512 35 | freq = 440.0 36 | ) 37 | phase := 0.0 38 | audio, err := Create(APIUnspecified) 39 | if err != nil { 40 | log.Fatal(err) 41 | } 42 | defer audio.Destroy() 43 | 44 | params := StreamParams{ 45 | DeviceID: uint(audio.DefaultOutputDevice()), 46 | NumChannels: 2, 47 | FirstChannel: 0, 48 | } 49 | options := StreamOptions{ 50 | Flags: FlagsAlsaUseDefault, 51 | } 52 | cb := func(out, in Buffer, dur time.Duration, status StreamStatus) int { 53 | samples := out.Float32() 54 | for i := 0; i < len(samples)/2; i++ { 55 | sample := float32(math.Sin(2 * math.Pi * phase)) 56 | phase += freq / sampleRate 57 | 58 | samples[i*2] = sample 59 | samples[i*2+1] = sample 60 | } 61 | return 0 62 | } 63 | err = audio.Open(¶ms, nil, FormatFloat32, sampleRate, bufSz, cb, &options) 64 | if err != nil { 65 | log.Fatal(err) 66 | } 67 | defer audio.Close() 68 | audio.Start() 69 | defer audio.Stop() 70 | time.Sleep(3 * time.Second) 71 | } 72 | -------------------------------------------------------------------------------- /contrib/python/pyrtaudio/PyRtAudioTest.py: -------------------------------------------------------------------------------- 1 | 2 | from __future__ import print_function 3 | import threading 4 | import rtaudio as rt 5 | 6 | from math import cos 7 | 8 | import struct 9 | 10 | 11 | class audio_generator: 12 | def __init__(self): 13 | self.idx = -1 14 | self.freq = 440. 15 | def __call__(self): 16 | self.idx += 1 17 | if self.idx%48000 == 0: 18 | self.freq *= 2**(1/12.) 19 | return 0.5*cos(2.*3.1416*self.freq*self.idx/48000.) 20 | 21 | 22 | class callback: 23 | def __init__(self, gen): 24 | self.gen = gen 25 | self.i = 0 26 | def __call__(self,playback, capture): 27 | [struct.pack_into("f", playback, 4*o, self.gen()) for o in range(256)] 28 | self.i = self.i + 256 29 | if self.i > 48000*10: 30 | print('.') 31 | return 1 32 | 33 | try: 34 | # if we have numpy, replace the above class 35 | import numpy as np 36 | class callback: 37 | def __init__(self, gen): 38 | print('Using Numpy.') 39 | self.freq = 440. 40 | t = np.arange(256, dtype=np.float32) / 48000.0 41 | self.phase = 2*np.pi*t 42 | self.inc = 2*np.pi*256/48000 43 | self.k = 0 44 | def __call__(self, playback, capture): 45 | # Calculate sinusoid using numpy vector operation, as 46 | # opposed to per-sample computations in the generator 47 | # above that must be collected and packed one at a time. 48 | self.k += 256 49 | if self.k > 48000: 50 | self.freq *= 2**(1/12.) 51 | self.k = 0 52 | self.phase += self.inc 53 | samples = 0.5*np.cos(self.phase * self.freq) 54 | 55 | # Ensure result is the right size! 56 | assert samples.shape[0] == 256 57 | assert samples.dtype == np.float32 58 | 59 | # Use numpy array view to do a once-copy into memoryview 60 | # (ie. we only do a single byte-wise copy of the final 61 | # result into 'playback') 62 | usamples = samples.view(dtype=np.uint8) 63 | playback_array = np.array(playback, copy=False) 64 | np.copyto(playback_array, usamples) 65 | except ModuleNotFoundError: 66 | print('Numpy not available, using struct.') 67 | 68 | dac = rt.RtAudio() 69 | 70 | n = dac.getDeviceCount() 71 | print('Number of devices available: ', n) 72 | 73 | for i in range(n): 74 | try: 75 | print(dac.getDeviceInfo(i)) 76 | except rt.RtError as e: 77 | print(e) 78 | 79 | 80 | print('Default output device: ', dac.getDefaultOutputDevice()) 81 | print('Default input device: ', dac.getDefaultInputDevice()) 82 | 83 | print('is stream open: ', dac.isStreamOpen()) 84 | print('is stream running: ', dac.isStreamRunning()) 85 | 86 | oParams = {'deviceId': 0, 'nChannels': 1, 'firstChannel': 0} 87 | iParams = {'deviceId': 0, 'nChannels': 1, 'firstChannel': 0} 88 | 89 | try: 90 | dac.openStream(oParams,oParams,48000,256,callback(audio_generator()) ) 91 | except rt.RtError as e: 92 | print(e) 93 | else: 94 | dac.startStream() 95 | 96 | import time 97 | print('latency: ', dac.getStreamLatency()) 98 | 99 | while (dac.isStreamRunning()): 100 | time.sleep(0.1) 101 | 102 | print(dac.getStreamTime()) 103 | 104 | dac.stopStream() 105 | dac.abortStream() 106 | dac.closeStream() 107 | -------------------------------------------------------------------------------- /contrib/python/pyrtaudio/readme: -------------------------------------------------------------------------------- 1 | PyRtAudio - a python wrapper around RtAudio that allows to perform audio i/o operations in real-time from the python language. 2 | 3 | By Antoine Lefebvre, 2011 4 | 5 | This software is in the development stage. Do not expect compatibility 6 | with future versions. Comments, suggestions, new features, bug fixes, 7 | etc. are welcome. 8 | 9 | 10 | This distribution of PyRtAudio contains the following: 11 | 12 | - rtaudiomodule.cpp: the python wrapper code 13 | - setup.py: a setup script use to compile and install PyRtAudio 14 | - examples: a single PyRtAudioTest.py script 15 | 16 | INSTALLATION 17 | 18 | The compilation and installation of the PyRtAudio module is handled by 19 | the python Distribution Utilities ("Distutils"). Provided that your 20 | system has a C++ compiler and is properly configure, the following 21 | command should be sufficient: 22 | 23 | >> python setup.py install 24 | 25 | Please refer to the distutils documentation for installation problems: http://docs.python.org/distutils/index.html 26 | 27 | LEGAL AND ETHICAL: 28 | 29 | The PyRtAudio license is the same as the RtAudio license: 30 | 31 | PyRtAudio: a python wrapper around RtAudio 32 | Copyright (c)2011 Antoine Lefebvre 33 | 34 | Permission is hereby granted, free of charge, to any person 35 | obtaining a copy of this software and associated documentation files 36 | (the "Software"), to deal in the Software without restriction, 37 | including without limitation the rights to use, copy, modify, merge, 38 | publish, distribute, sublicense, and/or sell copies of the Software, 39 | and to permit persons to whom the Software is furnished to do so, 40 | subject to the following conditions: 41 | 42 | The above copyright notice and this permission notice shall be 43 | included in all copies or substantial portions of the Software. 44 | 45 | Any person wishing to distribute modifications to the Software is 46 | asked to send the modifications to the original developer so that 47 | they can be incorporated into the canonical version. This is, 48 | however, not a binding provision of this license. 49 | 50 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 51 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 52 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 53 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 54 | ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 55 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 56 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 57 | 58 | -------------------------------------------------------------------------------- /contrib/python/pyrtaudio/setup.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | 3 | import os 4 | from distutils.core import setup, Extension 5 | 6 | if hasattr(os, 'uname'): 7 | OSNAME = os.uname()[0] 8 | else: 9 | OSNAME = 'Windows' 10 | 11 | 12 | define_macros = [] 13 | libraries = [] 14 | extra_link_args = [] 15 | extra_compile_args = ['-I../../../'] 16 | sources = ['rtaudiomodule.cpp', '../../../RtAudio.cpp'] 17 | 18 | 19 | if OSNAME == 'Linux': 20 | define_macros=[("__LINUX_ALSA__", ''), 21 | ('__LINUX_JACK__', '')] 22 | libraries = ['asound', 'jack', 'pthread'] 23 | 24 | elif OSNAME == 'Darwin': 25 | define_macros = [('__MACOSX_CORE__', '')] 26 | libraries = ['pthread', 'stdc++'] 27 | extra_link_args = ['-framework', 'CoreAudio'] 28 | 29 | elif OSNAME == 'Windows': 30 | define_macros = [('__WINDOWS_DS__', None), 31 | ('__WINDOWS_ASIO__', None), 32 | ('__LITTLE_ENDIAN__',None), 33 | ('WIN32',None)] 34 | libraries = ['winmm', 'dsound', 'Advapi32','Ole32','User32'] 35 | sources += ['../../../include/asio.cpp', 36 | '../../../include/asiodrivers.cpp', 37 | '../../../include/asiolist.cpp', 38 | '../../../include/iasiothiscallresolver.cpp'] 39 | extra_compile_args.append('-I../../../include/') 40 | extra_compile_args.append('-EHsc') 41 | 42 | 43 | audio = Extension('rtaudio', 44 | sources=sources, 45 | libraries=libraries, 46 | define_macros=define_macros, 47 | extra_compile_args = extra_compile_args, 48 | extra_link_args = extra_link_args, 49 | ) 50 | 51 | 52 | setup(name = 'rtaudio', 53 | version = '0.1', 54 | description = 'Python RtAudio interface', 55 | ext_modules = [audio]) 56 | 57 | -------------------------------------------------------------------------------- /doc/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | MAINTAINERCLEANFILES=Makefile.in 3 | 4 | CLEANFILES=doxygen-build.stamp 5 | 6 | DOX=Doxyfile 7 | 8 | EXTRA_DIST=html 9 | 10 | INSTIMAGES=html/doxygen.png 11 | 12 | DOC_STAMPS=doxygen-build.stamp 13 | 14 | DOC_DIR=$(HTML_DIR) 15 | 16 | all-local: doxygen-build.stamp 17 | 18 | doxygen-build.stamp: $(DOX) $(top_srcdir)/RtAudio.h 19 | @echo '*** Running doxygen ***' 20 | $(DOXYGEN) $(DOX) 21 | touch doxygen-build.stamp 22 | 23 | clean-local: 24 | rm -f *~ *.bak $(DOC_STAMPS) || true 25 | if test -d html; then rm -fr html; fi 26 | if test -d latex; then rm -fr latex; fi 27 | if test -d man; then rm -fr man; fi 28 | 29 | distclean-local: clean 30 | rm -f *.stamp || true 31 | if test -d html; then rm -rf html; fi 32 | 33 | html-local: $(DOC_STAMPS) 34 | -------------------------------------------------------------------------------- /doc/doxygen/acknowledge.txt: -------------------------------------------------------------------------------- 1 | /*! \page acknowledge Acknowledgements 2 | 3 | Many thanks to the following people for providing bug fixes and improvements: 4 | 43 | 44 | The RtAudio API incorporates many of the concepts developed in the PortAudio project by Phil Burk and Ross Bencina. Early development also incorporated ideas from Bill Schottstaedt's sndlib. The CCRMA SoundWire group provided valuable feedback during the API proposal stages. 45 | 46 | The early 2.0 version of RtAudio was slowly developed over the course of many months while in residence at the Institut Universitari de L'Audiovisual (IUA) in Barcelona, Spain and the Laboratory of Acoustics and Audio Signal Processing at the Helsinki University of Technology, Finland. Much subsequent development happened while working at the Center for Computer Research in Music and Acoustics (CCRMA) at Stanford University. The early stages of this work were supported in part by the United States Air Force Office of Scientific Research (grant \#F49620-99-1-0293). All recent versions of RtAudio have been completed while working as a professor of Music Technology at McGill University. 47 | 48 | */ 49 | -------------------------------------------------------------------------------- /doc/doxygen/apinotes.txt: -------------------------------------------------------------------------------- 1 | /*! \page apinotes API Notes 2 | 3 | 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. 4 | 5 | \section linux Linux: 6 | 7 | RtAudio for Linux was originally developed under Redhat Fedora distributions. Four different audio APIs are supported on Linux platforms: OSS (versions >= 4.0), ALSA, Jack, and PulseAudio. Note that the OSS API implementation was not tested in the latest version of RtAudio due to lack of availability ... bugs are likely. 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. 8 | 9 | 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. 10 | 11 | \section macosx Macintosh OS-X (CoreAudio and Jack): 12 | 13 | The Apple CoreAudio API is designed to use a separate callback procedure for each of its audio devices. An RtAudio duplex stream using two different devices is normal, as CoreAudio enumerates input and output devices separately. The numberOfBuffers parameter to the RtAudio::openStream() function has no affect in this implementation. 14 | 15 | It is not possible to have multiple instances of RtAudio streaming to/from the same CoreAudio device. 16 | 17 | The RtAudio Jack support can be compiled on Macintosh OS-X systems, as well as in Linux. 18 | 19 | \section windowsds Windows (DirectSound): 20 | 21 | The \c configure script provides support for the MinGW compiler. DirectSound support is specified with the "--with-ds" flag. 22 | 23 | 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. 24 | 25 | The DirectSound version of RtAudio can be compiled with or without the UNICODE preprocessor definition. 26 | 27 | \section windowsasio Windows (ASIO): 28 | 29 | ASIO support using MinGW and the \c configure script is specified with the "--with-asio" flag. 30 | 31 | 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 numberOfBuffers parameter to the RtAudio::openStream() function has no affect in this implementation. 32 | 33 | A number of ASIO source and header files are required for use with RtAudio. Specifically, an RtAudio project must include the following files: asio.h,cpp; asiodrivers.h,cpp; asiolist.h,cpp; asiodrvr.h; asiosys.h; ginclude.h; iasiodrv.h; iasiothiscallresolver.h,cpp. The Visual C++ projects found in /tests/Windows/ compile both ASIO and DirectSound support. 34 | 35 | The Steinberg provided asiolist class may 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 DEFINES -= UNICODE 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. 36 | 37 | */ 38 | -------------------------------------------------------------------------------- /doc/doxygen/compiling.txt: -------------------------------------------------------------------------------- 1 | /*! \page compiling Debugging & Compiling 2 | 3 | \section debug Debugging 4 | 5 | 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 that may help in determining the problem. Also, try using the programs included in the tests directory. The program audioprobe 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__. 6 | 7 | \section compile Compiling 8 | 9 | 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: 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 |
OS:Audio API:C++ Class:Preprocessor Definition:Library or Framework:Example Compiler Statement:
LinuxALSARtApiAlsa__LINUX_ALSA__asound, pthreadg++ -Wall -D__LINUX_ALSA__ -o audioprobe audioprobe.cpp RtAudio.cpp -lasound -lpthread
LinuxPulseAudioRtApiPulse__LINUX_PULSE__pthreadg++ -Wall -D__LINUX_PULSE__ -o audioprobe audioprobe.cpp RtAudio.cpp -lpthread -lpulse-simple -lpulse
LinuxOSSRtApiOss__LINUX_OSS__pthreadg++ -Wall -D__LINUX_OSS__ -o audioprobe audioprobe.cpp RtAudio.cpp -lpthread
Linux or Macintosh OS-XJack Audio ServerRtApiJack__UNIX_JACK__jack, pthreadg++ -Wall -D__UNIX_JACK__ -o audioprobe audioprobe.cpp RtAudio.cpp $(pkg-config --cflags --libs jack) -lpthread
Macintosh OS-XCoreAudioRtApiCore__MACOSX_CORE__pthread, CoreAudiog++ -Wall -D__MACOSX_CORE__ -o audioprobe audioprobe.cpp RtAudio.cpp -framework CoreAudio -framework CoreFoundation -lpthread
WindowsDirectSoundRtApiDs__WINDOWS_DS__dsound.lib (ver. 5.0 or higher), multithreadedMinGW: g++ -Wall -D__WINDOWS_DS__ -o audioprobe audioprobe.cpp RtAudio.cpp -lole32 -lwinmm -ldsound
WindowsASIORtApiAsio__WINDOWS_ASIO__various ASIO header and source filesMinGW: g++ -Wall -D__WINDOWS_ASIO__ -Iinclude -o audioprobe audioprobe.cpp RtAudio.cpp asio.cpp asiolist.cpp asiodrivers.cpp iasiothiscallresolver.cpp -lole32
WindowsWASAPIRtApiWasapi__WINDOWS_WASAPI__MinGW: FunctionDiscoveryKeys_devpkey.h, lksuser, lmfplat, lmfuuid, lwmcodecdspuuid, lwinmm, lole32MinGW: g++ -Wall -D__WINDOWS_WASAPI__ -Iinclude -o audioprobe audioprobe.cpp RtAudio.cpp -lole32 -lwinmm -lksuser -lmfplat -lmfuuid -lwmcodecdspuuid
87 |

88 | 89 | The example compiler statements above could be used to compile the audioprobe.cpp example file, assuming that audioprobe.cpp, RtAudio.h, RtAudio.cpp and any other necessary files all exist in the same directory or the include directory. 90 | 91 | 92 | */ 93 | -------------------------------------------------------------------------------- /doc/doxygen/duplex.txt: -------------------------------------------------------------------------------- 1 | /*! \page duplex Duplex Mode 2 | 3 | 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. 4 | 5 | \code 6 | #include "RtAudio.h" 7 | #include 8 | #include 9 | #include 10 | 11 | // Pass-through function. 12 | int inout( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames, 13 | double streamTime, RtAudioStreamStatus status, void *data ) 14 | { 15 | // Since the number of input and output channels is equal, we can do 16 | // a simple buffer copy operation here. 17 | if ( status ) std::cout << "Stream over/underflow detected." << std::endl; 18 | 19 | unsigned int *bytes = (unsigned int *) data; 20 | memcpy( outputBuffer, inputBuffer, *bytes ); 21 | return 0; 22 | } 23 | 24 | int main() 25 | { 26 | RtAudio adac; 27 | std::vector deviceIds = adac.getDeviceIds(); 28 | if ( deviceIds.size() < 1 ) { 29 | std::cout << "\nNo audio devices found!\n"; 30 | exit( 0 ); 31 | } 32 | 33 | // Set the same number of channels for both input and output. 34 | unsigned int bufferBytes, bufferFrames = 512; 35 | RtAudio::StreamParameters iParams, oParams; 36 | iParams.deviceId = deviceIds[0]; // first available device 37 | iParams.nChannels = 2; 38 | oParams.deviceId = deviceIds[0]; // first available device 39 | oParams.nChannels = 2; 40 | 41 | if ( adac.openStream( &oParams, &iParams, RTAUDIO_SINT32, 44100, 42 | &bufferFrames, &inout, (void *)&bufferBytes ) ) { 43 | std::cout << '\n' << adac.getErrorText() << '\n' << std::endl; 44 | exit( 0 ); // problem with device settings 45 | } 46 | 47 | bufferBytes = bufferFrames * 2 * 4; 48 | 49 | if ( adac.startStream() ) { 50 | std::cout << adac.getErrorText() << std::endl; 51 | goto cleanup; 52 | } 53 | 54 | char input; 55 | std::cout << "\nRunning ... press to quit.\n"; 56 | std::cin.get(input); 57 | 58 | // Block released ... stop the stream 59 | if ( adac.isStreamRunning() ) 60 | adac.stopStream(); // or could call adac.abortStream(); 61 | 62 | cleanup: 63 | if ( adac.isStreamOpen() ) adac.closeStream(); 64 | 65 | return 0; 66 | } 67 | \endcode 68 | 69 | In this example, audio recorded by the stream input will be played out during the next round of audio processing. 70 | 71 | Note that a duplex stream can (and often must) make use of two different devices (except when using the Linux Jack and Windows ASIO APIs). However, if the two devices do not share a common internal or external "sync", there may be timing problems due to possible device clock variations. 72 | 73 | */ 74 | -------------------------------------------------------------------------------- /doc/doxygen/error.txt: -------------------------------------------------------------------------------- 1 | /*! \page errors Error Handling 2 | 3 | RtAudio no longer makes use of C++ exceptions. Instead, the functions RtAudio::openStream(), RtAudio::startStream(), RtAudio::stopStream(), RtAudio::abortStream()) return an RtAudioErrorType variable, which will be RTAUDIO_NO_ERROR (value = 0) when successful. Any non-zero return value from those functions indicates an error has occurred. If an RtAudioErrorCallback() function has been set, the #RtAudioErrorType and textual details will be provided through that function. One can also obtain the last error message by calling the RtAudio::getErrorText() function. For all other functions, a warning message may be produced (returned through the RtAudioErrorCallback() if set, otherwise printed to stderr) 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 return or printing of warning messages (default value is enabled). There is a protected RtAudio method, error(), that can be modified to globally control how these messages are handled and reported. 4 | 5 | */ 6 | -------------------------------------------------------------------------------- /doc/doxygen/footer.html: -------------------------------------------------------------------------------- 1 |


2 | 3 | 4 | 5 |
©2001-2023 Gary P. Scavone, McGill University. All Rights Reserved.
Maintained by Gary P. Scavone.
6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /doc/doxygen/header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | The RtAudio Home Page 4 | 5 | 6 | 7 | 8 |
9 | Home   Class/Enum List   File List   Compound Members   C interface  
10 |
11 | -------------------------------------------------------------------------------- /doc/doxygen/license.txt: -------------------------------------------------------------------------------- 1 | /*! \page license License 2 | 3 | RtAudio: a set of realtime audio i/o C++ classes
4 | Copyright (c) 2001-2023 Gary P. Scavone 5 | 6 | Permission is hereby granted, free of charge, to any person 7 | obtaining a copy of this software and associated documentation files 8 | (the "Software"), to deal in the Software without restriction, 9 | including without limitation the rights to use, copy, modify, merge, 10 | publish, distribute, sublicense, and/or sell copies of the Software, 11 | and to permit persons to whom the Software is furnished to do so, 12 | subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be 15 | included in all copies or substantial portions of the Software. 16 | 17 | Any person wishing to distribute modifications to the Software is 18 | asked to send the modifications to the original developer so that 19 | they can be incorporated into the canonical version. This is, 20 | however, not a binding provision of this license. 21 | 22 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 23 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 24 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 25 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR 26 | ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 27 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 28 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 | 30 | */ 31 | -------------------------------------------------------------------------------- /doc/doxygen/multi.txt: -------------------------------------------------------------------------------- 1 | /*! \page multi Using Simultaneous Multiple APIs 2 | 3 | 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, then a WASAPI instance and then a DirectSound instance (on Linux systems, the default API search order is Alsa, Jack, Pulse 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. 4 | 5 | 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. 6 | 7 | */ 8 | -------------------------------------------------------------------------------- /doc/doxygen/playback.txt: -------------------------------------------------------------------------------- 1 | /*! \page playback Playback 2 | 3 | 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. 4 | 5 | \code 6 | #include "RtAudio.h" 7 | #include 8 | #include 9 | 10 | // Two-channel sawtooth wave generator. 11 | int saw( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames, 12 | double streamTime, RtAudioStreamStatus status, void *userData ) 13 | { 14 | unsigned int i, j; 15 | double *buffer = (double *) outputBuffer; 16 | double *lastValues = (double *) userData; 17 | 18 | if ( status ) 19 | std::cout << "Stream underflow detected!" << std::endl; 20 | 21 | // Write interleaved audio data. 22 | for ( i=0; i= 1.0 ) lastValues[j] -= 2.0; 28 | } 29 | } 30 | 31 | return 0; 32 | } 33 | 34 | int main() 35 | { 36 | RtAudio dac; 37 | std::vector deviceIds = dac.getDeviceIds(); 38 | if ( deviceIds.size() < 1 ) { 39 | std::cout << "\nNo audio devices found!\n"; 40 | exit( 0 ); 41 | } 42 | 43 | RtAudio::StreamParameters parameters; 44 | parameters.deviceId = dac.getDefaultOutputDevice(); 45 | parameters.nChannels = 2; 46 | parameters.firstChannel = 0; 47 | unsigned int sampleRate = 44100; 48 | unsigned int bufferFrames = 256; // 256 sample frames 49 | double data[2] = {0, 0}; 50 | 51 | if ( dac.openStream( ¶meters, NULL, RTAUDIO_FLOAT64, sampleRate, 52 | &bufferFrames, &saw, (void *)&data ) ) { 53 | std::cout << '\n' << dac.getErrorText() << '\n' << std::endl; 54 | exit( 0 ); // problem with device settings 55 | } 56 | 57 | // Stream is open ... now start it. 58 | if ( dac.startStream() ) { 59 | std::cout << dac.getErrorText() << std::endl; 60 | goto cleanup; 61 | } 62 | 63 | char input; 64 | std::cout << "\nPlaying ... press to quit.\n"; 65 | std::cin.get( input ); 66 | 67 | // Block released ... stop the stream 68 | if ( dac.isStreamRunning() ) 69 | dac.stopStream(); // or could call dac.abortStream(); 70 | 71 | cleanup: 72 | if ( dac.isStreamOpen() ) dac.closeStream(); 73 | 74 | return 0; 75 | } 76 | \endcode 77 | 78 | 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. 79 | 80 | 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). 81 | 82 | */ 83 | -------------------------------------------------------------------------------- /doc/doxygen/probe.txt: -------------------------------------------------------------------------------- 1 | /*! \page probe Probing Device Capabilities 2 | 3 | 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. RtAudio creates its own device IDs for each device and these values will remain valid for a given instance of the class, no matter whether new devices are plugged in or previously available devices are removed. 4 | 5 | \code 6 | 7 | // audioprobe.cpp 8 | 9 | #include 10 | #include "RtAudio.h" 11 | 12 | int main() 13 | { 14 | RtAudio audio; 15 | 16 | // Get the list of device IDs 17 | std::vector< unsigned int > ids = audio.getDeviceIds(); 18 | if ( ids.size() == 0 ) { 19 | std::cout << "No devices found." << std::endl; 20 | return 0; 21 | } 22 | 23 | // Scan through devices for various capabilities 24 | RtAudio::DeviceInfo info; 25 | for ( unsigned int n=0; n 9 | #include 10 | #include 11 | 12 | int record( void *outputBuffer, void *inputBuffer, unsigned int nBufferFrames, 13 | double streamTime, RtAudioStreamStatus status, void *userData ) 14 | { 15 | if ( status ) 16 | std::cout << "Stream overflow detected!" << std::endl; 17 | 18 | // Do something with the data in the "inputBuffer" buffer. 19 | 20 | return 0; 21 | } 22 | 23 | int main() 24 | { 25 | RtAudio adc; 26 | std::vector deviceIds = adc.getDeviceIds(); 27 | if ( deviceIds.size() < 1 ) { 28 | std::cout << "\nNo audio devices found!\n"; 29 | exit( 0 ); 30 | } 31 | 32 | RtAudio::StreamParameters parameters; 33 | parameters.deviceId = adc.getDefaultInputDevice(); 34 | parameters.nChannels = 2; 35 | parameters.firstChannel = 0; 36 | unsigned int sampleRate = 44100; 37 | unsigned int bufferFrames = 256; // 256 sample frames 38 | 39 | if ( adc.openStream( NULL, ¶meters, RTAUDIO_SINT16, 40 | sampleRate, &bufferFrames, &record ) ) { 41 | std::cout << '\n' << adc.getErrorText() << '\n' << std::endl; 42 | exit( 0 ); // problem with device settings 43 | } 44 | 45 | // Stream is open ... now start it. 46 | if ( adc.startStream() ) { 47 | std::cout << adc.getErrorText() << std::endl; 48 | goto cleanup; 49 | } 50 | 51 | char input; 52 | std::cout << "\nRecording ... press to quit.\n"; 53 | std::cin.get( input ); 54 | 55 | // Block released ... stop the stream 56 | if ( adc.isStreamRunning() ) 57 | adc.stopStream(); // or could call adc.abortStream(); 58 | 59 | cleanup: 60 | if ( adc.isStreamOpen() ) adc.closeStream(); 61 | 62 | return 0; 63 | } 64 | \endcode 65 | 66 | 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. 67 | 68 | */ 69 | -------------------------------------------------------------------------------- /doc/doxygen/settings.txt: -------------------------------------------------------------------------------- 1 | /*! \page settings Device Settings 2 | 3 | The next step in using RtAudio is to open a stream with particular device and parameter settings. 4 | 5 | \code 6 | 7 | #include "RtAudio.h" 8 | 9 | int main() 10 | { 11 | RtAudio dac; 12 | std::vector deviceIds = dac.getDeviceIds(); 13 | if ( deviceIds.size() < 1 ) exit( 0 ); // no devices available 14 | 15 | RtAudio::StreamParameters parameters; 16 | parameters.deviceId = dac.getDefaultOutputDevice(); 17 | parameters.nChannels = 2; 18 | unsigned int sampleRate = 44100; 19 | unsigned int bufferFrames = 256; // 256 sample frames 20 | 21 | RtAudio::StreamOptions options; 22 | options.flags = RTAUDIO_NONINTERLEAVED; 23 | 24 | if ( dac.openStream( ¶meters, NULL, RTAUDIO_FLOAT32, sampleRate, 25 | &bufferFrames, &myCallback, NULL, &options ) ) { 26 | std::cout << '\n' << dac.getErrorText() << '\n' << std::endl; 27 | exit( 0 ); // problem with device settings 28 | } 29 | 30 | // Normally, you would go on to start / stop a stream 31 | return 0; 32 | } 33 | \endcode 34 | 35 | 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 an unsupported sample rate or an invalid device ID), a non-zero #RtAudioErrorType value of RTAUDIO_INVALID_PARAMETER (or perhaps RTAUDIO_INVALID_USE) is returned. If a system error occurs when attempting to open the stream, an #RtAudioErrorType of RTAUDIO_SYSTEM_ERROR is returned. In either case, a descriptive error message can be retrieved using the RtAudio::getErrorText() function. 36 | 37 | RtAudio provides four signed integer and two floating point data formats that 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. 38 | 39 | 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. 40 | 41 | 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 (for example, higher sample rates may reduce the maximum number of channels). 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. 42 | 43 | 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. 44 | 45 | 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. 46 | 47 | */ 48 | -------------------------------------------------------------------------------- /doc/doxygen/tutorial.txt: -------------------------------------------------------------------------------- 1 | /*! \mainpage The RtAudio Home Page 2 | 3 | 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: 4 | 5 | - object-oriented C++ design 6 | - simple, common API across all supported platforms 7 | - only one source and one header file for easy inclusion in programming projects 8 | - allow simultaneous multi-api support 9 | - support dynamic connection of devices 10 | - provide extensive audio device parameter control 11 | - allow audio device capability probing 12 | - automatic internal conversion for data format, channel number compensation, (de)interleaving, and byte-swapping 13 | 14 | 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. 15 | 16 | \section whatsnew Latest Updates (Version 6.0.1) 17 | 18 | Changes in this release (from 6.0.0) include: 19 | 20 | - complete rewrite of device enumeration scheme for all APIs to provide persistent IDs within a given instance (significant API change) 21 | - discontinued use of C++ exceptions, switched to error code return values from various functions (significant API change) 22 | - corresponding updates to test programs and documentation 23 | - see git history for complete list of changes 24 | 25 | \section download Download 26 | 27 | Latest Release (1 August 2023): Version 6.0.1 28 | 29 | \section documentation Documentation Links 30 | 31 | -# \ref errors 32 | -# \ref probe 33 | -# \ref settings 34 | -# \ref playback 35 | -# \ref recording 36 | -# \ref duplex 37 | -# \ref multi 38 | -# \ref compiling 39 | -# \ref apinotes 40 | -# \ref acknowledge 41 | -# \ref license 42 | -# RtAudio on GitHub 43 | 44 | */ 45 | 46 | -# Bug Tracker (out of date) 47 | -# Possible Updates (out of date) 48 | -------------------------------------------------------------------------------- /doc/images/ccrma.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thestk/rtaudio/40e0d8140f14acd8552d2dc4f42dcc853274a12c/doc/images/ccrma.gif -------------------------------------------------------------------------------- /doc/images/mcgill.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thestk/rtaudio/40e0d8140f14acd8552d2dc4f42dcc853274a12c/doc/images/mcgill.gif -------------------------------------------------------------------------------- /doc/images/meson.build: -------------------------------------------------------------------------------- 1 | doxygen_images = files('ccrma.gif', 2 | 'mcgill.gif') 3 | 4 | foreach f : doxygen_images 5 | df = configure_file(input: f, 6 | output: '@PLAINNAME@', 7 | copy: true, 8 | install: get_option('install_docs'), 9 | install_dir : get_option('datadir') / 'doc' / 'rtaudio') 10 | endforeach 11 | -------------------------------------------------------------------------------- /doc/meson.build: -------------------------------------------------------------------------------- 1 | if get_option('docs') 2 | doxygen = find_program('doxygen') 3 | 4 | conf_data = configuration_data() 5 | conf_data.set('PACKAGE_VERSION', meson.project_version()) 6 | conf_data.set('top_srcdir', meson.project_source_root()) 7 | conf_data.set('top_builddir', meson.project_build_root()) 8 | 9 | doxyfile = configure_file(input : 'Doxyfile.in', 10 | output : 'Doxyfile', 11 | configuration : conf_data, 12 | install: false) 13 | 14 | doxygen_target = custom_target('doc', 15 | input: doxyfile, 16 | output: 'html', 17 | command: [doxygen, doxyfile], 18 | install: get_option('install_docs'), 19 | install_dir: get_option('datadir') / 'doc' / 'rtaudio') 20 | 21 | subdir('images') 22 | endif 23 | -------------------------------------------------------------------------------- /include/asio.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Steinberg Audio Stream I/O API 3 | (c) 1996, Steinberg Soft- und Hardware GmbH 4 | 5 | asio.cpp 6 | 7 | asio functions entries which translate the 8 | asio interface to the asiodrvr class methods 9 | */ 10 | 11 | #include 12 | #include "asiosys.h" // platform definition 13 | #include "asio.h" 14 | 15 | #if MAC 16 | #include "asiodrvr.h" 17 | 18 | #pragma export on 19 | 20 | AsioDriver *theAsioDriver = 0; 21 | 22 | extern "C" 23 | { 24 | 25 | long main() 26 | { 27 | return 'ASIO'; 28 | } 29 | 30 | #elif WINDOWS 31 | 32 | #include "windows.h" 33 | #include "iasiodrv.h" 34 | #include "asiodrivers.h" 35 | 36 | IASIO *theAsioDriver = 0; 37 | extern AsioDrivers *asioDrivers; 38 | 39 | #elif SGI || SUN || BEOS || LINUX 40 | #include "asiodrvr.h" 41 | static AsioDriver *theAsioDriver = 0; 42 | #endif 43 | 44 | //----------------------------------------------------------------------------------------------------- 45 | ASIOError ASIOInit(ASIODriverInfo *info) 46 | { 47 | #if MAC || SGI || SUN || BEOS || LINUX 48 | if(theAsioDriver) 49 | { 50 | delete theAsioDriver; 51 | theAsioDriver = 0; 52 | } 53 | info->driverVersion = 0; 54 | strcpy(info->name, "No ASIO Driver"); 55 | theAsioDriver = getDriver(); 56 | if(!theAsioDriver) 57 | { 58 | strcpy(info->errorMessage, "Not enough memory for the ASIO driver!"); 59 | return ASE_NotPresent; 60 | } 61 | if(!theAsioDriver->init(info->sysRef)) 62 | { 63 | theAsioDriver->getErrorMessage(info->errorMessage); 64 | delete theAsioDriver; 65 | theAsioDriver = 0; 66 | return ASE_NotPresent; 67 | } 68 | strcpy(info->errorMessage, "No ASIO Driver Error"); 69 | theAsioDriver->getDriverName(info->name); 70 | info->driverVersion = theAsioDriver->getDriverVersion(); 71 | return ASE_OK; 72 | 73 | #else 74 | 75 | info->driverVersion = 0; 76 | strcpy(info->name, "No ASIO Driver"); 77 | if(theAsioDriver) // must be loaded! 78 | { 79 | if(!theAsioDriver->init(info->sysRef)) 80 | { 81 | theAsioDriver->getErrorMessage(info->errorMessage); 82 | theAsioDriver = 0; 83 | return ASE_NotPresent; 84 | } 85 | 86 | strcpy(info->errorMessage, "No ASIO Driver Error"); 87 | theAsioDriver->getDriverName(info->name); 88 | info->driverVersion = theAsioDriver->getDriverVersion(); 89 | return ASE_OK; 90 | } 91 | return ASE_NotPresent; 92 | 93 | #endif // !MAC 94 | } 95 | 96 | ASIOError ASIOExit(void) 97 | { 98 | if(theAsioDriver) 99 | { 100 | #if WINDOWS 101 | if ( asioDrivers ) // added by Axel Holzinger 102 | asioDrivers->removeCurrentDriver(); 103 | #else 104 | delete theAsioDriver; 105 | #endif 106 | } 107 | theAsioDriver = 0; 108 | return ASE_OK; 109 | } 110 | 111 | ASIOError ASIOStart(void) 112 | { 113 | if(!theAsioDriver) 114 | return ASE_NotPresent; 115 | return theAsioDriver->start(); 116 | } 117 | 118 | ASIOError ASIOStop(void) 119 | { 120 | if(!theAsioDriver) 121 | return ASE_NotPresent; 122 | return theAsioDriver->stop(); 123 | } 124 | 125 | ASIOError ASIOGetChannels(long *numInputChannels, long *numOutputChannels) 126 | { 127 | if(!theAsioDriver) 128 | { 129 | *numInputChannels = *numOutputChannels = 0; 130 | return ASE_NotPresent; 131 | } 132 | return theAsioDriver->getChannels(numInputChannels, numOutputChannels); 133 | } 134 | 135 | ASIOError ASIOGetLatencies(long *inputLatency, long *outputLatency) 136 | { 137 | if(!theAsioDriver) 138 | { 139 | *inputLatency = *outputLatency = 0; 140 | return ASE_NotPresent; 141 | } 142 | return theAsioDriver->getLatencies(inputLatency, outputLatency); 143 | } 144 | 145 | ASIOError ASIOGetBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity) 146 | { 147 | if(!theAsioDriver) 148 | { 149 | *minSize = *maxSize = *preferredSize = *granularity = 0; 150 | return ASE_NotPresent; 151 | } 152 | return theAsioDriver->getBufferSize(minSize, maxSize, preferredSize, granularity); 153 | } 154 | 155 | ASIOError ASIOCanSampleRate(ASIOSampleRate sampleRate) 156 | { 157 | if(!theAsioDriver) 158 | return ASE_NotPresent; 159 | return theAsioDriver->canSampleRate(sampleRate); 160 | } 161 | 162 | ASIOError ASIOGetSampleRate(ASIOSampleRate *currentRate) 163 | { 164 | if(!theAsioDriver) 165 | return ASE_NotPresent; 166 | return theAsioDriver->getSampleRate(currentRate); 167 | } 168 | 169 | ASIOError ASIOSetSampleRate(ASIOSampleRate sampleRate) 170 | { 171 | if(!theAsioDriver) 172 | return ASE_NotPresent; 173 | return theAsioDriver->setSampleRate(sampleRate); 174 | } 175 | 176 | ASIOError ASIOGetClockSources(ASIOClockSource *clocks, long *numSources) 177 | { 178 | if(!theAsioDriver) 179 | { 180 | *numSources = 0; 181 | return ASE_NotPresent; 182 | } 183 | return theAsioDriver->getClockSources(clocks, numSources); 184 | } 185 | 186 | ASIOError ASIOSetClockSource(long reference) 187 | { 188 | if(!theAsioDriver) 189 | return ASE_NotPresent; 190 | return theAsioDriver->setClockSource(reference); 191 | } 192 | 193 | ASIOError ASIOGetSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp) 194 | { 195 | if(!theAsioDriver) 196 | return ASE_NotPresent; 197 | return theAsioDriver->getSamplePosition(sPos, tStamp); 198 | } 199 | 200 | ASIOError ASIOGetChannelInfo(ASIOChannelInfo *info) 201 | { 202 | if(!theAsioDriver) 203 | { 204 | info->channelGroup = -1; 205 | info->type = ASIOSTInt16MSB; 206 | strcpy(info->name, "None"); 207 | return ASE_NotPresent; 208 | } 209 | return theAsioDriver->getChannelInfo(info); 210 | } 211 | 212 | ASIOError ASIOCreateBuffers(ASIOBufferInfo *bufferInfos, long numChannels, 213 | long bufferSize, ASIOCallbacks *callbacks) 214 | { 215 | if(!theAsioDriver) 216 | { 217 | ASIOBufferInfo *info = bufferInfos; 218 | for(long i = 0; i < numChannels; i++, info++) 219 | info->buffers[0] = info->buffers[1] = 0; 220 | return ASE_NotPresent; 221 | } 222 | return theAsioDriver->createBuffers(bufferInfos, numChannels, bufferSize, callbacks); 223 | } 224 | 225 | ASIOError ASIODisposeBuffers(void) 226 | { 227 | if(!theAsioDriver) 228 | return ASE_NotPresent; 229 | return theAsioDriver->disposeBuffers(); 230 | } 231 | 232 | ASIOError ASIOControlPanel(void) 233 | { 234 | if(!theAsioDriver) 235 | return ASE_NotPresent; 236 | return theAsioDriver->controlPanel(); 237 | } 238 | 239 | ASIOError ASIOFuture(long selector, void *opt) 240 | { 241 | if(!theAsioDriver) 242 | return ASE_NotPresent; 243 | return theAsioDriver->future(selector, opt); 244 | } 245 | 246 | ASIOError ASIOOutputReady(void) 247 | { 248 | if(!theAsioDriver) 249 | return ASE_NotPresent; 250 | return theAsioDriver->outputReady(); 251 | } 252 | 253 | #if MAC 254 | } // extern "C" 255 | #pragma export off 256 | #endif 257 | 258 | 259 | -------------------------------------------------------------------------------- /include/asiodrivers.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "asiodrivers.h" 3 | 4 | AsioDrivers* asioDrivers = 0; 5 | 6 | bool loadAsioDriver(char *name); 7 | 8 | bool loadAsioDriver(char *name) 9 | { 10 | if(!asioDrivers) 11 | asioDrivers = new AsioDrivers(); 12 | if(asioDrivers) 13 | return asioDrivers->loadDriver(name); 14 | return false; 15 | } 16 | 17 | //------------------------------------------------------------------------------------ 18 | 19 | #if MAC 20 | 21 | bool resolveASIO(unsigned long aconnID); 22 | 23 | AsioDrivers::AsioDrivers() : CodeFragments("ASIO Drivers", 'AsDr', 'Asio') 24 | { 25 | connID = -1; 26 | curIndex = -1; 27 | } 28 | 29 | AsioDrivers::~AsioDrivers() 30 | { 31 | removeCurrentDriver(); 32 | } 33 | 34 | bool AsioDrivers::getCurrentDriverName(char *name) 35 | { 36 | if(curIndex >= 0) 37 | return getName(curIndex, name); 38 | return false; 39 | } 40 | 41 | long AsioDrivers::getDriverNames(char **names, long maxDrivers) 42 | { 43 | for(long i = 0; i < getNumFragments() && i < maxDrivers; i++) 44 | getName(i, names[i]); 45 | return getNumFragments() < maxDrivers ? getNumFragments() : maxDrivers; 46 | } 47 | 48 | bool AsioDrivers::loadDriver(char *name) 49 | { 50 | char dname[64]; 51 | unsigned long newID; 52 | 53 | for(long i = 0; i < getNumFragments(); i++) 54 | { 55 | if(getName(i, dname) && !strcmp(name, dname)) 56 | { 57 | if(newInstance(i, &newID)) 58 | { 59 | if(resolveASIO(newID)) 60 | { 61 | if(connID != -1) 62 | removeInstance(curIndex, connID); 63 | curIndex = i; 64 | connID = newID; 65 | return true; 66 | } 67 | } 68 | break; 69 | } 70 | } 71 | return false; 72 | } 73 | 74 | void AsioDrivers::removeCurrentDriver() 75 | { 76 | if(connID != -1) 77 | removeInstance(curIndex, connID); 78 | connID = -1; 79 | curIndex = -1; 80 | } 81 | 82 | //------------------------------------------------------------------------------------ 83 | 84 | #elif WINDOWS 85 | 86 | #include "iasiodrv.h" 87 | 88 | extern IASIO* theAsioDriver; 89 | 90 | AsioDrivers::AsioDrivers() : AsioDriverList() 91 | { 92 | curIndex = -1; 93 | } 94 | 95 | AsioDrivers::~AsioDrivers() 96 | { 97 | } 98 | 99 | bool AsioDrivers::getCurrentDriverName(char *name) 100 | { 101 | if(curIndex >= 0) 102 | return asioGetDriverName(curIndex, name, 32) == 0 ? true : false; 103 | name[0] = 0; 104 | return false; 105 | } 106 | 107 | long AsioDrivers::getDriverNames(char **names, long maxDrivers) 108 | { 109 | for(long i = 0; i < asioGetNumDev() && i < maxDrivers; i++) 110 | asioGetDriverName(i, names[i], 32); 111 | return asioGetNumDev() < maxDrivers ? asioGetNumDev() : maxDrivers; 112 | } 113 | 114 | bool AsioDrivers::loadDriver(char *name) 115 | { 116 | char dname[64]; 117 | char curName[64]; 118 | 119 | for(long i = 0; i < asioGetNumDev(); i++) 120 | { 121 | if(!asioGetDriverName(i, dname, 32) && !strcmp(name, dname)) 122 | { 123 | curName[0] = 0; 124 | getCurrentDriverName(curName); // in case we fail... 125 | removeCurrentDriver(); 126 | 127 | if(!asioOpenDriver(i, (void **)&theAsioDriver)) 128 | { 129 | curIndex = i; 130 | return true; 131 | } 132 | else 133 | { 134 | theAsioDriver = 0; 135 | if(curName[0] && strcmp(dname, curName)) 136 | loadDriver(curName); // try restore 137 | } 138 | break; 139 | } 140 | } 141 | return false; 142 | } 143 | 144 | void AsioDrivers::removeCurrentDriver() 145 | { 146 | if(curIndex != -1) 147 | asioCloseDriver(curIndex); 148 | curIndex = -1; 149 | } 150 | 151 | #elif SGI || BEOS 152 | 153 | #include "asiolist.h" 154 | 155 | AsioDrivers::AsioDrivers() 156 | : AsioDriverList() 157 | { 158 | curIndex = -1; 159 | } 160 | 161 | AsioDrivers::~AsioDrivers() 162 | { 163 | } 164 | 165 | bool AsioDrivers::getCurrentDriverName(char *name) 166 | { 167 | return false; 168 | } 169 | 170 | long AsioDrivers::getDriverNames(char **names, long maxDrivers) 171 | { 172 | return 0; 173 | } 174 | 175 | bool AsioDrivers::loadDriver(char *name) 176 | { 177 | return false; 178 | } 179 | 180 | void AsioDrivers::removeCurrentDriver() 181 | { 182 | } 183 | 184 | #else 185 | #error implement me 186 | #endif 187 | -------------------------------------------------------------------------------- /include/asiodrivers.h: -------------------------------------------------------------------------------- 1 | #ifndef __AsioDrivers__ 2 | #define __AsioDrivers__ 3 | 4 | #include "ginclude.h" 5 | 6 | #if MAC 7 | #include "CodeFragments.hpp" 8 | 9 | class AsioDrivers : public CodeFragments 10 | 11 | #elif WINDOWS 12 | #include 13 | #include "asiolist.h" 14 | 15 | class AsioDrivers : public AsioDriverList 16 | 17 | #elif SGI || BEOS 18 | #include "asiolist.h" 19 | 20 | class AsioDrivers : public AsioDriverList 21 | 22 | #else 23 | #error implement me 24 | #endif 25 | 26 | { 27 | public: 28 | AsioDrivers(); 29 | ~AsioDrivers(); 30 | 31 | bool getCurrentDriverName(char *name); 32 | long getDriverNames(char **names, long maxDrivers); 33 | bool loadDriver(char *name); 34 | void removeCurrentDriver(); 35 | long getCurrentDriverIndex() {return curIndex;} 36 | protected: 37 | unsigned long connID; 38 | long curIndex; 39 | }; 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /include/asiodrvr.h: -------------------------------------------------------------------------------- 1 | /* 2 | Steinberg Audio Stream I/O API 3 | (c) 1996, Steinberg Soft- und Hardware GmbH 4 | charlie (May 1996) 5 | 6 | asiodrvr.h 7 | c++ superclass to implement asio functionality. from this, 8 | you can derive whatever required 9 | */ 10 | 11 | #ifndef _asiodrvr_ 12 | #define _asiodrvr_ 13 | 14 | // cpu and os system we are running on 15 | #include "asiosys.h" 16 | // basic "C" interface 17 | #include "asio.h" 18 | 19 | class AsioDriver; 20 | extern AsioDriver *getDriver(); // for generic constructor 21 | 22 | #if WINDOWS 23 | #include 24 | #include "combase.h" 25 | #include "iasiodrv.h" 26 | class AsioDriver : public IASIO ,public CUnknown 27 | { 28 | public: 29 | AsioDriver(LPUNKNOWN pUnk, HRESULT *phr); 30 | 31 | DECLARE_IUNKNOWN 32 | // Factory method 33 | static CUnknown *CreateInstance(LPUNKNOWN pUnk, HRESULT *phr); 34 | // IUnknown 35 | virtual HRESULT STDMETHODCALLTYPE NonDelegatingQueryInterface(REFIID riid,void **ppvObject); 36 | 37 | #else 38 | 39 | class AsioDriver 40 | { 41 | public: 42 | AsioDriver(); 43 | #endif 44 | virtual ~AsioDriver(); 45 | 46 | virtual ASIOBool init(void* sysRef); 47 | virtual void getDriverName(char *name); // max 32 bytes incl. terminating zero 48 | virtual long getDriverVersion(); 49 | virtual void getErrorMessage(char *string); // max 124 bytes incl. 50 | 51 | virtual ASIOError start(); 52 | virtual ASIOError stop(); 53 | 54 | virtual ASIOError getChannels(long *numInputChannels, long *numOutputChannels); 55 | virtual ASIOError getLatencies(long *inputLatency, long *outputLatency); 56 | virtual ASIOError getBufferSize(long *minSize, long *maxSize, 57 | long *preferredSize, long *granularity); 58 | 59 | virtual ASIOError canSampleRate(ASIOSampleRate sampleRate); 60 | virtual ASIOError getSampleRate(ASIOSampleRate *sampleRate); 61 | virtual ASIOError setSampleRate(ASIOSampleRate sampleRate); 62 | virtual ASIOError getClockSources(ASIOClockSource *clocks, long *numSources); 63 | virtual ASIOError setClockSource(long reference); 64 | 65 | virtual ASIOError getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp); 66 | virtual ASIOError getChannelInfo(ASIOChannelInfo *info); 67 | 68 | virtual ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long numChannels, 69 | long bufferSize, ASIOCallbacks *callbacks); 70 | virtual ASIOError disposeBuffers(); 71 | 72 | virtual ASIOError controlPanel(); 73 | virtual ASIOError future(long selector, void *opt); 74 | virtual ASIOError outputReady(); 75 | }; 76 | #endif 77 | -------------------------------------------------------------------------------- /include/asioinfo.txt: -------------------------------------------------------------------------------- 1 | The Steinberg ASIO SDK and licensing agreement can be found at: 2 | 3 | - https://www.steinberg.net/developers/ 4 | -------------------------------------------------------------------------------- /include/asiolist.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "iasiodrv.h" 3 | #include "asiolist.h" 4 | 5 | #define ASIODRV_DESC "description" 6 | #define INPROC_SERVER "InprocServer32" 7 | #define ASIO_PATH "software\\asio" 8 | #define COM_CLSID "clsid" 9 | 10 | // ****************************************************************** 11 | // Local Functions 12 | // ****************************************************************** 13 | static LONG findDrvPath (char *clsidstr,char *dllpath,int dllpathsize) 14 | { 15 | HKEY hkEnum,hksub,hkpath; 16 | char databuf[512]; 17 | LONG cr,rc = -1; 18 | DWORD datatype,datasize; 19 | DWORD index; 20 | OFSTRUCT ofs; 21 | HFILE hfile; 22 | BOOL found = FALSE; 23 | 24 | #ifdef UNICODE 25 | CharLowerBuffA(clsidstr,strlen(clsidstr)); 26 | if ((cr = RegOpenKeyA(HKEY_CLASSES_ROOT,COM_CLSID,&hkEnum)) == ERROR_SUCCESS) { 27 | 28 | index = 0; 29 | while (cr == ERROR_SUCCESS && !found) { 30 | cr = RegEnumKeyA(hkEnum,index++,databuf,512); 31 | if (cr == ERROR_SUCCESS) { 32 | CharLowerBuffA(databuf,strlen(databuf)); 33 | if (!(strcmp(databuf,clsidstr))) { 34 | if ((cr = RegOpenKeyExA(hkEnum,databuf,0,KEY_READ,&hksub)) == ERROR_SUCCESS) { 35 | if ((cr = RegOpenKeyExA(hksub,INPROC_SERVER,0,KEY_READ,&hkpath)) == ERROR_SUCCESS) { 36 | datatype = REG_SZ; datasize = (DWORD)dllpathsize; 37 | cr = RegQueryValueEx(hkpath,0,0,&datatype,(LPBYTE)dllpath,&datasize); 38 | if (cr == ERROR_SUCCESS) { 39 | memset(&ofs,0,sizeof(OFSTRUCT)); 40 | ofs.cBytes = sizeof(OFSTRUCT); 41 | hfile = OpenFile(dllpath,&ofs,OF_EXIST); 42 | if (hfile) rc = 0; 43 | } 44 | RegCloseKey(hkpath); 45 | } 46 | RegCloseKey(hksub); 47 | } 48 | found = TRUE; // break out 49 | } 50 | } 51 | } 52 | RegCloseKey(hkEnum); 53 | } 54 | #else 55 | CharLowerBuff(clsidstr,strlen(clsidstr)); 56 | if ((cr = RegOpenKey(HKEY_CLASSES_ROOT,COM_CLSID,&hkEnum)) == ERROR_SUCCESS) { 57 | 58 | index = 0; 59 | while (cr == ERROR_SUCCESS && !found) { 60 | cr = RegEnumKey(hkEnum,index++,databuf,512); 61 | if (cr == ERROR_SUCCESS) { 62 | CharLowerBuff(databuf,strlen(databuf)); 63 | if (!(strcmp(databuf,clsidstr))) { 64 | if ((cr = RegOpenKeyEx(hkEnum,databuf,0,KEY_READ,&hksub)) == ERROR_SUCCESS) { 65 | if ((cr = RegOpenKeyEx(hksub,INPROC_SERVER,0,KEY_READ,&hkpath)) == ERROR_SUCCESS) { 66 | datatype = REG_SZ; datasize = (DWORD)dllpathsize; 67 | cr = RegQueryValueEx(hkpath,0,0,&datatype,(LPBYTE)dllpath,&datasize); 68 | if (cr == ERROR_SUCCESS) { 69 | memset(&ofs,0,sizeof(OFSTRUCT)); 70 | ofs.cBytes = sizeof(OFSTRUCT); 71 | hfile = OpenFile(dllpath,&ofs,OF_EXIST); 72 | if (hfile) rc = 0; 73 | } 74 | RegCloseKey(hkpath); 75 | } 76 | RegCloseKey(hksub); 77 | } 78 | found = TRUE; // break out 79 | } 80 | } 81 | } 82 | RegCloseKey(hkEnum); 83 | } 84 | #endif 85 | return rc; 86 | } 87 | 88 | 89 | static LPASIODRVSTRUCT newDrvStruct (HKEY hkey,char *keyname,int drvID,LPASIODRVSTRUCT lpdrv) 90 | { 91 | HKEY hksub; 92 | char databuf[256]; 93 | char dllpath[MAXPATHLEN]; 94 | WORD wData[100]; 95 | CLSID clsid; 96 | DWORD datatype,datasize; 97 | LONG cr,rc; 98 | 99 | if (!lpdrv) { 100 | if ((cr = RegOpenKeyExA(hkey,keyname,0,KEY_READ,&hksub)) == ERROR_SUCCESS) { 101 | 102 | datatype = REG_SZ; datasize = 256; 103 | cr = RegQueryValueExA(hksub,COM_CLSID,0,&datatype,(LPBYTE)databuf,&datasize); 104 | if (cr == ERROR_SUCCESS) { 105 | rc = findDrvPath (databuf,dllpath,MAXPATHLEN); 106 | if (rc == 0) { 107 | lpdrv = new ASIODRVSTRUCT[1]; 108 | if (lpdrv) { 109 | memset(lpdrv,0,sizeof(ASIODRVSTRUCT)); 110 | lpdrv->drvID = drvID; 111 | MultiByteToWideChar(CP_ACP,0,(LPCSTR)databuf,-1,(LPWSTR)wData,100); 112 | if ((cr = CLSIDFromString((LPOLESTR)wData,(LPCLSID)&clsid)) == S_OK) { 113 | memcpy(&lpdrv->clsid,&clsid,sizeof(CLSID)); 114 | } 115 | 116 | datatype = REG_SZ; datasize = 256; 117 | cr = RegQueryValueExA(hksub,ASIODRV_DESC,0,&datatype,(LPBYTE)databuf,&datasize); 118 | if (cr == ERROR_SUCCESS) { 119 | strcpy(lpdrv->drvname,databuf); 120 | } 121 | else strcpy(lpdrv->drvname,keyname); 122 | } 123 | } 124 | } 125 | RegCloseKey(hksub); 126 | } 127 | } 128 | else lpdrv->next = newDrvStruct(hkey,keyname,drvID+1,lpdrv->next); 129 | 130 | return lpdrv; 131 | } 132 | 133 | static void deleteDrvStruct (LPASIODRVSTRUCT lpdrv) 134 | { 135 | IASIO *iasio; 136 | 137 | if (lpdrv != 0) { 138 | deleteDrvStruct(lpdrv->next); 139 | if (lpdrv->asiodrv) { 140 | iasio = (IASIO *)lpdrv->asiodrv; 141 | iasio->Release(); 142 | } 143 | //delete lpdrv; 144 | delete[] lpdrv; // correction from Axel Holzinger 145 | } 146 | } 147 | 148 | 149 | static LPASIODRVSTRUCT getDrvStruct (int drvID,LPASIODRVSTRUCT lpdrv) 150 | { 151 | while (lpdrv) { 152 | if (lpdrv->drvID == drvID) return lpdrv; 153 | lpdrv = lpdrv->next; 154 | } 155 | return 0; 156 | } 157 | // ****************************************************************** 158 | 159 | 160 | // ****************************************************************** 161 | // AsioDriverList 162 | // ****************************************************************** 163 | AsioDriverList::AsioDriverList () 164 | { 165 | HKEY hkEnum = 0; 166 | char keyname[MAXDRVNAMELEN]; 167 | LPASIODRVSTRUCT pdl; 168 | LONG cr; 169 | DWORD index = 0; 170 | 171 | numdrv = 0; 172 | lpdrvlist = 0; 173 | 174 | #ifdef UNICODE 175 | cr = RegOpenKeyA(HKEY_LOCAL_MACHINE,ASIO_PATH,&hkEnum); 176 | #else 177 | cr = RegOpenKey(HKEY_LOCAL_MACHINE,ASIO_PATH,&hkEnum); 178 | #endif 179 | while (cr == ERROR_SUCCESS) { 180 | #ifdef UNICODE 181 | if ((cr = RegEnumKeyA(hkEnum,index++,keyname,MAXDRVNAMELEN))== ERROR_SUCCESS) { 182 | #else 183 | if ((cr = RegEnumKey(hkEnum,index++,keyname,MAXDRVNAMELEN))== ERROR_SUCCESS) { 184 | #endif 185 | lpdrvlist = newDrvStruct (hkEnum,keyname,0,lpdrvlist); 186 | } 187 | } 188 | if (hkEnum) RegCloseKey(hkEnum); 189 | 190 | pdl = lpdrvlist; 191 | while (pdl) { 192 | numdrv++; 193 | pdl = pdl->next; 194 | } 195 | 196 | coInitialized_ = false; 197 | if (numdrv) { 198 | HRESULT hr = CoInitialize(0); // initialize COM 199 | if( !FAILED( hr ) ) coInitialized_ = true; 200 | } 201 | } 202 | 203 | AsioDriverList::~AsioDriverList () 204 | { 205 | if (numdrv) { 206 | deleteDrvStruct(lpdrvlist); 207 | if( coInitialized_ ) CoUninitialize(); // balanced call. 208 | } 209 | } 210 | 211 | 212 | LONG AsioDriverList::asioGetNumDev (VOID) 213 | { 214 | return (LONG)numdrv; 215 | } 216 | 217 | 218 | LONG AsioDriverList::asioOpenDriver (int drvID,LPVOID *asiodrv) 219 | { 220 | LPASIODRVSTRUCT lpdrv = 0; 221 | long rc; 222 | 223 | if (!asiodrv) return DRVERR_INVALID_PARAM; 224 | 225 | if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) { 226 | if (!lpdrv->asiodrv) { 227 | rc = CoCreateInstance(lpdrv->clsid,0,CLSCTX_INPROC_SERVER,lpdrv->clsid,asiodrv); 228 | if (rc == S_OK) { 229 | lpdrv->asiodrv = *asiodrv; 230 | return 0; 231 | } 232 | // else if (rc == REGDB_E_CLASSNOTREG) 233 | // strcpy (info->messageText, "Driver not registered in the Registration Database!"); 234 | } 235 | else rc = DRVERR_DEVICE_ALREADY_OPEN; 236 | } 237 | else rc = DRVERR_DEVICE_NOT_FOUND; 238 | 239 | return rc; 240 | } 241 | 242 | 243 | LONG AsioDriverList::asioCloseDriver (int drvID) 244 | { 245 | LPASIODRVSTRUCT lpdrv = 0; 246 | IASIO *iasio; 247 | 248 | if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) { 249 | if (lpdrv->asiodrv) { 250 | iasio = (IASIO *)lpdrv->asiodrv; 251 | iasio->Release(); 252 | lpdrv->asiodrv = 0; 253 | } 254 | } 255 | 256 | return 0; 257 | } 258 | 259 | LONG AsioDriverList::asioGetDriverName (int drvID,char *drvname,int drvnamesize) 260 | { 261 | LPASIODRVSTRUCT lpdrv = 0; 262 | 263 | if (!drvname) return DRVERR_INVALID_PARAM; 264 | 265 | if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) { 266 | if (strlen(lpdrv->drvname) < (unsigned int)drvnamesize) { 267 | strcpy(drvname,lpdrv->drvname); 268 | } 269 | else { 270 | memcpy(drvname,lpdrv->drvname,drvnamesize-4); 271 | drvname[drvnamesize-4] = '.'; 272 | drvname[drvnamesize-3] = '.'; 273 | drvname[drvnamesize-2] = '.'; 274 | drvname[drvnamesize-1] = 0; 275 | } 276 | return 0; 277 | } 278 | return DRVERR_DEVICE_NOT_FOUND; 279 | } 280 | 281 | LONG AsioDriverList::asioGetDriverPath (int drvID,char *dllpath,int dllpathsize) 282 | { 283 | LPASIODRVSTRUCT lpdrv = 0; 284 | 285 | if (!dllpath) return DRVERR_INVALID_PARAM; 286 | 287 | if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) { 288 | if (strlen(lpdrv->dllpath) < (unsigned int)dllpathsize) { 289 | strcpy(dllpath,lpdrv->dllpath); 290 | return 0; 291 | } 292 | dllpath[0] = 0; 293 | return DRVERR_INVALID_PARAM; 294 | } 295 | return DRVERR_DEVICE_NOT_FOUND; 296 | } 297 | 298 | LONG AsioDriverList::asioGetDriverCLSID (int drvID,CLSID *clsid) 299 | { 300 | LPASIODRVSTRUCT lpdrv = 0; 301 | 302 | if (!clsid) return DRVERR_INVALID_PARAM; 303 | 304 | if ((lpdrv = getDrvStruct(drvID,lpdrvlist)) != 0) { 305 | memcpy(clsid,&lpdrv->clsid,sizeof(CLSID)); 306 | return 0; 307 | } 308 | return DRVERR_DEVICE_NOT_FOUND; 309 | } 310 | 311 | 312 | -------------------------------------------------------------------------------- /include/asiolist.h: -------------------------------------------------------------------------------- 1 | #ifndef __asiolist__ 2 | #define __asiolist__ 3 | 4 | #define DRVERR -5000 5 | #define DRVERR_INVALID_PARAM DRVERR-1 6 | #define DRVERR_DEVICE_ALREADY_OPEN DRVERR-2 7 | #define DRVERR_DEVICE_NOT_FOUND DRVERR-3 8 | 9 | #define MAXPATHLEN 512 10 | #define MAXDRVNAMELEN 128 11 | 12 | struct asiodrvstruct 13 | { 14 | int drvID; 15 | CLSID clsid; 16 | char dllpath[MAXPATHLEN]; 17 | char drvname[MAXDRVNAMELEN]; 18 | LPVOID asiodrv; 19 | struct asiodrvstruct *next; 20 | }; 21 | 22 | typedef struct asiodrvstruct ASIODRVSTRUCT; 23 | typedef ASIODRVSTRUCT *LPASIODRVSTRUCT; 24 | 25 | class AsioDriverList { 26 | public: 27 | AsioDriverList(); 28 | ~AsioDriverList(); 29 | 30 | LONG asioOpenDriver (int,VOID **); 31 | LONG asioCloseDriver (int); 32 | 33 | // nice to have 34 | LONG asioGetNumDev (VOID); 35 | LONG asioGetDriverName (int,char *,int); 36 | LONG asioGetDriverPath (int,char *,int); 37 | LONG asioGetDriverCLSID (int,CLSID *); 38 | 39 | // or use directly access 40 | LPASIODRVSTRUCT lpdrvlist; 41 | int numdrv; 42 | 43 | private: 44 | bool coInitialized_; 45 | }; 46 | 47 | typedef class AsioDriverList *LPASIODRIVERLIST; 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /include/asiosys.h: -------------------------------------------------------------------------------- 1 | #ifndef __asiosys__ 2 | #define __asiosys__ 3 | 4 | #if defined(_WIN32) || defined(_WIN64) 5 | #undef MAC 6 | #define PPC 0 7 | #define WINDOWS 1 8 | #define SGI 0 9 | #define SUN 0 10 | #define LINUX 0 11 | #define BEOS 0 12 | 13 | #define NATIVE_INT64 0 14 | #define IEEE754_64FLOAT 1 15 | 16 | #elif BEOS 17 | #define MAC 0 18 | #define PPC 0 19 | #define WINDOWS 0 20 | #define PC 0 21 | #define SGI 0 22 | #define SUN 0 23 | #define LINUX 0 24 | 25 | #define NATIVE_INT64 0 26 | #define IEEE754_64FLOAT 1 27 | 28 | #ifndef DEBUG 29 | #define DEBUG 0 30 | #if DEBUG 31 | void DEBUGGERMESSAGE(char *string); 32 | #else 33 | #define DEBUGGERMESSAGE(a) 34 | #endif 35 | #endif 36 | 37 | #elif SGI 38 | #define MAC 0 39 | #define PPC 0 40 | #define WINDOWS 0 41 | #define PC 0 42 | #define SUN 0 43 | #define LINUX 0 44 | #define BEOS 0 45 | 46 | #define NATIVE_INT64 0 47 | #define IEEE754_64FLOAT 1 48 | 49 | #ifndef DEBUG 50 | #define DEBUG 0 51 | #if DEBUG 52 | void DEBUGGERMESSAGE(char *string); 53 | #else 54 | #define DEBUGGERMESSAGE(a) 55 | #endif 56 | #endif 57 | 58 | #else // MAC 59 | 60 | #define MAC 1 61 | #define PPC 1 62 | #define WINDOWS 0 63 | #define PC 0 64 | #define SGI 0 65 | #define SUN 0 66 | #define LINUX 0 67 | #define BEOS 0 68 | 69 | #define NATIVE_INT64 0 70 | #define IEEE754_64FLOAT 1 71 | 72 | #ifndef DEBUG 73 | #define DEBUG 0 74 | #if DEBUG 75 | void DEBUGGERMESSAGE(char *string); 76 | #else 77 | #define DEBUGGERMESSAGE(a) 78 | #endif 79 | #endif 80 | #endif 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /include/ginclude.h: -------------------------------------------------------------------------------- 1 | #ifndef __gInclude__ 2 | #define __gInclude__ 3 | 4 | #if SGI 5 | #undef BEOS 6 | #undef MAC 7 | #undef WINDOWS 8 | // 9 | #define ASIO_BIG_ENDIAN 1 10 | #define ASIO_CPU_MIPS 1 11 | #elif defined(_WIN32) || defined(_WIN64) 12 | #undef BEOS 13 | #undef MAC 14 | #undef SGI 15 | #define WINDOWS 1 16 | #define ASIO_LITTLE_ENDIAN 1 17 | #define ASIO_CPU_X86 1 18 | #elif BEOS 19 | #undef MAC 20 | #undef SGI 21 | #undef WINDOWS 22 | #define ASIO_LITTLE_ENDIAN 1 23 | #define ASIO_CPU_X86 1 24 | // 25 | #else 26 | #define MAC 1 27 | #undef BEOS 28 | #undef WINDOWS 29 | #undef SGI 30 | #define ASIO_BIG_ENDIAN 1 31 | #define ASIO_CPU_PPC 1 32 | #endif 33 | 34 | // always 35 | #define NATIVE_INT64 0 36 | #define IEEE754_64FLOAT 1 37 | 38 | #endif // __gInclude__ 39 | -------------------------------------------------------------------------------- /include/iasiodrv.h: -------------------------------------------------------------------------------- 1 | #include "asiosys.h" 2 | #include "asio.h" 3 | 4 | /* Forward Declarations */ 5 | 6 | #ifndef __ASIODRIVER_FWD_DEFINED__ 7 | #define __ASIODRIVER_FWD_DEFINED__ 8 | typedef interface IASIO IASIO; 9 | #endif /* __ASIODRIVER_FWD_DEFINED__ */ 10 | 11 | interface IASIO : public IUnknown 12 | { 13 | 14 | virtual ASIOBool init(void *sysHandle) = 0; 15 | virtual void getDriverName(char *name) = 0; 16 | virtual long getDriverVersion() = 0; 17 | virtual void getErrorMessage(char *string) = 0; 18 | virtual ASIOError start() = 0; 19 | virtual ASIOError stop() = 0; 20 | virtual ASIOError getChannels(long *numInputChannels, long *numOutputChannels) = 0; 21 | virtual ASIOError getLatencies(long *inputLatency, long *outputLatency) = 0; 22 | virtual ASIOError getBufferSize(long *minSize, long *maxSize, 23 | long *preferredSize, long *granularity) = 0; 24 | virtual ASIOError canSampleRate(ASIOSampleRate sampleRate) = 0; 25 | virtual ASIOError getSampleRate(ASIOSampleRate *sampleRate) = 0; 26 | virtual ASIOError setSampleRate(ASIOSampleRate sampleRate) = 0; 27 | virtual ASIOError getClockSources(ASIOClockSource *clocks, long *numSources) = 0; 28 | virtual ASIOError setClockSource(long reference) = 0; 29 | virtual ASIOError getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp) = 0; 30 | virtual ASIOError getChannelInfo(ASIOChannelInfo *info) = 0; 31 | virtual ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long numChannels, 32 | long bufferSize, ASIOCallbacks *callbacks) = 0; 33 | virtual ASIOError disposeBuffers() = 0; 34 | virtual ASIOError controlPanel() = 0; 35 | virtual ASIOError future(long selector,void *opt) = 0; 36 | virtual ASIOError outputReady() = 0; 37 | }; 38 | -------------------------------------------------------------------------------- /include/iasiothiscallresolver.h: -------------------------------------------------------------------------------- 1 | // **************************************************************************** 2 | // 3 | // Changed: I have modified this file slightly (includes) to work with 4 | // RtAudio. RtAudio.cpp must include this file after asio.h. 5 | // 6 | // File: IASIOThiscallResolver.h 7 | // Description: The IASIOThiscallResolver class implements the IASIO 8 | // interface and acts as a proxy to the real IASIO interface by 9 | // calling through its vptr table using the thiscall calling 10 | // convention. To put it another way, we interpose 11 | // IASIOThiscallResolver between ASIO SDK code and the driver. 12 | // This is necessary because most non-Microsoft compilers don't 13 | // implement the thiscall calling convention used by IASIO. 14 | // 15 | // iasiothiscallresolver.cpp contains the background of this 16 | // problem plus a technical description of the vptr 17 | // manipulations. 18 | // 19 | // In order to use this mechanism one simply has to add 20 | // iasiothiscallresolver.cpp to the list of files to compile 21 | // and #include 22 | // 23 | // Note that this #include must come after the other ASIO SDK 24 | // #includes, for example: 25 | // 26 | // #include 27 | // #include 28 | // #include 29 | // #include 30 | // #include 31 | // 32 | // Actually the important thing is to #include 33 | // after . We have 34 | // incorporated a test to enforce this ordering. 35 | // 36 | // The code transparently takes care of the interposition by 37 | // using macro substitution to intercept calls to ASIOInit() 38 | // and ASIOExit(). We save the original ASIO global 39 | // "theAsioDriver" in our "that" variable, and then set 40 | // "theAsioDriver" to equal our IASIOThiscallResolver instance. 41 | // 42 | // Whilst this method of resolving the thiscall problem requires 43 | // the addition of #include to client 44 | // code it has the advantage that it does not break the terms 45 | // of the ASIO licence by publishing it. We are NOT modifying 46 | // any Steinberg code here, we are merely implementing the IASIO 47 | // interface in the same way that we would need to do if we 48 | // wished to provide an open source ASIO driver. 49 | // 50 | // For compilation with MinGW -lole32 needs to be added to the 51 | // linker options. For BORLAND, linking with Import32.lib is 52 | // sufficient. 53 | // 54 | // The dependencies are with: CoInitialize, CoUninitialize, 55 | // CoCreateInstance, CLSIDFromString - used by asiolist.cpp 56 | // and are required on Windows whether ThiscallResolver is used 57 | // or not. 58 | // 59 | // Searching for the above strings in the root library path 60 | // of your compiler should enable the correct libraries to be 61 | // identified if they aren't immediately obvious. 62 | // 63 | // Note that the current implementation of IASIOThiscallResolver 64 | // is not COM compliant - it does not correctly implement the 65 | // IUnknown interface. Implementing it is not necessary because 66 | // it is not called by parts of the ASIO SDK which call through 67 | // theAsioDriver ptr. The IUnknown methods are implemented as 68 | // assert(false) to ensure that the code fails if they are 69 | // ever called. 70 | // Restrictions: None. Public Domain & Open Source distribute freely 71 | // You may use IASIOThiscallResolver commercially as well as 72 | // privately. 73 | // You the user assume the responsibility for the use of the 74 | // files, binary or text, and there is no guarantee or warranty, 75 | // expressed or implied, including but not limited to the 76 | // implied warranties of merchantability and fitness for a 77 | // particular purpose. You assume all responsibility and agree 78 | // to hold no entity, copyright holder or distributors liable 79 | // for any loss of data or inaccurate representations of data 80 | // as a result of using IASIOThiscallResolver. 81 | // Version: 1.4 Added separate macro CALL_THISCALL_1_DOUBLE from 82 | // Andrew Baldwin, and volatile for whole gcc asm blocks, 83 | // both for compatibility with newer gcc versions. Cleaned up 84 | // Borland asm to use one less register. 85 | // 1.3 Switched to including assert.h for better compatibility. 86 | // Wrapped entire .h and .cpp contents with a check for 87 | // _MSC_VER to provide better compatibility with MS compilers. 88 | // Changed Singleton implementation to use static instance 89 | // instead of freestore allocated instance. Removed ASIOExit 90 | // macro as it is no longer needed. 91 | // 1.2 Removed semicolons from ASIOInit and ASIOExit macros to 92 | // allow them to be embedded in expressions (if statements). 93 | // Cleaned up some comments. Removed combase.c dependency (it 94 | // doesn't compile with BCB anyway) by stubbing IUnknown. 95 | // 1.1 Incorporated comments from Ross Bencina including things 96 | // such as changing name from ThiscallResolver to 97 | // IASIOThiscallResolver, tidying up the constructor, fixing 98 | // a bug in IASIOThiscallResolver::ASIOExit() and improving 99 | // portability through the use of conditional compilation 100 | // 1.0 Initial working version. 101 | // Created: 6/09/2003 102 | // Authors: Fraser Adams 103 | // Ross Bencina 104 | // Rene G. Ceballos 105 | // Martin Fay 106 | // Antti Silvast 107 | // Andrew Baldwin 108 | // 109 | // **************************************************************************** 110 | 111 | 112 | #ifndef included_iasiothiscallresolver_h 113 | #define included_iasiothiscallresolver_h 114 | 115 | // We only need IASIOThiscallResolver at all if we are on Win32. For other 116 | // platforms we simply bypass the IASIOThiscallResolver definition to allow us 117 | // to be safely #include'd whatever the platform to keep client code portable 118 | //#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) 119 | #if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) && !defined(_WIN64) 120 | 121 | 122 | // If microsoft compiler we can call IASIO directly so IASIOThiscallResolver 123 | // is not used. 124 | #if !defined(_MSC_VER) 125 | 126 | 127 | // The following is in order to ensure that this header is only included after 128 | // the other ASIO headers (except for the case of iasiothiscallresolver.cpp). 129 | // We need to do this because IASIOThiscallResolver works by eclipsing the 130 | // original definition of ASIOInit() with a macro (see below). 131 | #if !defined(iasiothiscallresolver_sourcefile) 132 | #if !defined(__ASIO_H) 133 | #error iasiothiscallresolver.h must be included AFTER asio.h 134 | #endif 135 | #endif 136 | 137 | #include 138 | #include "iasiodrv.h" /* From ASIO SDK */ 139 | 140 | 141 | class IASIOThiscallResolver : public IASIO { 142 | private: 143 | IASIO* that_; // Points to the real IASIO 144 | 145 | static IASIOThiscallResolver instance; // Singleton instance 146 | 147 | // Constructors - declared private so construction is limited to 148 | // our Singleton instance 149 | IASIOThiscallResolver(); 150 | IASIOThiscallResolver(IASIO* that); 151 | public: 152 | 153 | // Methods from the IUnknown interface. We don't fully implement IUnknown 154 | // because the ASIO SDK never calls these methods through theAsioDriver ptr. 155 | // These methods are implemented as assert(false). 156 | virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppv); 157 | virtual ULONG STDMETHODCALLTYPE AddRef(); 158 | virtual ULONG STDMETHODCALLTYPE Release(); 159 | 160 | // Methods from the IASIO interface, implemented as forwarning calls to that. 161 | virtual ASIOBool init(void *sysHandle); 162 | virtual void getDriverName(char *name); 163 | virtual long getDriverVersion(); 164 | virtual void getErrorMessage(char *string); 165 | virtual ASIOError start(); 166 | virtual ASIOError stop(); 167 | virtual ASIOError getChannels(long *numInputChannels, long *numOutputChannels); 168 | virtual ASIOError getLatencies(long *inputLatency, long *outputLatency); 169 | virtual ASIOError getBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity); 170 | virtual ASIOError canSampleRate(ASIOSampleRate sampleRate); 171 | virtual ASIOError getSampleRate(ASIOSampleRate *sampleRate); 172 | virtual ASIOError setSampleRate(ASIOSampleRate sampleRate); 173 | virtual ASIOError getClockSources(ASIOClockSource *clocks, long *numSources); 174 | virtual ASIOError setClockSource(long reference); 175 | virtual ASIOError getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp); 176 | virtual ASIOError getChannelInfo(ASIOChannelInfo *info); 177 | virtual ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long numChannels, long bufferSize, ASIOCallbacks *callbacks); 178 | virtual ASIOError disposeBuffers(); 179 | virtual ASIOError controlPanel(); 180 | virtual ASIOError future(long selector,void *opt); 181 | virtual ASIOError outputReady(); 182 | 183 | // Class method, see ASIOInit() macro below. 184 | static ASIOError ASIOInit(ASIODriverInfo *info); // Delegates to ::ASIOInit 185 | }; 186 | 187 | 188 | // Replace calls to ASIOInit with our interposing version. 189 | // This macro enables us to perform thiscall resolution simply by #including 190 | // after the asio #includes (this file _must_ be 191 | // included _after_ the asio #includes) 192 | 193 | #define ASIOInit(name) IASIOThiscallResolver::ASIOInit((name)) 194 | 195 | 196 | #endif /* !defined(_MSC_VER) */ 197 | 198 | #endif /* Win32 */ 199 | 200 | #endif /* included_iasiothiscallresolver_h */ 201 | 202 | 203 | -------------------------------------------------------------------------------- /install.txt: -------------------------------------------------------------------------------- 1 | RtAudio - a set of C++ classes which provide a common API for realtime audio input/output across Linux (native ALSA, JACK, PulseAudio, and OSS), Macintosh OS X (CoreAudio and JACK), and Windows (DirectSound, ASIO and WASAPI) operating systems. 2 | 3 | By Gary P. Scavone, 2001-2023. 4 | 5 | To configure and compile (on Unix systems and MinGW): 6 | 7 | 1. Unpack the RtAudio distribution (tar -xzf rtaudio-x.x.tar.gz). 8 | 9 | 2. From within the directory containing this file, run configure: 10 | 11 | ./configure 12 | 13 | If you checked out the code from git, just run "autogen.sh". 14 | 15 | 3. Typing "make" will compile static and shared libraries, as well as the example programs in the "tests/" directory. 16 | 17 | A few options can be passed to configure (or the autogen.sh script), including: 18 | 19 | --enable-debug = enable various debug output 20 | --with-alsa = choose native ALSA API support (linux only) 21 | --with-pulse = choose native PulseAudio API support (linux only) 22 | --with-oss = choose OSS API support (unixes) 23 | --with-jack = choose JACK server support (linux or Macintosh OS-X) 24 | --with-core = choose CoreAudio API support (Macintosh OS-X only) 25 | --with-asio = choose ASIO API support (windows only) 26 | --with-wasapi = choose Windows Audio System API support (windows only) 27 | --with-ds = choose DirectSound API support (windows only) 28 | 29 | Typing "./configure --help" will display all the available options. Note that you can provide more than one "--with-" flag to the configure script to enable multiple API support. 30 | 31 | If you wish to use a different compiler than that selected by configure, specify that compiler in the command line (e.g. to use CC): 32 | 33 | ./configure CXX=CC 34 | 35 | 36 | CMAKE USAGE: 37 | 38 | CMake support is provided via the CMakeLists.txt files. Assuming you have CMake installed on your system, a typical usage would involve the following steps (from within the parent distribution directory): 39 | 40 | mkdir _build_ 41 | cd _build_ 42 | cmake e.g. cmake .. -DRTAUDIO_WINDOWS_WASAPI=ON 43 | 44 | 45 | VCPKG USAGE: 46 | 47 | You can build and install rtaudio using [vcpkg](https://github.com/Microsoft/vcpkg/) dependency manager: 48 | 49 | git clone https://github.com/Microsoft/vcpkg.git 50 | cd vcpkg 51 | ./bootstrap-vcpkg.sh # ./bootstrap-vcpkg.bat for Windows 52 | ./vcpkg integrate install 53 | ./vcpkg install rtaudio 54 | 55 | The rtaudio port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository. 56 | 57 | 58 | WINDOWS: 59 | 60 | All Windows audio APIs in RtAudio compile with either the MinGW compiler (tested with latest tdm64-gcc-4.8.1) or MS Visual Studio. 61 | 62 | Visual C++ 6.0 project files (very old) are included for the test programs in the /tests/Windows/ directory. These projects compile API support for ASIO, WASAPI and DirectSound. 63 | 64 | 65 | LINUX OSS: 66 | 67 | The OSS API support in RtAudio has not been tested for many years. I'm not even sure there are OSS drivers supporting recent linux kernels. In all likelihood, the OSS API code in RtAudio will disappear within the next year or two (if you don't want this to happen, let me know). 68 | -------------------------------------------------------------------------------- /meson.build: -------------------------------------------------------------------------------- 1 | project('RtAudio', 'cpp', 2 | version: '6.0.1', 3 | 4 | default_options: ['warning_level=3', 5 | 'c_std=c99', 6 | 'cpp_std=c++11', 7 | 'default_library=both']) 8 | 9 | fs = import('fs') 10 | pkg = import('pkgconfig') 11 | 12 | rt_h = fs.read('RtAudio.h').strip().split('\n') 13 | foreach line : rt_h 14 | if line.startswith('#define RTAUDIO_VERSION_MAJOR') 15 | rt_version_major = line.split()[2] 16 | elif line.startswith('#define RTAUDIO_VERSION_MINOR') 17 | rt_version_minor = line.split()[2] 18 | elif line.startswith('#define RTAUDIO_VERSION_PATCH') 19 | rt_version_patch = line.split()[2] 20 | elif line.startswith('#define RTAUDIO_VERSION_BETA') 21 | rt_version_beta = line.split()[2] 22 | endif 23 | endforeach 24 | if rt_version_beta.to_int() > 0 25 | rt_version = rt_version_major + '.' + rt_version_minor + '.' + rt_version_patch + 'beta' + rt_version_beta 26 | else 27 | rt_version = rt_version_major + '.' + rt_version_minor + '.' + rt_version_patch 28 | endif 29 | 30 | assert(meson.project_version() == rt_version, 'Meson\'s RtAudio version does not match the version in header file.') 31 | 32 | ac_file = fs.read('configure.ac').strip().split('\n') 33 | foreach line : ac_file 34 | if line.startswith('m4_define([lt_current],') 35 | lt_current = line.substring(-2,-1).to_int() 36 | elif line.startswith('m4_define([lt_revision],') 37 | lt_revision = line.substring(-2,-1).to_int() 38 | elif line.startswith('m4_define([lt_age],') 39 | lt_age = line.substring(-2,-1).to_int() 40 | endif 41 | endforeach 42 | 43 | so_version = '@0@.@1@.@2@'.format(lt_current - lt_age, lt_age, lt_revision) 44 | 45 | src = ['RtAudio.cpp', 'rtaudio_c.cpp'] 46 | incdir = include_directories('include') 47 | 48 | install_headers('RtAudio.h', 'rtaudio_c.h', subdir: 'rtaudio') 49 | 50 | compiler = meson.get_compiler('cpp') 51 | 52 | deps = [] 53 | defines = ['-DRTAUDIO_EXPORT'] 54 | 55 | if compiler.has_function('gettimeofday', prefix: '#include ') 56 | defines += '-DHAVE_GETTIMEOFDAY' 57 | endif 58 | 59 | if get_option('debug') == true 60 | defines += '-D__RTAUDIO_DEBUG__' 61 | endif 62 | 63 | deps += dependency('threads') 64 | 65 | alsa_dep = dependency('alsa', required: get_option('alsa')) 66 | if alsa_dep.found() 67 | defines += '-D__LINUX_ALSA__' 68 | deps += alsa_dep 69 | endif 70 | 71 | jack_dep = dependency('jack', required: get_option('jack')) 72 | if jack_dep.found() 73 | defines += '-D__UNIX_JACK__' 74 | deps += jack_dep 75 | endif 76 | 77 | if get_option('oss') == true 78 | defines += '-D__LINUX_OSS__' 79 | endif 80 | 81 | pulsesimple_dep = dependency('libpulse-simple', required: get_option('pulse')) 82 | if pulsesimple_dep.found() 83 | defines += '-D__LINUX_PULSE__' 84 | deps += pulsesimple_dep 85 | endif 86 | 87 | core_dep = dependency('appleframeworks', modules: ['CoreAudio', 'CoreFoundation'], required: get_option('core')) 88 | if core_dep.found() 89 | defines += '-D__MACOSX_CORE__' 90 | deps += core_dep 91 | endif 92 | 93 | dsound_dep = compiler.find_library('dsound', required: get_option('dsound')) 94 | if dsound_dep.found() 95 | defines += '-D__WINDOWS_DS__' 96 | deps += dsound_dep 97 | endif 98 | 99 | 100 | wasapi_found = compiler.check_header('audioclient.h', required: get_option('wasapi')) 101 | if wasapi_found 102 | deps += compiler.find_library('mfplat', required: true) 103 | deps += compiler.find_library('mfuuid', required: true) 104 | deps += compiler.find_library('ksuser', required: true) 105 | deps += compiler.find_library('wmcodecdspuuid', required: true) 106 | defines += '-D__WINDOWS_WASAPI__' 107 | endif 108 | 109 | asio_found = compiler.check_header('windows.h', required: get_option('asio')) 110 | if asio_found 111 | src += ['include/asio.cpp', 112 | 'include/asiolist.cpp', 113 | 'include/asiodrivers.cpp', 114 | 'include/iasiothiscallresolver.cpp'] 115 | defines += '-D__WINDOWS_ASIO__' 116 | endif 117 | 118 | if host_machine.system() == 'windows' 119 | deps += compiler.find_library('ole32', required: true) 120 | deps += compiler.find_library('winmm', required: true) 121 | endif 122 | 123 | rtaudio = library('rtaudio', src, 124 | version: so_version, 125 | include_directories: incdir, 126 | cpp_args: defines, 127 | dependencies: deps, 128 | gnu_symbol_visibility: 'hidden', 129 | install: true) 130 | rtaudio_dep = declare_dependency(include_directories : '.', 131 | link_with : rtaudio) 132 | meson.override_dependency('rtaudio', rtaudio_dep) 133 | 134 | subdir('tests') 135 | subdir('doc') 136 | 137 | pkg.generate(rtaudio, 138 | description: 'RtAudio - a set of C++ classes that provide a common API for realtime audio input/output', 139 | subdirs: 'rtaudio') 140 | 141 | summary({'ALSA': alsa_dep.found(), 142 | 'OSS': get_option('oss'), 143 | 'JACK': jack_dep.found(), 144 | 'PulseAudio': pulsesimple_dep.found(), 145 | 'CoreAudio': core_dep.found(), 146 | 'DirectAudio': dsound_dep.found(), 147 | 'WASAPI': wasapi_found, 148 | 'ASIO': asio_found}, bool_yn: true, section: 'Audio Backends') 149 | -------------------------------------------------------------------------------- /meson_options.txt: -------------------------------------------------------------------------------- 1 | # Audio Backends 2 | option('jack', type : 'feature', value : 'auto', description: 'Build with JACK Backend') 3 | option('alsa', type : 'feature', value : 'auto', description: 'Build with ALSA Backend') 4 | option('pulse', type : 'feature', value : 'auto', description: 'Build with Pulseaudio Backend') 5 | option('oss', type : 'boolean', value : 'false', description: 'Build with OSS Backend') 6 | option('core', type : 'feature', value : 'auto', description: 'Build with CoreAudio Backend') 7 | option('dsound', type : 'feature', value : 'auto', description: 'Build with DirectSound Backend') 8 | option('asio', type : 'feature', value : 'auto', description: 'Build with ASIO Backend') 9 | option('wasapi', type : 'feature', value : 'auto', description: 'Build with WASAPI Backend') 10 | 11 | # 12 | option('docs', type : 'boolean', value : 'false', description: 'Generate API documentation') 13 | option('install_docs', type : 'boolean', value : 'false', description: 'Install API documentation') 14 | -------------------------------------------------------------------------------- /rtaudio.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=${prefix} 3 | libdir=${exec_prefix}/lib 4 | includedir=${prefix}/include/rtaudio 5 | 6 | Name: librtaudio 7 | Description: RtAudio - a set of C++ classes that provide a common API for realtime audio input/output 8 | Version: @PACKAGE_VERSION@ 9 | Requires.private: @req@ 10 | Libs: -L${libdir} -lrtaudio 11 | Libs.private: -lpthread @req_libs@ 12 | Cflags: -pthread -I${includedir} @api@ 13 | -------------------------------------------------------------------------------- /rtaudio_c.cpp: -------------------------------------------------------------------------------- 1 | #include "rtaudio_c.h" 2 | #include "RtAudio.h" 3 | 4 | #include 5 | 6 | #define MAX_ERROR_MESSAGE_LENGTH 512 7 | 8 | struct rtaudio { 9 | RtAudio *audio; 10 | 11 | rtaudio_error_t errtype; 12 | char errmsg[MAX_ERROR_MESSAGE_LENGTH]; 13 | }; 14 | 15 | const char *rtaudio_version() { return RTAUDIO_VERSION; } 16 | 17 | extern "C" const RtAudio::Api rtaudio_compiled_apis[]; 18 | const rtaudio_api_t *rtaudio_compiled_api() { 19 | return (rtaudio_api_t *) &rtaudio_compiled_apis[0]; 20 | } 21 | 22 | extern "C" const unsigned int rtaudio_num_compiled_apis; 23 | unsigned int rtaudio_get_num_compiled_apis(void) { 24 | return rtaudio_num_compiled_apis; 25 | } 26 | 27 | extern "C" const char* rtaudio_api_names[][2]; 28 | const char *rtaudio_api_name(rtaudio_api_t api) { 29 | if (api < 0 || api >= RTAUDIO_API_NUM) 30 | return NULL; 31 | return rtaudio_api_names[api][0]; 32 | } 33 | 34 | const char *rtaudio_api_display_name(rtaudio_api_t api) 35 | { 36 | if (api < 0 || api >= RTAUDIO_API_NUM) 37 | return "Unknown"; 38 | return rtaudio_api_names[api][1]; 39 | } 40 | 41 | rtaudio_api_t rtaudio_compiled_api_by_name(const char *name) { 42 | RtAudio::Api api = RtAudio::UNSPECIFIED; 43 | if (name) { 44 | api = RtAudio::getCompiledApiByName(name); 45 | } 46 | return (rtaudio_api_t)api; 47 | } 48 | 49 | const char *rtaudio_error(rtaudio_t audio) { 50 | if (audio->errtype == RTAUDIO_ERROR_NONE) { 51 | return NULL; 52 | } 53 | return audio->errmsg; 54 | } 55 | 56 | rtaudio_error_t rtaudio_error_type(rtaudio_t audio) { 57 | return audio->errtype; 58 | } 59 | 60 | rtaudio_t rtaudio_create(rtaudio_api_t api) { 61 | rtaudio_t audio = new struct rtaudio(); 62 | audio->errtype = RTAUDIO_ERROR_NONE; 63 | audio->audio = new RtAudio((RtAudio::Api)api, 64 | [audio](RtAudioErrorType type, const std::string &errorText){ 65 | audio->errtype = (rtaudio_error_t)type; 66 | strncpy(audio->errmsg, errorText.c_str(), errorText.size() - 1); 67 | }); 68 | return audio; 69 | } 70 | 71 | void rtaudio_destroy(rtaudio_t audio) { delete audio->audio; delete audio; } 72 | 73 | rtaudio_api_t rtaudio_current_api(rtaudio_t audio) { 74 | return (rtaudio_api_t)audio->audio->getCurrentApi(); 75 | } 76 | 77 | int rtaudio_device_count(rtaudio_t audio) { 78 | return audio->audio->getDeviceCount(); 79 | } 80 | 81 | unsigned int rtaudio_get_device_id(rtaudio_t audio, int i) { 82 | std::vector deviceIds = audio->audio->getDeviceIds(); 83 | if ( i >= 0 && i < (int) deviceIds.size() ) 84 | return deviceIds[i]; 85 | else 86 | return 0; 87 | } 88 | 89 | rtaudio_device_info_t rtaudio_get_device_info(rtaudio_t audio, unsigned int id) { 90 | rtaudio_device_info_t result; 91 | std::memset(&result, 0, sizeof(result)); 92 | 93 | audio->errtype = RTAUDIO_ERROR_NONE; 94 | RtAudio::DeviceInfo info = audio->audio->getDeviceInfo(id); 95 | if (audio->errtype != RTAUDIO_ERROR_NONE) 96 | return result; 97 | 98 | result.id = info.ID; 99 | result.output_channels = info.outputChannels; 100 | result.input_channels = info.inputChannels; 101 | result.duplex_channels = info.duplexChannels; 102 | result.is_default_output = info.isDefaultOutput; 103 | result.is_default_input = info.isDefaultInput; 104 | result.native_formats = info.nativeFormats; 105 | result.preferred_sample_rate = info.preferredSampleRate; 106 | strncpy(result.name, info.name.c_str(), sizeof(result.name) - 1); 107 | for (unsigned int j = 0; j < info.sampleRates.size(); j++) { 108 | if (j < sizeof(result.sample_rates) / sizeof(result.sample_rates[0])) { 109 | result.sample_rates[j] = info.sampleRates[j]; 110 | } 111 | } 112 | return result; 113 | } 114 | 115 | unsigned int rtaudio_get_default_output_device(rtaudio_t audio) { 116 | return audio->audio->getDefaultOutputDevice(); 117 | } 118 | 119 | unsigned int rtaudio_get_default_input_device(rtaudio_t audio) { 120 | return audio->audio->getDefaultInputDevice(); 121 | } 122 | 123 | 124 | rtaudio_error_t rtaudio_open_stream(rtaudio_t audio, 125 | rtaudio_stream_parameters_t *output_params, 126 | rtaudio_stream_parameters_t *input_params, 127 | rtaudio_format_t format, unsigned int sample_rate, 128 | unsigned int *buffer_frames, rtaudio_cb_t cb, 129 | void *userdata, rtaudio_stream_options_t *options, 130 | rtaudio_error_cb_t /*errcb*/) 131 | { 132 | audio->errtype = RTAUDIO_ERROR_NONE; 133 | RtAudio::StreamParameters *in = NULL; 134 | RtAudio::StreamParameters *out = NULL; 135 | RtAudio::StreamOptions *opts = NULL; 136 | 137 | RtAudio::StreamParameters inparams; 138 | RtAudio::StreamParameters outparams; 139 | RtAudio::StreamOptions stream_opts; 140 | 141 | if (input_params != NULL) { 142 | inparams.deviceId = input_params->device_id; 143 | inparams.nChannels = input_params->num_channels; 144 | inparams.firstChannel = input_params->first_channel; 145 | in = &inparams; 146 | } 147 | if (output_params != NULL) { 148 | outparams.deviceId = output_params->device_id; 149 | outparams.nChannels = output_params->num_channels; 150 | outparams.firstChannel = output_params->first_channel; 151 | out = &outparams; 152 | } 153 | 154 | if (options != NULL) { 155 | stream_opts.flags = (RtAudioStreamFlags)options->flags; 156 | stream_opts.numberOfBuffers = options->num_buffers; 157 | stream_opts.priority = options->priority; 158 | if (strlen(options->name) > 0) { 159 | stream_opts.streamName = std::string(options->name); 160 | } 161 | opts = &stream_opts; 162 | } 163 | 164 | audio->audio->openStream(out, in, (RtAudioFormat)format, sample_rate, 165 | buffer_frames, cb, (void *)userdata, opts); //, NULL); 166 | return audio->errtype; 167 | } 168 | 169 | void rtaudio_close_stream(rtaudio_t audio) { audio->audio->closeStream(); } 170 | 171 | rtaudio_error_t rtaudio_start_stream(rtaudio_t audio) { 172 | audio->errtype = RTAUDIO_ERROR_NONE; 173 | audio->audio->startStream(); 174 | return audio->errtype; 175 | } 176 | 177 | rtaudio_error_t rtaudio_stop_stream(rtaudio_t audio) { 178 | audio->errtype = RTAUDIO_ERROR_NONE; 179 | audio->audio->stopStream(); 180 | return audio->errtype; 181 | } 182 | 183 | rtaudio_error_t rtaudio_abort_stream(rtaudio_t audio) { 184 | audio->errtype = RTAUDIO_ERROR_NONE; 185 | audio->audio->abortStream(); 186 | return audio->errtype; 187 | } 188 | 189 | int rtaudio_is_stream_open(rtaudio_t audio) { 190 | return !!audio->audio->isStreamOpen(); 191 | } 192 | 193 | int rtaudio_is_stream_running(rtaudio_t audio) { 194 | return !!audio->audio->isStreamRunning(); 195 | } 196 | 197 | double rtaudio_get_stream_time(rtaudio_t audio) { 198 | audio->errtype = RTAUDIO_ERROR_NONE; 199 | return audio->audio->getStreamTime(); 200 | } 201 | 202 | void rtaudio_set_stream_time(rtaudio_t audio, double time) { 203 | audio->errtype = RTAUDIO_ERROR_NONE; 204 | audio->audio->setStreamTime(time); 205 | } 206 | 207 | long rtaudio_get_stream_latency(rtaudio_t audio) { 208 | audio->errtype = RTAUDIO_ERROR_NONE; 209 | return audio->audio->getStreamLatency(); 210 | } 211 | 212 | unsigned int rtaudio_get_stream_sample_rate(rtaudio_t audio) { 213 | audio->errtype = RTAUDIO_ERROR_NONE; 214 | return audio->audio->getStreamSampleRate(); 215 | } 216 | 217 | void rtaudio_show_warnings(rtaudio_t audio, int show) { 218 | audio->audio->showWarnings(!!show); 219 | } 220 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories(..) 2 | if (WIN32) 3 | include_directories(../include) 4 | endif (WIN32) 5 | 6 | list(GET LIB_TARGETS 0 LIBRTAUDIO) 7 | 8 | add_executable(audioprobe audioprobe.cpp) 9 | target_link_libraries(audioprobe ${LIBRTAUDIO} ${LINKLIBS}) 10 | 11 | add_executable(playsaw playsaw.cpp) 12 | target_link_libraries(playsaw ${LIBRTAUDIO} ${LINKLIBS}) 13 | 14 | add_executable(playraw playraw.cpp) 15 | target_link_libraries(playraw ${LIBRTAUDIO} ${LINKLIBS}) 16 | 17 | add_executable(record record.cpp) 18 | target_link_libraries(record ${LIBRTAUDIO} ${LINKLIBS}) 19 | 20 | add_executable(duplex duplex.cpp) 21 | target_link_libraries(duplex ${LIBRTAUDIO} ${LINKLIBS}) 22 | 23 | add_executable(apinames apinames.cpp) 24 | target_link_libraries(apinames ${LIBRTAUDIO} ${LINKLIBS}) 25 | 26 | add_executable(testall testall.cpp) 27 | target_link_libraries(testall ${LIBRTAUDIO} ${LINKLIBS}) 28 | 29 | add_executable(teststops teststops.cpp) 30 | target_link_libraries(teststops ${LIBRTAUDIO} ${LINKLIBS}) 31 | 32 | add_test(NAME apinames COMMAND apinames) 33 | -------------------------------------------------------------------------------- /tests/Debug/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thestk/rtaudio/40e0d8140f14acd8552d2dc4f42dcc853274a12c/tests/Debug/.placeholder -------------------------------------------------------------------------------- /tests/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | noinst_PROGRAMS = audioprobe playsaw playraw record duplex apinames testall teststops 3 | 4 | AM_CXXFLAGS = -Wall -I$(top_srcdir) 5 | 6 | audioprobe_SOURCES = audioprobe.cpp 7 | audioprobe_LDADD = $(top_builddir)/librtaudio.la 8 | 9 | playsaw_SOURCES = playsaw.cpp 10 | playsaw_LDADD = $(top_builddir)/librtaudio.la 11 | 12 | playraw_SOURCES = playraw.cpp 13 | playraw_LDADD = $(top_builddir)/librtaudio.la 14 | 15 | record_SOURCES = record.cpp 16 | record_LDADD = $(top_builddir)/librtaudio.la 17 | 18 | duplex_SOURCES = duplex.cpp 19 | duplex_LDADD = $(top_builddir)/librtaudio.la 20 | 21 | apinames_SOURCES = apinames.cpp 22 | apinames_LDADD = $(top_builddir)/librtaudio.la 23 | 24 | testall_SOURCES = testall.cpp 25 | testall_LDADD = $(top_builddir)/librtaudio.la 26 | 27 | teststops_SOURCES = teststops.cpp 28 | teststops_LDADD = $(top_builddir)/librtaudio.la 29 | 30 | EXTRA_DIST = Windows CMakeLists.txt 31 | 32 | TESTS = apinames 33 | -------------------------------------------------------------------------------- /tests/Release/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thestk/rtaudio/40e0d8140f14acd8552d2dc4f42dcc853274a12c/tests/Release/.placeholder -------------------------------------------------------------------------------- /tests/Windows/Debug/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thestk/rtaudio/40e0d8140f14acd8552d2dc4f42dcc853274a12c/tests/Windows/Debug/.placeholder -------------------------------------------------------------------------------- /tests/Windows/Release/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thestk/rtaudio/40e0d8140f14acd8552d2dc4f42dcc853274a12c/tests/Windows/Release/.placeholder -------------------------------------------------------------------------------- /tests/Windows/audioprobe.dsp: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="audioprobe" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Console Application" 0x0103 6 | 7 | CFG=audioprobe - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "audioprobe.mak". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "audioprobe.mak" CFG="audioprobe - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "audioprobe - Win32 Release" (based on "Win32 (x86) Console Application") 21 | !MESSAGE "audioprobe - Win32 Debug" (based on "Win32 (x86) Console Application") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP AllowPerConfigDependencies 0 26 | # PROP Scc_ProjName "" 27 | # PROP Scc_LocalPath "" 28 | CPP=cl.exe 29 | RSC=rc.exe 30 | 31 | !IF "$(CFG)" == "audioprobe - Win32 Release" 32 | 33 | # PROP BASE Use_MFC 0 34 | # PROP BASE Use_Debug_Libraries 0 35 | # PROP BASE Output_Dir "audioprobe___Win32_Release" 36 | # PROP BASE Intermediate_Dir "audioprobe___Win32_Release" 37 | # PROP BASE Target_Dir "" 38 | # PROP Use_MFC 0 39 | # PROP Use_Debug_Libraries 0 40 | # PROP Output_Dir "" 41 | # PROP Intermediate_Dir "Release" 42 | # PROP Ignore_Export_Lib 0 43 | # PROP Target_Dir "" 44 | # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 45 | # ADD CPP /nologo /MT /W3 /GX /O2 /I "../../" /I "../../include" /D "NDEBUG" /D "__WINDOWS_DS__" /D "__WINDOWS_ASIO__" /D "__WINDOWS_WASAPI__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 46 | # ADD BASE RSC /l 0x409 /d "NDEBUG" 47 | # ADD RSC /l 0x409 /d "NDEBUG" 48 | BSC32=bscmake.exe 49 | # ADD BASE BSC32 /nologo 50 | # ADD BSC32 /nologo 51 | LINK32=link.exe 52 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 53 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib /nologo /subsystem:console /machine:I386 54 | 55 | !ELSEIF "$(CFG)" == "audioprobe - Win32 Debug" 56 | 57 | # PROP BASE Use_MFC 0 58 | # PROP BASE Use_Debug_Libraries 1 59 | # PROP BASE Output_Dir "audioprobe___Win32_Debug" 60 | # PROP BASE Intermediate_Dir "audioprobe___Win32_Debug" 61 | # PROP BASE Target_Dir "" 62 | # PROP Use_MFC 0 63 | # PROP Use_Debug_Libraries 1 64 | # PROP Output_Dir "" 65 | # PROP Intermediate_Dir "Debug" 66 | # PROP Ignore_Export_Lib 0 67 | # PROP Target_Dir "" 68 | # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c 69 | # ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../" /I "../../include" /D "_DEBUG" /D "__WINDOWS_DS__" /D "__WINDOWS_ASIO__" /D "__WINDOWS_WASAPI__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c 70 | # ADD BASE RSC /l 0x409 /d "_DEBUG" 71 | # ADD RSC /l 0x409 /d "_DEBUG" 72 | BSC32=bscmake.exe 73 | # ADD BASE BSC32 /nologo 74 | # ADD BSC32 /nologo 75 | LINK32=link.exe 76 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept 77 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept 78 | 79 | !ENDIF 80 | 81 | # Begin Target 82 | 83 | # Name "audioprobe - Win32 Release" 84 | # Name "audioprobe - Win32 Debug" 85 | # Begin Group "Source Files" 86 | 87 | # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" 88 | # Begin Source File 89 | 90 | SOURCE=..\..\include\asio.cpp 91 | # End Source File 92 | # Begin Source File 93 | 94 | SOURCE=..\..\include\asiodrivers.cpp 95 | # End Source File 96 | # Begin Source File 97 | 98 | SOURCE=..\..\include\asiolist.cpp 99 | # End Source File 100 | # Begin Source File 101 | 102 | SOURCE=..\audioprobe.cpp 103 | # End Source File 104 | # Begin Source File 105 | 106 | SOURCE=..\..\include\iasiothiscallresolver.cpp 107 | # End Source File 108 | # Begin Source File 109 | 110 | SOURCE=..\..\RtAudio.cpp 111 | # End Source File 112 | # End Group 113 | # Begin Group "Header Files" 114 | 115 | # PROP Default_Filter "h;hpp;hxx;hm;inl" 116 | # Begin Source File 117 | 118 | SOURCE=..\..\include\asio.h 119 | # End Source File 120 | # Begin Source File 121 | 122 | SOURCE=..\..\include\asiodrivers.h 123 | # End Source File 124 | # Begin Source File 125 | 126 | SOURCE=..\..\include\asiodrvr.h 127 | # End Source File 128 | # Begin Source File 129 | 130 | SOURCE=..\..\include\asiolist.h 131 | # End Source File 132 | # Begin Source File 133 | 134 | SOURCE=..\..\include\asiosys.h 135 | # End Source File 136 | # Begin Source File 137 | 138 | SOURCE=..\..\include\ginclude.h 139 | # End Source File 140 | # Begin Source File 141 | 142 | SOURCE=..\..\include\iasiodrv.h 143 | # End Source File 144 | # Begin Source File 145 | 146 | SOURCE=..\..\include\iasiothiscallresolver.h 147 | # End Source File 148 | # Begin Source File 149 | 150 | SOURCE=..\..\RtAudio.h 151 | # End Source File 152 | # End Group 153 | # Begin Group "Resource Files" 154 | 155 | # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" 156 | # End Group 157 | # End Target 158 | # End Project 159 | -------------------------------------------------------------------------------- /tests/Windows/duplex.dsp: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="duplex" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Console Application" 0x0103 6 | 7 | CFG=duplex - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "duplex.mak". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "duplex.mak" CFG="duplex - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "duplex - Win32 Release" (based on "Win32 (x86) Console Application") 21 | !MESSAGE "duplex - Win32 Debug" (based on "Win32 (x86) Console Application") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP AllowPerConfigDependencies 0 26 | # PROP Scc_ProjName "" 27 | # PROP Scc_LocalPath "" 28 | CPP=cl.exe 29 | RSC=rc.exe 30 | 31 | !IF "$(CFG)" == "duplex - Win32 Release" 32 | 33 | # PROP BASE Use_MFC 0 34 | # PROP BASE Use_Debug_Libraries 0 35 | # PROP BASE Output_Dir "duplex___Win32_Release" 36 | # PROP BASE Intermediate_Dir "duplex___Win32_Release" 37 | # PROP BASE Target_Dir "" 38 | # PROP Use_MFC 0 39 | # PROP Use_Debug_Libraries 0 40 | # PROP Output_Dir "" 41 | # PROP Intermediate_Dir "Release" 42 | # PROP Ignore_Export_Lib 0 43 | # PROP Target_Dir "" 44 | # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 45 | # ADD CPP /nologo /MT /W3 /GX /O2 /I "../../" /I "../../include" /D "NDEBUG" /D "__WINDOWS_DS__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_ASIO__" /D "__WINDOWS_WASAPI__" /YX /FD /c 46 | # ADD BASE RSC /l 0x409 /d "NDEBUG" 47 | # ADD RSC /l 0x409 /d "NDEBUG" 48 | BSC32=bscmake.exe 49 | # ADD BASE BSC32 /nologo 50 | # ADD BSC32 /nologo 51 | LINK32=link.exe 52 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 53 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib /nologo /subsystem:console /machine:I386 54 | 55 | !ELSEIF "$(CFG)" == "duplex - Win32 Debug" 56 | 57 | # PROP BASE Use_MFC 0 58 | # PROP BASE Use_Debug_Libraries 1 59 | # PROP BASE Output_Dir "duplex___Win32_Debug" 60 | # PROP BASE Intermediate_Dir "duplex___Win32_Debug" 61 | # PROP BASE Target_Dir "" 62 | # PROP Use_MFC 0 63 | # PROP Use_Debug_Libraries 1 64 | # PROP Output_Dir "" 65 | # PROP Intermediate_Dir "Debug" 66 | # PROP Ignore_Export_Lib 0 67 | # PROP Target_Dir "" 68 | # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c 69 | # ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../" /I "../../include" /D "_DEBUG" /D "__WINDOWS_ASIO__.__WINDOWS_DS__" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_ASIO__" /D "__WINDOWS_DS__" /D "__WINDOWS_WASAPI__" /YX /FD /GZ /c 70 | # ADD BASE RSC /l 0x409 /d "_DEBUG" 71 | # ADD RSC /l 0x409 /d "_DEBUG" 72 | BSC32=bscmake.exe 73 | # ADD BASE BSC32 /nologo 74 | # ADD BSC32 /nologo 75 | LINK32=link.exe 76 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept 77 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept 78 | 79 | !ENDIF 80 | 81 | # Begin Target 82 | 83 | # Name "duplex - Win32 Release" 84 | # Name "duplex - Win32 Debug" 85 | # Begin Group "Source Files" 86 | 87 | # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" 88 | # Begin Source File 89 | 90 | SOURCE=..\..\include\asio.cpp 91 | # End Source File 92 | # Begin Source File 93 | 94 | SOURCE=..\..\include\asiodrivers.cpp 95 | # End Source File 96 | # Begin Source File 97 | 98 | SOURCE=..\..\include\asiolist.cpp 99 | # End Source File 100 | # Begin Source File 101 | 102 | SOURCE=..\duplex.cpp 103 | # End Source File 104 | # Begin Source File 105 | 106 | SOURCE=..\..\include\iasiothiscallresolver.cpp 107 | # End Source File 108 | # Begin Source File 109 | 110 | SOURCE=..\..\RtAudio.cpp 111 | # End Source File 112 | # End Group 113 | # Begin Group "Header Files" 114 | 115 | # PROP Default_Filter "h;hpp;hxx;hm;inl" 116 | # Begin Source File 117 | 118 | SOURCE=..\..\include\asio.h 119 | # End Source File 120 | # Begin Source File 121 | 122 | SOURCE=..\..\include\asiodrivers.h 123 | # End Source File 124 | # Begin Source File 125 | 126 | SOURCE=..\..\include\asiodrvr.h 127 | # End Source File 128 | # Begin Source File 129 | 130 | SOURCE=..\..\include\asiolist.h 131 | # End Source File 132 | # Begin Source File 133 | 134 | SOURCE=..\..\include\asiosys.h 135 | # End Source File 136 | # Begin Source File 137 | 138 | SOURCE=..\..\include\ginclude.h 139 | # End Source File 140 | # Begin Source File 141 | 142 | SOURCE=..\..\include\iasiodrv.h 143 | # End Source File 144 | # Begin Source File 145 | 146 | SOURCE=..\..\include\iasiothiscallresolver.h 147 | # End Source File 148 | # Begin Source File 149 | 150 | SOURCE=..\..\RtAudio.h 151 | # End Source File 152 | # End Group 153 | # Begin Group "Resource Files" 154 | 155 | # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" 156 | # End Group 157 | # End Target 158 | # End Project 159 | -------------------------------------------------------------------------------- /tests/Windows/playraw.dsp: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="playraw" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Console Application" 0x0103 6 | 7 | CFG=playraw - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "playraw.mak". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "playraw.mak" CFG="playraw - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "playraw - Win32 Release" (based on "Win32 (x86) Console Application") 21 | !MESSAGE "playraw - Win32 Debug" (based on "Win32 (x86) Console Application") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP AllowPerConfigDependencies 0 26 | # PROP Scc_ProjName "" 27 | # PROP Scc_LocalPath "" 28 | CPP=cl.exe 29 | RSC=rc.exe 30 | 31 | !IF "$(CFG)" == "playraw - Win32 Release" 32 | 33 | # PROP BASE Use_MFC 0 34 | # PROP BASE Use_Debug_Libraries 0 35 | # PROP BASE Output_Dir "playraw___Win32_Release" 36 | # PROP BASE Intermediate_Dir "playraw___Win32_Release" 37 | # PROP BASE Target_Dir "" 38 | # PROP Use_MFC 0 39 | # PROP Use_Debug_Libraries 0 40 | # PROP Output_Dir "" 41 | # PROP Intermediate_Dir "Release" 42 | # PROP Ignore_Export_Lib 0 43 | # PROP Target_Dir "" 44 | # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 45 | # ADD CPP /nologo /MT /W3 /GX /O2 /I "../../" /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_ASIO__" /D "__WINDOWS_DS__" /D "__WINDOWS_WASAPI__" /YX /FD /c 46 | # ADD BASE RSC /l 0x409 /d "NDEBUG" 47 | # ADD RSC /l 0x409 /d "NDEBUG" 48 | BSC32=bscmake.exe 49 | # ADD BASE BSC32 /nologo 50 | # ADD BSC32 /nologo 51 | LINK32=link.exe 52 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 53 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib /nologo /subsystem:console /machine:I386 54 | 55 | !ELSEIF "$(CFG)" == "playraw - Win32 Debug" 56 | 57 | # PROP BASE Use_MFC 0 58 | # PROP BASE Use_Debug_Libraries 1 59 | # PROP BASE Output_Dir "playraw___Win32_Debug" 60 | # PROP BASE Intermediate_Dir "playraw___Win32_Debug" 61 | # PROP BASE Target_Dir "" 62 | # PROP Use_MFC 0 63 | # PROP Use_Debug_Libraries 1 64 | # PROP Output_Dir "" 65 | # PROP Intermediate_Dir "Debug" 66 | # PROP Ignore_Export_Lib 0 67 | # PROP Target_Dir "" 68 | # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c 69 | # ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../" /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_ASIO__" /D "__WINDOWS_DS__" /D "__WINDOWS_WASAPI__" /YX /FD /GZ /c 70 | # ADD BASE RSC /l 0x409 /d "_DEBUG" 71 | # ADD RSC /l 0x409 /d "_DEBUG" 72 | BSC32=bscmake.exe 73 | # ADD BASE BSC32 /nologo 74 | # ADD BSC32 /nologo 75 | LINK32=link.exe 76 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept 77 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept 78 | 79 | !ENDIF 80 | 81 | # Begin Target 82 | 83 | # Name "playraw - Win32 Release" 84 | # Name "playraw - Win32 Debug" 85 | # Begin Group "Source Files" 86 | 87 | # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" 88 | # Begin Source File 89 | 90 | SOURCE=..\..\include\asio.cpp 91 | # End Source File 92 | # Begin Source File 93 | 94 | SOURCE=..\..\include\asiodrivers.cpp 95 | # End Source File 96 | # Begin Source File 97 | 98 | SOURCE=..\..\include\asiolist.cpp 99 | # End Source File 100 | # Begin Source File 101 | 102 | SOURCE=..\..\include\iasiothiscallresolver.cpp 103 | # End Source File 104 | # Begin Source File 105 | 106 | SOURCE=..\playraw.cpp 107 | # End Source File 108 | # Begin Source File 109 | 110 | SOURCE=..\..\RtAudio.cpp 111 | # End Source File 112 | # End Group 113 | # Begin Group "Header Files" 114 | 115 | # PROP Default_Filter "h;hpp;hxx;hm;inl" 116 | # Begin Source File 117 | 118 | SOURCE=..\..\include\asio.h 119 | # End Source File 120 | # Begin Source File 121 | 122 | SOURCE=..\..\include\asiodrivers.h 123 | # End Source File 124 | # Begin Source File 125 | 126 | SOURCE=..\..\include\asiodrvr.h 127 | # End Source File 128 | # Begin Source File 129 | 130 | SOURCE=..\..\include\asiolist.h 131 | # End Source File 132 | # Begin Source File 133 | 134 | SOURCE=..\..\include\asiosys.h 135 | # End Source File 136 | # Begin Source File 137 | 138 | SOURCE=..\..\include\ginclude.h 139 | # End Source File 140 | # Begin Source File 141 | 142 | SOURCE=..\..\include\iasiodrv.h 143 | # End Source File 144 | # Begin Source File 145 | 146 | SOURCE=..\..\include\iasiothiscallresolver.h 147 | # End Source File 148 | # Begin Source File 149 | 150 | SOURCE=..\..\RtAudio.h 151 | # End Source File 152 | # End Group 153 | # Begin Group "Resource Files" 154 | 155 | # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" 156 | # End Group 157 | # End Target 158 | # End Project 159 | -------------------------------------------------------------------------------- /tests/Windows/playsaw.dsp: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="playsaw" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Console Application" 0x0103 6 | 7 | CFG=playsaw - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "playsaw.mak". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "playsaw.mak" CFG="playsaw - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "playsaw - Win32 Release" (based on "Win32 (x86) Console Application") 21 | !MESSAGE "playsaw - Win32 Debug" (based on "Win32 (x86) Console Application") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP AllowPerConfigDependencies 0 26 | # PROP Scc_ProjName "" 27 | # PROP Scc_LocalPath "" 28 | CPP=cl.exe 29 | RSC=rc.exe 30 | 31 | !IF "$(CFG)" == "playsaw - Win32 Release" 32 | 33 | # PROP BASE Use_MFC 0 34 | # PROP BASE Use_Debug_Libraries 0 35 | # PROP BASE Output_Dir "playsaw___Win32_Release" 36 | # PROP BASE Intermediate_Dir "playsaw___Win32_Release" 37 | # PROP BASE Target_Dir "" 38 | # PROP Use_MFC 0 39 | # PROP Use_Debug_Libraries 0 40 | # PROP Output_Dir "" 41 | # PROP Intermediate_Dir "Release" 42 | # PROP Ignore_Export_Lib 0 43 | # PROP Target_Dir "" 44 | # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 45 | # ADD CPP /nologo /MT /W3 /GX /O2 /I "../../" /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_ASIO__" /D "__WINDOWS_DS__" /D "__WINDOWS_WASAPI__" /YX /FD /c 46 | # ADD BASE RSC /l 0x409 /d "NDEBUG" 47 | # ADD RSC /l 0x409 /d "NDEBUG" 48 | BSC32=bscmake.exe 49 | # ADD BASE BSC32 /nologo 50 | # ADD BSC32 /nologo 51 | LINK32=link.exe 52 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 53 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib /nologo /subsystem:console /machine:I386 54 | 55 | !ELSEIF "$(CFG)" == "playsaw - Win32 Debug" 56 | 57 | # PROP BASE Use_MFC 0 58 | # PROP BASE Use_Debug_Libraries 1 59 | # PROP BASE Output_Dir "playsaw___Win32_Debug" 60 | # PROP BASE Intermediate_Dir "playsaw___Win32_Debug" 61 | # PROP BASE Target_Dir "" 62 | # PROP Use_MFC 0 63 | # PROP Use_Debug_Libraries 1 64 | # PROP Output_Dir "" 65 | # PROP Intermediate_Dir "Debug" 66 | # PROP Ignore_Export_Lib 0 67 | # PROP Target_Dir "" 68 | # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c 69 | # ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../" /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_ASIO__" /D "__WINDOWS_DS__" /D "__WINDOWS_WASAPI__" /YX /FD /GZ /c 70 | # ADD BASE RSC /l 0x409 /d "_DEBUG" 71 | # ADD RSC /l 0x409 /d "_DEBUG" 72 | BSC32=bscmake.exe 73 | # ADD BASE BSC32 /nologo 74 | # ADD BSC32 /nologo 75 | LINK32=link.exe 76 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept 77 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept 78 | 79 | !ENDIF 80 | 81 | # Begin Target 82 | 83 | # Name "playsaw - Win32 Release" 84 | # Name "playsaw - Win32 Debug" 85 | # Begin Group "Source Files" 86 | 87 | # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" 88 | # Begin Source File 89 | 90 | SOURCE=..\..\include\asio.cpp 91 | # End Source File 92 | # Begin Source File 93 | 94 | SOURCE=..\..\include\asiodrivers.cpp 95 | # End Source File 96 | # Begin Source File 97 | 98 | SOURCE=..\..\include\asiolist.cpp 99 | # End Source File 100 | # Begin Source File 101 | 102 | SOURCE=..\..\include\iasiothiscallresolver.cpp 103 | # End Source File 104 | # Begin Source File 105 | 106 | SOURCE=..\playsaw.cpp 107 | # End Source File 108 | # Begin Source File 109 | 110 | SOURCE=..\..\RtAudio.cpp 111 | # End Source File 112 | # End Group 113 | # Begin Group "Header Files" 114 | 115 | # PROP Default_Filter "h;hpp;hxx;hm;inl" 116 | # Begin Source File 117 | 118 | SOURCE=..\..\include\asio.h 119 | # End Source File 120 | # Begin Source File 121 | 122 | SOURCE=..\..\include\asiodrivers.h 123 | # End Source File 124 | # Begin Source File 125 | 126 | SOURCE=..\..\include\asiodrvr.h 127 | # End Source File 128 | # Begin Source File 129 | 130 | SOURCE=..\..\include\asiolist.h 131 | # End Source File 132 | # Begin Source File 133 | 134 | SOURCE=..\..\include\asiosys.h 135 | # End Source File 136 | # Begin Source File 137 | 138 | SOURCE=..\..\include\ginclude.h 139 | # End Source File 140 | # Begin Source File 141 | 142 | SOURCE=..\..\include\iasiodrv.h 143 | # End Source File 144 | # Begin Source File 145 | 146 | SOURCE=..\..\include\iasiothiscallresolver.h 147 | # End Source File 148 | # Begin Source File 149 | 150 | SOURCE=..\..\RtAudio.h 151 | # End Source File 152 | # End Group 153 | # Begin Group "Resource Files" 154 | 155 | # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" 156 | # End Group 157 | # End Target 158 | # End Project 159 | -------------------------------------------------------------------------------- /tests/Windows/record.dsp: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="record" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Console Application" 0x0103 6 | 7 | CFG=record - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "record.mak". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "record.mak" CFG="record - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "record - Win32 Release" (based on "Win32 (x86) Console Application") 21 | !MESSAGE "record - Win32 Debug" (based on "Win32 (x86) Console Application") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP AllowPerConfigDependencies 0 26 | # PROP Scc_ProjName "" 27 | # PROP Scc_LocalPath "" 28 | CPP=cl.exe 29 | RSC=rc.exe 30 | 31 | !IF "$(CFG)" == "record - Win32 Release" 32 | 33 | # PROP BASE Use_MFC 0 34 | # PROP BASE Use_Debug_Libraries 0 35 | # PROP BASE Output_Dir "record___Win32_Release" 36 | # PROP BASE Intermediate_Dir "record___Win32_Release" 37 | # PROP BASE Target_Dir "" 38 | # PROP Use_MFC 0 39 | # PROP Use_Debug_Libraries 0 40 | # PROP Output_Dir "" 41 | # PROP Intermediate_Dir "Release" 42 | # PROP Ignore_Export_Lib 0 43 | # PROP Target_Dir "" 44 | # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 45 | # ADD CPP /nologo /MT /W3 /GX /O2 /I "../../" /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_ASIO__" /D "__WINDOWS_DS__" /D "__WINDOWS_WASAPI__" /YX /FD /c 46 | # ADD BASE RSC /l 0x409 /d "NDEBUG" 47 | # ADD RSC /l 0x409 /d "NDEBUG" 48 | BSC32=bscmake.exe 49 | # ADD BASE BSC32 /nologo 50 | # ADD BSC32 /nologo 51 | LINK32=link.exe 52 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 53 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib /nologo /subsystem:console /machine:I386 54 | 55 | !ELSEIF "$(CFG)" == "record - Win32 Debug" 56 | 57 | # PROP BASE Use_MFC 0 58 | # PROP BASE Use_Debug_Libraries 1 59 | # PROP BASE Output_Dir "record___Win32_Debug" 60 | # PROP BASE Intermediate_Dir "record___Win32_Debug" 61 | # PROP BASE Target_Dir "" 62 | # PROP Use_MFC 0 63 | # PROP Use_Debug_Libraries 1 64 | # PROP Output_Dir "" 65 | # PROP Intermediate_Dir "Debug" 66 | # PROP Ignore_Export_Lib 0 67 | # PROP Target_Dir "" 68 | # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c 69 | # ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../" /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_ASIO__" /D "__WINDOWS_DS__" /D "__WINDOWS_WASAPI__" /YX /FD /GZ /c 70 | # ADD BASE RSC /l 0x409 /d "_DEBUG" 71 | # ADD RSC /l 0x409 /d "_DEBUG" 72 | BSC32=bscmake.exe 73 | # ADD BASE BSC32 /nologo 74 | # ADD BSC32 /nologo 75 | LINK32=link.exe 76 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept 77 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept 78 | 79 | !ENDIF 80 | 81 | # Begin Target 82 | 83 | # Name "record - Win32 Release" 84 | # Name "record - Win32 Debug" 85 | # Begin Group "Source Files" 86 | 87 | # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" 88 | # Begin Source File 89 | 90 | SOURCE=..\..\include\asio.cpp 91 | # End Source File 92 | # Begin Source File 93 | 94 | SOURCE=..\..\include\asiodrivers.cpp 95 | # End Source File 96 | # Begin Source File 97 | 98 | SOURCE=..\..\include\asiolist.cpp 99 | # End Source File 100 | # Begin Source File 101 | 102 | SOURCE=..\..\include\iasiothiscallresolver.cpp 103 | # End Source File 104 | # Begin Source File 105 | 106 | SOURCE=..\record.cpp 107 | # End Source File 108 | # Begin Source File 109 | 110 | SOURCE=..\..\RtAudio.cpp 111 | # End Source File 112 | # End Group 113 | # Begin Group "Header Files" 114 | 115 | # PROP Default_Filter "h;hpp;hxx;hm;inl" 116 | # Begin Source File 117 | 118 | SOURCE=..\..\include\asio.h 119 | # End Source File 120 | # Begin Source File 121 | 122 | SOURCE=..\..\include\asiodrivers.h 123 | # End Source File 124 | # Begin Source File 125 | 126 | SOURCE=..\..\include\asiodrvr.h 127 | # End Source File 128 | # Begin Source File 129 | 130 | SOURCE=..\..\include\asiolist.h 131 | # End Source File 132 | # Begin Source File 133 | 134 | SOURCE=..\..\include\asiosys.h 135 | # End Source File 136 | # Begin Source File 137 | 138 | SOURCE=..\..\include\ginclude.h 139 | # End Source File 140 | # Begin Source File 141 | 142 | SOURCE=..\..\include\iasiodrv.h 143 | # End Source File 144 | # Begin Source File 145 | 146 | SOURCE=..\..\include\iasiothiscallresolver.h 147 | # End Source File 148 | # Begin Source File 149 | 150 | SOURCE=..\..\RtAudio.h 151 | # End Source File 152 | # End Group 153 | # Begin Group "Resource Files" 154 | 155 | # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" 156 | # End Group 157 | # End Target 158 | # End Project 159 | -------------------------------------------------------------------------------- /tests/Windows/rtaudio.dsw: -------------------------------------------------------------------------------- 1 | Microsoft Developer Studio Workspace File, Format Version 6.00 2 | # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! 3 | 4 | ############################################################################### 5 | 6 | Project: "audioprobe"=.\audioprobe.dsp - Package Owner=<4> 7 | 8 | Package=<5> 9 | {{{ 10 | }}} 11 | 12 | Package=<4> 13 | {{{ 14 | }}} 15 | 16 | ############################################################################### 17 | 18 | Project: "duplex"=.\duplex.dsp - Package Owner=<4> 19 | 20 | Package=<5> 21 | {{{ 22 | }}} 23 | 24 | Package=<4> 25 | {{{ 26 | }}} 27 | 28 | ############################################################################### 29 | 30 | Project: "playraw"=.\playraw.dsp - Package Owner=<4> 31 | 32 | Package=<5> 33 | {{{ 34 | }}} 35 | 36 | Package=<4> 37 | {{{ 38 | }}} 39 | 40 | ############################################################################### 41 | 42 | Project: "playsaw"=.\playsaw.dsp - Package Owner=<4> 43 | 44 | Package=<5> 45 | {{{ 46 | }}} 47 | 48 | Package=<4> 49 | {{{ 50 | }}} 51 | 52 | ############################################################################### 53 | 54 | Project: "record"=.\record.dsp - Package Owner=<4> 55 | 56 | Package=<5> 57 | {{{ 58 | }}} 59 | 60 | Package=<4> 61 | {{{ 62 | }}} 63 | 64 | ############################################################################### 65 | 66 | Project: "testall"=.\testall.dsp - Package Owner=<4> 67 | 68 | Package=<5> 69 | {{{ 70 | }}} 71 | 72 | Package=<4> 73 | {{{ 74 | }}} 75 | 76 | ############################################################################### 77 | 78 | Project: "teststops"=.\teststops.dsp - Package Owner=<4> 79 | 80 | Package=<5> 81 | {{{ 82 | }}} 83 | 84 | Package=<4> 85 | {{{ 86 | }}} 87 | 88 | ############################################################################### 89 | 90 | Global: 91 | 92 | Package=<5> 93 | {{{ 94 | }}} 95 | 96 | Package=<3> 97 | {{{ 98 | }}} 99 | 100 | ############################################################################### 101 | 102 | -------------------------------------------------------------------------------- /tests/Windows/testall.dsp: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="testall" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Console Application" 0x0103 6 | 7 | CFG=testall - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "testall.mak". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "testall.mak" CFG="testall - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "testall - Win32 Release" (based on "Win32 (x86) Console Application") 21 | !MESSAGE "testall - Win32 Debug" (based on "Win32 (x86) Console Application") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP AllowPerConfigDependencies 0 26 | # PROP Scc_ProjName "" 27 | # PROP Scc_LocalPath "" 28 | CPP=cl.exe 29 | RSC=rc.exe 30 | 31 | !IF "$(CFG)" == "testall - Win32 Release" 32 | 33 | # PROP BASE Use_MFC 0 34 | # PROP BASE Use_Debug_Libraries 0 35 | # PROP BASE Output_Dir "testall___Win32_Release" 36 | # PROP BASE Intermediate_Dir "testall___Win32_Release" 37 | # PROP BASE Target_Dir "" 38 | # PROP Use_MFC 0 39 | # PROP Use_Debug_Libraries 0 40 | # PROP Output_Dir "" 41 | # PROP Intermediate_Dir "Release" 42 | # PROP Ignore_Export_Lib 0 43 | # PROP Target_Dir "" 44 | # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 45 | # ADD CPP /nologo /MT /W3 /GX /O2 /I "../../" /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_ASIO__" /D "__WINDOWS_DS__" /D "__WINDOWS_WASAPI__" /YX /FD /c 46 | # ADD BASE RSC /l 0x409 /d "NDEBUG" 47 | # ADD RSC /l 0x409 /d "NDEBUG" 48 | BSC32=bscmake.exe 49 | # ADD BASE BSC32 /nologo 50 | # ADD BSC32 /nologo 51 | LINK32=link.exe 52 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 53 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib /nologo /subsystem:console /machine:I386 54 | 55 | !ELSEIF "$(CFG)" == "testall - Win32 Debug" 56 | 57 | # PROP BASE Use_MFC 0 58 | # PROP BASE Use_Debug_Libraries 1 59 | # PROP BASE Output_Dir "testall___Win32_Debug" 60 | # PROP BASE Intermediate_Dir "testall___Win32_Debug" 61 | # PROP BASE Target_Dir "" 62 | # PROP Use_MFC 0 63 | # PROP Use_Debug_Libraries 1 64 | # PROP Output_Dir "" 65 | # PROP Intermediate_Dir "Debug" 66 | # PROP Ignore_Export_Lib 0 67 | # PROP Target_Dir "" 68 | # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c 69 | # ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../" /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_ASIO__" /D "__WINDOWS_DS__" /D "__WINDOWS_WASAPI__" /YX /FD /GZ /c 70 | # ADD BASE RSC /l 0x409 /d "_DEBUG" 71 | # ADD RSC /l 0x409 /d "_DEBUG" 72 | BSC32=bscmake.exe 73 | # ADD BASE BSC32 /nologo 74 | # ADD BSC32 /nologo 75 | LINK32=link.exe 76 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept 77 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept 78 | 79 | !ENDIF 80 | 81 | # Begin Target 82 | 83 | # Name "testall - Win32 Release" 84 | # Name "testall - Win32 Debug" 85 | # Begin Group "Source Files" 86 | 87 | # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" 88 | # Begin Source File 89 | 90 | SOURCE=..\..\include\asio.cpp 91 | # End Source File 92 | # Begin Source File 93 | 94 | SOURCE=..\..\include\asiodrivers.cpp 95 | # End Source File 96 | # Begin Source File 97 | 98 | SOURCE=..\..\include\asiolist.cpp 99 | # End Source File 100 | # Begin Source File 101 | 102 | SOURCE=..\..\include\iasiothiscallresolver.cpp 103 | # End Source File 104 | # Begin Source File 105 | 106 | SOURCE=..\..\RtAudio.cpp 107 | # End Source File 108 | # Begin Source File 109 | 110 | SOURCE=..\testall.cpp 111 | # End Source File 112 | # End Group 113 | # Begin Group "Header Files" 114 | 115 | # PROP Default_Filter "h;hpp;hxx;hm;inl" 116 | # Begin Source File 117 | 118 | SOURCE=..\..\include\asio.h 119 | # End Source File 120 | # Begin Source File 121 | 122 | SOURCE=..\..\include\asiodrivers.h 123 | # End Source File 124 | # Begin Source File 125 | 126 | SOURCE=..\..\include\asiodrvr.h 127 | # End Source File 128 | # Begin Source File 129 | 130 | SOURCE=..\..\include\asiolist.h 131 | # End Source File 132 | # Begin Source File 133 | 134 | SOURCE=..\..\include\asiosys.h 135 | # End Source File 136 | # Begin Source File 137 | 138 | SOURCE=..\..\include\ginclude.h 139 | # End Source File 140 | # Begin Source File 141 | 142 | SOURCE=..\..\include\iasiodrv.h 143 | # End Source File 144 | # Begin Source File 145 | 146 | SOURCE=..\..\include\iasiothiscallresolver.h 147 | # End Source File 148 | # Begin Source File 149 | 150 | SOURCE=..\..\RtAudio.h 151 | # End Source File 152 | # End Group 153 | # Begin Group "Resource Files" 154 | 155 | # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" 156 | # End Group 157 | # End Target 158 | # End Project 159 | -------------------------------------------------------------------------------- /tests/Windows/teststops.dsp: -------------------------------------------------------------------------------- 1 | # Microsoft Developer Studio Project File - Name="teststops" - Package Owner=<4> 2 | # Microsoft Developer Studio Generated Build File, Format Version 6.00 3 | # ** DO NOT EDIT ** 4 | 5 | # TARGTYPE "Win32 (x86) Console Application" 0x0103 6 | 7 | CFG=teststops - Win32 Debug 8 | !MESSAGE This is not a valid makefile. To build this project using NMAKE, 9 | !MESSAGE use the Export Makefile command and run 10 | !MESSAGE 11 | !MESSAGE NMAKE /f "teststops.mak". 12 | !MESSAGE 13 | !MESSAGE You can specify a configuration when running NMAKE 14 | !MESSAGE by defining the macro CFG on the command line. For example: 15 | !MESSAGE 16 | !MESSAGE NMAKE /f "teststops.mak" CFG="teststops - Win32 Debug" 17 | !MESSAGE 18 | !MESSAGE Possible choices for configuration are: 19 | !MESSAGE 20 | !MESSAGE "teststops - Win32 Release" (based on "Win32 (x86) Console Application") 21 | !MESSAGE "teststops - Win32 Debug" (based on "Win32 (x86) Console Application") 22 | !MESSAGE 23 | 24 | # Begin Project 25 | # PROP AllowPerConfigDependencies 0 26 | # PROP Scc_ProjName "" 27 | # PROP Scc_LocalPath "" 28 | CPP=cl.exe 29 | RSC=rc.exe 30 | 31 | !IF "$(CFG)" == "teststops - Win32 Release" 32 | 33 | # PROP BASE Use_MFC 0 34 | # PROP BASE Use_Debug_Libraries 0 35 | # PROP BASE Output_Dir "teststops___Win32_Release" 36 | # PROP BASE Intermediate_Dir "teststops___Win32_Release" 37 | # PROP BASE Target_Dir "" 38 | # PROP Use_MFC 0 39 | # PROP Use_Debug_Libraries 0 40 | # PROP Output_Dir "" 41 | # PROP Intermediate_Dir "Release" 42 | # PROP Ignore_Export_Lib 0 43 | # PROP Target_Dir "" 44 | # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 45 | # ADD CPP /nologo /MT /W3 /GX /O2 /I "../../" /I "../../include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_ASIO__" /D "__WINDOWS_DS__" /D "__WINDOWS_WASAPI__" /YX /FD /c 46 | # ADD BASE RSC /l 0x409 /d "NDEBUG" 47 | # ADD RSC /l 0x409 /d "NDEBUG" 48 | BSC32=bscmake.exe 49 | # ADD BASE BSC32 /nologo 50 | # ADD BSC32 /nologo 51 | LINK32=link.exe 52 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 53 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib /nologo /subsystem:console /machine:I386 54 | 55 | !ELSEIF "$(CFG)" == "teststops - Win32 Debug" 56 | 57 | # PROP BASE Use_MFC 0 58 | # PROP BASE Use_Debug_Libraries 1 59 | # PROP BASE Output_Dir "teststops___Win32_Debug" 60 | # PROP BASE Intermediate_Dir "teststops___Win32_Debug" 61 | # PROP BASE Target_Dir "" 62 | # PROP Use_MFC 0 63 | # PROP Use_Debug_Libraries 1 64 | # PROP Output_Dir "" 65 | # PROP Intermediate_Dir "Debug" 66 | # PROP Ignore_Export_Lib 0 67 | # PROP Target_Dir "" 68 | # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c 69 | # ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../../" /I "../../include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "__WINDOWS_ASIO__" /D "__WINDOWS_DS__" /D "__WINDOWS_WASAPI__" /YX /FD /GZ /c 70 | # ADD BASE RSC /l 0x409 /d "_DEBUG" 71 | # ADD RSC /l 0x409 /d "_DEBUG" 72 | BSC32=bscmake.exe 73 | # ADD BASE BSC32 /nologo 74 | # ADD BSC32 /nologo 75 | LINK32=link.exe 76 | # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept 77 | # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib dsound.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept 78 | 79 | !ENDIF 80 | 81 | # Begin Target 82 | 83 | # Name "teststops - Win32 Release" 84 | # Name "teststops - Win32 Debug" 85 | # Begin Group "Source Files" 86 | 87 | # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" 88 | # Begin Source File 89 | 90 | SOURCE=..\..\include\asio.cpp 91 | # End Source File 92 | # Begin Source File 93 | 94 | SOURCE=..\..\include\asiodrivers.cpp 95 | # End Source File 96 | # Begin Source File 97 | 98 | SOURCE=..\..\include\asiolist.cpp 99 | # End Source File 100 | # Begin Source File 101 | 102 | SOURCE=..\..\include\iasiothiscallresolver.cpp 103 | # End Source File 104 | # Begin Source File 105 | 106 | SOURCE=..\..\RtAudio.cpp 107 | # End Source File 108 | # Begin Source File 109 | 110 | SOURCE=..\teststops.cpp 111 | # End Source File 112 | # End Group 113 | # Begin Group "Header Files" 114 | 115 | # PROP Default_Filter "h;hpp;hxx;hm;inl" 116 | # Begin Source File 117 | 118 | SOURCE=..\..\include\asio.h 119 | # End Source File 120 | # Begin Source File 121 | 122 | SOURCE=..\..\include\asiodrivers.h 123 | # End Source File 124 | # Begin Source File 125 | 126 | SOURCE=..\..\include\asiodrvr.h 127 | # End Source File 128 | # Begin Source File 129 | 130 | SOURCE=..\..\include\asiolist.h 131 | # End Source File 132 | # Begin Source File 133 | 134 | SOURCE=..\..\include\asiosys.h 135 | # End Source File 136 | # Begin Source File 137 | 138 | SOURCE=..\..\include\ginclude.h 139 | # End Source File 140 | # Begin Source File 141 | 142 | SOURCE=..\..\include\iasiodrv.h 143 | # End Source File 144 | # Begin Source File 145 | 146 | SOURCE=..\..\include\iasiothiscallresolver.h 147 | # End Source File 148 | # Begin Source File 149 | 150 | SOURCE=..\..\RtAudio.h 151 | # End Source File 152 | # End Group 153 | # Begin Group "Resource Files" 154 | 155 | # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" 156 | # End Group 157 | # End Target 158 | # End Project 159 | -------------------------------------------------------------------------------- /tests/apinames.cpp: -------------------------------------------------------------------------------- 1 | /******************************************/ 2 | /* 3 | apinames.cpp 4 | by Jean Pierre Cimalando, 2018. 5 | 6 | This program tests parts of RtAudio related 7 | to API names, the conversion from name to API 8 | and vice-versa. 9 | */ 10 | /******************************************/ 11 | 12 | #include "RtAudio.h" 13 | #include 14 | #include 15 | #include 16 | 17 | int test_cpp() { 18 | std::vector apis; 19 | RtAudio::getCompiledApi( apis ); 20 | 21 | // ensure the known APIs return valid names 22 | std::cout << "API names by identifier (C++):\n"; 23 | for ( size_t i = 0; i < apis.size() ; ++i ) { 24 | const std::string name = RtAudio::getApiName(apis[i]); 25 | if (name.empty()) { 26 | std::cout << "Invalid name for API " << (int)apis[i] << "\n"; 27 | exit(1); 28 | } 29 | const std::string displayName = RtAudio::getApiDisplayName(apis[i]); 30 | if (displayName.empty()) { 31 | std::cout << "Invalid display name for API " << (int)apis[i] << "\n"; 32 | exit(1); 33 | } 34 | std::cout << "* " << (int)apis[i] << " '" << name << "': '" << displayName << "'\n"; 35 | } 36 | 37 | // ensure unknown APIs return the empty string 38 | { 39 | const std::string name = RtAudio::getApiName((RtAudio::Api)-1); 40 | if (!name.empty()) { 41 | std::cout << "Bad string for invalid API '" << name << "'\n"; 42 | exit(1); 43 | } 44 | const std::string displayName = RtAudio::getApiDisplayName((RtAudio::Api)-1); 45 | if (displayName!="Unknown") { 46 | std::cout << "Bad display string for invalid API '" << displayName << "'\n"; 47 | exit(1); 48 | } 49 | } 50 | 51 | // try getting API identifier by name 52 | std::cout << "API identifiers by name (C++):\n"; 53 | for ( size_t i = 0; i < apis.size() ; ++i ) { 54 | std::string name = RtAudio::getApiName(apis[i]); 55 | if ( RtAudio::getCompiledApiByName(name) != apis[i] ) { 56 | std::cout << "Bad identifier for API '" << name << "'\n"; 57 | exit( 1 ); 58 | } 59 | std::cout << "* '" << name << "': " << (int)apis[i] << "\n"; 60 | 61 | for ( size_t j = 0; j < name.size(); ++j ) 62 | name[j] = (j & 1) ? toupper(name[j]) : tolower(name[j]); 63 | RtAudio::Api api = RtAudio::getCompiledApiByName(name); 64 | if ( api != RtAudio::UNSPECIFIED ) { 65 | std::cout << "Identifier " << (int)api << " for invalid API '" << name << "'\n"; 66 | exit( 1 ); 67 | } 68 | } 69 | 70 | // try getting an API identifier by unknown name 71 | { 72 | RtAudio::Api api; 73 | api = RtAudio::getCompiledApiByName(""); 74 | if ( api != RtAudio::UNSPECIFIED ) { 75 | std::cout << "Bad identifier for unknown API name\n"; 76 | exit( 1 ); 77 | } 78 | } 79 | 80 | return 0; 81 | } 82 | 83 | #include "rtaudio_c.h" 84 | 85 | int test_c() { 86 | const rtaudio_api_t *apis = rtaudio_compiled_api(); 87 | 88 | // ensure the known APIs return valid names 89 | std::cout << "API names by identifier (C):\n"; 90 | for ( size_t i = 0; apis[i] != RTAUDIO_API_UNSPECIFIED; ++i) { 91 | const std::string name = rtaudio_api_name(apis[i]); 92 | if (name.empty()) { 93 | std::cout << "Invalid name for API " << (int)apis[i] << "\n"; 94 | exit(1); 95 | } 96 | const std::string displayName = rtaudio_api_display_name(apis[i]); 97 | if (displayName.empty()) { 98 | std::cout << "Invalid display name for API " << (int)apis[i] << "\n"; 99 | exit(1); 100 | } 101 | std::cout << "* " << (int)apis[i] << " '" << name << "': '" << displayName << "'\n"; 102 | } 103 | 104 | // ensure unknown APIs return the empty string 105 | { 106 | const char *s = rtaudio_api_name((rtaudio_api_t)-1); 107 | const std::string name(s?s:""); 108 | if (!name.empty()) { 109 | std::cout << "Bad string for invalid API '" << name << "'\n"; 110 | exit(1); 111 | } 112 | s = rtaudio_api_display_name((rtaudio_api_t)-1); 113 | const std::string displayName(s?s:""); 114 | if (displayName!="Unknown") { 115 | std::cout << "Bad display string for invalid API '" << displayName << "'\n"; 116 | exit(1); 117 | } 118 | } 119 | 120 | // try getting API identifier by name 121 | std::cout << "API identifiers by name (C):\n"; 122 | for ( size_t i = 0; apis[i] != RTAUDIO_API_UNSPECIFIED ; ++i ) { 123 | const char *s = rtaudio_api_name(apis[i]); 124 | std::string name(s?s:""); 125 | if ( rtaudio_compiled_api_by_name(name.c_str()) != apis[i] ) { 126 | std::cout << "Bad identifier for API '" << name << "'\n"; 127 | exit( 1 ); 128 | } 129 | std::cout << "* '" << name << "': " << (int)apis[i] << "\n"; 130 | 131 | for ( size_t j = 0; j < name.size(); ++j ) 132 | name[j] = (j & 1) ? toupper(name[j]) : tolower(name[j]); 133 | rtaudio_api_t api = rtaudio_compiled_api_by_name(name.c_str()); 134 | if ( api != RTAUDIO_API_UNSPECIFIED ) { 135 | std::cout << "Identifier " << (int)api << " for invalid API '" << name << "'\n"; 136 | exit( 1 ); 137 | } 138 | } 139 | 140 | // try getting an API identifier by unknown name 141 | { 142 | rtaudio_api_t api; 143 | api = rtaudio_compiled_api_by_name(""); 144 | if ( api != RTAUDIO_API_UNSPECIFIED ) { 145 | std::cout << "Bad identifier for unknown API name\n"; 146 | exit( 1 ); 147 | } 148 | } 149 | 150 | return 0; 151 | } 152 | 153 | int main() 154 | { 155 | test_cpp(); 156 | test_c(); 157 | } 158 | -------------------------------------------------------------------------------- /tests/audioprobe.cpp: -------------------------------------------------------------------------------- 1 | /******************************************/ 2 | /* 3 | audioprobe.cpp 4 | by Gary P. Scavone, 2001 5 | 6 | Probe audio system and prints device info. 7 | */ 8 | /******************************************/ 9 | 10 | #include "RtAudio.h" 11 | #include 12 | #include 13 | 14 | void usage( void ) { 15 | // Error function in case of incorrect command-line 16 | // argument specifications 17 | std::cout << "\nuseage: audioprobe \n"; 18 | std::cout << " where apiname = an optional api (ex., 'core', default = all compiled),\n"; 19 | std::cout << " and nRepeats = an optional number of times to repeat the device query (default = 0),\n"; 20 | std::cout << " which can be used to test device (dis)connections.\n\n"; 21 | exit( 0 ); 22 | } 23 | 24 | std::vector< RtAudio::Api > listApis() 25 | { 26 | std::vector< RtAudio::Api > apis; 27 | RtAudio :: getCompiledApi( apis ); 28 | 29 | std::cout << "\nCompiled APIs:\n"; 30 | for ( size_t i=0; i devices = audio.getDeviceIds(); 44 | std::cout << "\nFound " << devices.size() << " device(s) ...\n"; 45 | 46 | for (unsigned int i=0; i apis = listApis(); 95 | 96 | // minimal command-line checking 97 | if (argc > 3 ) usage(); 98 | unsigned int nRepeats = 0; 99 | if ( argc > 2 ) nRepeats = (unsigned int) atoi( argv[2] ); 100 | 101 | char input; 102 | for ( size_t api=0; api < apis.size(); api++ ) { 103 | if (argc < 2 || apis[api] == RtAudio::getCompiledApiByName(argv[1]) ) { 104 | RtAudio audio(apis[api]); 105 | for ( size_t n=0; n <= nRepeats; n++ ) { 106 | listDevices(audio); 107 | if ( n < nRepeats ) { 108 | std::cout << std::endl; 109 | std::cout << "\nWaiting ... press to repeat.\n"; 110 | std::cin.get(input); 111 | } 112 | } 113 | } 114 | } 115 | 116 | return 0; 117 | } 118 | -------------------------------------------------------------------------------- /tests/duplex.cpp: -------------------------------------------------------------------------------- 1 | /******************************************/ 2 | /* 3 | duplex.cpp 4 | by Gary P. Scavone, 2006-2019. 5 | 6 | This program opens a duplex stream and passes 7 | input directly through to the output. 8 | */ 9 | /******************************************/ 10 | 11 | #include "RtAudio.h" 12 | #include 13 | #include 14 | #include 15 | #include 16 | /* 17 | typedef int8_t MY_TYPE; 18 | #define FORMAT RTAUDIO_SINT8 19 | */ 20 | 21 | typedef int16_t MY_TYPE; 22 | #define FORMAT RTAUDIO_SINT16 23 | 24 | /* 25 | typedef S24 MY_TYPE; 26 | #define FORMAT RTAUDIO_SINT24 27 | 28 | typedef int32_t MY_TYPE; 29 | #define FORMAT RTAUDIO_SINT32 30 | 31 | typedef float MY_TYPE; 32 | #define FORMAT RTAUDIO_FLOAT32 33 | 34 | typedef double MY_TYPE; 35 | #define FORMAT RTAUDIO_FLOAT64 36 | */ 37 | 38 | void usage( void ) { 39 | // Error function in case of incorrect command-line 40 | // argument specifications 41 | std::cout << "\nuseage: duplex N fs \n"; 42 | std::cout << " where N = number of channels,\n"; 43 | std::cout << " fs = the sample rate,\n"; 44 | std::cout << " iDevice = optional input device index to use (default = 0),\n"; 45 | std::cout << " oDevice = optional output device index to use (default = 0),\n"; 46 | std::cout << " iChannelOffset = an optional input channel offset (default = 0),\n"; 47 | std::cout << " and oChannelOffset = optional output channel offset (default = 0).\n\n"; 48 | exit( 0 ); 49 | } 50 | 51 | unsigned int getDeviceIndex( std::vector deviceNames, bool isInput = false ) 52 | { 53 | unsigned int i; 54 | std::string keyHit; 55 | std::cout << '\n'; 56 | for ( i=0; i> i; 64 | } while ( i >= deviceNames.size() ); 65 | std::getline( std::cin, keyHit ); // used to clear out stdin 66 | return i; 67 | } 68 | 69 | double streamTimePrintIncrement = 1.0; // seconds 70 | double streamTimePrintTime = 1.0; // seconds 71 | 72 | int inout( void *outputBuffer, void *inputBuffer, unsigned int /*nBufferFrames*/, 73 | double streamTime, RtAudioStreamStatus status, void *data ) 74 | { 75 | // Since the number of input and output channels is equal, we can do 76 | // a simple buffer copy operation here. 77 | if ( status ) std::cout << "Stream over/underflow detected." << std::endl; 78 | 79 | if ( streamTime >= streamTimePrintTime ) { 80 | std::cout << "streamTime = " << streamTime << std::endl; 81 | streamTimePrintTime += streamTimePrintIncrement; 82 | } 83 | 84 | unsigned int *bytes = (unsigned int *) data; 85 | memcpy( outputBuffer, inputBuffer, *bytes ); 86 | return 0; 87 | } 88 | 89 | int main( int argc, char *argv[] ) 90 | { 91 | unsigned int channels, fs, bufferBytes, oDevice = 0, iDevice = 0, iOffset = 0, oOffset = 0; 92 | 93 | // Minimal command-line checking 94 | if (argc < 3 || argc > 7 ) usage(); 95 | 96 | RtAudio adac; 97 | std::vector deviceIds = adac.getDeviceIds(); 98 | if ( deviceIds.size() < 1 ) { 99 | std::cout << "\nNo audio devices found!\n"; 100 | exit( 1 ); 101 | } 102 | 103 | channels = (unsigned int) atoi(argv[1]); 104 | fs = (unsigned int) atoi(argv[2]); 105 | if ( argc > 3 ) 106 | iDevice = (unsigned int) atoi(argv[3]); 107 | if ( argc > 4 ) 108 | oDevice = (unsigned int) atoi(argv[4]); 109 | if ( argc > 5 ) 110 | iOffset = (unsigned int) atoi(argv[5]); 111 | if ( argc > 6 ) 112 | oOffset = (unsigned int) atoi(argv[6]); 113 | 114 | // Let RtAudio print messages to stderr. 115 | adac.showWarnings( true ); 116 | 117 | // Set the same number of channels for both input and output. 118 | unsigned int bufferFrames = 512; 119 | RtAudio::StreamParameters iParams, oParams; 120 | iParams.nChannels = channels; 121 | iParams.firstChannel = iOffset; 122 | oParams.nChannels = channels; 123 | oParams.firstChannel = oOffset; 124 | 125 | if ( iDevice == 0 ) 126 | iParams.deviceId = adac.getDefaultInputDevice(); 127 | else { 128 | if ( iDevice >= deviceIds.size() ) 129 | iDevice = getDeviceIndex( adac.getDeviceNames(), true ); 130 | iParams.deviceId = deviceIds[iDevice]; 131 | } 132 | if ( oDevice == 0 ) 133 | oParams.deviceId = adac.getDefaultOutputDevice(); 134 | else { 135 | if ( oDevice >= deviceIds.size() ) 136 | oDevice = getDeviceIndex( adac.getDeviceNames() ); 137 | oParams.deviceId = deviceIds[oDevice]; 138 | } 139 | 140 | RtAudio::StreamOptions options; 141 | //options.flags |= RTAUDIO_NONINTERLEAVED; 142 | 143 | bufferBytes = bufferFrames * channels * sizeof( MY_TYPE ); 144 | if ( adac.openStream( &oParams, &iParams, FORMAT, fs, &bufferFrames, &inout, (void *)&bufferBytes, &options ) ) { 145 | goto cleanup; 146 | } 147 | 148 | if ( adac.isStreamOpen() == false ) goto cleanup; 149 | 150 | // Test RtAudio functionality for reporting latency. 151 | std::cout << "\nStream latency = " << adac.getStreamLatency() << " frames" << std::endl; 152 | 153 | if ( adac.startStream() ) goto cleanup; 154 | 155 | char input; 156 | std::cout << "\nRunning ... press to quit (buffer frames = " << bufferFrames << ").\n"; 157 | std::cin.get(input); 158 | 159 | // Stop the stream. 160 | if ( adac.isStreamRunning() ) 161 | adac.stopStream(); 162 | 163 | cleanup: 164 | if ( adac.isStreamOpen() ) adac.closeStream(); 165 | 166 | return 0; 167 | } 168 | -------------------------------------------------------------------------------- /tests/meson.build: -------------------------------------------------------------------------------- 1 | apinames = executable('apinames', 'apinames.cpp', dependencies: rtaudio_dep) 2 | test('API names', apinames) 3 | 4 | audioprobe = executable('audioprobe', 'audioprobe.cpp', dependencies: rtaudio_dep) 5 | duplex = executable('duplex', 'duplex.cpp', dependencies: rtaudio_dep) 6 | playraw = executable('playraw', 'playraw.cpp', dependencies: rtaudio_dep) 7 | playsaw = executable('playsaw', 'playsaw.cpp', dependencies: rtaudio_dep) 8 | record = executable('record', 'record.cpp', dependencies: rtaudio_dep) 9 | testall = executable('testall', 'testall.cpp', dependencies: rtaudio_dep) 10 | teststops = executable('teststops', 'teststops.cpp', dependencies: rtaudio_dep) 11 | -------------------------------------------------------------------------------- /tests/playraw.cpp: -------------------------------------------------------------------------------- 1 | /******************************************/ 2 | /* 3 | playraw.cpp 4 | by Gary P. Scavone, 2007 5 | 6 | Play a specified raw file. It is necessary 7 | that the file be of the same data format as 8 | defined below. 9 | */ 10 | /******************************************/ 11 | 12 | #include "RtAudio.h" 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | /* 20 | typedef int8_t MY_TYPE; 21 | #define FORMAT RTAUDIO_SINT8 22 | #define SCALE 127.0 23 | */ 24 | 25 | typedef int16_t MY_TYPE; 26 | #define FORMAT RTAUDIO_SINT16 27 | #define SCALE 32767.0 28 | 29 | /* 30 | typedef S24 MY_TYPE; 31 | #define FORMAT RTAUDIO_SINT24 32 | #define SCALE 8388607.0 33 | 34 | typedef int32_t MY_TYPE; 35 | #define FORMAT RTAUDIO_SINT32 36 | #define SCALE 2147483647.0 37 | 38 | typedef float MY_TYPE; 39 | #define FORMAT RTAUDIO_FLOAT32 40 | #define SCALE 1.0; 41 | 42 | typedef double MY_TYPE; 43 | #define FORMAT RTAUDIO_FLOAT64 44 | #define SCALE 1.0; 45 | */ 46 | 47 | // Platform-dependent sleep routines. 48 | #if defined( WIN32 ) 49 | #include 50 | #define SLEEP( milliseconds ) Sleep( (DWORD) milliseconds ) 51 | #else // Unix variants 52 | #include 53 | #define SLEEP( milliseconds ) usleep( (unsigned long) (milliseconds * 1000.0) ) 54 | #endif 55 | 56 | void usage( void ) { 57 | // Error function in case of incorrect command-line 58 | // argument specifications 59 | std::cout << "\nuseage: playraw N fs file \n"; 60 | std::cout << " where N = number of channels,\n"; 61 | std::cout << " fs = the sample rate, \n"; 62 | std::cout << " file = the raw file to play,\n"; 63 | std::cout << " device = optional device index to use (default = 0),\n"; 64 | std::cout << " and channelOffset = an optional channel offset on the device (default = 0).\n\n"; 65 | exit( 0 ); 66 | } 67 | 68 | unsigned int getDeviceIndex( std::vector deviceNames ) 69 | { 70 | unsigned int i; 71 | std::string keyHit; 72 | std::cout << '\n'; 73 | for ( i=0; i> i; 78 | } while ( i >= deviceNames.size() ); 79 | std::getline( std::cin, keyHit ); // used to clear out stdin 80 | return i; 81 | } 82 | 83 | struct OutputData { 84 | FILE *fd; 85 | unsigned int channels; 86 | }; 87 | 88 | // Interleaved buffers 89 | int output( void *outputBuffer, void * /*inputBuffer*/, unsigned int nBufferFrames, 90 | double /*streamTime*/, RtAudioStreamStatus /*status*/, void *data ) 91 | { 92 | OutputData *oData = (OutputData*) data; 93 | 94 | // In general, it's not a good idea to do file input in the audio 95 | // callback function but I'm doing it here because I don't know the 96 | // length of the file we are reading. 97 | unsigned int count = fread( outputBuffer, oData->channels * sizeof( MY_TYPE ), nBufferFrames, oData->fd); 98 | if ( count < nBufferFrames ) { 99 | unsigned int bytes = (nBufferFrames - count) * oData->channels * sizeof( MY_TYPE ); 100 | unsigned int startByte = count * oData->channels * sizeof( MY_TYPE ); 101 | memset( (char *)(outputBuffer)+startByte, 0, bytes ); 102 | return 1; 103 | } 104 | 105 | return 0; 106 | } 107 | 108 | int main( int argc, char *argv[] ) 109 | { 110 | unsigned int channels, fs, bufferFrames, device = 0, offset = 0; 111 | char *file; 112 | 113 | // minimal command-line checking 114 | if ( argc < 4 || argc > 6 ) usage(); 115 | 116 | RtAudio dac; 117 | std::vector deviceIds = dac.getDeviceIds(); 118 | if ( deviceIds.size() < 1 ) { 119 | std::cout << "\nNo audio devices found!\n"; 120 | exit( 0 ); 121 | } 122 | 123 | channels = (unsigned int) atoi( argv[1]) ; 124 | fs = (unsigned int) atoi( argv[2] ); 125 | file = argv[3]; 126 | if ( argc > 4 ) 127 | device = (unsigned int) atoi( argv[4] ); 128 | if ( argc > 5 ) 129 | offset = (unsigned int) atoi( argv[5] ); 130 | 131 | OutputData data; 132 | data.fd = fopen( file, "rb" ); 133 | if ( !data.fd ) { 134 | std::cout << "Unable to find or open file!\n"; 135 | exit( 1 ); 136 | } 137 | 138 | // Set our stream parameters for output only. 139 | bufferFrames = 512; 140 | RtAudio::StreamParameters oParams; 141 | oParams.deviceId = device; 142 | oParams.nChannels = channels; 143 | oParams.firstChannel = offset; 144 | 145 | if ( device == 0 ) 146 | oParams.deviceId = dac.getDefaultOutputDevice(); 147 | else { 148 | if ( device >= deviceIds.size() ) 149 | device = getDeviceIndex( dac.getDeviceNames() ); 150 | oParams.deviceId = deviceIds[device]; 151 | } 152 | 153 | data.channels = channels; 154 | 155 | if ( dac.openStream( &oParams, NULL, FORMAT, fs, &bufferFrames, &output, (void *)&data ) ) 156 | goto cleanup; 157 | 158 | if ( dac.isStreamOpen() == false ) goto cleanup; 159 | 160 | if ( dac.startStream() ) goto cleanup; 161 | 162 | std::cout << "\nPlaying raw file " << file << " (buffer frames = " << bufferFrames << ")." << std::endl; 163 | while ( 1 ) { 164 | SLEEP( 100 ); // wake every 100 ms to check if we're done 165 | if ( dac.isStreamRunning() == false ) break; 166 | } 167 | 168 | cleanup: 169 | fclose( data.fd ); 170 | dac.closeStream(); 171 | 172 | return 0; 173 | } 174 | -------------------------------------------------------------------------------- /tests/playsaw.cpp: -------------------------------------------------------------------------------- 1 | /******************************************/ 2 | /* 3 | playsaw.cpp 4 | by Gary P. Scavone, 2006-2019. 5 | 6 | This program will output sawtooth waveforms 7 | of different frequencies on each channel. 8 | */ 9 | /******************************************/ 10 | 11 | #include "RtAudio.h" 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | /* 18 | typedef int8_t MY_TYPE; 19 | #define FORMAT RTAUDIO_SINT8 20 | #define SCALE 127.0 21 | */ 22 | 23 | typedef int16_t MY_TYPE; 24 | #define FORMAT RTAUDIO_SINT16 25 | #define SCALE 32767.0 26 | 27 | /* 28 | typedef S24 MY_TYPE; 29 | #define FORMAT RTAUDIO_SINT24 30 | #define SCALE 8388607.0 31 | 32 | typedef int32_t MY_TYPE; 33 | #define FORMAT RTAUDIO_SINT32 34 | #define SCALE 2147483647.0 35 | 36 | typedef float MY_TYPE; 37 | #define FORMAT RTAUDIO_FLOAT32 38 | #define SCALE 1.0 39 | 40 | typedef double MY_TYPE; 41 | #define FORMAT RTAUDIO_FLOAT64 42 | #define SCALE 1.0 43 | */ 44 | 45 | // Platform-dependent sleep routines. 46 | #if defined( WIN32 ) 47 | #include 48 | #define SLEEP( milliseconds ) Sleep( (DWORD) milliseconds ) 49 | #else // Unix variants 50 | #include 51 | #define SLEEP( milliseconds ) usleep( (unsigned long) (milliseconds * 1000.0) ) 52 | #endif 53 | 54 | // Interrupt handler function 55 | bool done; 56 | static void finish( int /*ignore*/ ){ done = true; } 57 | 58 | #define BASE_RATE 0.005 59 | #define TIME 1.0 60 | 61 | void usage( void ) { 62 | // Error function in case of incorrect command-line 63 | // argument specifications 64 | std::cout << "\nuseage: playsaw N fs