This commit is contained in:
Juan Linietsky 2015-05-09 13:09:20 -03:00
commit 1fd1b7a91b
34 changed files with 306 additions and 191 deletions

View File

@ -1381,7 +1381,7 @@ Globals::Globals() {
set("application/name","" ); set("application/name","" );
set("application/main_scene",""); set("application/main_scene","");
custom_prop_info["application/main_scene"]=PropertyInfo(Variant::STRING,"application/main_scene",PROPERTY_HINT_FILE,"xml,res,scn,xscn"); custom_prop_info["application/main_scene"]=PropertyInfo(Variant::STRING,"application/main_scene",PROPERTY_HINT_FILE,"scn,res,xscn,xml");
set("application/disable_stdout",false); set("application/disable_stdout",false);
set("application/use_shared_user_dir",true); set("application/use_shared_user_dir",true);

View File

@ -92,7 +92,9 @@ void PackedData::add_path(const String& pkg_path, const String& path, uint64_t o
void PackedData::add_pack_source(PackSource *p_source) { void PackedData::add_pack_source(PackSource *p_source) {
sources.push_back(p_source); if (p_source != NULL) {
sources.push_back(p_source);
}
}; };
PackedData *PackedData::singleton=NULL; PackedData *PackedData::singleton=NULL;

View File

@ -1850,7 +1850,7 @@ void ResourceFormatSaverXMLInstance::escape(String& p_str) {
p_str=p_str.replace(">","<"); p_str=p_str.replace(">","<");
p_str=p_str.replace("'","'"); p_str=p_str.replace("'","'");
p_str=p_str.replace("\"","""); p_str=p_str.replace("\"",""");
for (int i=1;i<32;i++) { for (char i=1;i<32;i++) {
char chr[2]={i,0}; char chr[2]={i,0};
const char hexn[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; const char hexn[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};

View File

@ -36,8 +36,9 @@ uint32_t Math::default_seed=1;
#define PHI 0x9e3779b9 #define PHI 0x9e3779b9
static uint32_t Q[4096], c = 362436; #if 0
static uint32_t Q[4096];
#endif
uint32_t Math::rand_from_seed(uint32_t *seed) { uint32_t Math::rand_from_seed(uint32_t *seed) {
@ -269,7 +270,7 @@ bool Math::is_inf(double p_val) {
uint32_t Math::larger_prime(uint32_t p_val) { uint32_t Math::larger_prime(uint32_t p_val) {
static const int primes[] = { static const uint32_t primes[] = {
5, 5,
13, 13,
23, 23,

View File

@ -34,8 +34,6 @@ func _fixed_process(delta):
#create forces #create forces
var force = Vector2(0,GRAVITY) var force = Vector2(0,GRAVITY)
var stop = velocity.x!=0.0
var walk_left = Input.is_action_pressed("move_left") var walk_left = Input.is_action_pressed("move_left")
var walk_right = Input.is_action_pressed("move_right") var walk_right = Input.is_action_pressed("move_right")

Binary file not shown.

Binary file not shown.

View File

@ -1,6 +1,8 @@
extends Control extends Control
var mousepos
func _fixed_process(delta): func _fixed_process(delta):
var modetext = "Mode:\n" var modetext = "Mode:\n"
@ -31,7 +33,7 @@ func _fixed_process(delta):
get_node("Label_Size").set_text(str("Size:\n", OS.get_window_size() ) ) get_node("Label_Size").set_text(str("Size:\n", OS.get_window_size() ) )
get_node("Label_MousePosition").set_text(str("Mouse Position:\n", Input.get_mouse_pos() ) ) get_node("Label_MousePosition").set_text(str("Mouse Position:\n", mousepos ) )
get_node("Label_Screen_Count").set_text( str("Screen_Count:\n", OS.get_screen_count() ) ) get_node("Label_Screen_Count").set_text( str("Screen_Count:\n", OS.get_screen_count() ) )
@ -126,6 +128,12 @@ func check_wm_api():
func _ready(): func _ready():
if( check_wm_api() ): if( check_wm_api() ):
set_fixed_process(true) set_fixed_process(true)
set_process_input(true)
func _input(ev):
if (ev.type==InputEvent.MOUSE_MOTION):
mousepos = ev.pos
func _on_Button_MoveTo_pressed(): func _on_Button_MoveTo_pressed():

View File

@ -36,6 +36,7 @@
#include <mpc/reader.h> #include <mpc/reader.h>
#include "internal.h" #include "internal.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> // memset()
#define STDIO_MAGIC 0xF34B963C ///< Just a random safe-check value... #define STDIO_MAGIC 0xF34B963C ///< Just a random safe-check value...
typedef struct mpc_reader_stdio_t { typedef struct mpc_reader_stdio_t {

View File

@ -11,21 +11,21 @@ public:
ColorRgb() ColorRgb()
: r(0) : b(0)
, g(0) , g(0)
, b(0) { , r(0) {
} }
ColorRgb(T red, T green, T blue) ColorRgb(T red, T green, T blue)
: r(red) : b(blue)
, g(green) , g(green)
, b(blue) { , r(red) {
} }
ColorRgb(const ColorRgb<T> &x) ColorRgb(const ColorRgb<T> &x)
: r(x.r) : b(x.b)
, g(x.g) , g(x.g)
, b(x.b) { , r(x.r) {
} }
ColorRgb<int> operator *(int x) { ColorRgb<int> operator *(int x) {

View File

@ -46,6 +46,7 @@
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <climits> #include <climits>
#include <algorithm>
// Static variable definitions. // Static variable definitions.
const unsigned int RtApi::MAX_SAMPLE_RATES = 14; 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_DESTROY(A) DeleteCriticalSection(A)
#define MUTEX_LOCK(A) EnterCriticalSection(A) #define MUTEX_LOCK(A) EnterCriticalSection(A)
#define MUTEX_UNLOCK(A) LeaveCriticalSection(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__) #elif defined(__LINUX_ALSA__) || defined(__LINUX_PULSE__) || defined(__UNIX_JACK__) || defined(__LINUX_OSS__) || defined(__MACOSX_CORE__)
// pthread API // pthread API
#define MUTEX_INITIALIZE(A) pthread_mutex_init(A, NULL) #define MUTEX_INITIALIZE(A) pthread_mutex_init(A, NULL)
@ -184,7 +201,7 @@ RtAudio :: RtAudio( RtAudio::Api api )
getCompiledApi( apis ); getCompiledApi( apis );
for ( unsigned int i=0; i<apis.size(); i++ ) { for ( unsigned int i=0; i<apis.size(); i++ ) {
openRtApi( apis[i] ); openRtApi( apis[i] );
if ( rtapi_->getDeviceCount() ) break; if ( rtapi_ && rtapi_->getDeviceCount() ) break;
} }
if ( rtapi_ ) return; if ( rtapi_ ) return;
@ -766,9 +783,14 @@ RtAudio::DeviceInfo RtApiCore :: getDeviceInfo( unsigned int device )
bool haveValueRange = false; bool haveValueRange = false;
info.sampleRates.clear(); info.sampleRates.clear();
for ( UInt32 i=0; i<nRanges; i++ ) { for ( UInt32 i=0; i<nRanges; i++ ) {
if ( rangeList[i].mMinimum == rangeList[i].mMaximum ) if ( rangeList[i].mMinimum == rangeList[i].mMaximum ) {
info.sampleRates.push_back( (unsigned int) rangeList[i].mMinimum ); unsigned int tmpSr = (unsigned int) rangeList[i].mMinimum;
else { info.sampleRates.push_back( tmpSr );
if ( !info.preferredSampleRate || ( tmpSr <= 48000 && tmpSr > info.preferredSampleRate ) )
info.preferredSampleRate = tmpSr;
} else {
haveValueRange = true; haveValueRange = true;
if ( rangeList[i].mMinimum > minimumRate ) minimumRate = rangeList[i].mMinimum; if ( rangeList[i].mMinimum > minimumRate ) minimumRate = rangeList[i].mMinimum;
if ( rangeList[i].mMaximum < maximumRate ) maximumRate = rangeList[i].mMaximum; if ( rangeList[i].mMaximum < maximumRate ) maximumRate = rangeList[i].mMaximum;
@ -777,8 +799,12 @@ RtAudio::DeviceInfo RtApiCore :: getDeviceInfo( unsigned int device )
if ( haveValueRange ) { if ( haveValueRange ) {
for ( unsigned int k=0; k<MAX_SAMPLE_RATES; k++ ) { 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] ); 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; CoreHandle *handle = (CoreHandle *) stream_.apiHandle;
if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) { 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 ) if ( stream_.state == STREAM_RUNNING )
AudioDeviceStop( handle->id[0], callbackHandler ); 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 ) #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 ( 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 ) if ( stream_.state == STREAM_RUNNING )
AudioDeviceStop( handle->id[1], callbackHandler ); 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 ) #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. // Get the current jack server sample rate.
info.sampleRates.clear(); 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 // Count the available ports containing the client name as device
// channels. Jack "input ports" equal RtAudio output channels. // channels. Jack "input ports" equal RtAudio output channels.
@ -2769,8 +2821,12 @@ RtAudio::DeviceInfo RtApiAsio :: getDeviceInfo( unsigned int device )
info.sampleRates.clear(); info.sampleRates.clear();
for ( unsigned int i=0; i<MAX_SAMPLE_RATES; i++ ) { for ( unsigned int i=0; i<MAX_SAMPLE_RATES; i++ ) {
result = ASIOCanSampleRate( (ASIOSampleRate) SAMPLE_RATES[i] ); result = ASIOCanSampleRate( (ASIOSampleRate) SAMPLE_RATES[i] );
if ( result == ASE_OK ) if ( result == ASE_OK ) {
info.sampleRates.push_back( SAMPLE_RATES[i] ); 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. // 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, unsigned int firstChannel, unsigned int sampleRate,
RtAudioFormat format, unsigned int *bufferSize, RtAudioFormat format, unsigned int *bufferSize,
RtAudio::StreamOptions *options ) RtAudio::StreamOptions *options )
{ {////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool isDuplexInput = mode == INPUT && stream_.mode == OUTPUT;
// For ASIO, a duplex stream MUST use the same driver. // 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!"; errorText_ = "RtApiAsio::probeDeviceOpen: an ASIO duplex stream must use the same device for input and output!";
return FAILURE; return FAILURE;
} }
@ -2845,7 +2904,7 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
} }
// Only load the driver once for duplex stream. // 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 // The getDeviceInfo() function will not work when a stream is open
// because ASIO does not allow multiple devices to run at the same // because ASIO does not allow multiple devices to run at the same
// time. Thus, we'll probe the system before opening a stream and // 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. // Check the device channel count.
long inputChannels, outputChannels; long inputChannels, outputChannels;
result = ASIOGetChannels( &inputChannels, &outputChannels ); result = ASIOGetChannels( &inputChannels, &outputChannels );
if ( result != ASE_OK ) { if ( result != ASE_OK ) {
drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: error (" << getAsioErrorString( result ) << ") getting channel count (" << driverName << ")."; errorStream_ << "RtApiAsio::probeDeviceOpen: error (" << getAsioErrorString( result ) << ") getting channel count (" << driverName << ").";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
return FAILURE; goto error;
} }
if ( ( mode == OUTPUT && (channels+firstChannel) > (unsigned int) outputChannels) || if ( ( mode == OUTPUT && (channels+firstChannel) > (unsigned int) outputChannels) ||
( mode == INPUT && (channels+firstChannel) > (unsigned int) inputChannels) ) { ( mode == INPUT && (channels+firstChannel) > (unsigned int) inputChannels) ) {
drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") does not support requested channel count (" << channels << ") + offset (" << firstChannel << ")."; errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") does not support requested channel count (" << channels << ") + offset (" << firstChannel << ").";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
return FAILURE; goto error;
} }
stream_.nDeviceChannels[mode] = channels; stream_.nDeviceChannels[mode] = channels;
stream_.nUserChannels[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. // Verify the sample rate is supported.
result = ASIOCanSampleRate( (ASIOSampleRate) sampleRate ); result = ASIOCanSampleRate( (ASIOSampleRate) sampleRate );
if ( result != ASE_OK ) { if ( result != ASE_OK ) {
drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") does not support requested sample rate (" << sampleRate << ")."; errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") does not support requested sample rate (" << sampleRate << ").";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
return FAILURE; goto error;
} }
// Get the current sample rate // Get the current sample rate
ASIOSampleRate currentRate; ASIOSampleRate currentRate;
result = ASIOGetSampleRate( &currentRate ); result = ASIOGetSampleRate( &currentRate );
if ( result != ASE_OK ) { if ( result != ASE_OK ) {
drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error getting sample rate."; errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error getting sample rate.";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
return FAILURE; goto error;
} }
// Set the sample rate only if necessary // Set the sample rate only if necessary
if ( currentRate != sampleRate ) { if ( currentRate != sampleRate ) {
result = ASIOSetSampleRate( (ASIOSampleRate) sampleRate ); result = ASIOSetSampleRate( (ASIOSampleRate) sampleRate );
if ( result != ASE_OK ) { if ( result != ASE_OK ) {
drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error setting sample rate (" << sampleRate << ")."; errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error setting sample rate (" << sampleRate << ").";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
return FAILURE; goto error;
} }
} }
@ -2924,10 +2984,9 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
else channelInfo.isInput = true; else channelInfo.isInput = true;
result = ASIOGetChannelInfo( &channelInfo ); result = ASIOGetChannelInfo( &channelInfo );
if ( result != ASE_OK ) { if ( result != ASE_OK ) {
drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") getting data format."; errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") getting data format.";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
return FAILURE; goto error;
} }
// Assuming WINDOWS host is always little-endian. // 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 ) { if ( stream_.deviceFormat[mode] == 0 ) {
drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") data format not supported by RtAudio."; errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") data format not supported by RtAudio.";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
return FAILURE; goto error;
} }
// Set the buffer size. For a duplex stream, this will end up // 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; long minSize, maxSize, preferSize, granularity;
result = ASIOGetBufferSize( &minSize, &maxSize, &preferSize, &granularity ); result = ASIOGetBufferSize( &minSize, &maxSize, &preferSize, &granularity );
if ( result != ASE_OK ) { if ( result != ASE_OK ) {
drivers.removeCurrentDriver();
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") getting buffer size."; errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") getting buffer size.";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
return FAILURE; goto error;
} }
if ( *bufferSize < (unsigned int) minSize ) *bufferSize = (unsigned int) minSize; if ( isDuplexInput ) {
else if ( *bufferSize > (unsigned int) maxSize ) *bufferSize = (unsigned int) maxSize; // When this is the duplex input (output was opened before), then we have to use the same
else if ( granularity == -1 ) { // buffersize as the output, because it might use the preferred buffer size, which most
// Make sure bufferSize is a power of two. // likely wasn't passed as input to this. The buffer sizes have to be identically anyway,
int log2_of_min_size = 0; // So instead of throwing an error, make them equal. The caller uses the reference
int log2_of_max_size = 0; // to the "bufferSize" param as usual to set up processing buffers.
for ( unsigned int i = 0; i < sizeof(long) * 8; i++ ) { *bufferSize = stream_.bufferSize;
if ( minSize & ((long)1 << i) ) log2_of_min_size = i;
if ( maxSize & ((long)1 << i) ) log2_of_max_size = i;
}
long min_delta = std::abs( (long)*bufferSize - ((long)1 << log2_of_min_size) ); } else {
int min_delta_num = log2_of_min_size; if ( *bufferSize == 0 ) *bufferSize = preferSize;
else if ( *bufferSize < (unsigned int) minSize ) *bufferSize = (unsigned int) minSize;
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 ( *bufferSize > (unsigned int) maxSize ) *bufferSize = (unsigned int) maxSize;
} else if ( granularity == -1 ) {
else if ( granularity != 0 ) { // Make sure bufferSize is a power of two.
// Set to an even multiple of granularity, rounding up. int log2_of_min_size = 0;
*bufferSize = (*bufferSize + granularity-1) / granularity * granularity; int log2_of_max_size = 0;
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;
}
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!"; errorText_ = "RtApiAsio::probeDeviceOpen: input/output buffersize discrepancy!";
return FAILURE; goto error;
} }
*/
stream_.bufferSize = *bufferSize; stream_.bufferSize = *bufferSize;
stream_.nBuffers = 2; stream_.nBuffers = 2;
@ -3022,16 +3094,13 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
stream_.deviceInterleaved[mode] = false; stream_.deviceInterleaved[mode] = false;
// Allocate, if necessary, our AsioHandle structure for the stream. // Allocate, if necessary, our AsioHandle structure for the stream.
AsioHandle *handle = (AsioHandle *) stream_.apiHandle;
if ( handle == 0 ) { if ( handle == 0 ) {
try { try {
handle = new AsioHandle; handle = new AsioHandle;
} }
catch ( std::bad_alloc& ) { catch ( std::bad_alloc& ) {
//if ( handle == NULL ) {
drivers.removeCurrentDriver();
errorText_ = "RtApiAsio::probeDeviceOpen: error allocating AsioHandle memory."; errorText_ = "RtApiAsio::probeDeviceOpen: error allocating AsioHandle memory.";
return FAILURE; goto error;
} }
handle->bufferInfos = 0; 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 // Create the ASIO internal buffers. Since RtAudio sets up input
// and output separately, we'll have to dispose of previously // and output separately, we'll have to dispose of previously
// created output buffers for a duplex stream. // created output buffers for a duplex stream.
long inputLatency, outputLatency;
if ( mode == INPUT && stream_.mode == OUTPUT ) { if ( mode == INPUT && stream_.mode == OUTPUT ) {
ASIODisposeBuffers(); ASIODisposeBuffers();
if ( handle->bufferInfos ) free( handle->bufferInfos ); if ( handle->bufferInfos ) free( handle->bufferInfos );
} }
// Allocate, initialize, and save the bufferInfos in our stream callbackInfo structure. // Allocate, initialize, and save the bufferInfos in our stream callbackInfo structure.
bool buffersAllocated = false; unsigned int i;
unsigned int i, nChannels = stream_.nDeviceChannels[0] + stream_.nDeviceChannels[1]; nChannels = stream_.nDeviceChannels[0] + stream_.nDeviceChannels[1];
handle->bufferInfos = (ASIOBufferInfo *) malloc( nChannels * sizeof(ASIOBufferInfo) ); handle->bufferInfos = (ASIOBufferInfo *) malloc( nChannels * sizeof(ASIOBufferInfo) );
if ( handle->bufferInfos == NULL ) { if ( handle->bufferInfos == NULL ) {
errorStream_ << "RtApiAsio::probeDeviceOpen: error allocating bufferInfo memory for driver (" << driverName << ")."; errorStream_ << "RtApiAsio::probeDeviceOpen: error allocating bufferInfo memory for driver (" << driverName << ").";
@ -3075,18 +3143,37 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
infos->buffers[0] = infos->buffers[1] = 0; 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. // Set up the ASIO callback structure and create the ASIO data buffers.
asioCallbacks.bufferSwitch = &bufferSwitch; asioCallbacks.bufferSwitch = &bufferSwitch;
asioCallbacks.sampleRateDidChange = &sampleRateChanged; asioCallbacks.sampleRateDidChange = &sampleRateChanged;
asioCallbacks.asioMessage = &asioMessages; asioCallbacks.asioMessage = &asioMessages;
asioCallbacks.bufferSwitchTimeInfo = NULL; asioCallbacks.bufferSwitchTimeInfo = NULL;
result = ASIOCreateBuffers( handle->bufferInfos, nChannels, stream_.bufferSize, &asioCallbacks ); 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 ) { if ( result != ASE_OK ) {
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") creating buffers."; errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") creating buffers.";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
goto error; goto error;
} }
buffersAllocated = true; buffersAllocated = true;
stream_.state = STREAM_STOPPED;
// Set flags for buffer conversion. // Set flags for buffer conversion.
stream_.doConvertBuffer[mode] = false; stream_.doConvertBuffer[mode] = false;
@ -3109,11 +3196,9 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
bool makeBuffer = true; bool makeBuffer = true;
bufferBytes = stream_.nDeviceChannels[mode] * formatBytes( stream_.deviceFormat[mode] ); bufferBytes = stream_.nDeviceChannels[mode] * formatBytes( stream_.deviceFormat[mode] );
if ( mode == INPUT ) { if ( isDuplexInput && stream_.deviceBuffer ) {
if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) { unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] );
unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] ); if ( bufferBytes <= bytesOut ) makeBuffer = false;
if ( bufferBytes <= bytesOut ) makeBuffer = false;
}
} }
if ( makeBuffer ) { 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 // Determine device latencies
long inputLatency, outputLatency;
result = ASIOGetLatencies( &inputLatency, &outputLatency ); result = ASIOGetLatencies( &inputLatency, &outputLatency );
if ( result != ASE_OK ) { if ( result != ASE_OK ) {
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") getting latency."; 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; return SUCCESS;
error: error:
if ( buffersAllocated ) if ( !isDuplexInput ) {
ASIODisposeBuffers(); // the cleanup for error in the duplex input, is done by RtApi::openStream
drivers.removeCurrentDriver(); // So we clean up for single channel only
if ( handle ) { if ( buffersAllocated )
CloseHandle( handle->condition ); ASIODisposeBuffers();
if ( handle->bufferInfos )
free( handle->bufferInfos );
delete handle;
stream_.apiHandle = 0;
}
for ( int i=0; i<2; i++ ) { drivers.removeCurrentDriver();
if ( stream_.userBuffer[i] ) {
free( stream_.userBuffer[i] ); if ( handle ) {
stream_.userBuffer[i] = 0; CloseHandle( handle->condition );
if ( handle->bufferInfos )
free( handle->bufferInfos );
delete handle;
stream_.apiHandle = 0;
}
if ( stream_.userBuffer[mode] ) {
free( stream_.userBuffer[mode] );
stream_.userBuffer[mode] = 0;
}
if ( stream_.deviceBuffer ) {
free( stream_.deviceBuffer );
stream_.deviceBuffer = 0;
} }
} }
if ( stream_.deviceBuffer ) {
free( stream_.deviceBuffer );
stream_.deviceBuffer = 0;
}
return FAILURE; return FAILURE;
} }////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void RtApiAsio :: closeStream() void RtApiAsio :: closeStream()
{ {
@ -3635,12 +3716,12 @@ public:
outIndex_( 0 ) {} outIndex_( 0 ) {}
~WasapiBuffer() { ~WasapiBuffer() {
delete buffer_; free( buffer_ );
} }
// sets the length of the internal ring buffer // sets the length of the internal ring buffer
void setBufferSize( unsigned int bufferSize, unsigned int formatBytes ) { void setBufferSize( unsigned int bufferSize, unsigned int formatBytes ) {
delete buffer_; free( buffer_ );
buffer_ = ( char* ) calloc( bufferSize, formatBytes ); buffer_ = ( char* ) calloc( bufferSize, formatBytes );
@ -3799,7 +3880,7 @@ void convertBufferWasapi( char* outBuffer,
float sampleStep = 1.0f / sampleRatio; float sampleStep = 1.0f / sampleRatio;
float inSampleFraction = 0.0f; 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 // frame-by-frame, copy each relative input sample into it's corresponding output sample
for ( unsigned int outSample = 0; outSample < outSampleCount; outSample++ ) for ( unsigned int outSample = 0; outSample < outSampleCount; outSample++ )
@ -3945,7 +4026,6 @@ RtAudio::DeviceInfo RtApiWasapi::getDeviceInfo( unsigned int device )
RtAudio::DeviceInfo info; RtAudio::DeviceInfo info;
unsigned int captureDeviceCount = 0; unsigned int captureDeviceCount = 0;
unsigned int renderDeviceCount = 0; unsigned int renderDeviceCount = 0;
std::wstring deviceName;
std::string defaultDeviceName; std::string defaultDeviceName;
bool isCaptureDevice = false; bool isCaptureDevice = false;
@ -4048,8 +4128,7 @@ RtAudio::DeviceInfo RtApiWasapi::getDeviceInfo( unsigned int device )
goto Exit; goto Exit;
} }
deviceName = defaultDeviceNameProp.pwszVal; defaultDeviceName = convertCharPointerToStdString(defaultDeviceNameProp.pwszVal);
defaultDeviceName = std::string( deviceName.begin(), deviceName.end() );
// name // name
hr = devicePtr->OpenPropertyStore( STGM_READ, &devicePropStore ); hr = devicePtr->OpenPropertyStore( STGM_READ, &devicePropStore );
@ -4066,8 +4145,7 @@ RtAudio::DeviceInfo RtApiWasapi::getDeviceInfo( unsigned int device )
goto Exit; goto Exit;
} }
deviceName = deviceNameProp.pwszVal; info.name =convertCharPointerToStdString(deviceNameProp.pwszVal);
info.name = std::string( deviceName.begin(), deviceName.end() );
// is default // is default
if ( isCaptureDevice ) { if ( isCaptureDevice ) {
@ -4110,6 +4188,7 @@ RtAudio::DeviceInfo RtApiWasapi::getDeviceInfo( unsigned int device )
for ( unsigned int i = 0; i < MAX_SAMPLE_RATES; i++ ) { for ( unsigned int i = 0; i < MAX_SAMPLE_RATES; i++ ) {
info.sampleRates.push_back( SAMPLE_RATES[i] ); info.sampleRates.push_back( SAMPLE_RATES[i] );
} }
info.preferredSampleRate = deviceFormat->nSamplesPerSec;
// native format // native format
info.nativeFormats = 0; info.nativeFormats = 0;
@ -5245,14 +5324,11 @@ unsigned int RtApiDs :: getDeviceCount( void )
error( RtAudioError::WARNING ); error( RtAudioError::WARNING );
} }
// Clean out any devices that may have disappeared. // Clean out any devices that may have disappeared (code update submitted by Eli Zehngut).
std::vector< int > indices; for ( unsigned int i=0; i<dsDevices.size(); ) {
for ( unsigned int i=0; i<dsDevices.size(); i++ ) if ( dsDevices[i].found == false ) dsDevices.erase( dsDevices.begin() + i );
if ( dsDevices[i].found == false ) indices.push_back( i ); else 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++ );
return static_cast<unsigned int>(dsDevices.size()); return static_cast<unsigned int>(dsDevices.size());
} }
@ -5308,8 +5384,12 @@ RtAudio::DeviceInfo RtApiDs :: getDeviceInfo( unsigned int device )
info.sampleRates.clear(); info.sampleRates.clear();
for ( unsigned int k=0; k<MAX_SAMPLE_RATES; k++ ) { for ( unsigned int k=0; k<MAX_SAMPLE_RATES; k++ ) {
if ( SAMPLE_RATES[k] >= (unsigned int) outCaps.dwMinSecondarySampleRate && 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] ); 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. // Get format information.
@ -6264,6 +6344,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) { if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!"; errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR ); error( RtAudioError::SYSTEM_ERROR );
return; return;
} }
@ -6271,6 +6352,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) { if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!"; errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR ); error( RtAudioError::SYSTEM_ERROR );
return; return;
} }
@ -6279,6 +6361,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) { if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!"; errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR ); error( RtAudioError::SYSTEM_ERROR );
return; return;
} }
@ -6286,6 +6369,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) { if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!"; errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR ); error( RtAudioError::SYSTEM_ERROR );
return; return;
} }
@ -6307,6 +6391,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) { if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!"; errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR ); error( RtAudioError::SYSTEM_ERROR );
return; return;
} }
@ -6399,6 +6484,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) { if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") locking buffer during playback!"; errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") locking buffer during playback!";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR ); error( RtAudioError::SYSTEM_ERROR );
return; return;
} }
@ -6412,6 +6498,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) { if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") unlocking buffer during playback!"; errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") unlocking buffer during playback!";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR ); error( RtAudioError::SYSTEM_ERROR );
return; return;
} }
@ -6448,6 +6535,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) { if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!"; errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR ); error( RtAudioError::SYSTEM_ERROR );
return; return;
} }
@ -6509,6 +6597,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) { if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!"; errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR ); error( RtAudioError::SYSTEM_ERROR );
return; return;
} }
@ -6523,6 +6612,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) { if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") locking capture buffer!"; errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") locking capture buffer!";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR ); error( RtAudioError::SYSTEM_ERROR );
return; return;
} }
@ -6544,6 +6634,7 @@ void RtApiDs :: callbackEvent()
if ( FAILED( result ) ) { if ( FAILED( result ) ) {
errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") unlocking capture buffer!"; errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") unlocking capture buffer!";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
MUTEX_UNLOCK( &stream_.mutex );
error( RtAudioError::SYSTEM_ERROR ); error( RtAudioError::SYSTEM_ERROR );
return; return;
} }
@ -6582,21 +6673,6 @@ static unsigned __stdcall callbackHandler( void *ptr )
return 0; 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, static BOOL CALLBACK deviceQueryCallback( LPGUID lpguid,
LPCTSTR description, LPCTSTR description,
LPCTSTR /*module*/, LPCTSTR /*module*/,
@ -6638,7 +6714,7 @@ static BOOL CALLBACK deviceQueryCallback( LPGUID lpguid,
} }
// If good device, then save its name and guid. // 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 ( name == "Primary Sound Driver" || name == "Primary Sound Capture Driver" )
if ( lpguid == NULL ) if ( lpguid == NULL )
name = "Default Device"; name = "Default Device";
@ -6820,6 +6896,7 @@ RtAudio::DeviceInfo RtApiAlsa :: getDeviceInfo( unsigned int device )
// Count cards and devices // Count cards and devices
card = -1; card = -1;
subdevice = -1;
snd_card_next( &card ); snd_card_next( &card );
while ( card >= 0 ) { while ( card >= 0 ) {
sprintf( name, "hw:%d", card ); sprintf( name, "hw:%d", card );
@ -7033,8 +7110,12 @@ RtAudio::DeviceInfo RtApiAlsa :: getDeviceInfo( unsigned int device )
// Test our discrete set of sample rate values. // Test our discrete set of sample rate values.
info.sampleRates.clear(); info.sampleRates.clear();
for ( unsigned int i=0; i<MAX_SAMPLE_RATES; i++ ) { 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] ); 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 ) { if ( info.sampleRates.size() == 0 ) {
snd_pcm_close( phandle ); snd_pcm_close( phandle );
@ -7959,6 +8040,8 @@ void RtApiAlsa :: callbackEvent()
errorStream_ << "RtApiAlsa::callbackEvent: error preparing device after underrun, " << snd_strerror( result ) << "."; errorStream_ << "RtApiAlsa::callbackEvent: error preparing device after underrun, " << snd_strerror( result ) << ".";
errorText_ = errorStream_.str(); errorText_ = errorStream_.str();
} }
else
errorText_ = "RtApiAlsa::callbackEvent: audio write error, underrun.";
} }
else { else {
errorStream_ << "RtApiAlsa::callbackEvent: error, current state is " << snd_pcm_state_name( state ) << ", " << snd_strerror( result ) << "."; 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 ) for ( const unsigned int *sr = SUPPORTED_SAMPLERATES; *sr; ++sr )
info.sampleRates.push_back( *sr ); info.sampleRates.push_back( *sr );
info.preferredSampleRate = 48000;
info.nativeFormats = RTAUDIO_SINT16 | RTAUDIO_SINT32 | RTAUDIO_FLOAT32; info.nativeFormats = RTAUDIO_SINT16 | RTAUDIO_SINT32 | RTAUDIO_FLOAT32;
return info; return info;
@ -8429,7 +8513,7 @@ bool RtApiPulse::probeDeviceOpen( unsigned int device, StreamMode mode,
pah = static_cast<PulseAudioHandle *>( stream_.apiHandle ); pah = static_cast<PulseAudioHandle *>( stream_.apiHandle );
int error; int error;
if ( !options->streamName.empty() ) streamName = options->streamName; if ( options && !options->streamName.empty() ) streamName = options->streamName;
switch ( mode ) { switch ( mode ) {
case INPUT: case INPUT:
pa_buffer_attr buffer_attr; 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++ ) { for ( unsigned int k=0; k<MAX_SAMPLE_RATES; k++ ) {
if ( ainfo.rates[i] == SAMPLE_RATES[k] ) { if ( ainfo.rates[i] == SAMPLE_RATES[k] ) {
info.sampleRates.push_back( 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; break;
} }
} }
@ -8643,8 +8731,12 @@ RtAudio::DeviceInfo RtApiOss :: getDeviceInfo( unsigned int device )
else { else {
// Check min and max rate values; // Check min and max rate values;
for ( unsigned int k=0; k<MAX_SAMPLE_RATES; k++ ) { 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] ); info.sampleRates.push_back( SAMPLE_RATES[k] );
if ( !info.preferredSampleRate || ( SAMPLE_RATES[k] <= 48000 && SAMPLE_RATES[k] > info.preferredSampleRate ) )
info.preferredSampleRate = SAMPLE_RATES[k];
}
} }
} }

