Merge branch 'winrt' into 'master'

WASAPI: fixed MonoToStereo converter could write beyond the allowed memory region if sample format is packed 24-bit integer, fixed DEF file by adding missing WASAPI API

Merged-on: https://assembla.com/code/portaudio/git/merge_requests/6928491
This commit is contained in:
Dmitry Kostjuchenko 2018-10-21 10:24:52 +00:00
commit 0cdb346fdc
2 changed files with 99 additions and 33 deletions

View file

@ -41,10 +41,14 @@ PaUtil_InitializeX86PlainConverters @52
PaAsio_GetInputChannelName @53 PaAsio_GetInputChannelName @53
PaAsio_GetOutputChannelName @54 PaAsio_GetOutputChannelName @54
PaUtil_SetDebugPrintFunction @55 PaUtil_SetDebugPrintFunction @55
PaWasapi_GetDeviceDefaultFormat @56 PaWasapi_GetAudioClient @56
PaWasapi_GetDeviceRole @57 PaWasapi_UpdateDeviceList @57
PaWasapi_ThreadPriorityBoost @58 PaWasapi_GetDeviceCurrentFormat @58
PaWasapi_ThreadPriorityRevert @59 PaWasapi_GetDeviceDefaultFormat @59
PaWasapi_GetFramesPerHostBuffer @60 PaWasapi_GetDeviceRole @60
PaWasapi_GetJackDescription @61 PaWasapi_ThreadPriorityBoost @61
PaWasapi_GetJackCount @62 PaWasapi_ThreadPriorityRevert @62
PaWasapi_GetFramesPerHostBuffer @63
PaWasapi_GetJackCount @64
PaWasapi_GetJackDescription @65
PaWasapi_SetDefaultInterfaceId @66

View file

