* Clean up whitespace in src/os/win in preparation for .editorconfig. Convert tabs to 4 spaces. Indent by 4 spaces. Strip trailing whitespace. Ensure EOL at EOF.
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
+ 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);
+ hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
#endif
if( FAILED(hr) && 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
+ 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();
{
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();
+ 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;
- }
+ }
}
-}
\ No newline at end of file
+}
*/
/*
- * 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.
*/
/**
@brief Data type used to hold the result of an attempt to initialize COM
- using PaWinUtil_CoInitialize. Must be retained between a call to
+ using PaWinUtil_CoInitialize. Must be retained between a call to
PaWinUtil_CoInitialize and a matching call to PaWinUtil_CoUninitialize.
*/
typedef struct PaWinUtilComInitializationResult{
@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
+ @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
/**
- @brief Uninitialize the Microsoft COM subsystem on the current thread using
+ @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.
*/
/*
- * 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.
*/
#endif
#if PA_USE_WASAPI
- PaWasapi_Initialize,
+ PaWasapi_Initialize,
#endif
#if PA_USE_WDMKS
*/
/*
- * 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.
*/
@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() */
+ #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
+ #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"
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
+ 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.
else
{
#ifndef UNDER_CE
- #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
+ #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
return GetTickCount64() * .001;
- #else
+ #else
return timeGetTime() * .001;
- #endif
+ #endif
#else
return GetTickCount() * .001;
-#endif
+#endif
}
}
*/
/*
- * 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.
*/
#endif
-static GUID pawin_ksDataFormatSubtypeGuidBase =
- { (USHORT)(WAVE_FORMAT_PCM), 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 };
+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 )
+void PaWin_InitializeWaveFormatEx( PaWinWaveFormat *waveFormat,
+ int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate )
{
- WAVEFORMATEX *waveFormatEx = (WAVEFORMATEX*)waveFormat;
+ WAVEFORMATEX *waveFormatEx = (WAVEFORMATEX*)waveFormat;
int bytesPerSample = Pa_GetSampleSize(sampleFormat);
- unsigned long bytesPerFrame = numChannels * bytesPerSample;
-
+ 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;
+ 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 )
+void PaWin_InitializeWaveFormatExtensible( PaWinWaveFormat *waveFormat,
+ int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate,
+ PaWinWaveFormatChannelMask channelMask )
{
- WAVEFORMATEX *waveFormatEx = (WAVEFORMATEX*)waveFormat;
+ WAVEFORMATEX *waveFormatEx = (WAVEFORMATEX*)waveFormat;
int bytesPerSample = Pa_GetSampleSize(sampleFormat);
- unsigned long bytesPerFrame = numChannels * bytesPerSample;
+ 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;
+ 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));
PaWinWaveFormatChannelMask PaWin_DefaultChannelMask( int numChannels )
{
- switch( numChannels ){
- case 1:
- return PAWIN_SPEAKER_MONO;
- case 2:
- return PAWIN_SPEAKER_STEREO;
- case 3:
+ 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:
+ case 4:
+ return PAWIN_SPEAKER_QUAD;
+ case 5:
return PAWIN_SPEAKER_QUAD | PAWIN_SPEAKER_FRONT_CENTER;
- case 6:
+ 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
+ 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;
+ return PAWIN_SPEAKER_5POINT1;
/* case 7: */
- case 8:
+ 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.
+ 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;
- }
+ 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.
+ /* 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;
+ return PAWIN_SPEAKER_DIRECTOUT;
- /* Note that Alec Rogers proposed the following as an alternate method to
+ /* 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.
*/
/*
- * 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 <mmreg.h>
#ifndef WAVE_FORMAT_IEEE_FLOAT
#define WAVE_FORMAT_IEEE_FLOAT 0x0003 // MinGW32 does not define this
-#endif
+#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 <winioctl.h> // MinGW32 does not define this automatically
#if defined(__GNUC__)
}
-static int KSFilterPinPropertyIdentifiersInclude(
+static int KSFilterPinPropertyIdentifiersInclude(
HANDLE deviceHandle, int pinId, unsigned long property, const GUID *identifierSet, unsigned long identifierId )
{
KSMULTIPLE_ITEM* item = NULL;
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 ) )
+ ( identifier[i].Id == identifierId ) )
{
result = 1;
break;
}
-/* 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;
+ ULONG i;
int pinCount, pinId;
int result = 0;
KSPIN_DATAFLOW requiredDataflowDirection = (isInput ? KSPIN_DATAFLOW_OUT : KSPIN_DATAFLOW_IN );
-
+
if( !wcharDevicePath )
return 0;
KSPIN_DATAFLOW dataflow = GetKSFilterPinPropertyDataflow( deviceHandle, pinId );
if( ( dataflow == requiredDataflowDirection ) &&
(( communication == KSPIN_COMMUNICATION_SINK) ||
- ( communication == KSPIN_COMMUNICATION_BOTH))
- && ( KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId,
+ ( communication == KSPIN_COMMUNICATION_BOTH))
+ && ( KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId,
KSPROPERTY_PIN_INTERFACES, &pa_KSINTERFACESETID_Standard, KSINTERFACE_STANDARD_STREAMING )
- || KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId,
+ || KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId,
KSPROPERTY_PIN_INTERFACES, &pa_KSINTERFACESETID_Standard, KSINTERFACE_STANDARD_LOOPED_STREAMING ) )
- && KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId,
+ && 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 )
{
&& ( 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 )
if( dataRangeAudio->MaximumChannels < 0xFFFFUL && (int)dataRangeAudio->MaximumChannels > result )
result = (int)dataRangeAudio->MaximumChannels;
}
-
+
dataRange = (KSDATARANGE*)( ((char*)dataRange) + dataRange->FormatSize);
}
}
}
}
-
+
CloseHandle( deviceHandle );
return result;
}
*/
/*
- * 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.
*/
}
#endif /* __cplusplus */
-#endif /* PA_WIN_WDMKS_UTILS_H */
\ No newline at end of file
+#endif /* PA_WIN_WDMKS_UTILS_H */
*/
/*
- * 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.
*/
#if defined(_WIN64) || defined(_WIN32_WCE)
/*
- -EMT64/AMD64 uses different asm
- -VC2005 doesn't allow _WIN64 with inline assembly either!
+ -EMT64/AMD64 uses different asm
+ -VC2005 doesn't allow _WIN64 with inline assembly either!
*/
void PaUtil_InitializeX86PlainConverters( void )
{
mov ecx, count
imul ecx, eax
add ecx, esi
-
+
mov edi, destinationBuffer
-
+
mov ebx, destinationStride
imul ebx, edx
fstcw savedFpuControlWord
fldcw fpuControlWord_
- fld int32Scaler_ // stack: (int)0x7FFFFFFF
+ fld int32Scaler_ // stack: (int)0x7FFFFFFF
Float32_To_Int32_loop:
mov ecx, count
imul ecx, eax
add ecx, esi
-
+
mov edi, destinationBuffer
-
+
mov ebx, destinationStride
imul ebx, edx
fstcw savedFpuControlWord
fldcw fpuControlWord_
- fld int32Scaler_ // stack: (int)0x7FFFFFFF
+ fld int32Scaler_ // stack: (int)0x7FFFFFFF
Float32_To_Int32_Clip_loop:
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
Float32_To_Int32_Clip_stored:
- //add edi, ebx // increment destination ptr
+ //add edi, ebx // increment destination ptr
lea edi, [edi+ebx]
cmp esi, ecx // has src ptr reached end?
unsigned long ditherPrevious = ditherGenerator->previous;
unsigned long ditherRandSeed1 = ditherGenerator->randSeed1;
unsigned long ditherRandSeed2 = ditherGenerator->randSeed2;
-
+
__asm{
// esi -> source ptr
// eax -> source byte stride
mov ecx, count
imul ecx, eax
add ecx, esi
-
+
mov edi, destinationBuffer
-
+
mov ebx, destinationStride
imul ebx, edx
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
+ 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
*/
shr edx, PA_DITHER_SHIFT_
mov ditherRandSeed2, eax
shr eax, PA_DITHER_SHIFT_
- //add eax, edx // eax -> current
+ //add eax, edx // eax -> current
lea eax, [eax+edx]
mov edx, ditherPrevious
neg edx
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
signed long temp;
(void) ditherGenerator; // unused parameter
-
+
while( count-- )
{
// convert to 32 bit and drop the low 8 bits
*/
short savedFpuControlWord;
-
+
signed long tempInt32;
(void) ditherGenerator; /* unused parameter */
-
+
__asm{
// esi -> source ptr
// eax -> source byte stride
fstcw savedFpuControlWord
fldcw fpuControlWord_
- fld int24Scaler_ // stack: (int)0x7FFFFF
+ fld int24Scaler_ // stack: (int)0x7FFFFF
Float32_To_Int24_loop:
//mov byte ptr [edi+2], DH
mov word ptr [edi+1], DX
- //add edi, ebx // increment destination ptr
+ //add edi, ebx // increment destination ptr
lea edi, [edi+ebx]
cmp esi, ecx // has src ptr reached end?
signed long temp;
(void) ditherGenerator; // unused parameter
-
+
while( count-- )
{
// convert to 32 bit and drop the low 8 bits
*/
short savedFpuControlWord;
-
+
signed long tempInt32;
(void) ditherGenerator; /* unused parameter */
-
+
__asm{
// esi -> source ptr
// eax -> source byte stride
fstcw savedFpuControlWord
fldcw fpuControlWord_
- fld int24Scaler_ // stack: (int)0x7FFFFF
+ fld int24Scaler_ // stack: (int)0x7FFFFF
Float32_To_Int24_Clip_loop:
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
//mov byte ptr [edi+2], DH
mov word ptr [edi+1], DX
- //add edi, ebx // increment destination ptr
+ //add edi, ebx // increment destination ptr
lea edi, [edi+ebx]
cmp esi, ecx // has src ptr reached end?
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
// 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);
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
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
+ 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
shr edx, PA_DITHER_SHIFT_
mov ditherRandSeed2, eax
shr eax, PA_DITHER_SHIFT_
- //add eax, edx // eax -> current
+ //add eax, edx // eax -> current
lea eax, [eax+edx]
mov edx, ditherPrevious
neg edx
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
//mov byte ptr [edi+2], DH
mov word ptr [edi+1], DX
- //add edi, ebx // increment destination ptr
+ //add edi, ebx // increment destination ptr
lea edi, [edi+ebx]
cmp esi, ecx // has src ptr reached end?
*/
short savedFpuControlWord;
-
+
(void) ditherGenerator; /* unused parameter */
__asm{
add edi, ebx // increment destination ptr
//lea edi, [edi+ebx]
-
+
cmp esi, ecx // has src ptr reached end?
jne Float32_To_Int16_loop
*/
short savedFpuControlWord;
-
+
(void) ditherGenerator; /* unused parameter */
__asm{
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 edi, ebx // increment destination ptr
//lea edi, [edi+ebx]
-
+
cmp esi, ecx // has src ptr reached end?
jne Float32_To_Int16_Clip_loop
{
float dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
- // use smaller scaler to prevent overflow when we add the dither
+ // 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 );
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
+ 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
*/
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
+ //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
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 edi, ebx // increment destination ptr
//lea edi, [edi+ebx]
-
+
cmp esi, ecx // has src ptr reached end?
jne Float32_To_Int16_DitherClip_loop
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;
*/
/*
- * 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.
*/