diff options
Diffstat (limited to 'portaudio/src/os')
-rw-r--r-- | portaudio/src/os/unix/pa_unix_hostapis.c | 103 | ||||
-rw-r--r-- | portaudio/src/os/unix/pa_unix_util.c | 710 | ||||
-rw-r--r-- | portaudio/src/os/unix/pa_unix_util.h | 224 | ||||
-rw-r--r-- | portaudio/src/os/win/pa_win_coinitialize.c | 148 | ||||
-rw-r--r-- | portaudio/src/os/win/pa_win_coinitialize.h | 94 | ||||
-rw-r--r-- | portaudio/src/os/win/pa_win_hostapis.c | 100 | ||||
-rw-r--r-- | portaudio/src/os/win/pa_win_util.c | 160 | ||||
-rw-r--r-- | portaudio/src/os/win/pa_win_waveformat.c | 163 | ||||
-rw-r--r-- | portaudio/src/os/win/pa_win_wdmks_utils.c | 309 | ||||
-rw-r--r-- | portaudio/src/os/win/pa_win_wdmks_utils.h | 65 | ||||
-rw-r--r-- | portaudio/src/os/win/pa_x86_plain_converters.c | 1218 | ||||
-rw-r--r-- | portaudio/src/os/win/pa_x86_plain_converters.h | 60 |
12 files changed, 0 insertions, 3354 deletions
diff --git a/portaudio/src/os/unix/pa_unix_hostapis.c b/portaudio/src/os/unix/pa_unix_hostapis.c deleted file mode 100644 index 7f1a51f..0000000 --- a/portaudio/src/os/unix/pa_unix_hostapis.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * $Id$ - * Portable Audio I/O Library UNIX initialization table - * - * Based on the Open Source API proposed by Ross Bencina - * Copyright (c) 1999-2002 Ross Bencina, Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * The text above constitutes the entire PortAudio license; however, - * the PortAudio community also makes the following non-binding requests: - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. It is also - * requested that these non-binding requests be included along with the - * license above. - */ - -/** @file - @ingroup unix_src -*/ - -#include "pa_hostapi.h" - -PaError PaJack_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); -PaError PaAlsa_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); -PaError PaOSS_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); -/* Added for IRIX, Pieter, oct 2, 2003: */ -PaError PaSGI_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); -/* Linux AudioScience HPI */ -PaError PaAsiHpi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); -PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); -PaError PaSkeleton_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); - -/** Note that on Linux, ALSA is placed before OSS so that the former is preferred over the latter. - */ - -PaUtilHostApiInitializer *paHostApiInitializers[] = - { -#ifdef __linux__ - -#if PA_USE_ALSA - PaAlsa_Initialize, -#endif - -#if PA_USE_OSS - PaOSS_Initialize, -#endif - -#else /* __linux__ */ - -#if PA_USE_OSS - PaOSS_Initialize, -#endif - -#if PA_USE_ALSA - PaAlsa_Initialize, -#endif - -#endif /* __linux__ */ - -#if PA_USE_JACK - PaJack_Initialize, -#endif - /* Added for IRIX, Pieter, oct 2, 2003: */ -#if PA_USE_SGI - PaSGI_Initialize, -#endif - -#if PA_USE_ASIHPI - PaAsiHpi_Initialize, -#endif - -#if PA_USE_COREAUDIO - PaMacCore_Initialize, -#endif - -#if PA_USE_SKELETON - PaSkeleton_Initialize, -#endif - - 0 /* NULL terminated array */ - }; diff --git a/portaudio/src/os/unix/pa_unix_util.c b/portaudio/src/os/unix/pa_unix_util.c deleted file mode 100644 index 459b2be..0000000 --- a/portaudio/src/os/unix/pa_unix_util.c +++ /dev/null @@ -1,710 +0,0 @@ -/* - * $Id$ - * Portable Audio I/O Library - * UNIX platform-specific support functions - * - * Based on the Open Source API proposed by Ross Bencina - * Copyright (c) 1999-2000 Ross Bencina - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * The text above constitutes the entire PortAudio license; however, - * the PortAudio community also makes the following non-binding requests: - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. It is also - * requested that these non-binding requests be included along with the - * license above. - */ - -/** @file - @ingroup unix_src -*/ - -#include <pthread.h> -#include <unistd.h> -#include <stdlib.h> -#include <time.h> -#include <sys/time.h> -#include <assert.h> -#include <string.h> /* For memset */ -#include <math.h> -#include <errno.h> - -#if defined(__APPLE__) && !defined(HAVE_MACH_ABSOLUTE_TIME) -#define HAVE_MACH_ABSOLUTE_TIME -#endif -#ifdef HAVE_MACH_ABSOLUTE_TIME -#include <mach/mach_time.h> -#endif - -#include "pa_util.h" -#include "pa_unix_util.h" -#include "pa_debugprint.h" - -/* - Track memory allocations to avoid leaks. - */ - -#if PA_TRACK_MEMORY -static int numAllocations_ = 0; -#endif - - -void *PaUtil_AllocateMemory( long size ) -{ - void *result = malloc( size ); - -#if PA_TRACK_MEMORY - if( result != NULL ) numAllocations_ += 1; -#endif - return result; -} - - -void PaUtil_FreeMemory( void *block ) -{ - if( block != NULL ) - { - free( block ); -#if PA_TRACK_MEMORY - numAllocations_ -= 1; -#endif - - } -} - - -int PaUtil_CountCurrentlyAllocatedBlocks( void ) -{ -#if PA_TRACK_MEMORY - return numAllocations_; -#else - return 0; -#endif -} - - -void Pa_Sleep( long msec ) -{ -#ifdef HAVE_NANOSLEEP - struct timespec req = {0}, rem = {0}; - PaTime time = msec / 1.e3; - req.tv_sec = (time_t)time; - assert(time - req.tv_sec < 1.0); - req.tv_nsec = (long)((time - req.tv_sec) * 1.e9); - nanosleep(&req, &rem); - /* XXX: Try sleeping the remaining time (contained in rem) if interrupted by a signal? */ -#else - while( msec > 999 ) /* For OpenBSD and IRIX, argument */ - { /* to usleep must be < 1000000. */ - usleep( 999000 ); - msec -= 999; - } - usleep( msec * 1000 ); -#endif -} - -#ifdef HAVE_MACH_ABSOLUTE_TIME -/* - Discussion on the CoreAudio mailing list suggests that calling - gettimeofday (or anything else in the BSD layer) is not real-time - safe, so we use mach_absolute_time on OSX. This implementation is - based on these two links: - - Technical Q&A QA1398 - Mach Absolute Time Units - http://developer.apple.com/mac/library/qa/qa2004/qa1398.html - - Tutorial: Performance and Time. - http://www.macresearch.org/tutorial_performance_and_time -*/ - -/* Scaler to convert the result of mach_absolute_time to seconds */ -static double machSecondsConversionScaler_ = 0.0; -#endif - -void PaUtil_InitializeClock( void ) -{ -#ifdef HAVE_MACH_ABSOLUTE_TIME - mach_timebase_info_data_t info; - kern_return_t err = mach_timebase_info( &info ); - if( err == 0 ) - machSecondsConversionScaler_ = 1e-9 * (double) info.numer / (double) info.denom; -#endif -} - - -PaTime PaUtil_GetTime( void ) -{ -#ifdef HAVE_MACH_ABSOLUTE_TIME - return mach_absolute_time() * machSecondsConversionScaler_; -#elif defined(HAVE_CLOCK_GETTIME) - struct timespec tp; - clock_gettime(CLOCK_REALTIME, &tp); - return (PaTime)(tp.tv_sec + tp.tv_nsec * 1e-9); -#else - struct timeval tv; - gettimeofday( &tv, NULL ); - return (PaTime) tv.tv_usec * 1e-6 + tv.tv_sec; -#endif -} - -PaError PaUtil_InitializeThreading( PaUtilThreading *threading ) -{ - (void) paUtilErr_; - return paNoError; -} - -void PaUtil_TerminateThreading( PaUtilThreading *threading ) -{ -} - -PaError PaUtil_StartThreading( PaUtilThreading *threading, void *(*threadRoutine)(void *), void *data ) -{ - pthread_create( &threading->callbackThread, NULL, threadRoutine, data ); - return paNoError; -} - -PaError PaUtil_CancelThreading( PaUtilThreading *threading, int wait, PaError *exitResult ) -{ - PaError result = paNoError; - void *pret; - - if( exitResult ) - *exitResult = paNoError; - - /* If pthread_cancel is not supported (Android platform) whole this function can lead to indefinite waiting if - working thread (callbackThread) has'n received any stop signals from outside, please keep - this in mind when considering using PaUtil_CancelThreading - */ -#ifdef PTHREAD_CANCELED - /* Only kill the thread if it isn't in the process of stopping (flushing adaptation buffers) */ - if( !wait ) - pthread_cancel( threading->callbackThread ); /* XXX: Safe to call this if the thread has exited on its own? */ -#endif - pthread_join( threading->callbackThread, &pret ); - -#ifdef PTHREAD_CANCELED - if( pret && PTHREAD_CANCELED != pret ) -#else - /* !wait means the thread may have been canceled */ - if( pret && wait ) -#endif - { - if( exitResult ) - *exitResult = *(PaError *) pret; - free( pret ); - } - - return result; -} - -/* Threading */ -/* paUnixMainThread - * We have to be a bit careful with defining this global variable, - * as explained below. */ -#ifdef __APPLE__ -/* apple/gcc has a "problem" with global vars and dynamic libs. - Initializing it seems to fix the problem. - Described a bit in this thread: - http://gcc.gnu.org/ml/gcc/2005-06/msg00179.html -*/ -pthread_t paUnixMainThread = 0; -#else -/*pthreads are opaque. We don't know that assigning it an int value - always makes sense, so we don't initialize it unless we have to.*/ -pthread_t paUnixMainThread = 0; -#endif - -PaError PaUnixThreading_Initialize( void ) -{ - paUnixMainThread = pthread_self(); - return paNoError; -} - -static PaError BoostPriority( PaUnixThread* self ) -{ - PaError result = paNoError; - struct sched_param spm = { 0 }; - /* Priority should only matter between contending FIFO threads? */ - spm.sched_priority = 1; - - assert( self ); - - if( pthread_setschedparam( self->thread, SCHED_FIFO, &spm ) != 0 ) - { - PA_UNLESS( errno == EPERM, paInternalError ); /* Lack permission to raise priority */ - PA_DEBUG(( "Failed bumping priority\n" )); - result = 0; - } - else - { - result = 1; /* Success */ - } -error: - return result; -} - -PaError PaUnixThread_New( PaUnixThread* self, void* (*threadFunc)( void* ), void* threadArg, PaTime waitForChild, - int rtSched ) -{ - PaError result = paNoError; - pthread_attr_t attr; - int started = 0; - - memset( self, 0, sizeof (PaUnixThread) ); - PaUnixMutex_Initialize( &self->mtx ); - PA_ASSERT_CALL( pthread_cond_init( &self->cond, NULL ), 0 ); - - self->parentWaiting = 0 != waitForChild; - - /* Spawn thread */ - -/* Temporarily disabled since we should test during configuration for presence of required mman.h header */ -#if 0 -#if defined _POSIX_MEMLOCK && (_POSIX_MEMLOCK != -1) - if( rtSched ) - { - if( mlockall( MCL_CURRENT | MCL_FUTURE ) < 0 ) - { - int savedErrno = errno; /* In case errno gets overwritten */ - assert( savedErrno != EINVAL ); /* Most likely a programmer error */ - PA_UNLESS( (savedErrno == EPERM), paInternalError ); - PA_DEBUG(( "%s: Failed locking memory\n", __FUNCTION__ )); - } - else - PA_DEBUG(( "%s: Successfully locked memory\n", __FUNCTION__ )); - } -#endif -#endif - - PA_UNLESS( !pthread_attr_init( &attr ), paInternalError ); - /* Priority relative to other processes */ - PA_UNLESS( !pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM ), paInternalError ); - - PA_UNLESS( !pthread_create( &self->thread, &attr, threadFunc, threadArg ), paInternalError ); - started = 1; - - if( rtSched ) - { -#if 0 - if( self->useWatchdog ) - { - int err; - struct sched_param wdSpm = { 0 }; - /* Launch watchdog, watchdog sets callback thread priority */ - int prio = PA_MIN( self->rtPrio + 4, sched_get_priority_max( SCHED_FIFO ) ); - wdSpm.sched_priority = prio; - - PA_UNLESS( !pthread_attr_init( &attr ), paInternalError ); - PA_UNLESS( !pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED ), paInternalError ); - PA_UNLESS( !pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM ), paInternalError ); - PA_UNLESS( !pthread_attr_setschedpolicy( &attr, SCHED_FIFO ), paInternalError ); - PA_UNLESS( !pthread_attr_setschedparam( &attr, &wdSpm ), paInternalError ); - if( (err = pthread_create( &self->watchdogThread, &attr, &WatchdogFunc, self )) ) - { - PA_UNLESS( err == EPERM, paInternalError ); - /* Permission error, go on without realtime privileges */ - PA_DEBUG(( "Failed bumping priority\n" )); - } - else - { - int policy; - self->watchdogRunning = 1; - PA_ENSURE_SYSTEM( pthread_getschedparam( self->watchdogThread, &policy, &wdSpm ), 0 ); - /* Check if priority is right, policy could potentially differ from SCHED_FIFO (but that's alright) */ - if( wdSpm.sched_priority != prio ) - { - PA_DEBUG(( "Watchdog priority not set correctly (%d)\n", wdSpm.sched_priority )); - PA_ENSURE( paInternalError ); - } - } - } - else -#endif - PA_ENSURE( BoostPriority( self ) ); - - { - int policy; - struct sched_param spm; - pthread_getschedparam(self->thread, &policy, &spm); - } - } - - if( self->parentWaiting ) - { - PaTime till; - struct timespec ts; - int res = 0; - PaTime now; - - PA_ENSURE( PaUnixMutex_Lock( &self->mtx ) ); - - /* Wait for stream to be started */ - now = PaUtil_GetTime(); - till = now + waitForChild; - - while( self->parentWaiting && !res ) - { - if( waitForChild > 0 ) - { - ts.tv_sec = (time_t) floor( till ); - ts.tv_nsec = (long) ((till - floor( till )) * 1e9); - res = pthread_cond_timedwait( &self->cond, &self->mtx.mtx, &ts ); - } - else - { - res = pthread_cond_wait( &self->cond, &self->mtx.mtx ); - } - } - - PA_ENSURE( PaUnixMutex_Unlock( &self->mtx ) ); - - PA_UNLESS( !res || ETIMEDOUT == res, paInternalError ); - PA_DEBUG(( "%s: Waited for %g seconds for stream to start\n", __FUNCTION__, PaUtil_GetTime() - now )); - if( ETIMEDOUT == res ) - { - PA_ENSURE( paTimedOut ); - } - } - -end: - return result; -error: - if( started ) - { - PaUnixThread_Terminate( self, 0, NULL ); - } - - goto end; -} - -PaError PaUnixThread_Terminate( PaUnixThread* self, int wait, PaError* exitResult ) -{ - PaError result = paNoError; - void* pret; - - if( exitResult ) - { - *exitResult = paNoError; - } -#if 0 - if( watchdogExitResult ) - *watchdogExitResult = paNoError; - - if( th->watchdogRunning ) - { - pthread_cancel( th->watchdogThread ); - PA_ENSURE_SYSTEM( pthread_join( th->watchdogThread, &pret ), 0 ); - - if( pret && pret != PTHREAD_CANCELED ) - { - if( watchdogExitResult ) - *watchdogExitResult = *(PaError *) pret; - free( pret ); - } - } -#endif - - /* Only kill the thread if it isn't in the process of stopping (flushing adaptation buffers) */ - /* TODO: Make join time out */ - self->stopRequested = wait; - if( !wait ) - { - PA_DEBUG(( "%s: Canceling thread %d\n", __FUNCTION__, self->thread )); - /* XXX: Safe to call this if the thread has exited on its own? */ -#ifdef PTHREAD_CANCELED - pthread_cancel( self->thread ); -#endif - } - PA_DEBUG(( "%s: Joining thread %d\n", __FUNCTION__, self->thread )); - PA_ENSURE_SYSTEM( pthread_join( self->thread, &pret ), 0 ); - -#ifdef PTHREAD_CANCELED - if( pret && PTHREAD_CANCELED != pret ) -#else - /* !wait means the thread may have been canceled */ - if( pret && wait ) -#endif - { - if( exitResult ) - { - *exitResult = *(PaError*)pret; - } - free( pret ); - } - -error: - PA_ASSERT_CALL( PaUnixMutex_Terminate( &self->mtx ), paNoError ); - PA_ASSERT_CALL( pthread_cond_destroy( &self->cond ), 0 ); - - return result; -} - -PaError PaUnixThread_PrepareNotify( PaUnixThread* self ) -{ - PaError result = paNoError; - PA_UNLESS( self->parentWaiting, paInternalError ); - - PA_ENSURE( PaUnixMutex_Lock( &self->mtx ) ); - self->locked = 1; - -error: - return result; -} - -PaError PaUnixThread_NotifyParent( PaUnixThread* self ) -{ - PaError result = paNoError; - PA_UNLESS( self->parentWaiting, paInternalError ); - - if( !self->locked ) - { - PA_ENSURE( PaUnixMutex_Lock( &self->mtx ) ); - self->locked = 1; - } - self->parentWaiting = 0; - pthread_cond_signal( &self->cond ); - PA_ENSURE( PaUnixMutex_Unlock( &self->mtx ) ); - self->locked = 0; - -error: - return result; -} - -int PaUnixThread_StopRequested( PaUnixThread* self ) -{ - return self->stopRequested; -} - -PaError PaUnixMutex_Initialize( PaUnixMutex* self ) -{ - PaError result = paNoError; - PA_ASSERT_CALL( pthread_mutex_init( &self->mtx, NULL ), 0 ); - return result; -} - -PaError PaUnixMutex_Terminate( PaUnixMutex* self ) -{ - PaError result = paNoError; - PA_ASSERT_CALL( pthread_mutex_destroy( &self->mtx ), 0 ); - return result; -} - -/** Lock mutex. - * - * We're disabling thread cancellation while the thread is holding a lock, so mutexes are - * properly unlocked at termination time. - */ -PaError PaUnixMutex_Lock( PaUnixMutex* self ) -{ - PaError result = paNoError; - -#ifdef PTHREAD_CANCEL - int oldState; - PA_ENSURE_SYSTEM( pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &oldState ), 0 ); -#endif - PA_ENSURE_SYSTEM( pthread_mutex_lock( &self->mtx ), 0 ); - -error: - return result; -} - -/** Unlock mutex. - * - * Thread cancellation is enabled again after the mutex is properly unlocked. - */ -PaError PaUnixMutex_Unlock( PaUnixMutex* self ) -{ - PaError result = paNoError; - - PA_ENSURE_SYSTEM( pthread_mutex_unlock( &self->mtx ), 0 ); -#ifdef PTHREAD_CANCEL - int oldState; - PA_ENSURE_SYSTEM( pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, &oldState ), 0 ); -#endif - -error: - return result; -} - - -#if 0 -static void OnWatchdogExit( void *userData ) -{ - PaAlsaThreading *th = (PaAlsaThreading *) userData; - struct sched_param spm = { 0 }; - assert( th ); - - PA_ASSERT_CALL( pthread_setschedparam( th->callbackThread, SCHED_OTHER, &spm ), 0 ); /* Lower before exiting */ - PA_DEBUG(( "Watchdog exiting\n" )); -} - -static void *WatchdogFunc( void *userData ) -{ - PaError result = paNoError, *pres = NULL; - int err; - PaAlsaThreading *th = (PaAlsaThreading *) userData; - unsigned intervalMsec = 500; - const PaTime maxSeconds = 3.; /* Max seconds between callbacks */ - PaTime timeThen = PaUtil_GetTime(), timeNow, timeElapsed, cpuTimeThen, cpuTimeNow, cpuTimeElapsed; - double cpuLoad, avgCpuLoad = 0.; - int throttled = 0; - - assert( th ); - - /* Execute OnWatchdogExit when exiting */ - pthread_cleanup_push( &OnWatchdogExit, th ); - - /* Boost priority of callback thread */ - PA_ENSURE( result = BoostPriority( th ) ); - if( !result ) - { - /* Boost failed, might as well exit */ - pthread_exit( NULL ); - } - - cpuTimeThen = th->callbackCpuTime; - { - int policy; - struct sched_param spm = { 0 }; - pthread_getschedparam( pthread_self(), &policy, &spm ); - PA_DEBUG(( "%s: Watchdog priority is %d\n", __FUNCTION__, spm.sched_priority )); - } - - while( 1 ) - { - double lowpassCoeff = 0.9, lowpassCoeff1 = 0.99999 - lowpassCoeff; - - /* Test before and after in case whatever underlying sleep call isn't interrupted by pthread_cancel */ - pthread_testcancel(); - Pa_Sleep( intervalMsec ); - pthread_testcancel(); - - if( PaUtil_GetTime() - th->callbackTime > maxSeconds ) - { - PA_DEBUG(( "Watchdog: Terminating callback thread\n" )); - /* Tell thread to terminate */ - err = pthread_kill( th->callbackThread, SIGKILL ); - pthread_exit( NULL ); - } - - PA_DEBUG(( "%s: PortAudio reports CPU load: %g\n", __FUNCTION__, PaUtil_GetCpuLoad( th->cpuLoadMeasurer ) )); - - /* Check if we should throttle, or unthrottle :P */ - cpuTimeNow = th->callbackCpuTime; - cpuTimeElapsed = cpuTimeNow - cpuTimeThen; - cpuTimeThen = cpuTimeNow; - - timeNow = PaUtil_GetTime(); - timeElapsed = timeNow - timeThen; - timeThen = timeNow; - cpuLoad = cpuTimeElapsed / timeElapsed; - avgCpuLoad = avgCpuLoad * lowpassCoeff + cpuLoad * lowpassCoeff1; - /* - if( throttled ) - PA_DEBUG(( "Watchdog: CPU load: %g, %g\n", avgCpuLoad, cpuTimeElapsed )); - */ - if( PaUtil_GetCpuLoad( th->cpuLoadMeasurer ) > .925 ) - { - static int policy; - static struct sched_param spm = { 0 }; - static const struct sched_param defaultSpm = { 0 }; - PA_DEBUG(( "%s: Throttling audio thread, priority %d\n", __FUNCTION__, spm.sched_priority )); - - pthread_getschedparam( th->callbackThread, &policy, &spm ); - if( !pthread_setschedparam( th->callbackThread, SCHED_OTHER, &defaultSpm ) ) - { - throttled = 1; - } - else - PA_DEBUG(( "Watchdog: Couldn't lower priority of audio thread: %s\n", strerror( errno ) )); - - /* Give other processes a go, before raising priority again */ - PA_DEBUG(( "%s: Watchdog sleeping for %lu msecs before unthrottling\n", __FUNCTION__, th->throttledSleepTime )); - Pa_Sleep( th->throttledSleepTime ); - - /* Reset callback priority */ - if( pthread_setschedparam( th->callbackThread, SCHED_FIFO, &spm ) != 0 ) - { - PA_DEBUG(( "%s: Couldn't raise priority of audio thread: %s\n", __FUNCTION__, strerror( errno ) )); - } - - if( PaUtil_GetCpuLoad( th->cpuLoadMeasurer ) >= .99 ) - intervalMsec = 50; - else - intervalMsec = 100; - - /* - lowpassCoeff = .97; - lowpassCoeff1 = .99999 - lowpassCoeff; - */ - } - else if( throttled && avgCpuLoad < .8 ) - { - intervalMsec = 500; - throttled = 0; - - /* - lowpassCoeff = .9; - lowpassCoeff1 = .99999 - lowpassCoeff; - */ - } - } - - pthread_cleanup_pop( 1 ); /* Execute cleanup on exit */ - -error: - /* Shouldn't get here in the normal case */ - - /* Pass on error code */ - pres = malloc( sizeof (PaError) ); - *pres = result; - - pthread_exit( pres ); -} - -static void CallbackUpdate( PaAlsaThreading *th ) -{ - th->callbackTime = PaUtil_GetTime(); - th->callbackCpuTime = PaUtil_GetCpuLoad( th->cpuLoadMeasurer ); -} - -/* -static void *CanaryFunc( void *userData ) -{ - const unsigned intervalMsec = 1000; - PaUtilThreading *th = (PaUtilThreading *) userData; - - while( 1 ) - { - th->canaryTime = PaUtil_GetTime(); - - pthread_testcancel(); - Pa_Sleep( intervalMsec ); - } - - pthread_exit( NULL ); -} -*/ -#endif diff --git a/portaudio/src/os/unix/pa_unix_util.h b/portaudio/src/os/unix/pa_unix_util.h deleted file mode 100644 index 2228cb3..0000000 --- a/portaudio/src/os/unix/pa_unix_util.h +++ /dev/null @@ -1,224 +0,0 @@ -/* - * $Id$ - * Portable Audio I/O Library - * UNIX platform-specific support functions - * - * Based on the Open Source API proposed by Ross Bencina - * Copyright (c) 1999-2000 Ross Bencina - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * The text above constitutes the entire PortAudio license; however, - * the PortAudio community also makes the following non-binding requests: - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. It is also - * requested that these non-binding requests be included along with the - * license above. - */ - -/** @file - @ingroup unix_src -*/ - -#ifndef PA_UNIX_UTIL_H -#define PA_UNIX_UTIL_H - -#include "pa_cpuload.h" -#include <assert.h> -#include <pthread.h> -#include <signal.h> - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - -#define PA_MIN(x,y) ( (x) < (y) ? (x) : (y) ) -#define PA_MAX(x,y) ( (x) > (y) ? (x) : (y) ) - -/* Utilize GCC branch prediction for error tests */ -#if defined __GNUC__ && __GNUC__ >= 3 -#define UNLIKELY(expr) __builtin_expect( (expr), 0 ) -#else -#define UNLIKELY(expr) (expr) -#endif - -#define STRINGIZE_HELPER(expr) #expr -#define STRINGIZE(expr) STRINGIZE_HELPER(expr) - -#define PA_UNLESS(expr, code) \ - do { \ - if( UNLIKELY( (expr) == 0 ) ) \ - { \ - PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \ - result = (code); \ - goto error; \ - } \ - } while (0); - -static PaError paUtilErr_; /* Used with PA_ENSURE */ - -/* Check PaError */ -#define PA_ENSURE(expr) \ - do { \ - if( UNLIKELY( (paUtilErr_ = (expr)) < paNoError ) ) \ - { \ - PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \ - result = paUtilErr_; \ - goto error; \ - } \ - } while (0); - -#define PA_ASSERT_CALL(expr, success) \ - paUtilErr_ = (expr); \ - assert( success == paUtilErr_ ); - -#define PA_ENSURE_SYSTEM(expr, success) \ - do { \ - if( UNLIKELY( (paUtilErr_ = (expr)) != success ) ) \ - { \ - /* PaUtil_SetLastHostErrorInfo should only be used in the main thread */ \ - if( pthread_equal(pthread_self(), paUnixMainThread) ) \ - { \ - PaUtil_SetLastHostErrorInfo( paALSA, paUtilErr_, strerror( paUtilErr_ ) ); \ - } \ - PaUtil_DebugPrint( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" ); \ - result = paUnanticipatedHostError; \ - goto error; \ - } \ - } while( 0 ); - -typedef struct { - pthread_t callbackThread; -} PaUtilThreading; - -PaError PaUtil_InitializeThreading( PaUtilThreading *threading ); -void PaUtil_TerminateThreading( PaUtilThreading *threading ); -PaError PaUtil_StartThreading( PaUtilThreading *threading, void *(*threadRoutine)(void *), void *data ); -PaError PaUtil_CancelThreading( PaUtilThreading *threading, int wait, PaError *exitResult ); - -/* State accessed by utility functions */ - -/* -void PaUnix_SetRealtimeScheduling( int rt ); - -void PaUtil_InitializeThreading( PaUtilThreading *th, PaUtilCpuLoadMeasurer *clm ); - -PaError PaUtil_CreateCallbackThread( PaUtilThreading *th, void *(*CallbackThreadFunc)( void * ), PaStream *s ); - -PaError PaUtil_KillCallbackThread( PaUtilThreading *th, PaError *exitResult ); - -void PaUtil_CallbackUpdate( PaUtilThreading *th ); -*/ - -extern pthread_t paUnixMainThread; - -typedef struct -{ - pthread_mutex_t mtx; -} PaUnixMutex; - -PaError PaUnixMutex_Initialize( PaUnixMutex* self ); -PaError PaUnixMutex_Terminate( PaUnixMutex* self ); -PaError PaUnixMutex_Lock( PaUnixMutex* self ); -PaError PaUnixMutex_Unlock( PaUnixMutex* self ); - -typedef struct -{ - pthread_t thread; - int parentWaiting; - int stopRequested; - int locked; - PaUnixMutex mtx; - pthread_cond_t cond; - volatile sig_atomic_t stopRequest; -} PaUnixThread; - -/** Initialize global threading state. - */ -PaError PaUnixThreading_Initialize( void ); - -/** Perish, passing on eventual error code. - * - * A thin wrapper around pthread_exit, will automatically pass on any error code to the joining thread. - * If the result indicates an error, i.e. it is not equal to paNoError, this function will automatically - * allocate a pointer so the error is passed on with pthread_exit. If the result indicates that all is - * well however, only a NULL pointer will be handed to pthread_exit. Thus, the joining thread should - * check whether a non-NULL result pointer is obtained from pthread_join and make sure to free it. - * @param result: The error code to pass on to the joining thread. - */ -#define PaUnixThreading_EXIT(result) \ - do { \ - PaError* pres = NULL; \ - if( paNoError != (result) ) \ - { \ - pres = malloc( sizeof (PaError) ); \ - *pres = (result); \ - } \ - pthread_exit( pres ); \ - } while (0); - -/** Spawn a thread. - * - * Intended for spawning the callback thread from the main thread. This function can even block (for a certain - * time or indefinitely) until notified by the callback thread (using PaUnixThread_NotifyParent), which can be - * useful in order to make sure that callback has commenced before returning from Pa_StartStream. - * @param threadFunc: The function to be executed in the child thread. - * @param waitForChild: If not 0, wait for child thread to call PaUnixThread_NotifyParent. Less than 0 means - * wait for ever, greater than 0 wait for the specified time. - * @param rtSched: Enable realtime scheduling? - * @return: If timed out waiting on child, paTimedOut. - */ -PaError PaUnixThread_New( PaUnixThread* self, void* (*threadFunc)( void* ), void* threadArg, PaTime waitForChild, - int rtSched ); - -/** Terminate thread. - * - * @param wait: If true, request that background thread stop and wait until it does, else cancel it. - * @param exitResult: If non-null this will upon return contain the exit status of the thread. - */ -PaError PaUnixThread_Terminate( PaUnixThread* self, int wait, PaError* exitResult ); - -/** Prepare to notify waiting parent thread. - * - * An internal lock must be held before the parent is notified in PaUnixThread_NotifyParent, call this to - * acquire it beforehand. - * @return: If parent is not waiting, paInternalError. - */ -PaError PaUnixThread_PrepareNotify( PaUnixThread* self ); - -/** Notify waiting parent thread. - * - * @return: If parent timed out waiting, paTimedOut. If parent was never waiting, paInternalError. - */ -PaError PaUnixThread_NotifyParent( PaUnixThread* self ); - -/** Has the parent thread requested this thread to stop? - */ -int PaUnixThread_StopRequested( PaUnixThread* self ); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif diff --git a/portaudio/src/os/win/pa_win_coinitialize.c b/portaudio/src/os/win/pa_win_coinitialize.c deleted file mode 100644 index cdb1fb9..0000000 --- a/portaudio/src/os/win/pa_win_coinitialize.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Microsoft COM initialization routines - * Copyright (c) 1999-2011 Ross Bencina, Dmitry Kostjuchenko - * - * Based on the Open Source API proposed by Ross Bencina - * Copyright (c) 1999-2011 Ross Bencina, Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * The text above constitutes the entire PortAudio license; however, - * the PortAudio community also makes the following non-binding requests: - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. It is also - * requested that these non-binding requests be included along with the - * license above. - */ - -/** @file - @ingroup win_src - - @brief Microsoft COM initialization routines. -*/ - -#include <windows.h> -#include <objbase.h> - -#include "portaudio.h" -#include "pa_util.h" -#include "pa_debugprint.h" - -#include "pa_win_coinitialize.h" - - -#if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) && !defined(_WIN32_WCE) && !(defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)) /* MSC version 6 and above */ -#pragma comment( lib, "ole32.lib" ) -#endif - - -/* use some special bit patterns here to try to guard against uninitialized memory errors */ -#define PAWINUTIL_COM_INITIALIZED (0xb38f) -#define PAWINUTIL_COM_NOT_INITIALIZED (0xf1cd) - - -PaError PaWinUtil_CoInitialize( PaHostApiTypeId hostApiType, PaWinUtilComInitializationResult *comInitializationResult ) -{ - HRESULT hr; - - comInitializationResult->state = PAWINUTIL_COM_NOT_INITIALIZED; - - /* - If COM is already initialized CoInitialize will either return - FALSE, or RPC_E_CHANGED_MODE if it was initialised in a different - threading mode. In either case we shouldn't consider it an error - but we need to be careful to not call CoUninitialize() if - RPC_E_CHANGED_MODE was returned. - */ - -#if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY != WINAPI_FAMILY_APP) - hr = CoInitialize(0); /* use legacy-safe equivalent to CoInitializeEx(NULL, COINIT_APARTMENTTHREADED) */ -#else - hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); -#endif - if( FAILED(hr) && hr != RPC_E_CHANGED_MODE ) - { - PA_DEBUG(("CoInitialize(0) failed. hr=%d\n", hr)); - - if( hr == E_OUTOFMEMORY ) - return paInsufficientMemory; - - { - char *lpMsgBuf; - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - hr, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &lpMsgBuf, - 0, - NULL - ); - PaUtil_SetLastHostErrorInfo( hostApiType, hr, lpMsgBuf ); - LocalFree( lpMsgBuf ); - } - - return paUnanticipatedHostError; - } - - if( hr != RPC_E_CHANGED_MODE ) - { - comInitializationResult->state = PAWINUTIL_COM_INITIALIZED; - - /* - Memorize calling thread id and report warning on Uninitialize if - calling thread is different as CoInitialize must match CoUninitialize - in the same thread. - */ - comInitializationResult->initializingThreadId = GetCurrentThreadId(); - } - - return paNoError; -} - - -void PaWinUtil_CoUninitialize( PaHostApiTypeId hostApiType, PaWinUtilComInitializationResult *comInitializationResult ) -{ - if( comInitializationResult->state != PAWINUTIL_COM_NOT_INITIALIZED - && comInitializationResult->state != PAWINUTIL_COM_INITIALIZED ){ - - PA_DEBUG(("ERROR: PaWinUtil_CoUninitialize called without calling PaWinUtil_CoInitialize\n")); - } - - if( comInitializationResult->state == PAWINUTIL_COM_INITIALIZED ) - { - DWORD currentThreadId = GetCurrentThreadId(); - if( comInitializationResult->initializingThreadId != currentThreadId ) - { - PA_DEBUG(("ERROR: failed PaWinUtil_CoUninitialize calling thread[%lu] does not match initializing thread[%lu]\n", - currentThreadId, comInitializationResult->initializingThreadId)); - } - else - { - CoUninitialize(); - - comInitializationResult->state = PAWINUTIL_COM_NOT_INITIALIZED; - } - } -} diff --git a/portaudio/src/os/win/pa_win_coinitialize.h b/portaudio/src/os/win/pa_win_coinitialize.h deleted file mode 100644 index deb60c3..0000000 --- a/portaudio/src/os/win/pa_win_coinitialize.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Microsoft COM initialization routines - * Copyright (c) 1999-2011 Ross Bencina, Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * The text above constitutes the entire PortAudio license; however, - * the PortAudio community also makes the following non-binding requests: - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. It is also - * requested that these non-binding requests be included along with the - * license above. - */ - -/** @file - @ingroup win_src - - @brief Microsoft COM initialization routines. -*/ - -#ifndef PA_WIN_COINITIALIZE_H -#define PA_WIN_COINITIALIZE_H - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - - -/** - @brief Data type used to hold the result of an attempt to initialize COM - using PaWinUtil_CoInitialize. Must be retained between a call to - PaWinUtil_CoInitialize and a matching call to PaWinUtil_CoUninitialize. -*/ -typedef struct PaWinUtilComInitializationResult{ - int state; - DWORD initializingThreadId; -} PaWinUtilComInitializationResult; - - -/** - @brief Initialize Microsoft COM subsystem on the current thread. - - @param hostApiType the host API type id of the caller. Used for error reporting. - - @param comInitializationResult An output parameter. The value pointed to by - this parameter stores information required by PaWinUtil_CoUninitialize - to correctly uninitialize COM. The value should be retained and later - passed to PaWinUtil_CoUninitialize. - - If PaWinUtil_CoInitialize returns paNoError, the caller must later call - PaWinUtil_CoUninitialize once. -*/ -PaError PaWinUtil_CoInitialize( PaHostApiTypeId hostApiType, PaWinUtilComInitializationResult *comInitializationResult ); - - -/** - @brief Uninitialize the Microsoft COM subsystem on the current thread using - the result of a previous call to PaWinUtil_CoInitialize. Must be called on the same - thread as PaWinUtil_CoInitialize. - - @param hostApiType the host API type id of the caller. Used for error reporting. - - @param comInitializationResult An input parameter. A pointer to a value previously - initialized by a call to PaWinUtil_CoInitialize. -*/ -void PaWinUtil_CoUninitialize( PaHostApiTypeId hostApiType, PaWinUtilComInitializationResult *comInitializationResult ); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* PA_WIN_COINITIALIZE_H */ diff --git a/portaudio/src/os/win/pa_win_hostapis.c b/portaudio/src/os/win/pa_win_hostapis.c deleted file mode 100644 index f8a4651..0000000 --- a/portaudio/src/os/win/pa_win_hostapis.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * $Id$ - * Portable Audio I/O Library Windows initialization table - * - * Based on the Open Source API proposed by Ross Bencina - * Copyright (c) 1999-2008 Ross Bencina, Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * The text above constitutes the entire PortAudio license; however, - * the PortAudio community also makes the following non-binding requests: - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. It is also - * requested that these non-binding requests be included along with the - * license above. - */ - -/** @file - @ingroup win_src - - @brief Win32 host API initialization function table. -*/ - -/* This is needed to make this source file depend on CMake option changes - and at the same time make it transparent for clients not using CMake. -*/ -#ifdef PORTAUDIO_CMAKE_GENERATED -#include "options_cmake.h" -#endif - -#include "pa_hostapi.h" - - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - -PaError PaSkeleton_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); -PaError PaWinMme_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); -PaError PaWinDs_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); -PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); -PaError PaWinWdm_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); -PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index ); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - -PaUtilHostApiInitializer *paHostApiInitializers[] = - { - -#if PA_USE_WMME - PaWinMme_Initialize, -#endif - -#if PA_USE_DS - PaWinDs_Initialize, -#endif - -#if PA_USE_ASIO - PaAsio_Initialize, -#endif - -#if PA_USE_WASAPI - PaWasapi_Initialize, -#endif - -#if PA_USE_WDMKS - PaWinWdm_Initialize, -#endif - -#if PA_USE_SKELETON - PaSkeleton_Initialize, /* just for testing. last in list so it isn't marked as default. */ -#endif - - 0 /* NULL terminated array */ - }; diff --git a/portaudio/src/os/win/pa_win_util.c b/portaudio/src/os/win/pa_win_util.c deleted file mode 100644 index b86f7af..0000000 --- a/portaudio/src/os/win/pa_win_util.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * $Id$ - * Portable Audio I/O Library - * Win32 platform-specific support functions - * - * Based on the Open Source API proposed by Ross Bencina - * Copyright (c) 1999-2008 Ross Bencina - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * The text above constitutes the entire PortAudio license; however, - * the PortAudio community also makes the following non-binding requests: - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. It is also - * requested that these non-binding requests be included along with the - * license above. - */ - -/** @file - @ingroup win_src - - @brief Win32 implementation of platform-specific PaUtil support functions. -*/ - -#include <windows.h> - -#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) - #include <sys/timeb.h> /* for _ftime_s() */ -#else - #include <mmsystem.h> /* for timeGetTime() */ - #if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) && !defined(_WIN32_WCE) /* MSC version 6 and above */ - #pragma comment( lib, "winmm.lib" ) - #endif -#endif - -#include "pa_util.h" - -/* - Track memory allocations to avoid leaks. - */ - -#if PA_TRACK_MEMORY -static int numAllocations_ = 0; -#endif - - -void *PaUtil_AllocateMemory( long size ) -{ - void *result = GlobalAlloc( GPTR, size ); - -#if PA_TRACK_MEMORY - if( result != NULL ) numAllocations_ += 1; -#endif - return result; -} - - -void PaUtil_FreeMemory( void *block ) -{ - if( block != NULL ) - { - GlobalFree( block ); -#if PA_TRACK_MEMORY - numAllocations_ -= 1; -#endif - - } -} - - -int PaUtil_CountCurrentlyAllocatedBlocks( void ) -{ -#if PA_TRACK_MEMORY - return numAllocations_; -#else - return 0; -#endif -} - - -void Pa_Sleep( long msec ) -{ - Sleep( msec ); -} - -static int usePerformanceCounter_; -static double secondsPerTick_; - -void PaUtil_InitializeClock( void ) -{ - LARGE_INTEGER ticksPerSecond; - - if( QueryPerformanceFrequency( &ticksPerSecond ) != 0 ) - { - usePerformanceCounter_ = 1; - secondsPerTick_ = 1.0 / (double)ticksPerSecond.QuadPart; - } - else - { - usePerformanceCounter_ = 0; - } -} - - -double PaUtil_GetTime( void ) -{ - LARGE_INTEGER time; - - if( usePerformanceCounter_ ) - { - /* - Note: QueryPerformanceCounter has a known issue where it can skip forward - by a few seconds (!) due to a hardware bug on some PCI-ISA bridge hardware. - This is documented here: - http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q274323& - - The work-arounds are not very paletable and involve querying GetTickCount - at every time step. - - Using rdtsc is not a good option on multi-core systems. - - For now we just use QueryPerformanceCounter(). It's good, most of the time. - */ - QueryPerformanceCounter( &time ); - return time.QuadPart * secondsPerTick_; - } - else - { -#ifndef UNDER_CE - #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) - return GetTickCount64() * .001; - #else - return timeGetTime() * .001; - #endif -#else - return GetTickCount() * .001; -#endif - } -} diff --git a/portaudio/src/os/win/pa_win_waveformat.c b/portaudio/src/os/win/pa_win_waveformat.c deleted file mode 100644 index 0436a39..0000000 --- a/portaudio/src/os/win/pa_win_waveformat.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * PortAudio Portable Real-Time Audio Library - * Windows WAVEFORMAT* data structure utilities - * portaudio.h should be included before this file. - * - * Copyright (c) 2007 Ross Bencina - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * The text above constitutes the entire PortAudio license; however, - * the PortAudio community also makes the following non-binding requests: - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. It is also - * requested that these non-binding requests be included along with the - * license above. - */ - -#include <windows.h> -#include <mmsystem.h> -#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) - #include <mmreg.h> /* for WAVEFORMATEX */ -#endif - -#include "portaudio.h" -#include "pa_win_waveformat.h" - - -#if !defined(WAVE_FORMAT_EXTENSIBLE) -#define WAVE_FORMAT_EXTENSIBLE 0xFFFE -#endif - - -static GUID pawin_ksDataFormatSubtypeGuidBase = - { (USHORT)(WAVE_FORMAT_PCM), 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }; - - -int PaWin_SampleFormatToLinearWaveFormatTag( PaSampleFormat sampleFormat ) -{ - if( sampleFormat == paFloat32 ) - return PAWIN_WAVE_FORMAT_IEEE_FLOAT; - - return PAWIN_WAVE_FORMAT_PCM; -} - - -void PaWin_InitializeWaveFormatEx( PaWinWaveFormat *waveFormat, - int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate ) -{ - WAVEFORMATEX *waveFormatEx = (WAVEFORMATEX*)waveFormat; - int bytesPerSample = Pa_GetSampleSize(sampleFormat); - unsigned long bytesPerFrame = numChannels * bytesPerSample; - - waveFormatEx->wFormatTag = waveFormatTag; - waveFormatEx->nChannels = (WORD)numChannels; - waveFormatEx->nSamplesPerSec = (DWORD)sampleRate; - waveFormatEx->nAvgBytesPerSec = waveFormatEx->nSamplesPerSec * bytesPerFrame; - waveFormatEx->nBlockAlign = (WORD)bytesPerFrame; - waveFormatEx->wBitsPerSample = bytesPerSample * 8; - waveFormatEx->cbSize = 0; -} - - -void PaWin_InitializeWaveFormatExtensible( PaWinWaveFormat *waveFormat, - int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate, - PaWinWaveFormatChannelMask channelMask ) -{ - WAVEFORMATEX *waveFormatEx = (WAVEFORMATEX*)waveFormat; - int bytesPerSample = Pa_GetSampleSize(sampleFormat); - unsigned long bytesPerFrame = numChannels * bytesPerSample; - GUID guid; - - waveFormatEx->wFormatTag = WAVE_FORMAT_EXTENSIBLE; - waveFormatEx->nChannels = (WORD)numChannels; - waveFormatEx->nSamplesPerSec = (DWORD)sampleRate; - waveFormatEx->nAvgBytesPerSec = waveFormatEx->nSamplesPerSec * bytesPerFrame; - waveFormatEx->nBlockAlign = (WORD)bytesPerFrame; - waveFormatEx->wBitsPerSample = bytesPerSample * 8; - waveFormatEx->cbSize = 22; - - memcpy(&waveFormat->fields[PAWIN_INDEXOF_WVALIDBITSPERSAMPLE], - &waveFormatEx->wBitsPerSample, sizeof(WORD)); - - memcpy(&waveFormat->fields[PAWIN_INDEXOF_DWCHANNELMASK], - &channelMask, sizeof(DWORD)); - - guid = pawin_ksDataFormatSubtypeGuidBase; - guid.Data1 = (USHORT)waveFormatTag; - memcpy(&waveFormat->fields[PAWIN_INDEXOF_SUBFORMAT], &guid, sizeof(GUID)); -} - -PaWinWaveFormatChannelMask PaWin_DefaultChannelMask( int numChannels ) -{ - switch( numChannels ){ - case 1: - return PAWIN_SPEAKER_MONO; - case 2: - return PAWIN_SPEAKER_STEREO; - case 3: - return PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_FRONT_RIGHT; - case 4: - return PAWIN_SPEAKER_QUAD; - case 5: - return PAWIN_SPEAKER_QUAD | PAWIN_SPEAKER_FRONT_CENTER; - case 6: - /* The meaning of the PAWIN_SPEAKER_5POINT1 flag has changed over time: - http://msdn2.microsoft.com/en-us/library/aa474707.aspx - We use PAWIN_SPEAKER_5POINT1 (not PAWIN_SPEAKER_5POINT1_SURROUND) - because on some cards (eg Audigy) PAWIN_SPEAKER_5POINT1_SURROUND - results in a virtual mixdown placing the rear output in the - front _and_ rear speakers. - */ - return PAWIN_SPEAKER_5POINT1; - /* case 7: */ - case 8: - /* RoBi: PAWIN_SPEAKER_7POINT1_SURROUND fits normal surround sound setups better than PAWIN_SPEAKER_7POINT1, f.i. NVidia HDMI Audio - output is silent on channels 5&6 with NVidia drivers, and channel 7&8 with Microsoft HD Audio driver using PAWIN_SPEAKER_7POINT1. - With PAWIN_SPEAKER_7POINT1_SURROUND both setups work OK. */ - return PAWIN_SPEAKER_7POINT1_SURROUND; - } - - /* Apparently some Audigy drivers will output silence - if the direct-out constant (0) is used. So this is not ideal. - - RoBi 2012-12-19: Also, NVidia driver seem to output garbage instead. Again not very ideal. - */ - return PAWIN_SPEAKER_DIRECTOUT; - - /* Note that Alec Rogers proposed the following as an alternate method to - generate the default channel mask, however it doesn't seem to be an improvement - over the above, since some drivers will matrix outputs mapping to non-present - speakers across multiple physical speakers. - - if(nChannels==1) { - pwfFormat->dwChannelMask = SPEAKER_FRONT_CENTER; - } - else { - pwfFormat->dwChannelMask = 0; - for(i=0; i<nChannels; i++) - pwfFormat->dwChannelMask = (pwfFormat->dwChannelMask << 1) | 0x1; - } - */ -} diff --git a/portaudio/src/os/win/pa_win_wdmks_utils.c b/portaudio/src/os/win/pa_win_wdmks_utils.c deleted file mode 100644 index 3373146..0000000 --- a/portaudio/src/os/win/pa_win_wdmks_utils.c +++ /dev/null @@ -1,309 +0,0 @@ -/* - * PortAudio Portable Real-Time Audio Library - * Windows WDM KS utilities - * - * Copyright (c) 1999 - 2007 Andrew Baldwin, Ross Bencina - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * The text above constitutes the entire PortAudio license; however, - * the PortAudio community also makes the following non-binding requests: - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. It is also - * requested that these non-binding requests be included along with the - * license above. - */ - -#include <windows.h> -#include <mmreg.h> -#ifndef WAVE_FORMAT_IEEE_FLOAT - #define WAVE_FORMAT_IEEE_FLOAT 0x0003 // MinGW32 does not define this -#endif -#ifndef _WAVEFORMATEXTENSIBLE_ - #define _WAVEFORMATEXTENSIBLE_ // MinGW32 does not define this -#endif -#ifndef _INC_MMREG - #define _INC_MMREG // for STATIC_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT -#endif -#include <winioctl.h> // MinGW32 does not define this automatically - -#if defined(__GNUC__) - -#include "../../hostapi/wasapi/mingw-include/ks.h" -#include "../../hostapi/wasapi/mingw-include/ksmedia.h" - -#else - -#include <ks.h> -#include <ksmedia.h> - -#endif - -#include <stdio.h> // just for some development printfs - -#include "portaudio.h" -#include "pa_util.h" -#include "pa_win_wdmks_utils.h" - - -/* PortAudio-local instances of GUIDs previously sourced from ksguid.lib */ - -/* GUID KSDATAFORMAT_TYPE_AUDIO */ -static const GUID pa_KSDATAFORMAT_TYPE_AUDIO = { STATIC_KSDATAFORMAT_TYPE_AUDIO }; - -/* GUID KSDATAFORMAT_SUBTYPE_IEEE_FLOAT */ -static const GUID pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { STATIC_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT }; - -/* GUID KSDATAFORMAT_SUBTYPE_PCM */ -static const GUID pa_KSDATAFORMAT_SUBTYPE_PCM = { STATIC_KSDATAFORMAT_SUBTYPE_PCM }; - -/* GUID KSDATAFORMAT_SUBTYPE_WAVEFORMATEX */ -static const GUID pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX = { STATIC_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX }; - -/* GUID KSMEDIUMSETID_Standard */ -static const GUID pa_KSMEDIUMSETID_Standard = { STATIC_KSMEDIUMSETID_Standard }; - -/* GUID KSINTERFACESETID_Standard */ -static const GUID pa_KSINTERFACESETID_Standard = { STATIC_KSINTERFACESETID_Standard }; - -/* GUID KSPROPSETID_Pin */ -static const GUID pa_KSPROPSETID_Pin = { STATIC_KSPROPSETID_Pin }; - -#define pa_IS_VALID_WAVEFORMATEX_GUID(Guid)\ - (!memcmp(((PUSHORT)&pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX) + 1, ((PUSHORT)(Guid)) + 1, sizeof(GUID) - sizeof(USHORT))) - - -static PaError WdmGetPinPropertySimple( - HANDLE handle, - unsigned long pinId, - unsigned long property, - void* value, - unsigned long valueSize ) -{ - DWORD bytesReturned; - KSP_PIN ksPProp; - ksPProp.Property.Set = pa_KSPROPSETID_Pin; - ksPProp.Property.Id = property; - ksPProp.Property.Flags = KSPROPERTY_TYPE_GET; - ksPProp.PinId = pinId; - ksPProp.Reserved = 0; - - if( DeviceIoControl( handle, IOCTL_KS_PROPERTY, &ksPProp, sizeof(KSP_PIN), - value, valueSize, &bytesReturned, NULL ) == 0 || bytesReturned != valueSize ) - { - return paUnanticipatedHostError; - } - else - { - return paNoError; - } -} - - -static PaError WdmGetPinPropertyMulti( - HANDLE handle, - unsigned long pinId, - unsigned long property, - KSMULTIPLE_ITEM** ksMultipleItem) -{ - unsigned long multipleItemSize = 0; - KSP_PIN ksPProp; - DWORD bytesReturned; - - *ksMultipleItem = 0; - - ksPProp.Property.Set = pa_KSPROPSETID_Pin; - ksPProp.Property.Id = property; - ksPProp.Property.Flags = KSPROPERTY_TYPE_GET; - ksPProp.PinId = pinId; - ksPProp.Reserved = 0; - - if( DeviceIoControl( handle, IOCTL_KS_PROPERTY, &ksPProp.Property, - sizeof(KSP_PIN), NULL, 0, &multipleItemSize, NULL ) == 0 && GetLastError() != ERROR_MORE_DATA ) - { - return paUnanticipatedHostError; - } - - *ksMultipleItem = (KSMULTIPLE_ITEM*)PaUtil_AllocateMemory( multipleItemSize ); - if( !*ksMultipleItem ) - { - return paInsufficientMemory; - } - - if( DeviceIoControl( handle, IOCTL_KS_PROPERTY, &ksPProp, sizeof(KSP_PIN), - (void*)*ksMultipleItem, multipleItemSize, &bytesReturned, NULL ) == 0 || bytesReturned != multipleItemSize ) - { - PaUtil_FreeMemory( ksMultipleItem ); - return paUnanticipatedHostError; - } - - return paNoError; -} - - -static int GetKSFilterPinCount( HANDLE deviceHandle ) -{ - DWORD result; - - if( WdmGetPinPropertySimple( deviceHandle, 0, KSPROPERTY_PIN_CTYPES, &result, sizeof(result) ) == paNoError ){ - return result; - }else{ - return 0; - } -} - - -static KSPIN_COMMUNICATION GetKSFilterPinPropertyCommunication( HANDLE deviceHandle, int pinId ) -{ - KSPIN_COMMUNICATION result; - - if( WdmGetPinPropertySimple( deviceHandle, pinId, KSPROPERTY_PIN_COMMUNICATION, &result, sizeof(result) ) == paNoError ){ - return result; - }else{ - return KSPIN_COMMUNICATION_NONE; - } -} - - -static KSPIN_DATAFLOW GetKSFilterPinPropertyDataflow( HANDLE deviceHandle, int pinId ) -{ - KSPIN_DATAFLOW result; - - if( WdmGetPinPropertySimple( deviceHandle, pinId, KSPROPERTY_PIN_DATAFLOW, &result, sizeof(result) ) == paNoError ){ - return result; - }else{ - return (KSPIN_DATAFLOW)0; - } -} - - -static int KSFilterPinPropertyIdentifiersInclude( - HANDLE deviceHandle, int pinId, unsigned long property, const GUID *identifierSet, unsigned long identifierId ) -{ - KSMULTIPLE_ITEM* item = NULL; - KSIDENTIFIER* identifier; - int i; - int result = 0; - - if( WdmGetPinPropertyMulti( deviceHandle, pinId, property, &item) != paNoError ) - return 0; - - identifier = (KSIDENTIFIER*)(item+1); - - for( i = 0; i < (int)item->Count; i++ ) - { - if( !memcmp( (void*)&identifier[i].Set, (void*)identifierSet, sizeof( GUID ) ) && - ( identifier[i].Id == identifierId ) ) - { - result = 1; - break; - } - } - - PaUtil_FreeMemory( item ); - - return result; -} - - -/* return the maximum channel count supported by any pin on the device. - if isInput is non-zero we query input pins, otherwise output pins. -*/ -int PaWin_WDMKS_QueryFilterMaximumChannelCount( void *wcharDevicePath, int isInput ) -{ - HANDLE deviceHandle; - ULONG i; - int pinCount, pinId; - int result = 0; - KSPIN_DATAFLOW requiredDataflowDirection = (isInput ? KSPIN_DATAFLOW_OUT : KSPIN_DATAFLOW_IN ); - - if( !wcharDevicePath ) - return 0; - - deviceHandle = CreateFileW( (LPCWSTR)wcharDevicePath, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL ); - if( deviceHandle == INVALID_HANDLE_VALUE ) - return 0; - - pinCount = GetKSFilterPinCount( deviceHandle ); - for( pinId = 0; pinId < pinCount; ++pinId ) - { - KSPIN_COMMUNICATION communication = GetKSFilterPinPropertyCommunication( deviceHandle, pinId ); - KSPIN_DATAFLOW dataflow = GetKSFilterPinPropertyDataflow( deviceHandle, pinId ); - if( ( dataflow == requiredDataflowDirection ) && - (( communication == KSPIN_COMMUNICATION_SINK) || - ( communication == KSPIN_COMMUNICATION_BOTH)) - && ( KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId, - KSPROPERTY_PIN_INTERFACES, &pa_KSINTERFACESETID_Standard, KSINTERFACE_STANDARD_STREAMING ) - || KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId, - KSPROPERTY_PIN_INTERFACES, &pa_KSINTERFACESETID_Standard, KSINTERFACE_STANDARD_LOOPED_STREAMING ) ) - && KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId, - KSPROPERTY_PIN_MEDIUMS, &pa_KSMEDIUMSETID_Standard, KSMEDIUM_STANDARD_DEVIO ) ) - { - KSMULTIPLE_ITEM* item = NULL; - if( WdmGetPinPropertyMulti( deviceHandle, pinId, KSPROPERTY_PIN_DATARANGES, &item ) == paNoError ) - { - KSDATARANGE *dataRange = (KSDATARANGE*)(item+1); - - for( i=0; i < item->Count; ++i ){ - - if( pa_IS_VALID_WAVEFORMATEX_GUID(&dataRange->SubFormat) - || memcmp( (void*)&dataRange->SubFormat, (void*)&pa_KSDATAFORMAT_SUBTYPE_PCM, sizeof(GUID) ) == 0 - || memcmp( (void*)&dataRange->SubFormat, (void*)&pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, sizeof(GUID) ) == 0 - || ( ( memcmp( (void*)&dataRange->MajorFormat, (void*)&pa_KSDATAFORMAT_TYPE_AUDIO, sizeof(GUID) ) == 0 ) - && ( memcmp( (void*)&dataRange->SubFormat, (void*)&KSDATAFORMAT_SUBTYPE_WILDCARD, sizeof(GUID) ) == 0 ) ) ) - { - KSDATARANGE_AUDIO *dataRangeAudio = (KSDATARANGE_AUDIO*)dataRange; - - /* - printf( ">>> %d %d %d %d %S\n", isInput, dataflow, communication, dataRangeAudio->MaximumChannels, devicePath ); - - if( memcmp((void*)&dataRange->Specifier, (void*)&KSDATAFORMAT_SPECIFIER_WAVEFORMATEX, sizeof(GUID) ) == 0 ) - printf( "\tspecifier: KSDATAFORMAT_SPECIFIER_WAVEFORMATEX\n" ); - else if( memcmp((void*)&dataRange->Specifier, (void*)&KSDATAFORMAT_SPECIFIER_DSOUND, sizeof(GUID) ) == 0 ) - printf( "\tspecifier: KSDATAFORMAT_SPECIFIER_DSOUND\n" ); - else if( memcmp((void*)&dataRange->Specifier, (void*)&KSDATAFORMAT_SPECIFIER_WILDCARD, sizeof(GUID) ) == 0 ) - printf( "\tspecifier: KSDATAFORMAT_SPECIFIER_WILDCARD\n" ); - else - printf( "\tspecifier: ?\n" ); - */ - - /* - We assume that very high values for MaximumChannels are not useful and indicate - that the driver isn't prepared to tell us the real number of channels which it supports. - */ - if( dataRangeAudio->MaximumChannels < 0xFFFFUL && (int)dataRangeAudio->MaximumChannels > result ) - result = (int)dataRangeAudio->MaximumChannels; - } - - dataRange = (KSDATARANGE*)( ((char*)dataRange) + dataRange->FormatSize); - } - - PaUtil_FreeMemory( item ); - } - } - } - - CloseHandle( deviceHandle ); - return result; -} diff --git a/portaudio/src/os/win/pa_win_wdmks_utils.h b/portaudio/src/os/win/pa_win_wdmks_utils.h deleted file mode 100644 index f524cf7..0000000 --- a/portaudio/src/os/win/pa_win_wdmks_utils.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef PA_WIN_WDMKS_UTILS_H -#define PA_WIN_WDMKS_UTILS_H - -/* - * PortAudio Portable Real-Time Audio Library - * Windows WDM KS utilities - * - * Copyright (c) 1999 - 2007 Ross Bencina, Andrew Baldwin - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * The text above constitutes the entire PortAudio license; however, - * the PortAudio community also makes the following non-binding requests: - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. It is also - * requested that these non-binding requests be included along with the - * license above. - */ - -/** @file - @brief Utilities for working with the Windows WDM KS API -*/ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - Query for the maximum number of channels supported by any pin of the - specified device. Returns 0 if the query fails for any reason. - - @param wcharDevicePath A system level PnP interface path, supplied as a WCHAR unicode string. - Declared as void* to avoid introducing a dependency on wchar_t here. - - @param isInput A flag specifying whether to query for input (non-zero) or output (zero) channels. -*/ -int PaWin_WDMKS_QueryFilterMaximumChannelCount( void *wcharDevicePath, int isInput ); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* PA_WIN_WDMKS_UTILS_H */ diff --git a/portaudio/src/os/win/pa_x86_plain_converters.c b/portaudio/src/os/win/pa_x86_plain_converters.c deleted file mode 100644 index 1096994..0000000 --- a/portaudio/src/os/win/pa_x86_plain_converters.c +++ /dev/null @@ -1,1218 +0,0 @@ -/* - * Plain Intel IA32 assembly implementations of PortAudio sample converter functions. - * Copyright (c) 1999-2002 Ross Bencina, Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * The text above constitutes the entire PortAudio license; however, - * the PortAudio community also makes the following non-binding requests: - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. It is also - * requested that these non-binding requests be included along with the - * license above. - */ - -/** @file - @ingroup win_src -*/ - -#include "pa_x86_plain_converters.h" - -#include "pa_converters.h" -#include "pa_dither.h" - -/* - the main reason these versions are faster than the equivalent C versions - is that float -> int casting is expensive in C on x86 because the rounding - mode needs to be changed for every cast. these versions only set - the rounding mode once outside the loop. - - small additional speed gains are made by the way that clamping is - implemented. - -TODO: - o- inline dither code - o- implement Dither only (no-clip) versions - o- implement int8 and uint8 versions - o- test thoroughly - - o- the packed 24 bit functions could benefit from unrolling and avoiding - byte and word sized register access. -*/ - -/* -------------------------------------------------------------------------- */ - -/* -#define PA_CLIP_( val, min, max )\ - { val = ((val) < (min)) ? (min) : (((val) > (max)) ? (max) : (val)); } -*/ - -/* - the following notes were used to determine whether a floating point - value should be saturated (ie >1 or <-1) by loading it into an integer - register. these should be rewritten so that they make sense. - - an ieee floating point value - - 1.xxxxxxxxxxxxxxxxxxxx? - - - is less than or equal to 1 and greater than or equal to -1 either: - - if the mantissa is 0 and the unbiased exponent is 0 - - OR - - if the unbiased exponent < 0 - - this translates to: - - if the mantissa is 0 and the biased exponent is 7F - - or - - if the biased exponent is less than 7F - - - therefore the value is greater than 1 or less than -1 if - - the mantissa is not 0 and the biased exponent is 7F - - or - - if the biased exponent is greater than 7F - - - in other words, if we mask out the sign bit, the value is - greater than 1 or less than -1 if its integer representation is greater than: - - 0 01111111 0000 0000 0000 0000 0000 000 - - 0011 1111 1000 0000 0000 0000 0000 0000 => 0x3F800000 -*/ - -#if defined(_WIN64) || defined(_WIN32_WCE) - -/* - -EMT64/AMD64 uses different asm - -VC2005 doesn't allow _WIN64 with inline assembly either! - */ -void PaUtil_InitializeX86PlainConverters( void ) -{ -} - -#else - -/* -------------------------------------------------------------------------- */ - -static const short fpuControlWord_ = 0x033F; /*round to nearest, 64 bit precision, all exceptions masked*/ -static const double int32Scaler_ = 0x7FFFFFFF; -static const double ditheredInt32Scaler_ = 0x7FFFFFFE; -static const double int24Scaler_ = 0x7FFFFF; -static const double ditheredInt24Scaler_ = 0x7FFFFE; -static const double int16Scaler_ = 0x7FFF; -static const double ditheredInt16Scaler_ = 0x7FFE; - -#define PA_DITHER_BITS_ (15) -/* Multiply by PA_FLOAT_DITHER_SCALE_ to get a float between -2.0 and +1.99999 */ -#define PA_FLOAT_DITHER_SCALE_ (1.0F / ((1<<PA_DITHER_BITS_)-1)) -static const float const_float_dither_scale_ = PA_FLOAT_DITHER_SCALE_; -#define PA_DITHER_SHIFT_ ((32 - PA_DITHER_BITS_) + 1) - -/* -------------------------------------------------------------------------- */ - -static void Float32_To_Int32( - void *destinationBuffer, signed int destinationStride, - void *sourceBuffer, signed int sourceStride, - unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator ) -{ -/* - float *src = (float*)sourceBuffer; - signed long *dest = (signed long*)destinationBuffer; - (void)ditherGenerator; // unused parameter - - while( count-- ) - { - // REVIEW - double scaled = *src * 0x7FFFFFFF; - *dest = (signed long) scaled; - - src += sourceStride; - dest += destinationStride; - } -*/ - - short savedFpuControlWord; - - (void) ditherGenerator; /* unused parameter */ - - - __asm{ - // esi -> source ptr - // eax -> source byte stride - // edi -> destination ptr - // ebx -> destination byte stride - // ecx -> source end ptr - // edx -> temp - - mov esi, sourceBuffer - - mov edx, 4 // sizeof float32 and int32 - mov eax, sourceStride - imul eax, edx - - mov ecx, count - imul ecx, eax - add ecx, esi - - mov edi, destinationBuffer - - mov ebx, destinationStride - imul ebx, edx - - fwait - fstcw savedFpuControlWord - fldcw fpuControlWord_ - - fld int32Scaler_ // stack: (int)0x7FFFFFFF - - Float32_To_Int32_loop: - - // load unscaled value into st(0) - fld dword ptr [esi] // stack: value, (int)0x7FFFFFFF - add esi, eax // increment source ptr - //lea esi, [esi+eax] - fmul st(0), st(1) // st(0) *= st(1), stack: value*0x7FFFFFFF, (int)0x7FFFFFFF - /* - note: we could store to a temporary qword here which would cause - wraparound distortion instead of int indefinite 0x10. that would - be more work, and given that not enabling clipping is only advisable - when you know that your signal isn't going to clip it isn't worth it. - */ - fistp dword ptr [edi] // pop st(0) into dest, stack: (int)0x7FFFFFFF - - add edi, ebx // increment destination ptr - //lea edi, [edi+ebx] - - cmp esi, ecx // has src ptr reached end? - jne Float32_To_Int32_loop - - ffree st(0) - fincstp - - fwait - fnclex - fldcw savedFpuControlWord - } -} - -/* -------------------------------------------------------------------------- */ - -static void Float32_To_Int32_Clip( - void *destinationBuffer, signed int destinationStride, - void *sourceBuffer, signed int sourceStride, - unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator ) -{ -/* - float *src = (float*)sourceBuffer; - signed long *dest = (signed long*)destinationBuffer; - (void) ditherGenerator; // unused parameter - - while( count-- ) - { - // REVIEW - double scaled = *src * 0x7FFFFFFF; - PA_CLIP_( scaled, -2147483648., 2147483647. ); - *dest = (signed long) scaled; - - src += sourceStride; - dest += destinationStride; - } -*/ - - short savedFpuControlWord; - - (void) ditherGenerator; /* unused parameter */ - - __asm{ - // esi -> source ptr - // eax -> source byte stride - // edi -> destination ptr - // ebx -> destination byte stride - // ecx -> source end ptr - // edx -> temp - - mov esi, sourceBuffer - - mov edx, 4 // sizeof float32 and int32 - mov eax, sourceStride - imul eax, edx - - mov ecx, count - imul ecx, eax - add ecx, esi - - mov edi, destinationBuffer - - mov ebx, destinationStride - imul ebx, edx - - fwait - fstcw savedFpuControlWord - fldcw fpuControlWord_ - - fld int32Scaler_ // stack: (int)0x7FFFFFFF - - Float32_To_Int32_Clip_loop: - - mov edx, dword ptr [esi] // load floating point value into integer register - - and edx, 0x7FFFFFFF // mask off sign - cmp edx, 0x3F800000 // greater than 1.0 or less than -1.0 - - jg Float32_To_Int32_Clip_clamp - - // load unscaled value into st(0) - fld dword ptr [esi] // stack: value, (int)0x7FFFFFFF - add esi, eax // increment source ptr - //lea esi, [esi+eax] - fmul st(0), st(1) // st(0) *= st(1), stack: value*0x7FFFFFFF, (int)0x7FFFFFFF - fistp dword ptr [edi] // pop st(0) into dest, stack: (int)0x7FFFFFFF - jmp Float32_To_Int32_Clip_stored - - Float32_To_Int32_Clip_clamp: - mov edx, dword ptr [esi] // load floating point value into integer register - shr edx, 31 // move sign bit into bit 0 - add esi, eax // increment source ptr - //lea esi, [esi+eax] - add edx, 0x7FFFFFFF // convert to maximum range integers - mov dword ptr [edi], edx - - Float32_To_Int32_Clip_stored: - - //add edi, ebx // increment destination ptr - lea edi, [edi+ebx] - - cmp esi, ecx // has src ptr reached end? - jne Float32_To_Int32_Clip_loop - - ffree st(0) - fincstp - - fwait - fnclex - fldcw savedFpuControlWord - } -} - -/* -------------------------------------------------------------------------- */ - -static void Float32_To_Int32_DitherClip( - void *destinationBuffer, signed int destinationStride, - void *sourceBuffer, signed int sourceStride, - unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator ) -{ - /* - float *src = (float*)sourceBuffer; - signed long *dest = (signed long*)destinationBuffer; - - while( count-- ) - { - // REVIEW - double dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); - // use smaller scaler to prevent overflow when we add the dither - double dithered = ((double)*src * (2147483646.0)) + dither; - PA_CLIP_( dithered, -2147483648., 2147483647. ); - *dest = (signed long) dithered; - - - src += sourceStride; - dest += destinationStride; - } - */ - - short savedFpuControlWord; - - // spill storage: - signed long sourceByteStride; - signed long highpassedDither; - - // dither state: - unsigned long ditherPrevious = ditherGenerator->previous; - unsigned long ditherRandSeed1 = ditherGenerator->randSeed1; - unsigned long ditherRandSeed2 = ditherGenerator->randSeed2; - - __asm{ - // esi -> source ptr - // eax -> source byte stride - // edi -> destination ptr - // ebx -> destination byte stride - // ecx -> source end ptr - // edx -> temp - - mov esi, sourceBuffer - - mov edx, 4 // sizeof float32 and int32 - mov eax, sourceStride - imul eax, edx - - mov ecx, count - imul ecx, eax - add ecx, esi - - mov edi, destinationBuffer - - mov ebx, destinationStride - imul ebx, edx - - fwait - fstcw savedFpuControlWord - fldcw fpuControlWord_ - - fld ditheredInt32Scaler_ // stack: int scaler - - Float32_To_Int32_DitherClip_loop: - - mov edx, dword ptr [esi] // load floating point value into integer register - - and edx, 0x7FFFFFFF // mask off sign - cmp edx, 0x3F800000 // greater than 1.0 or less than -1.0 - - jg Float32_To_Int32_DitherClip_clamp - - // load unscaled value into st(0) - fld dword ptr [esi] // stack: value, int scaler - add esi, eax // increment source ptr - //lea esi, [esi+eax] - fmul st(0), st(1) // st(0) *= st(1), stack: value*(int scaler), int scaler - - /* - // call PaUtil_GenerateFloatTriangularDither with C calling convention - mov sourceByteStride, eax // save eax - mov sourceEnd, ecx // save ecx - push ditherGenerator // pass ditherGenerator parameter on stack - call PaUtil_GenerateFloatTriangularDither // stack: dither, value*(int scaler), int scaler - pop edx // clear parameter off stack - mov ecx, sourceEnd // restore ecx - mov eax, sourceByteStride // restore eax - */ - - // generate dither - mov sourceByteStride, eax // save eax - mov edx, 196314165 - mov eax, ditherRandSeed1 - mul edx // eax:edx = eax * 196314165 - //add eax, 907633515 - lea eax, [eax+907633515] - mov ditherRandSeed1, eax - mov edx, 196314165 - mov eax, ditherRandSeed2 - mul edx // eax:edx = eax * 196314165 - //add eax, 907633515 - lea eax, [eax+907633515] - mov edx, ditherRandSeed1 - shr edx, PA_DITHER_SHIFT_ - mov ditherRandSeed2, eax - shr eax, PA_DITHER_SHIFT_ - //add eax, edx // eax -> current - lea eax, [eax+edx] - mov edx, ditherPrevious - neg edx - lea edx, [eax+edx] // highpass = current - previous - mov highpassedDither, edx - mov ditherPrevious, eax // previous = current - mov eax, sourceByteStride // restore eax - fild highpassedDither - fmul const_float_dither_scale_ - // end generate dither, dither signal in st(0) - - faddp st(1), st(0) // stack: dither + value*(int scaler), int scaler - fistp dword ptr [edi] // pop st(0) into dest, stack: int scaler - jmp Float32_To_Int32_DitherClip_stored - - Float32_To_Int32_DitherClip_clamp: - mov edx, dword ptr [esi] // load floating point value into integer register - shr edx, 31 // move sign bit into bit 0 - add esi, eax // increment source ptr - //lea esi, [esi+eax] - add edx, 0x7FFFFFFF // convert to maximum range integers - mov dword ptr [edi], edx - - Float32_To_Int32_DitherClip_stored: - - //add edi, ebx // increment destination ptr - lea edi, [edi+ebx] - - cmp esi, ecx // has src ptr reached end? - jne Float32_To_Int32_DitherClip_loop - - ffree st(0) - fincstp - - fwait - fnclex - fldcw savedFpuControlWord - } - - ditherGenerator->previous = ditherPrevious; - ditherGenerator->randSeed1 = ditherRandSeed1; - ditherGenerator->randSeed2 = ditherRandSeed2; -} - -/* -------------------------------------------------------------------------- */ - -static void Float32_To_Int24( - void *destinationBuffer, signed int destinationStride, - void *sourceBuffer, signed int sourceStride, - unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator ) -{ -/* - float *src = (float*)sourceBuffer; - unsigned char *dest = (unsigned char*)destinationBuffer; - signed long temp; - - (void) ditherGenerator; // unused parameter - - while( count-- ) - { - // convert to 32 bit and drop the low 8 bits - double scaled = *src * 0x7FFFFFFF; - temp = (signed long) scaled; - - dest[0] = (unsigned char)(temp >> 8); - dest[1] = (unsigned char)(temp >> 16); - dest[2] = (unsigned char)(temp >> 24); - - src += sourceStride; - dest += destinationStride * 3; - } -*/ - - short savedFpuControlWord; - - signed long tempInt32; - - (void) ditherGenerator; /* unused parameter */ - - __asm{ - // esi -> source ptr - // eax -> source byte stride - // edi -> destination ptr - // ebx -> destination byte stride - // ecx -> source end ptr - // edx -> temp - - mov esi, sourceBuffer - - mov edx, 4 // sizeof float32 - mov eax, sourceStride - imul eax, edx - - mov ecx, count - imul ecx, eax - add ecx, esi - - mov edi, destinationBuffer - - mov edx, 3 // sizeof int24 - mov ebx, destinationStride - imul ebx, edx - - fwait - fstcw savedFpuControlWord - fldcw fpuControlWord_ - - fld int24Scaler_ // stack: (int)0x7FFFFF - - Float32_To_Int24_loop: - - // load unscaled value into st(0) - fld dword ptr [esi] // stack: value, (int)0x7FFFFF - add esi, eax // increment source ptr - //lea esi, [esi+eax] - fmul st(0), st(1) // st(0) *= st(1), stack: value*0x7FFFFF, (int)0x7FFFFF - fistp tempInt32 // pop st(0) into tempInt32, stack: (int)0x7FFFFF - mov edx, tempInt32 - - mov byte ptr [edi], DL - shr edx, 8 - //mov byte ptr [edi+1], DL - //mov byte ptr [edi+2], DH - mov word ptr [edi+1], DX - - //add edi, ebx // increment destination ptr - lea edi, [edi+ebx] - - cmp esi, ecx // has src ptr reached end? - jne Float32_To_Int24_loop - - ffree st(0) - fincstp - - fwait - fnclex - fldcw savedFpuControlWord - } -} - -/* -------------------------------------------------------------------------- */ - -static void Float32_To_Int24_Clip( - void *destinationBuffer, signed int destinationStride, - void *sourceBuffer, signed int sourceStride, - unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator ) -{ -/* - float *src = (float*)sourceBuffer; - unsigned char *dest = (unsigned char*)destinationBuffer; - signed long temp; - - (void) ditherGenerator; // unused parameter - - while( count-- ) - { - // convert to 32 bit and drop the low 8 bits - double scaled = *src * 0x7FFFFFFF; - PA_CLIP_( scaled, -2147483648., 2147483647. ); - temp = (signed long) scaled; - - dest[0] = (unsigned char)(temp >> 8); - dest[1] = (unsigned char)(temp >> 16); - dest[2] = (unsigned char)(temp >> 24); - - src += sourceStride; - dest += destinationStride * 3; - } -*/ - - short savedFpuControlWord; - - signed long tempInt32; - - (void) ditherGenerator; /* unused parameter */ - - __asm{ - // esi -> source ptr - // eax -> source byte stride - // edi -> destination ptr - // ebx -> destination byte stride - // ecx -> source end ptr - // edx -> temp - - mov esi, sourceBuffer - - mov edx, 4 // sizeof float32 - mov eax, sourceStride - imul eax, edx - - mov ecx, count - imul ecx, eax - add ecx, esi - - mov edi, destinationBuffer - - mov edx, 3 // sizeof int24 - mov ebx, destinationStride - imul ebx, edx - - fwait - fstcw savedFpuControlWord - fldcw fpuControlWord_ - - fld int24Scaler_ // stack: (int)0x7FFFFF - - Float32_To_Int24_Clip_loop: - - mov edx, dword ptr [esi] // load floating point value into integer register - - and edx, 0x7FFFFFFF // mask off sign - cmp edx, 0x3F800000 // greater than 1.0 or less than -1.0 - - jg Float32_To_Int24_Clip_clamp - - // load unscaled value into st(0) - fld dword ptr [esi] // stack: value, (int)0x7FFFFF - add esi, eax // increment source ptr - //lea esi, [esi+eax] - fmul st(0), st(1) // st(0) *= st(1), stack: value*0x7FFFFF, (int)0x7FFFFF - fistp tempInt32 // pop st(0) into tempInt32, stack: (int)0x7FFFFF - mov edx, tempInt32 - jmp Float32_To_Int24_Clip_store - - Float32_To_Int24_Clip_clamp: - mov edx, dword ptr [esi] // load floating point value into integer register - shr edx, 31 // move sign bit into bit 0 - add esi, eax // increment source ptr - //lea esi, [esi+eax] - add edx, 0x7FFFFF // convert to maximum range integers - - Float32_To_Int24_Clip_store: - - mov byte ptr [edi], DL - shr edx, 8 - //mov byte ptr [edi+1], DL - //mov byte ptr [edi+2], DH - mov word ptr [edi+1], DX - - //add edi, ebx // increment destination ptr - lea edi, [edi+ebx] - - cmp esi, ecx // has src ptr reached end? - jne Float32_To_Int24_Clip_loop - - ffree st(0) - fincstp - - fwait - fnclex - fldcw savedFpuControlWord - } -} - -/* -------------------------------------------------------------------------- */ - -static void Float32_To_Int24_DitherClip( - void *destinationBuffer, signed int destinationStride, - void *sourceBuffer, signed int sourceStride, - unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator ) -{ -/* - float *src = (float*)sourceBuffer; - unsigned char *dest = (unsigned char*)destinationBuffer; - signed long temp; - - while( count-- ) - { - // convert to 32 bit and drop the low 8 bits - - // FIXME: the dither amplitude here appears to be too small by 8 bits - double dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); - // use smaller scaler to prevent overflow when we add the dither - double dithered = ((double)*src * (2147483646.0)) + dither; - PA_CLIP_( dithered, -2147483648., 2147483647. ); - - temp = (signed long) dithered; - - dest[0] = (unsigned char)(temp >> 8); - dest[1] = (unsigned char)(temp >> 16); - dest[2] = (unsigned char)(temp >> 24); - - src += sourceStride; - dest += destinationStride * 3; - } -*/ - - short savedFpuControlWord; - - // spill storage: - signed long sourceByteStride; - signed long highpassedDither; - - // dither state: - unsigned long ditherPrevious = ditherGenerator->previous; - unsigned long ditherRandSeed1 = ditherGenerator->randSeed1; - unsigned long ditherRandSeed2 = ditherGenerator->randSeed2; - - signed long tempInt32; - - __asm{ - // esi -> source ptr - // eax -> source byte stride - // edi -> destination ptr - // ebx -> destination byte stride - // ecx -> source end ptr - // edx -> temp - - mov esi, sourceBuffer - - mov edx, 4 // sizeof float32 - mov eax, sourceStride - imul eax, edx - - mov ecx, count - imul ecx, eax - add ecx, esi - - mov edi, destinationBuffer - - mov edx, 3 // sizeof int24 - mov ebx, destinationStride - imul ebx, edx - - fwait - fstcw savedFpuControlWord - fldcw fpuControlWord_ - - fld ditheredInt24Scaler_ // stack: int scaler - - Float32_To_Int24_DitherClip_loop: - - mov edx, dword ptr [esi] // load floating point value into integer register - - and edx, 0x7FFFFFFF // mask off sign - cmp edx, 0x3F800000 // greater than 1.0 or less than -1.0 - - jg Float32_To_Int24_DitherClip_clamp - - // load unscaled value into st(0) - fld dword ptr [esi] // stack: value, int scaler - add esi, eax // increment source ptr - //lea esi, [esi+eax] - fmul st(0), st(1) // st(0) *= st(1), stack: value*(int scaler), int scaler - - /* - // call PaUtil_GenerateFloatTriangularDither with C calling convention - mov sourceByteStride, eax // save eax - mov sourceEnd, ecx // save ecx - push ditherGenerator // pass ditherGenerator parameter on stack - call PaUtil_GenerateFloatTriangularDither // stack: dither, value*(int scaler), int scaler - pop edx // clear parameter off stack - mov ecx, sourceEnd // restore ecx - mov eax, sourceByteStride // restore eax - */ - - // generate dither - mov sourceByteStride, eax // save eax - mov edx, 196314165 - mov eax, ditherRandSeed1 - mul edx // eax:edx = eax * 196314165 - //add eax, 907633515 - lea eax, [eax+907633515] - mov ditherRandSeed1, eax - mov edx, 196314165 - mov eax, ditherRandSeed2 - mul edx // eax:edx = eax * 196314165 - //add eax, 907633515 - lea eax, [eax+907633515] - mov edx, ditherRandSeed1 - shr edx, PA_DITHER_SHIFT_ - mov ditherRandSeed2, eax - shr eax, PA_DITHER_SHIFT_ - //add eax, edx // eax -> current - lea eax, [eax+edx] - mov edx, ditherPrevious - neg edx - lea edx, [eax+edx] // highpass = current - previous - mov highpassedDither, edx - mov ditherPrevious, eax // previous = current - mov eax, sourceByteStride // restore eax - fild highpassedDither - fmul const_float_dither_scale_ - // end generate dither, dither signal in st(0) - - faddp st(1), st(0) // stack: dither * value*(int scaler), int scaler - fistp tempInt32 // pop st(0) into tempInt32, stack: int scaler - mov edx, tempInt32 - jmp Float32_To_Int24_DitherClip_store - - Float32_To_Int24_DitherClip_clamp: - mov edx, dword ptr [esi] // load floating point value into integer register - shr edx, 31 // move sign bit into bit 0 - add esi, eax // increment source ptr - //lea esi, [esi+eax] - add edx, 0x7FFFFF // convert to maximum range integers - - Float32_To_Int24_DitherClip_store: - - mov byte ptr [edi], DL - shr edx, 8 - //mov byte ptr [edi+1], DL - //mov byte ptr [edi+2], DH - mov word ptr [edi+1], DX - - //add edi, ebx // increment destination ptr - lea edi, [edi+ebx] - - cmp esi, ecx // has src ptr reached end? - jne Float32_To_Int24_DitherClip_loop - - ffree st(0) - fincstp - - fwait - fnclex - fldcw savedFpuControlWord - } - - ditherGenerator->previous = ditherPrevious; - ditherGenerator->randSeed1 = ditherRandSeed1; - ditherGenerator->randSeed2 = ditherRandSeed2; -} - -/* -------------------------------------------------------------------------- */ - -static void Float32_To_Int16( - void *destinationBuffer, signed int destinationStride, - void *sourceBuffer, signed int sourceStride, - unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator ) -{ -/* - float *src = (float*)sourceBuffer; - signed short *dest = (signed short*)destinationBuffer; - (void)ditherGenerator; // unused parameter - - while( count-- ) - { - - short samp = (short) (*src * (32767.0f)); - *dest = samp; - - src += sourceStride; - dest += destinationStride; - } -*/ - - short savedFpuControlWord; - - (void) ditherGenerator; /* unused parameter */ - - __asm{ - // esi -> source ptr - // eax -> source byte stride - // edi -> destination ptr - // ebx -> destination byte stride - // ecx -> source end ptr - // edx -> temp - - mov esi, sourceBuffer - - mov edx, 4 // sizeof float32 - mov eax, sourceStride - imul eax, edx // source byte stride - - mov ecx, count - imul ecx, eax - add ecx, esi // source end ptr = count * source byte stride + source ptr - - mov edi, destinationBuffer - - mov edx, 2 // sizeof int16 - mov ebx, destinationStride - imul ebx, edx // destination byte stride - - fwait - fstcw savedFpuControlWord - fldcw fpuControlWord_ - - fld int16Scaler_ // stack: (int)0x7FFF - - Float32_To_Int16_loop: - - // load unscaled value into st(0) - fld dword ptr [esi] // stack: value, (int)0x7FFF - add esi, eax // increment source ptr - //lea esi, [esi+eax] - fmul st(0), st(1) // st(0) *= st(1), stack: value*0x7FFF, (int)0x7FFF - fistp word ptr [edi] // store scaled int into dest, stack: (int)0x7FFF - - add edi, ebx // increment destination ptr - //lea edi, [edi+ebx] - - cmp esi, ecx // has src ptr reached end? - jne Float32_To_Int16_loop - - ffree st(0) - fincstp - - fwait - fnclex - fldcw savedFpuControlWord - } -} - -/* -------------------------------------------------------------------------- */ - -static void Float32_To_Int16_Clip( - void *destinationBuffer, signed int destinationStride, - void *sourceBuffer, signed int sourceStride, - unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator ) -{ -/* - float *src = (float*)sourceBuffer; - signed short *dest = (signed short*)destinationBuffer; - (void)ditherGenerator; // unused parameter - - while( count-- ) - { - long samp = (signed long) (*src * (32767.0f)); - PA_CLIP_( samp, -0x8000, 0x7FFF ); - *dest = (signed short) samp; - - src += sourceStride; - dest += destinationStride; - } -*/ - - short savedFpuControlWord; - - (void) ditherGenerator; /* unused parameter */ - - __asm{ - // esi -> source ptr - // eax -> source byte stride - // edi -> destination ptr - // ebx -> destination byte stride - // ecx -> source end ptr - // edx -> temp - - mov esi, sourceBuffer - - mov edx, 4 // sizeof float32 - mov eax, sourceStride - imul eax, edx // source byte stride - - mov ecx, count - imul ecx, eax - add ecx, esi // source end ptr = count * source byte stride + source ptr - - mov edi, destinationBuffer - - mov edx, 2 // sizeof int16 - mov ebx, destinationStride - imul ebx, edx // destination byte stride - - fwait - fstcw savedFpuControlWord - fldcw fpuControlWord_ - - fld int16Scaler_ // stack: (int)0x7FFF - - Float32_To_Int16_Clip_loop: - - mov edx, dword ptr [esi] // load floating point value into integer register - - and edx, 0x7FFFFFFF // mask off sign - cmp edx, 0x3F800000 // greater than 1.0 or less than -1.0 - - jg Float32_To_Int16_Clip_clamp - - // load unscaled value into st(0) - fld dword ptr [esi] // stack: value, (int)0x7FFF - add esi, eax // increment source ptr - //lea esi, [esi+eax] - fmul st(0), st(1) // st(0) *= st(1), stack: value*0x7FFF, (int)0x7FFF - fistp word ptr [edi] // store scaled int into dest, stack: (int)0x7FFF - jmp Float32_To_Int16_Clip_stored - - Float32_To_Int16_Clip_clamp: - mov edx, dword ptr [esi] // load floating point value into integer register - shr edx, 31 // move sign bit into bit 0 - add esi, eax // increment source ptr - //lea esi, [esi+eax] - add dx, 0x7FFF // convert to maximum range integers - mov word ptr [edi], dx // store clamped into into dest - - Float32_To_Int16_Clip_stored: - - add edi, ebx // increment destination ptr - //lea edi, [edi+ebx] - - cmp esi, ecx // has src ptr reached end? - jne Float32_To_Int16_Clip_loop - - ffree st(0) - fincstp - - fwait - fnclex - fldcw savedFpuControlWord - } -} - -/* -------------------------------------------------------------------------- */ - -static void Float32_To_Int16_DitherClip( - void *destinationBuffer, signed int destinationStride, - void *sourceBuffer, signed int sourceStride, - unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator ) -{ -/* - float *src = (float*)sourceBuffer; - signed short *dest = (signed short*)destinationBuffer; - (void)ditherGenerator; // unused parameter - - while( count-- ) - { - - float dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator ); - // use smaller scaler to prevent overflow when we add the dither - float dithered = (*src * (32766.0f)) + dither; - signed long samp = (signed long) dithered; - PA_CLIP_( samp, -0x8000, 0x7FFF ); - *dest = (signed short) samp; - - src += sourceStride; - dest += destinationStride; - } -*/ - - short savedFpuControlWord; - - // spill storage: - signed long sourceByteStride; - signed long highpassedDither; - - // dither state: - unsigned long ditherPrevious = ditherGenerator->previous; - unsigned long ditherRandSeed1 = ditherGenerator->randSeed1; - unsigned long ditherRandSeed2 = ditherGenerator->randSeed2; - - __asm{ - // esi -> source ptr - // eax -> source byte stride - // edi -> destination ptr - // ebx -> destination byte stride - // ecx -> source end ptr - // edx -> temp - - mov esi, sourceBuffer - - mov edx, 4 // sizeof float32 - mov eax, sourceStride - imul eax, edx // source byte stride - - mov ecx, count - imul ecx, eax - add ecx, esi // source end ptr = count * source byte stride + source ptr - - mov edi, destinationBuffer - - mov edx, 2 // sizeof int16 - mov ebx, destinationStride - imul ebx, edx // destination byte stride - - fwait - fstcw savedFpuControlWord - fldcw fpuControlWord_ - - fld ditheredInt16Scaler_ // stack: int scaler - - Float32_To_Int16_DitherClip_loop: - - mov edx, dword ptr [esi] // load floating point value into integer register - - and edx, 0x7FFFFFFF // mask off sign - cmp edx, 0x3F800000 // greater than 1.0 or less than -1.0 - - jg Float32_To_Int16_DitherClip_clamp - - // load unscaled value into st(0) - fld dword ptr [esi] // stack: value, int scaler - add esi, eax // increment source ptr - //lea esi, [esi+eax] - fmul st(0), st(1) // st(0) *= st(1), stack: value*(int scaler), int scaler - - /* - // call PaUtil_GenerateFloatTriangularDither with C calling convention - mov sourceByteStride, eax // save eax - mov sourceEnd, ecx // save ecx - push ditherGenerator // pass ditherGenerator parameter on stack - call PaUtil_GenerateFloatTriangularDither // stack: dither, value*(int scaler), int scaler - pop edx // clear parameter off stack - mov ecx, sourceEnd // restore ecx - mov eax, sourceByteStride // restore eax - */ - - // generate dither - mov sourceByteStride, eax // save eax - mov edx, 196314165 - mov eax, ditherRandSeed1 - mul edx // eax:edx = eax * 196314165 - //add eax, 907633515 - lea eax, [eax+907633515] - mov ditherRandSeed1, eax - mov edx, 196314165 - mov eax, ditherRandSeed2 - mul edx // eax:edx = eax * 196314165 - //add eax, 907633515 - lea eax, [eax+907633515] - mov edx, ditherRandSeed1 - shr edx, PA_DITHER_SHIFT_ - mov ditherRandSeed2, eax - shr eax, PA_DITHER_SHIFT_ - //add eax, edx // eax -> current - lea eax, [eax+edx] // current = randSeed1>>x + randSeed2>>x - mov edx, ditherPrevious - neg edx - lea edx, [eax+edx] // highpass = current - previous - mov highpassedDither, edx - mov ditherPrevious, eax // previous = current - mov eax, sourceByteStride // restore eax - fild highpassedDither - fmul const_float_dither_scale_ - // end generate dither, dither signal in st(0) - - faddp st(1), st(0) // stack: dither * value*(int scaler), int scaler - fistp word ptr [edi] // store scaled int into dest, stack: int scaler - jmp Float32_To_Int16_DitherClip_stored - - Float32_To_Int16_DitherClip_clamp: - mov edx, dword ptr [esi] // load floating point value into integer register - shr edx, 31 // move sign bit into bit 0 - add esi, eax // increment source ptr - //lea esi, [esi+eax] - add dx, 0x7FFF // convert to maximum range integers - mov word ptr [edi], dx // store clamped into into dest - - Float32_To_Int16_DitherClip_stored: - - add edi, ebx // increment destination ptr - //lea edi, [edi+ebx] - - cmp esi, ecx // has src ptr reached end? - jne Float32_To_Int16_DitherClip_loop - - ffree st(0) - fincstp - - fwait - fnclex - fldcw savedFpuControlWord - } - - ditherGenerator->previous = ditherPrevious; - ditherGenerator->randSeed1 = ditherRandSeed1; - ditherGenerator->randSeed2 = ditherRandSeed2; -} - -/* -------------------------------------------------------------------------- */ - -void PaUtil_InitializeX86PlainConverters( void ) -{ - paConverters.Float32_To_Int32 = Float32_To_Int32; - paConverters.Float32_To_Int32_Clip = Float32_To_Int32_Clip; - paConverters.Float32_To_Int32_DitherClip = Float32_To_Int32_DitherClip; - - paConverters.Float32_To_Int24 = Float32_To_Int24; - paConverters.Float32_To_Int24_Clip = Float32_To_Int24_Clip; - paConverters.Float32_To_Int24_DitherClip = Float32_To_Int24_DitherClip; - - paConverters.Float32_To_Int16 = Float32_To_Int16; - paConverters.Float32_To_Int16_Clip = Float32_To_Int16_Clip; - paConverters.Float32_To_Int16_DitherClip = Float32_To_Int16_DitherClip; -} - -#endif - -/* -------------------------------------------------------------------------- */ diff --git a/portaudio/src/os/win/pa_x86_plain_converters.h b/portaudio/src/os/win/pa_x86_plain_converters.h deleted file mode 100644 index 8914ed1..0000000 --- a/portaudio/src/os/win/pa_x86_plain_converters.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Plain Intel IA32 assembly implementations of PortAudio sample converter functions. - * Copyright (c) 1999-2002 Ross Bencina, Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * The text above constitutes the entire PortAudio license; however, - * the PortAudio community also makes the following non-binding requests: - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. It is also - * requested that these non-binding requests be included along with the - * license above. - */ - -/** @file - @ingroup win_src -*/ - -#ifndef PA_X86_PLAIN_CONVERTERS_H -#define PA_X86_PLAIN_CONVERTERS_H - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - - -/** - @brief Install optimized converter functions suitable for all IA32 processors - - It is recommended to call PaUtil_InitializeX86PlainConverters prior to calling Pa_Initialize -*/ -void PaUtil_InitializeX86PlainConverters( void ); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* PA_X86_PLAIN_CONVERTERS_H */ |