@ -592,7 +592,7 @@ static HRESULT UnmarshalStreamComPointers(PaWasapiStream *stream);
static void ReleaseUnmarshaledSubComPointers(PaWasapiSubStream *substream); static void ReleaseUnmarshaledSubComPointers(PaWasapiSubStream *substream);
static void ReleaseUnmarshaledComPointers(PaWasapiStream *stream); static void ReleaseUnmarshaledComPointers(PaWasapiStream *stream);
// Local stream methods // Local methods
static void _StreamOnStop(PaWasapiStream *stream); static void _StreamOnStop(PaWasapiStream *stream);
static void _StreamFinish(PaWasapiStream *stream); static void _StreamFinish(PaWasapiStream *stream);
static void _StreamCleanup(PaWasapiStream *stream); static void _StreamCleanup(PaWasapiStream *stream);
@ -600,6 +600,7 @@ static HRESULT _PollGetOutputFramesAvailable(PaWasapiStream *stream, UINT32 *ava
static HRESULT _PollGetInputFramesAvailable(PaWasapiStream *stream, UINT32 *available); static HRESULT _PollGetInputFramesAvailable(PaWasapiStream *stream, UINT32 *available);
static void *PaWasapi_ReallocateMemory(void *prev, size_t size); static void *PaWasapi_ReallocateMemory(void *prev, size_t size);
static void PaWasapi_FreeMemory(void *ptr); static void PaWasapi_FreeMemory(void *ptr);
static PaSampleFormat WaveToPaFormat(const WAVEFORMATEXTENSIBLE *fmtext);
// Local statics // Local statics
@ -1268,27 +1269,88 @@ EMixDirection;
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
static void _MixMonoToStereo_1TO2_8(void *__to, const void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_1_TO_2(BYTE); } static void _MixMonoToStereo_1TO2_8(void *__to, const void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_1_TO_2(BYTE); }
static void _MixMonoToStereo_1TO2_16(void *__to, const void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_1_TO_2(short); } static void _MixMonoToStereo_1TO2_16(void *__to, const void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_1_TO_2(short); }
static void _MixMonoToStereo_1TO2_24(void *__to, const void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_1_TO_2(int); /* !!! int24 data is contained in 32-bit containers*/ } static void _MixMonoToStereo_1TO2_8_24(void *__to, const void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_1_TO_2(int); /* !!! int24 data is contained in 32-bit containers*/ }
static void _MixMonoToStereo_1TO2_32(void *__to, const void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_1_TO_2(int); } static void _MixMonoToStereo_1TO2_32(void *__to, const void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_1_TO_2(int); }
static void _MixMonoToStereo_1TO2_32f(void *__to, const void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_1_TO_2(float); } static void _MixMonoToStereo_1TO2_32f(void *__to, const void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_1_TO_2(float); }
static void _MixMonoToStereo_1TO2_24(void *__to, const void *__from, UINT32 count)
{
const UCHAR * __restrict from = (const UCHAR *)__from;
UCHAR * __restrict to = (UCHAR *)__to;
const UCHAR * __restrict end = to + (count * (2 * 3));
while (to != end)
{
to[0] = to[3] = from[0];
to[1] = to[4] = from[1];
to[2] = to[5] = from[2];
from += 3;
to += (2 * 3);
}
}
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
static void _MixMonoToStereo_2TO1_8(void *__to, const void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1_INT32(BYTE); } static void _MixMonoToStereo_2TO1_8(void *__to, const void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1_INT32(BYTE); }
static void _MixMonoToStereo_2TO1_16(void *__to, const void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1_INT32(short); } static void _MixMonoToStereo_2TO1_16(void *__to, const void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1_INT32(short); }
static void _MixMonoToStereo_2TO1_24(void *__to, const void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1_INT32(int); /* !!! int24 data is contained in 32-bit containers*/ } static void _MixMonoToStereo_2TO1_8_24(void *__to, const void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1_INT32(int); /* !!! int24 data is contained in 32-bit containers*/ }
static void _MixMonoToStereo_2TO1_32(void *__to, const void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1_INT64(int); } static void _MixMonoToStereo_2TO1_32(void *__to, const void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1_INT64(int); }
static void _MixMonoToStereo_2TO1_32f(void *__to, const void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1_FLT32(float); } static void _MixMonoToStereo_2TO1_32f(void *__to, const void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1_FLT32(float); }
static void _MixMonoToStereo_2TO1_24(void *__to, const void *__from, UINT32 count)
{
const UCHAR * __restrict from = (const UCHAR *)__from;
UCHAR * __restrict to = (UCHAR *)__to;
const UCHAR * __restrict end = to + (count * 3);
PaInt32 tempL, tempR, tempM;
while (to != end)
{
tempL = (((PaInt32)from[0]) << 8);
tempL = tempL | (((PaInt32)from[1]) << 16);
tempL = tempL | (((PaInt32)from[2]) << 24);
tempR = (((PaInt32)from[3]) << 8);
tempR = tempR | (((PaInt32)from[4]) << 16);
tempR = tempR | (((PaInt32)from[5]) << 24);
tempM = (tempL + tempR) >> 1;
to[0] = (UCHAR)(tempM >> 8);
to[1] = (UCHAR)(tempM >> 16);
to[2] = (UCHAR)(tempM >> 24);
from += (2 * 3);
to += 3;
}
}
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
static void _MixMonoToStereo_2TO1_8_L(void *__to, const void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1_L(BYTE); } static void _MixMonoToStereo_2TO1_8_L(void *__to, const void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1_L(BYTE); }
static void _MixMonoToStereo_2TO1_16_L(void *__to, const void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1_L(short); } static void _MixMonoToStereo_2TO1_16_L(void *__to, const void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1_L(short); }
static void _MixMonoToStereo_2TO1_24_L(void *__to, const void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1_L(int); /* !!! int24 data is contained in 32-bit containers*/ } static void _MixMonoToStereo_2TO1_8_24_L(void *__to, const void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1_L(int); /* !!! int24 data is contained in 32-bit containers*/ }
static void _MixMonoToStereo_2TO1_32_L(void *__to, const void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1_L(int); } static void _MixMonoToStereo_2TO1_32_L(void *__to, const void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1_L(int); }
static void _MixMonoToStereo_2TO1_32f_L(void *__to, const void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1_L(float); } static void _MixMonoToStereo_2TO1_32f_L(void *__to, const void *__from, UINT32 count) { _WASAPI_MONO_TO_STEREO_MIXER_2_TO_1_L(float); }
static void _MixMonoToStereo_2TO1_24_L(void *__to, const void *__from, UINT32 count)
{
const UCHAR * __restrict from = (const UCHAR *)__from;
UCHAR * __restrict to = (UCHAR *)__to;
const UCHAR * __restrict end = to + (count * 3);
while (to != end)
{
to[0] = from[0];
to[1] = from[1];
to[2] = from[2];
from += (2 * 3);
to += 3;
}
}
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
static MixMonoToStereoF GetMonoToStereoMixer(PaSampleFormat format, EMixDirection dir) static MixMonoToStereoF GetMonoToStereoMixer(const WAVEFORMATEXTENSIBLE *fmtext, EMixDirection dir)
{ {
PaSampleFormat format = WaveToPaFormat(fmtext);
switch (dir) switch (dir)
{ {
case MIX_DIR__1TO2: case MIX_DIR__1TO2:
@ -1296,7 +1358,7 @@ static MixMonoToStereoF GetMonoToStereoMixer(PaSampleFormat format, EMixDirectio
{ {
case paUInt8: return _MixMonoToStereo_1TO2_8; case paUInt8: return _MixMonoToStereo_1TO2_8;
case paInt16: return _MixMonoToStereo_1TO2_16; case paInt16: return _MixMonoToStereo_1TO2_16;
case paInt24: return _MixMonoToStereo_1TO2_24; case paInt24: return (fmtext->Format.wBitsPerSample == 32 ? _MixMonoToStereo_1TO2_8_24 : _MixMonoToStereo_1TO2_24);
case paInt32: return _MixMonoToStereo_1TO2_32; case paInt32: return _MixMonoToStereo_1TO2_32;
case paFloat32: return _MixMonoToStereo_1TO2_32f; case paFloat32: return _MixMonoToStereo_1TO2_32f;
} }
@ -1307,7 +1369,7 @@ static MixMonoToStereoF GetMonoToStereoMixer(PaSampleFormat format, EMixDirectio
{ {
case paUInt8: return _MixMonoToStereo_2TO1_8; case paUInt8: return _MixMonoToStereo_2TO1_8;
case paInt16: return _MixMonoToStereo_2TO1_16; case paInt16: return _MixMonoToStereo_2TO1_16;
case paInt24: return _MixMonoToStereo_2TO1_24; case paInt24: return (fmtext->Format.wBitsPerSample == 32 ? _MixMonoToStereo_2TO1_8_24 : _MixMonoToStereo_2TO1_24);
case paInt32: return _MixMonoToStereo_2TO1_32; case paInt32: return _MixMonoToStereo_2TO1_32;
case paFloat32: return _MixMonoToStereo_2TO1_32f; case paFloat32: return _MixMonoToStereo_2TO1_32f;
} }
@ -1318,7 +1380,7 @@ static MixMonoToStereoF GetMonoToStereoMixer(PaSampleFormat format, EMixDirectio
{ {
case paUInt8: return _MixMonoToStereo_2TO1_8_L; case paUInt8: return _MixMonoToStereo_2TO1_8_L;
case paInt16: return _MixMonoToStereo_2TO1_16_L; case paInt16: return _MixMonoToStereo_2TO1_16_L;
case paInt24: return _MixMonoToStereo_2TO1_24_L; case paInt24: return (fmtext->Format.wBitsPerSample == 32 ? _MixMonoToStereo_2TO1_8_24_L : _MixMonoToStereo_2TO1_24_L);
case paInt32: return _MixMonoToStereo_2TO1_32_L; case paInt32: return _MixMonoToStereo_2TO1_32_L;
case paFloat32: return _MixMonoToStereo_2TO1_32f_L; case paFloat32: return _MixMonoToStereo_2TO1_32f_L;
} }
@ -2259,27 +2321,27 @@ static void LogWAVEFORMATEXTENSIBLE(const WAVEFORMATEXTENSIBLE *in)
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
static PaSampleFormat WaveToPaFormat(const WAVEFORMATEXTENSIBLE *in) PaSampleFormat WaveToPaFormat(const WAVEFORMATEXTENSIBLE *fmtext)
{ {
const WAVEFORMATEX *old = (WAVEFORMATEX *)in; const WAVEFORMATEX *fmt = (WAVEFORMATEX *)fmtext;
switch (old->wFormatTag) switch (fmt->wFormatTag)
{ {
case WAVE_FORMAT_EXTENSIBLE: { case WAVE_FORMAT_EXTENSIBLE: {
if (IsEqualGUID(&in->SubFormat, &pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)) if (IsEqualGUID(&fmtext->SubFormat, &pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT))
{ {
if (in->Samples.wValidBitsPerSample == 32) if (fmtext->Samples.wValidBitsPerSample == 32)
return paFloat32; return paFloat32;
} }
else else
if (IsEqualGUID(&in->SubFormat, &pa_KSDATAFORMAT_SUBTYPE_PCM)) if (IsEqualGUID(&fmtext->SubFormat, &pa_KSDATAFORMAT_SUBTYPE_PCM))
{ {
switch (old->wBitsPerSample) switch (fmt->wBitsPerSample)
{ {
case 32: return paInt32; case 32: return paInt32;
case 24: return paInt24; case 24: return paInt24;
case 8: return paUInt8; case 16: return paInt16;
case 16: return paInt16; case 8: return paUInt8;
} }
} }
break; } break; }
@ -2288,12 +2350,12 @@ static PaSampleFormat WaveToPaFormat(const WAVEFORMATEXTENSIBLE *in)
return paFloat32; return paFloat32;
case WAVE_FORMAT_PCM: { case WAVE_FORMAT_PCM: {
switch (old->wBitsPerSample) switch (fmt->wBitsPerSample)
{ {
case 32: return paInt32; case 32: return paInt32;
case 24: return paInt24; case 24: return paInt24;
case 8: return paUInt8; case 16: return paInt16;
case 16: return paInt16; case 8: return paUInt8;
} }
break; } break; }
} }
@ -2808,7 +2870,7 @@ static HRESULT CreateAudioClient(PaWasapiStream *pStream, PaWasapiSubStream *pSu
}*/ }*/
// select mixer // select mixer
pSub->monoMixer = GetMonoToStereoMixer(WaveToPaFormat(&pSub->wavex), (pInfo->flow == eRender ? MIX_DIR__1TO2 : MIX_DIR__2TO1_L)); pSub->monoMixer = GetMonoToStereoMixer(&pSub->wavex, (pInfo->flow == eRender ? MIX_DIR__1TO2 : MIX_DIR__2TO1_L));
if (pSub->monoMixer == NULL) if (pSub->monoMixer == NULL)
{ {
(*pa_error) = paInvalidChannelCount; (*pa_error) = paInvalidChannelCount;
@ -3145,7 +3207,7 @@ static HRESULT CreateAudioClient(PaWasapiStream *pStream, PaWasapiSubStream *pSu
}*/ }*/
// Select mixer // Select mixer
pSub->monoMixer = GetMonoToStereoMixer(WaveToPaFormat(&pSub->wavex), (pInfo->flow == eRender ? MIX_DIR__1TO2 : MIX_DIR__2TO1_L)); pSub->monoMixer = GetMonoToStereoMixer(&pSub->wavex, (pInfo->flow == eRender ? MIX_DIR__1TO2 : MIX_DIR__2TO1_L));
if (pSub->monoMixer == NULL) if (pSub->monoMixer == NULL)
{ {
(*pa_error) = paInvalidChannelCount; (*pa_error) = paInvalidChannelCount;