View File

@ -310,12 +310,13 @@ class RtAudio
bool isDefaultOutput; /*!< true if this is the default output device. */ bool isDefaultOutput; /*!< true if this is the default output device. */
bool isDefaultInput; /*!< true if this is the default input 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). */ 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. */ RtAudioFormat nativeFormats; /*!< Bit mask of supported data formats. */
// Default constructor. // Default constructor.
DeviceInfo() DeviceInfo()
:probed(false), outputChannels(0), inputChannels(0), duplexChannels(0), :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. //! The structure for specifying input or ouput stream parameters.

View File

@ -1160,7 +1160,7 @@ void _vp_couple_quantize_normalize(int blobno,
However, this is a temporary patch. However, this is a temporary patch.
by Aoyumi @ 2004/04/18 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 /* elliptical
if(reM[j]+reA[j]<0){ if(reM[j]+reA[j]<0){
reM[j] = - (qeM[j] = (fabs(reM[j])+fabs(reA[j]))*derate*derate); reM[j] = - (qeM[j] = (fabs(reM[j])+fabs(reA[j]))*derate*derate);

View File

@ -251,7 +251,14 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
packed_data = memnew(PackedData); packed_data = memnew(PackedData);
#ifdef MINIZIP_ENABLED #ifdef MINIZIP_ENABLED
//XXX: always get_singleton() == 0x0
zip_packed_data = ZipArchive::get_singleton(); zip_packed_data = ZipArchive::get_singleton();
//TODO: remove this temporary fix
if (!zip_packed_data) {
zip_packed_data = memnew(ZipArchive);
}
packed_data->add_pack_source(zip_packed_data); packed_data->add_pack_source(zip_packed_data);
#endif #endif
@ -748,10 +755,12 @@ Error Main::setup(const char *execpath,int argc, char *argv[],bool p_second_phas
if (file_access_network_client) if (file_access_network_client)
memdelete(file_access_network_client); memdelete(file_access_network_client);
#ifdef MINIZIP_ENABLED // Note 1: *zip_packed_data live into *packed_data
if (zip_packed_data) // Note 2: PackedData::~PackedData destroy this.
memdelete( zip_packed_data ); //#ifdef MINIZIP_ENABLED
#endif // if (zip_packed_data)
// memdelete( zip_packed_data );
//#endif
unregister_core_types(); unregister_core_types();

View File

@ -317,8 +317,8 @@ void OS_X11::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
/* set the name and class hints for the window manager to use */ /* set the name and class hints for the window manager to use */
classHint = XAllocClassHint(); classHint = XAllocClassHint();
if (classHint) { if (classHint) {
classHint->res_name = "Godot"; classHint->res_name = (char *)"Godot";
classHint->res_class = "Godot"; classHint->res_class = (char *)"Godot";
} }
XSetClassHint(x11_display, x11_window, classHint); XSetClassHint(x11_display, x11_window, classHint);
XFree(classHint); XFree(classHint);

View File

@ -132,8 +132,7 @@ Matrix32 Camera2D::get_camera_transform() {
} }
Point2 screen_offset = (centered ? (screen_size * 0.5 * zoom) : Point2());; Point2 screen_offset = (centered ? (screen_size * 0.5 * zoom) : Point2());
screen_offset;
float angle = get_global_transform().get_rotation(); float angle = get_global_transform().get_rotation();
if(rotating){ if(rotating){

View File

@ -285,18 +285,18 @@ namespace cubic {
namespace circ { namespace circ {
static real_t in(real_t t, real_t b, real_t c, real_t d) static real_t in(real_t t, real_t b, real_t c, real_t d)
{ {
return -c * (sqrt(1 - (t /= d) * t) - 1) + b; return -c * (sqrt(1 - (t /= d) * t) - 1) + b; // TODO: ehrich: operation with t is undefined
} }
static real_t out(real_t t, real_t b, real_t c, real_t d) static real_t out(real_t t, real_t b, real_t c, real_t d)
{ {
return c * sqrt(1 - (t = t / d - 1) * t) + b; return c * sqrt(1 - (t = t / d - 1) * t) + b; // TODO: ehrich: operation with t is undefined
} }
static real_t in_out(real_t t, real_t b, real_t c, real_t d) static real_t in_out(real_t t, real_t b, real_t c, real_t d)
{ {
if ((t /= d / 2) < 1) return -c / 2 * (sqrt(1 - t * t) - 1) + b; if ((t /= d / 2) < 1) return -c / 2 * (sqrt(1 - t * t) - 1) + b;
return c / 2 * (sqrt(1 - t * (t -= 2)) + 1) + b; return c / 2 * (sqrt(1 - t * (t -= 2)) + 1) + b; // TODO: ehrich: operation with t is undefined
} }
static real_t out_in(real_t t, real_t b, real_t c, real_t d) static real_t out_in(real_t t, real_t b, real_t c, real_t d)
@ -364,15 +364,15 @@ namespace back {
static real_t out(real_t t, real_t b, real_t c, real_t d) static real_t out(real_t t, real_t b, real_t c, real_t d)
{ {
float s = 1.70158f; float s = 1.70158f;
return c * ((t = t / d- 1) * t * ((s + 1) * t + s) + 1) + b; return c * ((t = t / d- 1) * t * ((s + 1) * t + s) + 1) + b; // TODO: ehrich: operation with t is undefined
} }
static real_t in_out(real_t t, real_t b, real_t c, real_t d) static real_t in_out(real_t t, real_t b, real_t c, real_t d)
{ {
float s = 1.70158f; float s = 1.70158f;
if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= (1.525f)) + 1) * t - s)) + b; if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= (1.525f)) + 1) * t - s)) + b; // TODO: ehrich: operation with s is undefined
float postFix = t -= 2; float postFix = t -= 2;
return c / 2 * ((postFix) * t * (((s *= (1.525f)) + 1) * t + s) + 2) + b; return c / 2 * ((postFix) * t * (((s *= (1.525f)) + 1) * t + s) + 2) + b; // TODO: ehrich: operation with s is undefined
} }
static real_t out_in(real_t t, real_t b, real_t c, real_t d) static real_t out_in(real_t t, real_t b, real_t c, real_t d)

