diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/SCsub | 185 | ||||
| -rw-r--r-- | drivers/chibi/cp_player_data_control.cpp | 4 | ||||
| -rw-r--r-- | drivers/convex_decomp/b2Polygon.cpp | 1 | ||||
| -rw-r--r-- | drivers/gles2/shader_compiler_gles2.cpp | 61 | ||||
| -rw-r--r-- | drivers/gles2/shader_compiler_gles2.h | 7 | ||||
| -rw-r--r-- | drivers/mpc/mpc_reader.c | 1 | ||||
| -rw-r--r-- | drivers/pvr/ColorRgba.h | 12 | ||||
| -rw-r--r-- | drivers/rtaudio/RtAudio.cpp | 358 | ||||
| -rw-r--r-- | drivers/rtaudio/RtAudio.h | 3 | ||||
| -rw-r--r-- | drivers/theoraplayer/video_stream_theoraplayer.cpp | 2 | ||||
| -rw-r--r-- | drivers/vorbis/psy.c | 2 | ||||
| -rw-r--r-- | drivers/windows/dir_access_windows.cpp | 37 |
12 files changed, 417 insertions, 256 deletions
diff --git a/drivers/SCsub b/drivers/SCsub index a1a2191cb..6ab097362 100644 --- a/drivers/SCsub +++ b/drivers/SCsub @@ -1,91 +1,94 @@ -Import('env')
-
-env.drivers_sources=[]
-#env.add_source_files(env.drivers_sources,"*.cpp")
-env.Append(CPPPATH=["vorbis"])
-Export('env')
-
-SConscript('unix/SCsub');
-SConscript('alsa/SCsub');
-SConscript('pulseaudio/SCsub');
-SConscript('windows/SCsub');
-SConscript('gles2/SCsub');
-SConscript('gl_context/SCsub');
-SConscript('openssl/SCsub');
-
-if (env["png"]=="yes"):
- SConscript("png/SCsub");
-if (env["jpg"]=="yes"):
- SConscript("jpg/SCsub");
-if (env["webp"]=="yes"):
- SConscript("webp/SCsub");
-SConscript("dds/SCsub");
-SConscript("pvr/SCsub");
-SConscript("etc1/SCsub")
-if (env["builtin_zlib"]=="yes"):
- SConscript("builtin_zlib/SCsub");
-if (env["openssl"]=="builtin"):
- SConscript("builtin_openssl2/SCsub");
-
-SConscript("rtaudio/SCsub");
-SConscript("nedmalloc/SCsub");
-SConscript("trex/SCsub");
-SConscript("chibi/SCsub");
-if (env["vorbis"]=="yes" or env["speex"]=="yes" or env["theora"]=="yes"):
- SConscript("ogg/SCsub");
-if (env["vorbis"]=="yes"):
- SConscript("vorbis/SCsub");
-if (env["tools"]=="yes"):
- SConscript("convex_decomp/SCsub");
-
-if env["theora"]=="yes":
- SConscript("theoraplayer/SCsub")
-if (env["theora"]=="yes"):
- SConscript("theora/SCsub");
-if (env['speex']=='yes'):
- SConscript("speex/SCsub");
-if (env['musepack']=='yes'):
- SConscript("mpc/SCsub");
-if (env["squish"]=="yes" and env["tools"]=="yes"):
- SConscript("squish/SCsub");
-
-num = 0
-cur_base = ""
-total = len(env.drivers_sources)
-max_src = 64
-list = []
-lib_list = []
-
-import string
-
-for f in env.drivers_sources:
- fname = ""
- if type(f) == type(""):
- fname = env.File(f).path
- else:
- fname = env.File(f)[0].path
- #base = string.join(fname.split("/")[:-1], "/")
- fname = fname.replace("\\", "/")
- base = string.join(fname.split("/")[:2], "/")
- if base != cur_base and len(list) > max_src:
- lib = env.Library("drivers"+str(num), list)
- lib_list.append(lib)
- list = []
- num = num+1
- cur_base = base
- list.append(f)
-
-if len(list) > 0:
- lib = env.Library("drivers"+str(num), list)
- lib_list.append(lib)
-
-
-drivers_base=[]
-env.add_source_files(drivers_base,"*.cpp")
-lib_list.insert(0, env.Library("drivers", drivers_base))
-
-env.Prepend(LIBS=lib_list)
-
-#lib = env.Library("drivers",env.drivers_sources)
-#env.Prepend(LIBS=[lib])
-
+Import('env') + +env.drivers_sources=[] +#env.add_source_files(env.drivers_sources,"*.cpp") +env.Append(CPPPATH=["vorbis"]) +Export('env') + +SConscript('unix/SCsub'); +SConscript('alsa/SCsub'); +SConscript('pulseaudio/SCsub'); +SConscript('windows/SCsub'); +SConscript('gles2/SCsub'); +SConscript('gl_context/SCsub'); +SConscript('openssl/SCsub'); + +if (env["png"]=="yes"): + SConscript("png/SCsub"); +if (env["jpg"]=="yes"): + SConscript("jpg/SCsub"); +if (env["webp"]=="yes"): + SConscript("webp/SCsub"); +SConscript("dds/SCsub"); +SConscript("pvr/SCsub"); +SConscript("etc1/SCsub") +if (env["builtin_zlib"]=="yes"): + SConscript("builtin_zlib/SCsub"); +if (env["openssl"]=="builtin"): + SConscript("builtin_openssl2/SCsub"); + +SConscript("rtaudio/SCsub"); +SConscript("nedmalloc/SCsub"); +SConscript("trex/SCsub"); +SConscript("chibi/SCsub"); +if (env["vorbis"]=="yes" or env["speex"]=="yes" or env["theora"]=="yes"): + SConscript("ogg/SCsub"); +if (env["vorbis"]=="yes"): + SConscript("vorbis/SCsub"); +if (env["tools"]=="yes"): + SConscript("convex_decomp/SCsub"); + +if env["theora"]=="yes": + SConscript("theoraplayer/SCsub") +if (env["theora"]=="yes"): + SConscript("theora/SCsub"); +if (env['speex']=='yes'): + SConscript("speex/SCsub"); +if (env['musepack']=='yes'): + SConscript("mpc/SCsub"); +if (env["squish"]=="yes" and env["tools"]=="yes"): + SConscript("squish/SCsub"); + +num = 0 +cur_base = "" +total = len(env.drivers_sources) +max_src = 64 +list = [] +lib_list = [] + +import string + +if env['vsproj']=="yes": + env.AddToVSProject(env.drivers_sources) + +for f in env.drivers_sources: + fname = "" + if type(f) == type(""): + fname = env.File(f).path + else: + fname = env.File(f)[0].path + #base = string.join(fname.split("/")[:-1], "/") + fname = fname.replace("\\", "/") + base = string.join(fname.split("/")[:2], "/") + if base != cur_base and len(list) > max_src: + lib = env.Library("drivers"+str(num), list) + lib_list.append(lib) + list = [] + num = num+1 + cur_base = base + list.append(f) + +if len(list) > 0: + lib = env.Library("drivers"+str(num), list) + lib_list.append(lib) + + +drivers_base=[] +env.add_source_files(drivers_base,"*.cpp") +lib_list.insert(0, env.Library("drivers", drivers_base)) + +env.Prepend(LIBS=lib_list) + +#lib = env.Library("drivers",env.drivers_sources) +#env.Prepend(LIBS=[lib]) + diff --git a/drivers/chibi/cp_player_data_control.cpp b/drivers/chibi/cp_player_data_control.cpp index 4d30c1a70..d5ca648ff 100644 --- a/drivers/chibi/cp_player_data_control.cpp +++ b/drivers/chibi/cp_player_data_control.cpp @@ -233,7 +233,7 @@ int CPPlayer::get_channel_voice(int p_channel) { const char* CPPlayer::get_voice_sample_name(int p_voice) { - const char *name; + const char *name = NULL; @@ -302,7 +302,7 @@ const char * CPPlayer::get_voice_instrument_name(int p_voice) { - const char *name; + const char *name = NULL; diff --git a/drivers/convex_decomp/b2Polygon.cpp b/drivers/convex_decomp/b2Polygon.cpp index 49a3e74c2..668313967 100644 --- a/drivers/convex_decomp/b2Polygon.cpp +++ b/drivers/convex_decomp/b2Polygon.cpp @@ -970,6 +970,7 @@ int32 DecomposeConvex(b2Polygon* p, b2Polygon* results, int32 maxPolys) { } if (nTri < 1) { //Still no luck? Oh well... + delete[] triangulated; return -1; } int32 nPolys = PolygonizeTriangles(triangulated, nTri, results, maxPolys); diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp index 10da30acc..157f2e398 100644 --- a/drivers/gles2/shader_compiler_gles2.cpp +++ b/drivers/gles2/shader_compiler_gles2.cpp @@ -431,6 +431,42 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a // code="get_texpos(gl_ProjectionMatrixInverse * texture2D( depth_texture, clamp(("+dump_node_code(onode->arguments[1],p_level)+").xy,vec2(0.0),vec2(1.0))*gl_LightSource[5].specular.zw+gl_LightSource[5].specular.xy)"; //code="(texture2D( screen_texture, ("+dump_node_code(onode->arguments[1],p_level)+").xy).rgb"; break; + } else if (custom_h && callfunc=="cosh_custom") { + + if (!cosh_used) { + global_code= "float cosh_custom(float val)\n"\ + "{\n"\ + " float tmp = exp(val);\n"\ + " float cosH = (tmp + 1.0 / tmp) / 2.0;\n"\ + " return cosH;\n"\ + "}\n"+global_code; + cosh_used=true; + } + code="cosh_custom("+dump_node_code(onode->arguments[1],p_level)+""; + } else if (custom_h && callfunc=="sinh_custom") { + + if (!sinh_used) { + global_code= "float sinh_custom(float val)\n"\ + "{\n"\ + " float tmp = exp(val);\n"\ + " float sinH = (tmp - 1.0 / tmp) / 2.0;\n"\ + " return sinH;\n"\ + "}\n"+global_code; + sinh_used=true; + } + code="sinh_custom("+dump_node_code(onode->arguments[1],p_level)+""; + } else if (custom_h && callfunc=="tanh_custom") { + + if (!tanh_used) { + global_code= "float tanh_custom(float val)\n"\ + "{\n"\ + " float tmp = exp(val);\n"\ + " float tanH = (tmp - 1.0 / tmp) / (tmp + 1.0 / tmp);\n"\ + " return tanH;\n"\ + "}\n"+global_code; + tanh_used=true; + } + code="tanh_custom("+dump_node_code(onode->arguments[1],p_level)+""; } else { @@ -634,6 +670,9 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT r_flags.use_var2_interp=false; r_flags.uses_normalmap=false; r_flags.uses_normal=false; + sinh_used=false; + tanh_used=false; + cosh_used=false; String error; int errline,errcol; @@ -662,12 +701,18 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT r_flags.uses_shadow_color=uses_shadow_color; r_code_line=code; r_globals_line=global_code; - return OK; } ShaderCompilerGLES2::ShaderCompilerGLES2() { +#ifdef GLEW_ENABLED + //use custom functions because they are not supported in GLSL120 + custom_h=true; +#else + custom_h=false; +#endif + replace_table["bool"]= "bool"; replace_table["float" ]= "float"; replace_table["vec2" ]= "vec2"; @@ -686,9 +731,17 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() { replace_table["acos" ]= "acos"; replace_table["atan" ]= "atan"; replace_table["atan2"]= "atan"; - replace_table["sinh" ]= "sinh"; - replace_table["cosh" ]= "cosh"; - replace_table["tanh" ]= "tanh"; + + if (custom_h) { + replace_table["sinh" ]= "sinh_custom"; + replace_table["cosh" ]= "cosh_custom"; + replace_table["tanh" ]= "tanh_custom"; + } else { + replace_table["sinh" ]= "sinh"; + replace_table["cosh" ]= "cosh"; + replace_table["tanh" ]= "tanh"; + } + replace_table["pow" ]= "pow"; replace_table["exp" ]= "exp"; replace_table["log" ]= "log"; diff --git a/drivers/gles2/shader_compiler_gles2.h b/drivers/gles2/shader_compiler_gles2.h index 6dfc21399..43902a753 100644 --- a/drivers/gles2/shader_compiler_gles2.h +++ b/drivers/gles2/shader_compiler_gles2.h @@ -56,6 +56,13 @@ private: bool uses_worldvec; bool vertex_code_writes_vertex; bool uses_shadow_color; + + bool sinh_used; + bool tanh_used; + bool cosh_used; + + bool custom_h; + Flags *flags; StringName vname_discard; diff --git a/drivers/mpc/mpc_reader.c b/drivers/mpc/mpc_reader.c index e1d151fe5..550c5ecb5 100644 --- a/drivers/mpc/mpc_reader.c +++ b/drivers/mpc/mpc_reader.c @@ -36,6 +36,7 @@ #include <mpc/reader.h> #include "internal.h" #include <stdio.h> +#include <string.h> // memset() #define STDIO_MAGIC 0xF34B963C ///< Just a random safe-check value... typedef struct mpc_reader_stdio_t { diff --git a/drivers/pvr/ColorRgba.h b/drivers/pvr/ColorRgba.h index 6b46d65e3..070142056 100644 --- a/drivers/pvr/ColorRgba.h +++ b/drivers/pvr/ColorRgba.h @@ -11,21 +11,21 @@ public: ColorRgb() - : r(0) + : b(0) , g(0) - , b(0) { + , r(0) { } ColorRgb(T red, T green, T blue) - : r(red) + : b(blue) , g(green) - , b(blue) { + , r(red) { } ColorRgb(const ColorRgb<T> &x) - : r(x.r) + : b(x.b) , g(x.g) - , b(x.b) { + , r(x.r) { } ColorRgb<int> operator *(int x) { diff --git a/drivers/rtaudio/RtAudio.cpp b/drivers/rtaudio/RtAudio.cpp index 04e7b4422..8876f72e2 100644 --- a/drivers/rtaudio/RtAudio.cpp +++ b/drivers/rtaudio/RtAudio.cpp @@ -46,6 +46,7 @@ #include <cstdlib>
#include <cstring>
#include <climits>
+#include <algorithm>
// Static variable definitions.
const unsigned int RtApi::MAX_SAMPLE_RATES = 14;
@@ -63,6 +64,22 @@ const unsigned int RtApi::SAMPLE_RATES[] = { #define MUTEX_DESTROY(A) DeleteCriticalSection(A)
#define MUTEX_LOCK(A) EnterCriticalSection(A)
#define MUTEX_UNLOCK(A) LeaveCriticalSection(A)
+
+ #include "tchar.h"
+
+ static std::string convertCharPointerToStdString(const char *text)
+ {
+ return std::string(text);
+ }
+
+ static std::string convertCharPointerToStdString(const wchar_t *text)
+ {
+ int length = WideCharToMultiByte(CP_UTF8, 0, text, -1, NULL, 0, NULL, NULL);
+ std::string s( length-1, '\0' );
+ WideCharToMultiByte(CP_UTF8, 0, text, -1, &s[0], length, NULL, NULL);
+ return s;
+ }
+
#elif defined(__LINUX_ALSA__) || defined(__LINUX_PULSE__) || defined(__UNIX_JACK__) || defined(__LINUX_OSS__) || defined(__MACOSX_CORE__)
// pthread API
#define MUTEX_INITIALIZE(A) pthread_mutex_init(A, NULL)
@@ -184,7 +201,7 @@ RtAudio :: RtAudio( RtAudio::Api api ) getCompiledApi( apis );
for ( unsigned int i=0; i<apis.size(); i++ ) {
openRtApi( apis[i] );
- if ( rtapi_->getDeviceCount() ) break;
+ if ( rtapi_ && rtapi_->getDeviceCount() ) break;
}
if ( rtapi_ ) return;
@@ -766,9 +783,14 @@ RtAudio::DeviceInfo RtApiCore :: getDeviceInfo( unsigned int device ) bool haveValueRange = false;
info.sampleRates.clear();
for ( UInt32 i=0; i<nRanges; i++ ) {
- if ( rangeList[i].mMinimum == rangeList[i].mMaximum )
- info.sampleRates.push_back( (unsigned int) rangeList[i].mMinimum );
- else {
+ if ( rangeList[i].mMinimum == rangeList[i].mMaximum ) {
+ unsigned int tmpSr = (unsigned int) rangeList[i].mMinimum;
+ info.sampleRates.push_back( tmpSr );
+
+ if ( !info.preferredSampleRate || ( tmpSr <= 48000 && tmpSr > info.preferredSampleRate ) )
+ info.preferredSampleRate = tmpSr;
+
+ } else {
haveValueRange = true;
if ( rangeList[i].mMinimum > minimumRate ) minimumRate = rangeList[i].mMinimum;
if ( rangeList[i].mMaximum < maximumRate ) maximumRate = rangeList[i].mMaximum;
@@ -777,8 +799,12 @@ RtAudio::DeviceInfo RtApiCore :: getDeviceInfo( unsigned int device ) if ( haveValueRange ) {
for ( unsigned int k=0; k<MAX_SAMPLE_RATES; k++ ) {
- if ( SAMPLE_RATES[k] >= (unsigned int) minimumRate && SAMPLE_RATES[k] <= (unsigned int) maximumRate )
+ if ( SAMPLE_RATES[k] >= (unsigned int) minimumRate && SAMPLE_RATES[k] <= (unsigned int) maximumRate ) {
info.sampleRates.push_back( SAMPLE_RATES[k] );
+
+ if ( !info.preferredSampleRate || ( SAMPLE_RATES[k] <= 48000 && SAMPLE_RATES[k] > info.preferredSampleRate ) )
+ info.preferredSampleRate = SAMPLE_RATES[k];
+ }
}
}
@@ -1385,6 +1411,18 @@ void RtApiCore :: closeStream( void ) CoreHandle *handle = (CoreHandle *) stream_.apiHandle;
if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) {
+ if (handle) {
+ AudioObjectPropertyAddress property = { kAudioHardwarePropertyDevices,
+ kAudioObjectPropertyScopeGlobal,
+ kAudioObjectPropertyElementMaster };
+
+ property.mSelector = kAudioDeviceProcessorOverload;
+ property.mScope = kAudioObjectPropertyScopeGlobal;
+ if (AudioObjectRemovePropertyListener( handle->id[0], &property, xrunListener, (void *) handle ) != noErr) {
+ errorText_ = "RtApiCore::closeStream(): error removing property listener!";
+ error( RtAudioError::WARNING );
+ }
+ }
if ( stream_.state == STREAM_RUNNING )
AudioDeviceStop( handle->id[0], callbackHandler );
#if defined( MAC_OS_X_VERSION_10_5 ) && ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 )
@@ -1396,6 +1434,18 @@ void RtApiCore :: closeStream( void ) }
if ( stream_.mode == INPUT || ( stream_.mode == DUPLEX && stream_.device[0] != stream_.device[1] ) ) {
+ if (handle) {
+ AudioObjectPropertyAddress property = { kAudioHardwarePropertyDevices,
+ kAudioObjectPropertyScopeGlobal,
+ kAudioObjectPropertyElementMaster };
+
+ property.mSelector = kAudioDeviceProcessorOverload;
+ property.mScope = kAudioObjectPropertyScopeGlobal;
+ if (AudioObjectRemovePropertyListener( handle->id[1], &property, xrunListener, (void *) handle ) != noErr) {
+ errorText_ = "RtApiCore::closeStream(): error removing property listener!";
+ error( RtAudioError::WARNING );
+ }
+ }
if ( stream_.state == STREAM_RUNNING )
AudioDeviceStop( handle->id[1], callbackHandler );
#if defined( MAC_OS_X_VERSION_10_5 ) && ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 )
@@ -1989,7 +2039,9 @@ RtAudio::DeviceInfo RtApiJack :: getDeviceInfo( unsigned int device ) // Get the current jack server sample rate.
info.sampleRates.clear();
- info.sampleRates.push_back( jack_get_sample_rate( client ) );
+
+ info.preferredSampleRate = jack_get_sample_rate( client );
+ info.sampleRates.push_back( info.preferredSampleRate );
// Count the available ports containing the client name as device
// channels. Jack "input ports" equal RtAudio output channels.
@@ -2769,8 +2821,12 @@ RtAudio::DeviceInfo RtApiAsio :: getDeviceInfo( unsigned int device ) info.sampleRates.clear();
for ( unsigned int i=0; i<MAX_SAMPLE_RATES; i++ ) {
result = ASIOCanSampleRate( (ASIOSampleRate) SAMPLE_RATES[i] );
- if ( result == ASE_OK )
+ if ( result == ASE_OK ) {
info.sampleRates.push_back( SAMPLE_RATES[i] );
+
+ if ( !info.preferredSampleRate || ( SAMPLE_RATES[i] <= 48000 && SAMPLE_RATES[i] > info.preferredSampleRate ) )
+ info.preferredSampleRate = SAMPLE_RATES[i];
+ }
}
// Determine supported data types ... just check first channel and assume rest are the same.
@@ -2829,9 +2885,12 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne unsigned int firstChannel, unsigned int sampleRate,
RtAudioFormat format, unsigned int *bufferSize,
RtAudio::StreamOptions *options )
-{
+{////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ bool isDuplexInput = mode == INPUT && stream_.mode == OUTPUT;
+
// For ASIO, a duplex stream MUST use the same driver.
- if ( mode == INPUT && stream_.mode == OUTPUT && stream_.device[0] != device ) {
+ if ( isDuplexInput && stream_.device[0] != device ) {
errorText_ = "RtApiAsio::probeDeviceOpen: an ASIO duplex stream must use the same device for input and output!";
return FAILURE;
}
@@ -2845,7 +2904,7 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne }
// Only load the driver once for duplex stream.
- if ( mode != INPUT || stream_.mode != OUTPUT ) {
+ if ( !isDuplexInput ) {
// 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
@@ -2866,22 +2925,26 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne }
}
+ // keep them before any "goto error", they are used for error cleanup + goto device boundary checks
+ bool buffersAllocated = false;
+ AsioHandle *handle = (AsioHandle *) stream_.apiHandle;
+ unsigned int nChannels;
+
+
// Check the device channel count.
long inputChannels, outputChannels;
result = ASIOGetChannels( &inputChannels, &outputChannels );
if ( result != ASE_OK ) {
- drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: error (" << getAsioErrorString( result ) << ") getting channel count (" << driverName << ").";
errorText_ = errorStream_.str();
- return FAILURE;
+ goto error;
}
if ( ( mode == OUTPUT && (channels+firstChannel) > (unsigned int) outputChannels) ||
( mode == INPUT && (channels+firstChannel) > (unsigned int) inputChannels) ) {
- drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") does not support requested channel count (" << channels << ") + offset (" << firstChannel << ").";
errorText_ = errorStream_.str();
- return FAILURE;
+ goto error;
}
stream_.nDeviceChannels[mode] = channels;
stream_.nUserChannels[mode] = channels;
@@ -2890,30 +2953,27 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne // Verify the sample rate is supported.
result = ASIOCanSampleRate( (ASIOSampleRate) sampleRate );
if ( result != ASE_OK ) {
- drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") does not support requested sample rate (" << sampleRate << ").";
errorText_ = errorStream_.str();
- return FAILURE;
+ goto error;
}
// Get the current sample rate
ASIOSampleRate currentRate;
result = ASIOGetSampleRate( ¤tRate );
if ( result != ASE_OK ) {
- drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error getting sample rate.";
errorText_ = errorStream_.str();
- return FAILURE;
+ goto error;
}
// 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;
+ goto error;
}
}
@@ -2924,10 +2984,9 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne else channelInfo.isInput = true;
result = ASIOGetChannelInfo( &channelInfo );
if ( result != ASE_OK ) {
- drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") getting data format.";
errorText_ = errorStream_.str();
- return FAILURE;
+ goto error;
}
// Assuming WINDOWS host is always little-endian.
@@ -2956,10 +3015,9 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne }
if ( stream_.deviceFormat[mode] == 0 ) {
- drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") data format not supported by RtAudio.";
errorText_ = errorStream_.str();
- return FAILURE;
+ goto error;
}
// Set the buffer size. For a duplex stream, this will end up
@@ -2968,49 +3026,63 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne long minSize, maxSize, preferSize, granularity;
result = ASIOGetBufferSize( &minSize, &maxSize, &preferSize, &granularity );
if ( result != ASE_OK ) {
- drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") getting buffer size.";
errorText_ = errorStream_.str();
- return FAILURE;
+ goto error;
}
- if ( *bufferSize < (unsigned int) minSize ) *bufferSize = (unsigned int) minSize;
- else if ( *bufferSize > (unsigned int) maxSize ) *bufferSize = (unsigned int) maxSize;
- else if ( granularity == -1 ) {
- // Make sure bufferSize is a power of two.
- int log2_of_min_size = 0;
- int log2_of_max_size = 0;
+ if ( isDuplexInput ) {
+ // When this is the duplex input (output was opened before), then we have to use the same
+ // buffersize as the output, because it might use the preferred buffer size, which most
+ // likely wasn't passed as input to this. The buffer sizes have to be identically anyway,
+ // So instead of throwing an error, make them equal. The caller uses the reference
+ // to the "bufferSize" param as usual to set up processing buffers.
- for ( unsigned int i = 0; i < sizeof(long) * 8; i++ ) {
- if ( minSize & ((long)1 << i) ) log2_of_min_size = i;
- if ( maxSize & ((long)1 << i) ) log2_of_max_size = i;
- }
+ *bufferSize = stream_.bufferSize;
- long min_delta = std::abs( (long)*bufferSize - ((long)1 << log2_of_min_size) );
- int min_delta_num = log2_of_min_size;
+ } else {
+ if ( *bufferSize == 0 ) *bufferSize = preferSize;
+ else if ( *bufferSize < (unsigned int) minSize ) *bufferSize = (unsigned int) minSize;
+ else if ( *bufferSize > (unsigned int) maxSize ) *bufferSize = (unsigned int) maxSize;
+ else if ( granularity == -1 ) {
+ // Make sure bufferSize is a power of two.
+ int log2_of_min_size = 0;
+ int log2_of_max_size = 0;
- for (int i = log2_of_min_size + 1; i <= log2_of_max_size; i++) {
- long current_delta = std::abs( (long)*bufferSize - ((long)1 << i) );
- if (current_delta < min_delta) {
- min_delta = current_delta;
- min_delta_num = i;
+ for ( unsigned int i = 0; i < sizeof(long) * 8; i++ ) {
+ if ( minSize & ((long)1 << i) ) log2_of_min_size = i;
+ if ( maxSize & ((long)1 << i) ) log2_of_max_size = i;
}
- }
- *bufferSize = ( (unsigned int)1 << min_delta_num );
- if ( *bufferSize < (unsigned int) minSize ) *bufferSize = (unsigned int) minSize;
- else if ( *bufferSize > (unsigned int) maxSize ) *bufferSize = (unsigned int) maxSize;
- }
- else if ( granularity != 0 ) {
- // Set to an even multiple of granularity, rounding up.
- *bufferSize = (*bufferSize + granularity-1) / granularity * granularity;
+ long min_delta = std::abs( (long)*bufferSize - ((long)1 << log2_of_min_size) );
+ int min_delta_num = log2_of_min_size;
+
+ for (int i = log2_of_min_size + 1; i <= log2_of_max_size; i++) {
+ long current_delta = std::abs( (long)*bufferSize - ((long)1 << i) );
+ if (current_delta < min_delta) {
+ min_delta = current_delta;
+ min_delta_num = i;
+ }
+ }
+
+ *bufferSize = ( (unsigned int)1 << min_delta_num );
+ if ( *bufferSize < (unsigned int) minSize ) *bufferSize = (unsigned int) minSize;
+ else if ( *bufferSize > (unsigned int) maxSize ) *bufferSize = (unsigned int) maxSize;
+ }
+ else if ( granularity != 0 ) {
+ // Set to an even multiple of granularity, rounding up.
+ *bufferSize = (*bufferSize + granularity-1) / granularity * granularity;
+ }
}
- if ( mode == INPUT && stream_.mode == OUTPUT && stream_.bufferSize != *bufferSize ) {
- drivers.removeCurrentDriver();
+ /*
+ // we don't use it anymore, see above!
+ // Just left it here for the case...
+ if ( isDuplexInput && stream_.bufferSize != *bufferSize ) {
errorText_ = "RtApiAsio::probeDeviceOpen: input/output buffersize discrepancy!";
- return FAILURE;
+ goto error;
}
+ */
stream_.bufferSize = *bufferSize;
stream_.nBuffers = 2;
@@ -3022,16 +3094,13 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne stream_.deviceInterleaved[mode] = false;
// Allocate, if necessary, our AsioHandle structure for the stream.
- AsioHandle *handle = (AsioHandle *) stream_.apiHandle;
if ( handle == 0 ) {
try {
handle = new AsioHandle;
}
catch ( std::bad_alloc& ) {
- //if ( handle == NULL ) {
- drivers.removeCurrentDriver();
errorText_ = "RtApiAsio::probeDeviceOpen: error allocating AsioHandle memory.";
- return FAILURE;
+ goto error;
}
handle->bufferInfos = 0;
@@ -3046,15 +3115,14 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne // Create the ASIO internal buffers. Since RtAudio sets up input
// and output separately, we'll have to dispose of previously
// created output buffers for a duplex stream.
- long inputLatency, outputLatency;
if ( mode == INPUT && stream_.mode == OUTPUT ) {
ASIODisposeBuffers();
if ( handle->bufferInfos ) free( handle->bufferInfos );
}
// Allocate, initialize, and save the bufferInfos in our stream callbackInfo structure.
- bool buffersAllocated = false;
- unsigned int i, nChannels = stream_.nDeviceChannels[0] + stream_.nDeviceChannels[1];
+ unsigned int i;
+ nChannels = stream_.nDeviceChannels[0] + stream_.nDeviceChannels[1];
handle->bufferInfos = (ASIOBufferInfo *) malloc( nChannels * sizeof(ASIOBufferInfo) );
if ( handle->bufferInfos == NULL ) {
errorStream_ << "RtApiAsio::probeDeviceOpen: error allocating bufferInfo memory for driver (" << driverName << ").";
@@ -3075,6 +3143,15 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne infos->buffers[0] = infos->buffers[1] = 0;
}
+ // prepare for callbacks
+ stream_.sampleRate = sampleRate;
+ stream_.device[mode] = device;
+ stream_.mode = isDuplexInput ? DUPLEX : mode;
+
+ // store this class instance before registering callbacks, that are going to use it
+ asioCallbackInfo = &stream_.callbackInfo;
+ stream_.callbackInfo.object = (void *) this;
+
// Set up the ASIO callback structure and create the ASIO data buffers.
asioCallbacks.bufferSwitch = &bufferSwitch;
asioCallbacks.sampleRateDidChange = &sampleRateChanged;
@@ -3082,11 +3159,21 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne asioCallbacks.bufferSwitchTimeInfo = NULL;
result = ASIOCreateBuffers( handle->bufferInfos, nChannels, stream_.bufferSize, &asioCallbacks );
if ( result != ASE_OK ) {
+ // Standard method failed. This can happen with strict/misbehaving drivers that return valid buffer size ranges
+ // but only accept the preferred buffer size as parameter for ASIOCreateBuffers. eg. Creatives ASIO driver
+ // in that case, let's be naïve and try that instead
+ *bufferSize = preferSize;
+ stream_.bufferSize = *bufferSize;
+ result = ASIOCreateBuffers( handle->bufferInfos, nChannels, stream_.bufferSize, &asioCallbacks );
+ }
+
+ if ( result != ASE_OK ) {
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") creating buffers.";
errorText_ = errorStream_.str();
goto error;
}
- buffersAllocated = true;
+ buffersAllocated = true;
+ stream_.state = STREAM_STOPPED;
// Set flags for buffer conversion.
stream_.doConvertBuffer[mode] = false;
@@ -3109,11 +3196,9 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne bool makeBuffer = true;
bufferBytes = stream_.nDeviceChannels[mode] * formatBytes( stream_.deviceFormat[mode] );
- if ( mode == INPUT ) {
- if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) {
- unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] );
- if ( bufferBytes <= bytesOut ) makeBuffer = false;
- }
+ if ( isDuplexInput && stream_.deviceBuffer ) {
+ unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] );
+ if ( bufferBytes <= bytesOut ) makeBuffer = false;
}
if ( makeBuffer ) {
@@ -3127,18 +3212,8 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne }
}
- stream_.sampleRate = sampleRate;
- stream_.device[mode] = device;
- stream_.state = STREAM_STOPPED;
- asioCallbackInfo = &stream_.callbackInfo;
- stream_.callbackInfo.object = (void *) this;
- if ( stream_.mode == OUTPUT && mode == INPUT )
- // We had already set up an output stream.
- stream_.mode = DUPLEX;
- else
- stream_.mode = mode;
-
// Determine device latencies
+ long inputLatency, outputLatency;
result = ASIOGetLatencies( &inputLatency, &outputLatency );
if ( result != ASE_OK ) {
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") getting latency.";
@@ -3158,32 +3233,38 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne return SUCCESS;
error:
- if ( buffersAllocated )
- ASIODisposeBuffers();
- drivers.removeCurrentDriver();
+ if ( !isDuplexInput ) {
+ // the cleanup for error in the duplex input, is done by RtApi::openStream
+ // So we clean up for single channel only
- if ( handle ) {
- CloseHandle( handle->condition );
- if ( handle->bufferInfos )
- free( handle->bufferInfos );
- delete handle;
- stream_.apiHandle = 0;
- }
+ if ( buffersAllocated )
+ ASIODisposeBuffers();
- for ( int i=0; i<2; i++ ) {
- if ( stream_.userBuffer[i] ) {
- free( stream_.userBuffer[i] );
- stream_.userBuffer[i] = 0;
+ drivers.removeCurrentDriver();
+
+ if ( handle ) {
+ CloseHandle( handle->condition );
+ if ( handle->bufferInfos )
+ free( handle->bufferInfos );
+
+ delete handle;
+ stream_.apiHandle = 0;
}
- }
- if ( stream_.deviceBuffer ) {
- free( stream_.deviceBuffer );
- stream_.deviceBuffer = 0;
+
+ if ( stream_.userBuffer[mode] ) {
+ free( stream_.userBuffer[mode] );
+ stream_.userBuffer[mode] = 0;
+ }
+
+ if ( stream_.deviceBuffer ) {
+ free( stream_.deviceBuffer );
+ stream_.deviceBuffer = 0;
+ }
}
return FAILURE;
-}
+}////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void RtApiAsio :: closeStream()
{
@@ -3635,12 +3716,12 @@ public: outIndex_( 0 ) {}
~WasapiBuffer() {
- delete buffer_;
+ free( buffer_ );
}
// sets the length of the internal ring buffer
void setBufferSize( unsigned int bufferSize, unsigned int formatBytes ) {
- delete buffer_;
+ free( buffer_ );
buffer_ = ( char* ) calloc( bufferSize, formatBytes );
@@ -3799,7 +3880,7 @@ void convertBufferWasapi( char* outBuffer, float sampleStep = 1.0f / sampleRatio;
float inSampleFraction = 0.0f;
- outSampleCount = ( unsigned int ) ( inSampleCount * sampleRatio );
+ outSampleCount = ( unsigned int ) roundf( inSampleCount * sampleRatio );
// frame-by-frame, copy each relative input sample into it's corresponding output sample
for ( unsigned int outSample = 0; outSample < outSampleCount; outSample++ )
@@ -3945,7 +4026,6 @@ RtAudio::DeviceInfo RtApiWasapi::getDeviceInfo( unsigned int device ) RtAudio::DeviceInfo info;
unsigned int captureDeviceCount = 0;
unsigned int renderDeviceCount = 0;
- std::wstring deviceName;
std::string defaultDeviceName;
bool isCaptureDevice = false;
@@ -4048,8 +4128,7 @@ RtAudio::DeviceInfo RtApiWasapi::getDeviceInfo( unsigned int device ) goto Exit;
}
- deviceName = defaultDeviceNameProp.pwszVal;
- defaultDeviceName = std::string( deviceName.begin(), deviceName.end() );
+ defaultDeviceName = convertCharPointerToStdString(defaultDeviceNameProp.pwszVal);
// name
hr = devicePtr->OpenPropertyStore( STGM_READ, &devicePropStore );
@@ -4066,8 +4145,7 @@ RtAudio::DeviceInfo RtApiWasapi::getDeviceInfo( unsigned int device ) goto Exit;
}
- deviceName = deviceNameProp.pwszVal;
- info.name = std::string( deviceName.begin(), deviceName.end() );
+ info.name =convertCharPointerToStdString(deviceNameProp.pwszVal);
// is default
if ( isCaptureDevice ) {
@@ -4110,6 +4188,7 @@ RtAudio::DeviceInfo RtApiWasapi::getDeviceInfo( unsigned int device ) for ( unsigned int i = 0; i < MAX_SAMPLE_RATES; i++ ) {
info.sampleRates.push_back( SAMPLE_RATES[i] );
}
+ info.preferredSampleRate = deviceFormat->nSamplesPerSec;
// native format
info.nativeFormats = 0;
@@ -5245,14 +5324,11 @@ unsigned int RtApiDs :: getDeviceCount( void ) error( RtAudioError::WARNING );
}
- // Clean out any devices that may have disappeared.
- std::vector< int > indices;
- for ( unsigned int i=0; i<dsDevices.size(); i++ )
- if ( dsDevices[i].found == false ) indices.push_back( i );
- //unsigned int nErased = 0;
- for ( unsigned int i=0; i<indices.size(); i++ )
- dsDevices.erase( dsDevices.begin()+indices[i] );
- //dsDevices.erase( dsDevices.begin()-nErased++ );
+ // Clean out any devices that may have disappeared (code update submitted by Eli Zehngut).
+ for ( unsigned int i=0; i<dsDevices.size(); ) {
+ if ( dsDevices[i].found == false ) dsDevices.erase( dsDevices.begin() + i );
+ else i++;
+ }
return static_cast<unsigned int>(dsDevices.size());
}
@@ -5308,8 +5384,12 @@ RtAudio::DeviceInfo RtApiDs :: getDeviceInfo( unsigned int device ) info.sampleRates.clear();
for ( unsigned int k=0; k<MAX_SAMPLE_RATES; k++ ) {
if ( SAMPLE_RATES[k] >= (unsigned int) outCaps.dwMinSecondarySampleRate &&
- SAMPLE_RATES[k] <= (unsigned int) outCaps.dwMaxSecondarySampleRate )
+ SAMPLE_RATES[k] <= (unsigned int) outCaps.dwMaxSecondarySampleRate ) {
info.sampleRates.push_back( SAMPLE_RATES[k] );
+
+ if ( !info.preferredSampleRate || ( SAMPLE_RATES[k] <= 48000 && SAMPLE_RATES[k] > info.preferredSampleRate ) )
+ info.preferredSampleRate = SAMPLE_RATES[k];
+ }
}
// Get format information.
@@ -6264,6 +6344,7 @@ void RtApiDs :: callbackEvent() if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!";
errorText_ = errorStream_.str();
+ MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR );
return;
}
@@ -6271,6 +6352,7 @@ void RtApiDs :: callbackEvent() if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!";
errorText_ = errorStream_.str();
+ MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR );
return;
}
@@ -6279,6 +6361,7 @@ void RtApiDs :: callbackEvent() if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!";
errorText_ = errorStream_.str();
+ MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR );
return;
}
@@ -6286,6 +6369,7 @@ void RtApiDs :: callbackEvent() if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!";
errorText_ = errorStream_.str();
+ MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR );
return;
}
@@ -6307,6 +6391,7 @@ void RtApiDs :: callbackEvent() if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!";
errorText_ = errorStream_.str();
+ MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR );
return;
}
@@ -6399,6 +6484,7 @@ void RtApiDs :: callbackEvent() if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") locking buffer during playback!";
errorText_ = errorStream_.str();
+ MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR );
return;
}
@@ -6412,6 +6498,7 @@ void RtApiDs :: callbackEvent() if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") unlocking buffer during playback!";
errorText_ = errorStream_.str();
+ MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR );
return;
}
@@ -6448,6 +6535,7 @@ void RtApiDs :: callbackEvent() if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!";
errorText_ = errorStream_.str();
+ MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR );
return;
}
@@ -6509,6 +6597,7 @@ void RtApiDs :: callbackEvent() if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!";
errorText_ = errorStream_.str();
+ MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR );
return;
}
@@ -6523,6 +6612,7 @@ void RtApiDs :: callbackEvent() if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") locking capture buffer!";
errorText_ = errorStream_.str();
+ MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR );
return;
}
@@ -6544,6 +6634,7 @@ void RtApiDs :: callbackEvent() if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") unlocking capture buffer!";
errorText_ = errorStream_.str();
+ MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR );
return;
}
@@ -6582,21 +6673,6 @@ static unsigned __stdcall callbackHandler( void *ptr ) return 0;
}
-#include "tchar.h"
-
-static std::string convertTChar( LPCTSTR name )
-{
-#if defined( UNICODE ) || defined( _UNICODE )
- int length = WideCharToMultiByte(CP_UTF8, 0, name, -1, NULL, 0, NULL, NULL);
- std::string s( length-1, '\0' );
- WideCharToMultiByte(CP_UTF8, 0, name, -1, &s[0], length, NULL, NULL);
-#else
- std::string s( name );
-#endif
-
- return s;
-}
-
static BOOL CALLBACK deviceQueryCallback( LPGUID lpguid,
LPCTSTR description,
LPCTSTR /*module*/,
@@ -6638,7 +6714,7 @@ static BOOL CALLBACK deviceQueryCallback( LPGUID lpguid, }
// If good device, then save its name and guid.
- std::string name = convertTChar( description );
+ std::string name = convertCharPointerToStdString( description );
//if ( name == "Primary Sound Driver" || name == "Primary Sound Capture Driver" )
if ( lpguid == NULL )
name = "Default Device";
@@ -6820,6 +6896,7 @@ RtAudio::DeviceInfo RtApiAlsa :: getDeviceInfo( unsigned int device ) // Count cards and devices
card = -1;
+ subdevice = -1;
snd_card_next( &card );
while ( card >= 0 ) {
sprintf( name, "hw:%d", card );
@@ -7033,8 +7110,12 @@ RtAudio::DeviceInfo RtApiAlsa :: getDeviceInfo( unsigned int device ) // Test our discrete set of sample rate values.
info.sampleRates.clear();
for ( unsigned int i=0; i<MAX_SAMPLE_RATES; i++ ) {
- if ( snd_pcm_hw_params_test_rate( phandle, params, SAMPLE_RATES[i], 0 ) == 0 )
+ if ( snd_pcm_hw_params_test_rate( phandle, params, SAMPLE_RATES[i], 0 ) == 0 ) {
info.sampleRates.push_back( SAMPLE_RATES[i] );
+
+ if ( !info.preferredSampleRate || ( SAMPLE_RATES[i] <= 48000 && SAMPLE_RATES[i] > info.preferredSampleRate ) )
+ info.preferredSampleRate = SAMPLE_RATES[i];
+ }
}
if ( info.sampleRates.size() == 0 ) {
snd_pcm_close( phandle );
@@ -7959,6 +8040,8 @@ void RtApiAlsa :: callbackEvent() errorStream_ << "RtApiAlsa::callbackEvent: error preparing device after underrun, " << snd_strerror( result ) << ".";
errorText_ = errorStream_.str();
}
+ else
+ errorText_ = "RtApiAlsa::callbackEvent: audio write error, underrun.";
}
else {
errorStream_ << "RtApiAlsa::callbackEvent: error, current state is " << snd_pcm_state_name( state ) << ", " << snd_strerror( result ) << ".";
@@ -8067,6 +8150,7 @@ RtAudio::DeviceInfo RtApiPulse::getDeviceInfo( unsigned int /*device*/ ) for ( const unsigned int *sr = SUPPORTED_SAMPLERATES; *sr; ++sr )
info.sampleRates.push_back( *sr );
+ info.preferredSampleRate = 48000;
info.nativeFormats = RTAUDIO_SINT16 | RTAUDIO_SINT32 | RTAUDIO_FLOAT32;
return info;
@@ -8429,7 +8513,7 @@ bool RtApiPulse::probeDeviceOpen( unsigned int device, StreamMode mode, pah = static_cast<PulseAudioHandle *>( stream_.apiHandle );
int error;
- if ( !options->streamName.empty() ) streamName = options->streamName;
+ if ( options && !options->streamName.empty() ) streamName = options->streamName;
switch ( mode ) {
case INPUT:
pa_buffer_attr buffer_attr;
@@ -8635,6 +8719,10 @@ RtAudio::DeviceInfo RtApiOss :: getDeviceInfo( unsigned int device ) for ( unsigned int k=0; k<MAX_SAMPLE_RATES; k++ ) {
if ( ainfo.rates[i] == SAMPLE_RATES[k] ) {
info.sampleRates.push_back( SAMPLE_RATES[k] );
+
+ if ( !info.preferredSampleRate || ( SAMPLE_RATES[k] <= 48000 && SAMPLE_RATES[k] > info.preferredSampleRate ) )
+ info.preferredSampleRate = SAMPLE_RATES[k];
+
break;
}
}
@@ -8643,8 +8731,12 @@ RtAudio::DeviceInfo RtApiOss :: getDeviceInfo( unsigned int device ) else {
// Check min and max rate values;
for ( unsigned int k=0; k<MAX_SAMPLE_RATES; k++ ) {
- if ( ainfo.min_rate <= (int) SAMPLE_RATES[k] && ainfo.max_rate >= (int) SAMPLE_RATES[k] )
+ if ( ainfo.min_rate <= (int) SAMPLE_RATES[k] && ainfo.max_rate >= (int) SAMPLE_RATES[k] ) {
info.sampleRates.push_back( SAMPLE_RATES[k] );
+
+ if ( !info.preferredSampleRate || ( SAMPLE_RATES[k] <= 48000 && SAMPLE_RATES[k] > info.preferredSampleRate ) )
+ info.preferredSampleRate = SAMPLE_RATES[k];
+ }
}
}
diff --git a/drivers/rtaudio/RtAudio.h b/drivers/rtaudio/RtAudio.h index 1f1b63072..7d45d3652 100644 --- a/drivers/rtaudio/RtAudio.h +++ b/drivers/rtaudio/RtAudio.h @@ -310,12 +310,13 @@ class RtAudio bool isDefaultOutput; /*!< true if this is the default output device. */ bool isDefaultInput; /*!< true if this is the default input device. */ std::vector<unsigned int> sampleRates; /*!< Supported sample rates (queried from list of standard rates). */ + unsigned int preferredSampleRate; /*!< Preferred sample rate, eg. for WASAPI the system sample rate. */ RtAudioFormat nativeFormats; /*!< Bit mask of supported data formats. */ // Default constructor. DeviceInfo() :probed(false), outputChannels(0), inputChannels(0), duplexChannels(0), - isDefaultOutput(false), isDefaultInput(false), nativeFormats(0) {} + isDefaultOutput(false), isDefaultInput(false), preferredSampleRate(0), nativeFormats(0) {} }; //! The structure for specifying input or ouput stream parameters. diff --git a/drivers/theoraplayer/video_stream_theoraplayer.cpp b/drivers/theoraplayer/video_stream_theoraplayer.cpp index ecafda9d8..ef1f5651a 100644 --- a/drivers/theoraplayer/video_stream_theoraplayer.cpp +++ b/drivers/theoraplayer/video_stream_theoraplayer.cpp @@ -388,7 +388,7 @@ void VideoStreamTheoraplayer::pop_frame(Ref<ImageTexture> p_tex) { { DVector<uint8_t>::Write wr = data.write(); uint8_t* ptr = wr.ptr(); - memcpy(ptr, f->getBuffer(), imgsize); + copymem(ptr, f->getBuffer(), imgsize); } /* for (int i=0; i<h; i++) { diff --git a/drivers/vorbis/psy.c b/drivers/vorbis/psy.c index 9a86151ce..29d282437 100644 --- a/drivers/vorbis/psy.c +++ b/drivers/vorbis/psy.c @@ -1160,7 +1160,7 @@ void _vp_couple_quantize_normalize(int blobno, However, this is a temporary patch. by Aoyumi @ 2004/04/18 */ - /*float derate = (1.0 - de*((float)(j-limit+i) / (float)(n-limit))); + /*float derate = (1.0 - de*((float)(j-limit+i) / (float)(n-limit))); */ /* elliptical if(reM[j]+reA[j]<0){ reM[j] = - (qeM[j] = (fabs(reM[j])+fabs(reA[j]))*derate*derate); diff --git a/drivers/windows/dir_access_windows.cpp b/drivers/windows/dir_access_windows.cpp index a8fed91d9..7c81e8e05 100644 --- a/drivers/windows/dir_access_windows.cpp +++ b/drivers/windows/dir_access_windows.cpp @@ -167,6 +167,7 @@ Error DirAccessWindows::change_dir(String p_dir) { if (worked) { + GetCurrentDirectoryW(2048,real_current_dir_name); current_dir=real_current_dir_name; // TODO, utf8 parser current_dir=current_dir.replace("\\","/"); @@ -190,9 +191,9 @@ Error DirAccessWindows::make_dir(String p_dir) { #else - //p_dir=fix_path(p_dir); + p_dir=fix_path(p_dir); - p_dir.replace("/","\\"); + //p_dir.replace("/","\\"); bool success; int err; @@ -249,14 +250,14 @@ bool DirAccessWindows::file_exists(String p_file) { p_file=fix_path(p_file); - p_file.replace("/","\\"); + //p_file.replace("/","\\"); - WIN32_FILE_ATTRIBUTE_DATA fileInfo; + //WIN32_FILE_ATTRIBUTE_DATA fileInfo; DWORD fileAttr; - fileAttr = GetFileAttributesExW(p_file.c_str(), GetFileExInfoStandard, &fileInfo); - if (0 == fileAttr) + fileAttr = GetFileAttributesW(p_file.c_str()); + if (INVALID_FILE_ATTRIBUTES == fileAttr) return false; return !(fileAttr&FILE_ATTRIBUTE_DIRECTORY); @@ -272,17 +273,16 @@ bool DirAccessWindows::dir_exists(String p_dir) { else p_dir=fix_path(p_dir); - p_dir.replace("/","\\"); + //p_dir.replace("/","\\"); - WIN32_FILE_ATTRIBUTE_DATA fileInfo; + //WIN32_FILE_ATTRIBUTE_DATA fileInfo; DWORD fileAttr; - fileAttr = GetFileAttributesExW(p_dir.c_str(), GetFileExInfoStandard, &fileInfo); - if (0 == fileAttr) - return false; - + fileAttr = GetFileAttributesW(p_dir.c_str()); + if (INVALID_FILE_ATTRIBUTES == fileAttr) + return false; return (fileAttr&FILE_ATTRIBUTE_DIRECTORY); } @@ -313,12 +313,15 @@ Error DirAccessWindows::remove(String p_path) { p_path=fix_path(p_path); printf("erasing %s\n",p_path.utf8().get_data()); - WIN32_FILE_ATTRIBUTE_DATA fileInfo; - DWORD fileAttr = GetFileAttributesExW(p_path.c_str(), GetFileExInfoStandard, &fileInfo); - if (fileAttr == INVALID_FILE_ATTRIBUTES) - return FAILED; + //WIN32_FILE_ATTRIBUTE_DATA fileInfo; + //DWORD fileAttr = GetFileAttributesExW(p_path.c_str(), GetFileExInfoStandard, &fileInfo); + + DWORD fileAttr; - if (fileAttr & FILE_ATTRIBUTE_DIRECTORY) + fileAttr = GetFileAttributesW(p_path.c_str()); + if (INVALID_FILE_ATTRIBUTES == fileAttr) + return FAILED; + if ((fileAttr&FILE_ATTRIBUTE_DIRECTORY)) return ::_wrmdir(p_path.c_str())==0?OK:FAILED; else return ::_wunlink(p_path.c_str())==0?OK:FAILED; |
