mirror of
https://github.com/thestk/stk
synced 2026-01-13 21:11:53 +00:00
Version 4.3.1
This commit is contained in:
committed by
Stephen Sinclair
parent
27d9b79dc7
commit
d199342e86
122
src/RtAudio.cpp
122
src/RtAudio.cpp
@@ -38,7 +38,7 @@
|
||||
*/
|
||||
/************************************************************************/
|
||||
|
||||
// RtAudio: Version 4.0
|
||||
// RtAudio: Version 4.0.3
|
||||
|
||||
#include "RtAudio.h"
|
||||
#include <iostream>
|
||||
@@ -539,7 +539,7 @@ RtAudio::DeviceInfo RtApiCore :: getDeviceInfo( unsigned int device )
|
||||
error( RtError::WARNING );
|
||||
return info;
|
||||
}
|
||||
info.name.append( (const char *)name, strlen(name) + 1 );
|
||||
info.name.append( (const char *)name, strlen(name) );
|
||||
info.name.append( ": " );
|
||||
|
||||
dataSize = 256;
|
||||
@@ -552,7 +552,7 @@ RtAudio::DeviceInfo RtApiCore :: getDeviceInfo( unsigned int device )
|
||||
error( RtError::WARNING );
|
||||
return info;
|
||||
}
|
||||
info.name.append( (const char *)name, strlen(name) + 1 );
|
||||
info.name.append( (const char *)name, strlen(name) );
|
||||
|
||||
// Get the output stream "configuration".
|
||||
AudioBufferList *bufferList = nil;
|
||||
@@ -2291,10 +2291,10 @@ bool RtApiJack :: callbackEvent( unsigned long nframes )
|
||||
// on information found in
|
||||
// http://www.cs.wustl.edu/~schmidt/win32-cv-1.html.
|
||||
|
||||
#include "asio/asiosys.h"
|
||||
#include "asio/asio.h"
|
||||
#include "asio/iasiothiscallresolver.h"
|
||||
#include "asio/asiodrivers.h"
|
||||
#include "asiosys.h"
|
||||
#include "asio.h"
|
||||
#include "iasiothiscallresolver.h"
|
||||
#include "asiodrivers.h"
|
||||
#include <cmath>
|
||||
|
||||
AsioDrivers drivers;
|
||||
@@ -2366,11 +2366,14 @@ RtAudio::DeviceInfo RtApiAsio :: getDeviceInfo( unsigned int device )
|
||||
error( RtError::INVALID_USE );
|
||||
}
|
||||
|
||||
// Don't probe if a stream is already open.
|
||||
// If a stream is already open, we cannot probe other devices. Thus, use the saved results.
|
||||
if ( stream_.state != STREAM_CLOSED ) {
|
||||
errorText_ = "RtApiAsio::getDeviceInfo: unable to probe driver while a stream is open.";
|
||||
error( RtError::WARNING );
|
||||
return info;
|
||||
if ( device >= devices_.size() ) {
|
||||
errorText_ = "RtApiAsio::getDeviceInfo: device ID was not present before stream was opened.";
|
||||
error( RtError::WARNING );
|
||||
return info;
|
||||
}
|
||||
return devices_[ device ];
|
||||
}
|
||||
|
||||
char driverName[32];
|
||||
@@ -2463,6 +2466,16 @@ void bufferSwitch( long index, ASIOBool processNow )
|
||||
object->callbackEvent( index );
|
||||
}
|
||||
|
||||
void RtApiAsio :: saveDeviceInfo( void )
|
||||
{
|
||||
devices_.clear();
|
||||
|
||||
unsigned int nDevices = getDeviceCount();
|
||||
devices_.resize( nDevices );
|
||||
for ( unsigned int i=0; i<nDevices; i++ )
|
||||
devices_[i] = getDeviceInfo( i );
|
||||
}
|
||||
|
||||
bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
|
||||
unsigned int firstChannel, unsigned int sampleRate,
|
||||
RtAudioFormat format, unsigned int *bufferSize,
|
||||
@@ -2482,6 +2495,12 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// The getDeviceInfo() function will not work when a stream is open
|
||||
// because ASIO does not allow multiple devices to run at the same
|
||||
// time. Thus, we'll probe the system before opening a stream and
|
||||
// save the results for use by getDeviceInfo().
|
||||
this->saveDeviceInfo();
|
||||
|
||||
// Only load the driver once for duplex stream.
|
||||
if ( mode != INPUT || stream_.mode != OUTPUT ) {
|
||||
if ( !drivers.loadDriver( driverName ) ) {
|
||||
@@ -2528,15 +2547,27 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// Set the sample rate.
|
||||
result = ASIOSetSampleRate( (ASIOSampleRate) sampleRate );
|
||||
// Get the current sample rate
|
||||
ASIOSampleRate currentRate;
|
||||
result = ASIOGetSampleRate( ¤tRate );
|
||||
if ( result != ASE_OK ) {
|
||||
drivers.removeCurrentDriver();
|
||||
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error setting sample rate (" << sampleRate << ").";
|
||||
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error getting sample rate.";
|
||||
errorText_ = errorStream_.str();
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
// Set the sample rate only if necessary
|
||||
if ( currentRate != sampleRate ) {
|
||||
result = ASIOSetSampleRate( (ASIOSampleRate) sampleRate );
|
||||
if ( result != ASE_OK ) {
|
||||
drivers.removeCurrentDriver();
|
||||
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error setting sample rate (" << sampleRate << ").";
|
||||
errorText_ = errorStream_.str();
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
// Determine the driver data type.
|
||||
ASIOChannelInfo channelInfo;
|
||||
channelInfo.channel = 0;
|
||||
@@ -2696,7 +2727,8 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
|
||||
stream_.doConvertBuffer[mode] = true;
|
||||
|
||||
// Allocate necessary internal buffers
|
||||
unsigned long bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat );
|
||||
unsigned long bufferBytes;
|
||||
bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat );
|
||||
stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 );
|
||||
if ( stream_.userBuffer[mode] == NULL ) {
|
||||
errorText_ = "RtApiAsio::probeDeviceOpen: error allocating user buffer memory.";
|
||||
@@ -2958,8 +2990,8 @@ bool RtApiAsio :: callbackEvent( long bufferIndex )
|
||||
handle->internalDrain = true;
|
||||
}
|
||||
|
||||
unsigned int bufferBytes, i, j;
|
||||
unsigned int nChannels = stream_.nDeviceChannels[0] + stream_.nDeviceChannels[1];
|
||||
unsigned int nChannels, bufferBytes, i, j;
|
||||
nChannels = stream_.nDeviceChannels[0] + stream_.nDeviceChannels[1];
|
||||
if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
|
||||
|
||||
bufferBytes = stream_.bufferSize * formatBytes( stream_.deviceFormat[0] );
|
||||
@@ -3187,6 +3219,14 @@ static const char* getAsioErrorString( ASIOError result )
|
||||
#include <dsound.h>
|
||||
#include <assert.h>
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
// missing from latest mingw winapi
|
||||
#define WAVE_FORMAT_96M08 0x00010000 /* 96 kHz, Mono, 8-bit */
|
||||
#define WAVE_FORMAT_96S08 0x00020000 /* 96 kHz, Stereo, 8-bit */
|
||||
#define WAVE_FORMAT_96M16 0x00040000 /* 96 kHz, Mono, 16-bit */
|
||||
#define WAVE_FORMAT_96S16 0x00080000 /* 96 kHz, Stereo, 16-bit */
|
||||
#endif
|
||||
|
||||
#define MINIMUM_DEVICE_BUFFER_SIZE 32768
|
||||
|
||||
#ifdef _MSC_VER // if Microsoft Visual C++
|
||||
@@ -3223,7 +3263,7 @@ struct DsHandle {
|
||||
HANDLE condition;
|
||||
|
||||
DsHandle()
|
||||
:drainCounter(0), internalDrain(false) { id[0] = 0, id[1] = 0; xrun[0] = false; xrun[1] = false; bufferPointer[0] = 0; bufferPointer[1] = 0; }
|
||||
:drainCounter(0), internalDrain(false) { id[0] = 0; id[1] = 0; buffer[0] = 0; buffer[1] = 0; xrun[0] = false; xrun[1] = false; bufferPointer[0] = 0; bufferPointer[1] = 0; }
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -3247,7 +3287,7 @@ RtApiDs::RtDsStatistics RtApiDs::getDsStatistics()
|
||||
|
||||
// Declarations for utility functions, callbacks, and structures
|
||||
// specific to the DirectSound implementation.
|
||||
static bool CALLBACK deviceCountCallback( LPGUID lpguid,
|
||||
static BOOL CALLBACK deviceQueryCallback( LPGUID lpguid,
|
||||
LPCTSTR description,
|
||||
LPCTSTR module,
|
||||
LPVOID lpContext );
|
||||
@@ -3288,7 +3328,7 @@ unsigned int RtApiDs :: getDefaultInputDevice( void )
|
||||
{
|
||||
// Count output devices.
|
||||
EnumInfo info;
|
||||
HRESULT result = DirectSoundEnumerate( (LPDSENUMCALLBACK) deviceCountCallback, &info );
|
||||
HRESULT result = DirectSoundEnumerate( (LPDSENUMCALLBACK) deviceQueryCallback, &info );
|
||||
if ( FAILED( result ) ) {
|
||||
errorStream_ << "RtApiDs::getDefaultOutputDevice: error (" << getErrorString( result ) << ") counting output devices!";
|
||||
errorText_ = errorStream_.str();
|
||||
@@ -3299,7 +3339,7 @@ unsigned int RtApiDs :: getDefaultInputDevice( void )
|
||||
// Now enumerate input devices until we find the id = NULL.
|
||||
info.isInput = true;
|
||||
info.getDefault = true;
|
||||
result = DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK) deviceCountCallback, &info );
|
||||
result = DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK) deviceQueryCallback, &info );
|
||||
if ( FAILED( result ) ) {
|
||||
errorStream_ << "RtApiDs::getDefaultInputDevice: error (" << getErrorString( result ) << ") enumerating input devices!";
|
||||
errorText_ = errorStream_.str();
|
||||
@@ -3316,7 +3356,7 @@ unsigned int RtApiDs :: getDefaultOutputDevice( void )
|
||||
// Enumerate output devices until we find the id = NULL.
|
||||
EnumInfo info;
|
||||
info.getDefault = true;
|
||||
HRESULT result = DirectSoundEnumerate( (LPDSENUMCALLBACK) deviceCountCallback, &info );
|
||||
HRESULT result = DirectSoundEnumerate( (LPDSENUMCALLBACK) deviceQueryCallback, &info );
|
||||
if ( FAILED( result ) ) {
|
||||
errorStream_ << "RtApiDs::getDefaultOutputDevice: error (" << getErrorString( result ) << ") enumerating output devices!";
|
||||
errorText_ = errorStream_.str();
|
||||
@@ -3332,7 +3372,7 @@ unsigned int RtApiDs :: getDeviceCount( void )
|
||||
{
|
||||
// Count DirectSound devices.
|
||||
EnumInfo info;
|
||||
HRESULT result = DirectSoundEnumerate( (LPDSENUMCALLBACK) deviceCountCallback, &info );
|
||||
HRESULT result = DirectSoundEnumerate( (LPDSENUMCALLBACK) deviceQueryCallback, &info );
|
||||
if ( FAILED( result ) ) {
|
||||
errorStream_ << "RtApiDs::getDeviceCount: error (" << getErrorString( result ) << ") enumerating output devices!";
|
||||
errorText_ = errorStream_.str();
|
||||
@@ -3341,7 +3381,7 @@ unsigned int RtApiDs :: getDeviceCount( void )
|
||||
|
||||
// Count DirectSoundCapture devices.
|
||||
info.isInput = true;
|
||||
result = DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK) deviceCountCallback, &info );
|
||||
result = DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK) deviceQueryCallback, &info );
|
||||
if ( FAILED( result ) ) {
|
||||
errorStream_ << "RtApiDs::getDeviceCount: error (" << getErrorString( result ) << ") enumerating input devices!";
|
||||
errorText_ = errorStream_.str();
|
||||
@@ -3366,7 +3406,7 @@ RtAudio::DeviceInfo RtApiDs :: getDeviceInfo( unsigned int device )
|
||||
EnumInfo dsinfo;
|
||||
dsinfo.findIndex = true;
|
||||
dsinfo.index = device;
|
||||
HRESULT result = DirectSoundEnumerate( (LPDSENUMCALLBACK) deviceCountCallback, &dsinfo );
|
||||
HRESULT result = DirectSoundEnumerate( (LPDSENUMCALLBACK) deviceQueryCallback, &dsinfo );
|
||||
if ( FAILED( result ) ) {
|
||||
errorStream_ << "RtApiDs::getDeviceInfo: error (" << getErrorString( result ) << ") enumerating output devices!";
|
||||
errorText_ = errorStream_.str();
|
||||
@@ -3424,7 +3464,7 @@ RtAudio::DeviceInfo RtApiDs :: getDeviceInfo( unsigned int device )
|
||||
probeInput:
|
||||
|
||||
dsinfo.isInput = true;
|
||||
result = DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK) deviceCountCallback, &dsinfo );
|
||||
result = DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK) deviceQueryCallback, &dsinfo );
|
||||
if ( FAILED( result ) ) {
|
||||
errorStream_ << "RtApiDs::getDeviceInfo: error (" << getErrorString( result ) << ") enumerating input devices!";
|
||||
errorText_ = errorStream_.str();
|
||||
@@ -3534,7 +3574,7 @@ bool RtApiDs :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned
|
||||
EnumInfo dsinfo;
|
||||
dsinfo.findIndex = true;
|
||||
dsinfo.index = device;
|
||||
HRESULT result = DirectSoundEnumerate( (LPDSENUMCALLBACK) deviceCountCallback, &dsinfo );
|
||||
HRESULT result = DirectSoundEnumerate( (LPDSENUMCALLBACK) deviceQueryCallback, &dsinfo );
|
||||
if ( FAILED( result ) ) {
|
||||
errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") enumerating output devices!";
|
||||
errorText_ = errorStream_.str();
|
||||
@@ -3550,7 +3590,7 @@ bool RtApiDs :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned
|
||||
}
|
||||
else { // mode == INPUT
|
||||
dsinfo.isInput = true;
|
||||
HRESULT result = DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK) deviceCountCallback, &dsinfo );
|
||||
HRESULT result = DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK) deviceQueryCallback, &dsinfo );
|
||||
if ( FAILED( result ) ) {
|
||||
errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") enumerating input devices!";
|
||||
errorText_ = errorStream_.str();
|
||||
@@ -3858,6 +3898,7 @@ bool RtApiDs :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned
|
||||
}
|
||||
|
||||
// Set various stream parameters
|
||||
DsHandle *handle = 0;
|
||||
stream_.nDeviceChannels[mode] = channels + firstChannel;
|
||||
stream_.nUserChannels[mode] = channels;
|
||||
stream_.bufferSize = *bufferSize;
|
||||
@@ -3907,7 +3948,6 @@ bool RtApiDs :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned
|
||||
}
|
||||
|
||||
// Allocate our DsHandle structures for the stream.
|
||||
DsHandle *handle;
|
||||
if ( stream_.apiHandle == 0 ) {
|
||||
try {
|
||||
handle = new DsHandle;
|
||||
@@ -4078,7 +4118,7 @@ void RtApiDs :: startStream()
|
||||
duplexPrerollBytes = (int) ( 0.5 * stream_.sampleRate * formatBytes( stream_.deviceFormat[1] ) * stream_.nDeviceChannels[1] );
|
||||
}
|
||||
|
||||
HRESULT result;
|
||||
HRESULT result = 0;
|
||||
if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
|
||||
//statistics.outputFrameSize = formatBytes( stream_.deviceFormat[0] ) * stream_.nDeviceChannels[0];
|
||||
|
||||
@@ -4124,7 +4164,7 @@ void RtApiDs :: stopStream()
|
||||
|
||||
MUTEX_LOCK( &stream_.mutex );
|
||||
|
||||
HRESULT result;
|
||||
HRESULT result = 0;
|
||||
LPVOID audioPtr;
|
||||
DWORD dataLen;
|
||||
DsHandle *handle = (DsHandle *) stream_.apiHandle;
|
||||
@@ -4665,7 +4705,7 @@ std::string convertTChar( LPCTSTR name )
|
||||
return s;
|
||||
}
|
||||
|
||||
static bool CALLBACK deviceCountCallback( LPGUID lpguid,
|
||||
static BOOL CALLBACK deviceQueryCallback( LPGUID lpguid,
|
||||
LPCTSTR description,
|
||||
LPCTSTR module,
|
||||
LPVOID lpContext )
|
||||
@@ -4678,7 +4718,7 @@ static bool CALLBACK deviceCountCallback( LPGUID lpguid,
|
||||
LPDIRECTSOUNDCAPTURE object;
|
||||
|
||||
hr = DirectSoundCaptureCreate( lpguid, &object, NULL );
|
||||
if ( hr != DS_OK ) return true;
|
||||
if ( hr != DS_OK ) return TRUE;
|
||||
|
||||
caps.dwSize = sizeof(caps);
|
||||
hr = object->GetCaps( &caps );
|
||||
@@ -4692,7 +4732,7 @@ static bool CALLBACK deviceCountCallback( LPGUID lpguid,
|
||||
DSCAPS caps;
|
||||
LPDIRECTSOUND object;
|
||||
hr = DirectSoundCreate( lpguid, &object, NULL );
|
||||
if ( hr != DS_OK ) return true;
|
||||
if ( hr != DS_OK ) return TRUE;
|
||||
|
||||
caps.dwSize = sizeof(caps);
|
||||
hr = object->GetCaps( &caps );
|
||||
@@ -4703,20 +4743,20 @@ static bool CALLBACK deviceCountCallback( LPGUID lpguid,
|
||||
object->Release();
|
||||
}
|
||||
|
||||
if ( info->getDefault && lpguid == NULL ) return false;
|
||||
if ( info->getDefault && lpguid == NULL ) return FALSE;
|
||||
|
||||
if ( info->findIndex && info->counter > info->index ) {
|
||||
info->id = lpguid;
|
||||
info->name = convertTChar( description );
|
||||
return false;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return true;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static char* getErrorString( int code )
|
||||
{
|
||||
switch (code) {
|
||||
switch ( code ) {
|
||||
|
||||
case DSERR_ALLOCATED:
|
||||
return "Already allocated";
|
||||
@@ -5906,7 +5946,9 @@ extern "C" void *alsaCallbackHandler( void *ptr )
|
||||
#ifdef SCHED_RR
|
||||
// Set a higher scheduler priority (P.J. Leonard)
|
||||
struct sched_param param;
|
||||
param.sched_priority = 39; // Is this the best number?
|
||||
int min = sched_get_priority_min( SCHED_RR );
|
||||
int max = sched_get_priority_max( SCHED_RR );
|
||||
param.sched_priority = min + ( max - min ) / 2; // Is this the best number?
|
||||
sched_setscheduler( 0, SCHED_RR, ¶m );
|
||||
#endif
|
||||
|
||||
@@ -5928,7 +5970,7 @@ extern "C" void *alsaCallbackHandler( void *ptr )
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include "oss/soundcard.h"
|
||||
#include "soundcard.h"
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user