View File

@ -433,7 +433,7 @@ void Label::regenerate_word_cache() {
} }
if ((autowrap && line_width>=width && (last && last->char_pos >= 0 || not_latin)) || insert_newline) { if ((autowrap && (line_width >= width) && ((last && last->char_pos >= 0) || not_latin)) || insert_newline) {
if (not_latin) { if (not_latin) {
if (current_word_size>0) { if (current_word_size>0) {
WordCache *wc = memnew( WordCache ); WordCache *wc = memnew( WordCache );

View File

@ -272,7 +272,7 @@ void LineEdit::_input_event(InputEvent p_event) {
if (editable) { if (editable) {
selection_delete(); selection_delete();
CharType ucodestr[2]={k.unicode,0}; CharType ucodestr[2]={(CharType)k.unicode,0};
append_at_cursor(ucodestr); append_at_cursor(ucodestr);
emit_signal("text_changed",text); emit_signal("text_changed",text);
_change_notify("text"); _change_notify("text");

View File

@ -1440,7 +1440,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
} else { } else {
//different char, go back //different char, go back
const CharType chr[2] = {k.unicode, 0}; const CharType chr[2] = {(CharType)k.unicode, 0};
if(auto_brace_completion_enabled && _is_pair_symbol(chr[0])) { if(auto_brace_completion_enabled && _is_pair_symbol(chr[0])) {
_consume_pair_symbol(chr[0]); _consume_pair_symbol(chr[0]);
} else { } else {
@ -2062,7 +2062,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) {
if (readonly) if (readonly)
break; break;
const CharType chr[2] = {k.unicode, 0}; const CharType chr[2] = {(CharType)k.unicode, 0};
if(auto_brace_completion_enabled && _is_pair_symbol(chr[0])) { if(auto_brace_completion_enabled && _is_pair_symbol(chr[0])) {
_consume_pair_symbol(chr[0]); _consume_pair_symbol(chr[0]);

View File

@ -34,8 +34,10 @@
#include "self_list.h" #include "self_list.h"
#include "broad_phase_sw.h" #include "broad_phase_sw.h"
#define MAX_OBJECT_DISTANCE 10000000 #ifdef DEBUG_ENABLED
#define MAX_OBJECT_DISTANCE 10000000.0
#define MAX_OBJECT_DISTANCE_X2 (MAX_OBJECT_DISTANCE*MAX_OBJECT_DISTANCE) #define MAX_OBJECT_DISTANCE_X2 (MAX_OBJECT_DISTANCE*MAX_OBJECT_DISTANCE)
#endif
class SpaceSW; class SpaceSW;

View File

@ -551,7 +551,7 @@ bool PhysicsServerSW::body_is_shape_set_as_trigger(RID p_body, int p_shape_idx)
ERR_FAIL_COND_V(!body,false); ERR_FAIL_COND_V(!body,false);
ERR_FAIL_INDEX_V(p_shape_idx,body->get_shape_count(),false); ERR_FAIL_INDEX_V(p_shape_idx,body->get_shape_count(),false);
body->is_shape_set_as_trigger(p_shape_idx); return body->is_shape_set_as_trigger(p_shape_idx);
} }

View File

@ -863,17 +863,17 @@ public:
if (polygon->indices != NULL) { if (polygon->indices != NULL) {
r.pos=polygon->points[polygon->indices[0]]; r.pos=polygon->points[polygon->indices[0]];
for (int i=1; i<polygon->count; i++) { for (int i=1; i<l; i++) {
r.expand_to(polygon->points[polygon->indices[i]]); r.expand_to(polygon->points[polygon->indices[i]]);
}; }
} else { } else {
r.pos=polygon->points[0]; r.pos=polygon->points[0];
for (int i=1; i<polygon->count; i++) { for (int i=1; i<l; i++) {
r.expand_to(polygon->points[i]); r.expand_to(polygon->points[i]);
}; }
}; }
} break; } break;
case CanvasItem::Command::TYPE_CIRCLE: { case CanvasItem::Command::TYPE_CIRCLE: {

View File

@ -7281,7 +7281,7 @@ void VisualServerRaster::_draw_viewports() {
if (r.size.width==0) if (r.size.width==0)
r.size.width=window_w; r.size.width=window_w;
if (r.size.height==0) if (r.size.height==0)
r.size.height=window_w; r.size.height=window_h;
_draw_viewport(vp,r.pos.x,r.pos.y,r.size.width,r.size.height); _draw_viewport(vp,r.pos.x,r.pos.y,r.size.width,r.size.height);

View File

@ -65,7 +65,7 @@ static String _escape_string(const String& p_str) {
ret=ret.replace(">","&lt;"); ret=ret.replace(">","&lt;");
ret=ret.replace("'","&apos;"); ret=ret.replace("'","&apos;");
ret=ret.replace("\"","&quot;"); ret=ret.replace("\"","&quot;");
for (int i=1;i<32;i++) { for (char i=1;i<32;i++) {
char chr[2]={i,0}; char chr[2]={i,0};
ret=ret.replace(chr,"&#"+String::num(i)+";"); ret=ret.replace(chr,"&#"+String::num(i)+";");

View File

@ -1375,7 +1375,7 @@ void AnimationKeyEditor::_track_editor_input_event(const InputEvent& p_input) {
if (p_input.is_action("ui_up")) if (p_input.is_action("ui_up"))
selected_track--; selected_track--;
if (v_scroll->is_visible() && p_input.is_action("ui_page_up")) if (v_scroll->is_visible() && p_input.is_action("ui_page_up"))
selected_track--;; selected_track--;
if (selected_track<0) if (selected_track<0)
selected_track=0; selected_track=0;

View File

@ -940,19 +940,19 @@ String EditorFileSystem::get_file_type(const String& p_file) const {
EditorFileSystemDirectory *EditorFileSystem::get_path(const String& p_path) { EditorFileSystemDirectory *EditorFileSystem::get_path(const String& p_path) {
if (!filesystem || scanning) if (!filesystem || scanning)
return false; return NULL;
String f = Globals::get_singleton()->localize_path(p_path); String f = Globals::get_singleton()->localize_path(p_path);
if (!f.begins_with("res://")) if (!f.begins_with("res://"))
return false; return NULL;
f=f.substr(6,f.length()); f=f.substr(6,f.length());
f=f.replace("\\","/"); f=f.replace("\\","/");
if (f==String()) if (f==String())
return filesystem; return filesystem;
if (f.ends_with("/")) if (f.ends_with("/"))
f=f.substr(0,f.length()-1); f=f.substr(0,f.length()-1);
@ -960,7 +960,7 @@ EditorFileSystemDirectory *EditorFileSystem::get_path(const String& p_path) {
Vector<String> path = f.split("/"); Vector<String> path = f.split("/");
if (path.size()==0) if (path.size()==0)
return false; return NULL;
EditorFileSystemDirectory *fs=filesystem; EditorFileSystemDirectory *fs=filesystem;

View File

@ -51,6 +51,7 @@ static const char *flag_names[]={
NULL NULL
}; };
#if 0 // not used
static const char *flag_short_names[]={ static const char *flag_short_names[]={
"Stream", "Stream",
"FixBorder", "FixBorder",
@ -65,6 +66,7 @@ static const char *flag_short_names[]={
"Anisoropic", "Anisoropic",
NULL NULL
}; };
#endif
void EditorImportTextureOptions::set_format(EditorTextureImportPlugin::ImageFormat p_format) { void EditorImportTextureOptions::set_format(EditorTextureImportPlugin::ImageFormat p_format) {

View File

@ -539,7 +539,6 @@ void GraphCurveMapEdit::_plot_curve(const Vector2& p_a,const Vector2& p_b,const
if ((lastx != newx) || (lasty != newy)) if ((lastx != newx) || (lasty != newy))
{ {
#if 0 #if 0
/*
if(fix255) if(fix255)
{ {
/* use fixed array size (for the curve graph) */ /* use fixed array size (for the curve graph) */

View File

@ -3172,11 +3172,11 @@ void SpatialEditor::_init_indicators() {
int arrow_sides=6; int arrow_sides=6;
for(int i = 0; i < 7 ; i++) { for(int k = 0; k < 7 ; k++) {
Matrix3 ma(ivec,Math_PI*2*float(i)/arrow_sides); Matrix3 ma(ivec,Math_PI*2*float(k)/arrow_sides);
Matrix3 mb(ivec,Math_PI*2*float(i+1)/arrow_sides); Matrix3 mb(ivec,Math_PI*2*float(k+1)/arrow_sides);
for(int j=0;j<arrow_points-1;j++) { for(int j=0;j<arrow_points-1;j++) {

View File

@ -1257,7 +1257,8 @@ void SkeletonSpatialGizmo::redraw() {
//find closest axis //find closest axis
int closest=-1; int closest=-1;
float closest_d; float closest_d = 0.0;
for(int j=0;j<3;j++) { for(int j=0;j<3;j++) {
float dp = Math::abs(grests[parent].basis[j].normalized().dot(d)); float dp = Math::abs(grests[parent].basis[j].normalized().dot(d));
if (j==0 || dp>closest_d) if (j==0 || dp>closest_d)

View File

@ -136,7 +136,7 @@ Error PCKPacker::flush(bool p_verbose) {
count += 1; count += 1;
if (p_verbose) { if (p_verbose) {
if (count % 100 == 0) { if (count % 100 == 0) {
printf("%i/%i (%.2f\%)\r", count, files.size(), float(count) / files.size() * 100); printf("%i/%i (%.2f)\r", count, files.size(), float(count) / files.size() * 100);
fflush(stdout); fflush(stdout);
}; };
}; };