mirror of
https://github.com/cookiengineer/audacity
synced 2025-12-23 17:11:13 +01:00
Here we go, update portaudio-v19 to current upstream SVN (revision 1541), should all be working ...
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: pa_unix_util.c,v 1.11 2008-12-31 15:38:36 richardash1981 Exp $
|
||||
* $Id: pa_unix_util.c 1510 2010-06-10 08:05:29Z dmitrykos $
|
||||
* Portable Audio I/O Library
|
||||
* UNIX platform-specific support functions
|
||||
*
|
||||
@@ -51,6 +51,13 @@
|
||||
#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"
|
||||
@@ -118,27 +125,47 @@ void Pa_Sleep( long msec )
|
||||
#endif
|
||||
}
|
||||
|
||||
/* *** NOT USED YET: ***
|
||||
static int usePerformanceCounter_;
|
||||
static double microsecondsPerTick_;
|
||||
#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 )
|
||||
{
|
||||
/* TODO */
|
||||
#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_CLOCK_GETTIME
|
||||
#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 / 1.e9);
|
||||
return (PaTime)(tp.tv_sec + tp.tv_nsec * 1e-9);
|
||||
#else
|
||||
struct timeval tv;
|
||||
gettimeofday( &tv, NULL );
|
||||
return (PaTime) tv.tv_usec / 1000000. + tv.tv_sec;
|
||||
return (PaTime) tv.tv_usec * 1e-6 + tv.tv_sec;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -166,9 +193,15 @@ PaError PaUtil_CancelThreading( PaUtilThreading *threading, int wait, PaError *e
|
||||
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
|
||||
@@ -190,7 +223,7 @@ PaError PaUtil_CancelThreading( PaUtilThreading *threading, int wait, PaError *e
|
||||
/* paUnixMainThread
|
||||
* We have to be a bit careful with defining this global variable,
|
||||
* as explained below. */
|
||||
#ifdef __apple__
|
||||
#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:
|
||||
@@ -400,12 +433,19 @@ PaError PaUnixThread_Terminate( PaUnixThread* self, int wait, PaError* exitResul
|
||||
{
|
||||
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 )
|
||||
{
|
||||
@@ -479,9 +519,11 @@ PaError PaUnixMutex_Terminate( PaUnixMutex* self )
|
||||
PaError PaUnixMutex_Lock( PaUnixMutex* self )
|
||||
{
|
||||
PaError result = paNoError;
|
||||
int oldState;
|
||||
|
||||
#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:
|
||||
@@ -495,10 +537,12 @@ error:
|
||||
PaError PaUnixMutex_Unlock( PaUnixMutex* self )
|
||||
{
|
||||
PaError result = paNoError;
|
||||
int oldState;
|
||||
|
||||
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;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: pa_win_hostapis.c,v 1.8 2008-12-31 15:38:36 richardash1981 Exp $
|
||||
* $Id: pa_win_hostapis.c 1453 2010-02-16 09:46:08Z dmitrykos $
|
||||
* Portable Audio I/O Library Windows initialization table
|
||||
*
|
||||
* Based on the Open Source API proposed by Ross Bencina
|
||||
@@ -58,7 +58,7 @@ PaError PaWinMme_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
|
||||
PaError PaWinDs_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
|
||||
PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
|
||||
PaError PaWinWdm_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
|
||||
PaError PaWinWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
|
||||
PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
@@ -80,17 +80,17 @@ PaUtilHostApiInitializer *paHostApiInitializers[] =
|
||||
PaAsio_Initialize,
|
||||
#endif
|
||||
|
||||
/*
|
||||
#ifndef PA_NO_WASAPI
|
||||
PaWinWasapi_Initialize,
|
||||
PaWasapi_Initialize,
|
||||
#endif
|
||||
|
||||
/*
|
||||
#ifndef PA_NO_WDMKS
|
||||
PaWinWdm_Initialize,
|
||||
#endif
|
||||
*/
|
||||
|
||||
PaSkeleton_Initialize, /* just for testing */
|
||||
//PaSkeleton_Initialize, /* just for testing */
|
||||
|
||||
0 /* NULL terminated array */
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: pa_win_util.c,v 1.9 2009-05-25 21:40:17 richardash1981 Exp $
|
||||
* $Id: pa_win_util.c 1437 2009-12-10 08:10:08Z rossb $
|
||||
* Portable Audio I/O Library
|
||||
* Win32 platform-specific support functions
|
||||
*
|
||||
@@ -51,7 +51,7 @@
|
||||
|
||||
#include "pa_util.h"
|
||||
|
||||
#if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) /* MSC version 6 and above */
|
||||
#if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) && !defined(_WIN32_WCE) /* MSC version 6 and above */
|
||||
#pragma comment( lib, "winmm.lib" )
|
||||
#endif
|
||||
|
||||
|
||||
@@ -25,27 +25,62 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* 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
|
||||
* 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
|
||||
#include <ks.h>
|
||||
#include <ksmedia.h>
|
||||
#include <stdio.h> // just for some development printfs
|
||||
#include <stddef.h>
|
||||
#include <stdio.h> // just for some development printfs
|
||||
|
||||
#include "portaudio.h"
|
||||
#include "pa_util.h"
|
||||
#include "pa_win_wdmks_utils.h"
|
||||
|
||||
#if !defined(PA_WDMKS_NO_KSGUID_LIB) && !defined(PAWIN_WDMKS_NO_KSGUID_LIB)
|
||||
#if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) /* MSC version 6 and above */
|
||||
#pragma comment( lib, "ksguid.lib" )
|
||||
#endif
|
||||
#define pa_KSDATAFORMAT_TYPE_AUDIO KSDATAFORMAT_TYPE_AUDIO
|
||||
#define pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
|
||||
#define pa_KSDATAFORMAT_SUBTYPE_PCM KSDATAFORMAT_SUBTYPE_PCM
|
||||
#define pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX KSDATAFORMAT_SUBTYPE_WAVEFORMATEX
|
||||
#define pa_KSMEDIUMSETID_Standard KSMEDIUMSETID_Standard
|
||||
#define pa_KSINTERFACESETID_Standard KSINTERFACESETID_Standard
|
||||
#define pa_KSPROPSETID_Pin KSPROPSETID_Pin
|
||||
#else
|
||||
static const GUID pa_KSDATAFORMAT_TYPE_AUDIO = { STATIC_KSDATAFORMAT_TYPE_AUDIO };
|
||||
static const GUID pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { STATIC_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT };
|
||||
static const GUID pa_KSDATAFORMAT_SUBTYPE_PCM = { STATIC_KSDATAFORMAT_SUBTYPE_PCM };
|
||||
static const GUID pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX = { STATIC_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX };
|
||||
static const GUID pa_KSMEDIUMSETID_Standard = { STATIC_KSMEDIUMSETID_Standard };
|
||||
static const GUID pa_KSINTERFACESETID_Standard = { STATIC_KSINTERFACESETID_Standard };
|
||||
static const GUID pa_KSPROPSETID_Pin = { STATIC_KSPROPSETID_Pin };
|
||||
#endif
|
||||
|
||||
|
||||
#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,
|
||||
@@ -56,7 +91,7 @@ static PaError WdmGetPinPropertySimple(
|
||||
{
|
||||
DWORD bytesReturned;
|
||||
KSP_PIN ksPProp;
|
||||
ksPProp.Property.Set = KSPROPSETID_Pin;
|
||||
ksPProp.Property.Set = pa_KSPROPSETID_Pin;
|
||||
ksPProp.Property.Id = property;
|
||||
ksPProp.Property.Flags = KSPROPERTY_TYPE_GET;
|
||||
ksPProp.PinId = pinId;
|
||||
@@ -86,7 +121,7 @@ static PaError WdmGetPinPropertyMulti(
|
||||
|
||||
*ksMultipleItem = 0;
|
||||
|
||||
ksPProp.Property.Set = KSPROPSETID_Pin;
|
||||
ksPProp.Property.Set = pa_KSPROPSETID_Pin;
|
||||
ksPProp.Property.Id = property;
|
||||
ksPProp.Property.Flags = KSPROPERTY_TYPE_GET;
|
||||
ksPProp.PinId = pinId;
|
||||
@@ -151,20 +186,20 @@ static KSPIN_DATAFLOW GetKSFilterPinPropertyDataflow( HANDLE deviceHandle, int p
|
||||
}
|
||||
|
||||
|
||||
static int KSFilterPinPropertyIdentifiersInclude(
|
||||
static int KSFilterPinPropertyIdentifiersInclude(
|
||||
HANDLE deviceHandle, int pinId, unsigned long property, const GUID *identifierSet, unsigned long identifierId )
|
||||
{
|
||||
KSMULTIPLE_ITEM* item = NULL;
|
||||
KSIDENTIFIER* identifier;
|
||||
size_t i;
|
||||
int i;
|
||||
int result = 0;
|
||||
|
||||
if( WdmGetPinPropertyMulti( deviceHandle, pinId, property, &item) != paNoError )
|
||||
return 0;
|
||||
|
||||
|
||||
identifier = (KSIDENTIFIER*)(item+1);
|
||||
|
||||
for( i = 0; i < item->Count; i++ )
|
||||
for( i = 0; i < (int)item->Count; i++ )
|
||||
{
|
||||
if( !memcmp( (void*)&identifier[i].Set, (void*)identifierSet, sizeof( GUID ) ) &&
|
||||
( identifier[i].Id == identifierId ) )
|
||||
@@ -180,17 +215,17 @@ static int KSFilterPinPropertyIdentifiersInclude(
|
||||
}
|
||||
|
||||
|
||||
/* return the maximum channel count supported by any pin on the device.
|
||||
/* 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;
|
||||
size_t i;
|
||||
KSPIN_DATAFLOW requiredDataflowDirection = (isInput ? KSPIN_DATAFLOW_OUT : KSPIN_DATAFLOW_IN );
|
||||
|
||||
|
||||
if( !wcharDevicePath )
|
||||
return 0;
|
||||
|
||||
@@ -205,13 +240,13 @@ int PaWin_WDMKS_QueryFilterMaximumChannelCount( void *wcharDevicePath, int isInp
|
||||
KSPIN_DATAFLOW dataflow = GetKSFilterPinPropertyDataflow( deviceHandle, pinId );
|
||||
if( ( dataflow == requiredDataflowDirection ) &&
|
||||
(( communication == KSPIN_COMMUNICATION_SINK) ||
|
||||
( communication == KSPIN_COMMUNICATION_BOTH))
|
||||
&& ( KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId,
|
||||
KSPROPERTY_PIN_INTERFACES, &KSINTERFACESETID_Standard, KSINTERFACE_STANDARD_STREAMING )
|
||||
|| KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId,
|
||||
KSPROPERTY_PIN_INTERFACES, &KSINTERFACESETID_Standard, KSINTERFACE_STANDARD_LOOPED_STREAMING ) )
|
||||
&& KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId,
|
||||
KSPROPERTY_PIN_MEDIUMS, &KSMEDIUMSETID_Standard, KSMEDIUM_STANDARD_DEVIO ) )
|
||||
( 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 )
|
||||
@@ -220,17 +255,17 @@ int PaWin_WDMKS_QueryFilterMaximumChannelCount( void *wcharDevicePath, int isInp
|
||||
|
||||
for( i=0; i < item->Count; ++i ){
|
||||
|
||||
if( IS_VALID_WAVEFORMATEX_GUID(&dataRange->SubFormat)
|
||||
|| memcmp( (void*)&dataRange->SubFormat, (void*)&KSDATAFORMAT_SUBTYPE_PCM, sizeof(GUID) ) == 0
|
||||
|| memcmp( (void*)&dataRange->SubFormat, (void*)&KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, sizeof(GUID) ) == 0
|
||||
|| ( ( memcmp( (void*)&dataRange->MajorFormat, (void*)&KSDATAFORMAT_TYPE_AUDIO, sizeof(GUID) ) == 0 )
|
||||
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 )
|
||||
@@ -248,7 +283,7 @@ int PaWin_WDMKS_QueryFilterMaximumChannelCount( void *wcharDevicePath, int isInp
|
||||
if( dataRangeAudio->MaximumChannels < 0xFFFFUL && (int)dataRangeAudio->MaximumChannels > result )
|
||||
result = (int)dataRangeAudio->MaximumChannels;
|
||||
}
|
||||
|
||||
|
||||
dataRange = (KSDATARANGE*)( ((char*)dataRange) + dataRange->FormatSize);
|
||||
}
|
||||
|
||||
@@ -256,7 +291,7 @@ int PaWin_WDMKS_QueryFilterMaximumChannelCount( void *wcharDevicePath, int isInp
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CloseHandle( deviceHandle );
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ static const float const_float_dither_scale_ = PA_FLOAT_DITHER_SCALE_;
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#ifdef _WIN64
|
||||
#if defined(_WIN64) || defined(_WIN32_WCE)
|
||||
|
||||
/*
|
||||
-EMT64/AMD64 uses different asm
|
||||
|
||||
Reference in New Issue
Block a user