Support signed and unsigned 32-bit int output

This commit is contained in:
Chris Robinson 2012-02-14 11:44:57 -08:00
parent 5e1d1a52ba
commit 1140b3ae83
14 changed files with 128 additions and 9 deletions

View File

@ -887,6 +887,8 @@ const ALCchar *DevFmtTypeString(enum DevFmtType type)
case DevFmtUByte: return "Unsigned Byte";
case DevFmtShort: return "Signed Short";
case DevFmtUShort: return "Unsigned Short";
case DevFmtInt: return "Signed Int";
case DevFmtUInt: return "Unsigned Int";
case DevFmtFloat: return "Float";
}
return "(unknown type)";
@ -914,6 +916,8 @@ ALuint BytesFromDevFmt(enum DevFmtType type)
case DevFmtUByte: return sizeof(ALubyte);
case DevFmtShort: return sizeof(ALshort);
case DevFmtUShort: return sizeof(ALushort);
case DevFmtInt: return sizeof(ALint);
case DevFmtUInt: return sizeof(ALuint);
case DevFmtFloat: return sizeof(ALfloat);
}
return 0;

View File

@ -790,18 +790,22 @@ ALvoid CalcSourceParams(ALsource *ALSource, const ALCcontext *ALContext)
static __inline ALfloat aluF2F(ALfloat val)
{ return val; }
static __inline ALshort aluF2S(ALfloat val)
static __inline ALint aluF2I(ALfloat val)
{
if(val > 1.0f) return 32767;
if(val < -1.0f) return -32768;
return fastf2i(val*32767.0f);
if(val > 1.0f) return 2147483647;
if(val < -1.0f) return -2147483647-1;
return fastf2i(val*2147483647.0);
}
static __inline ALuint aluF2UI(ALfloat val)
{ return aluF2I(val)+2147483648u; }
static __inline ALshort aluF2S(ALfloat val)
{ return aluF2I(val)>>16; }
static __inline ALushort aluF2US(ALfloat val)
{ return aluF2S(val)+32768; }
static __inline ALbyte aluF2B(ALfloat val)
{ return aluF2S(val)>>8; }
{ return aluF2I(val)>>24; }
static __inline ALubyte aluF2UB(ALfloat val)
{ return aluF2US(val)>>8; }
{ return aluF2B(val)+128; }
#define DECL_TEMPLATE(T, N, func) \
static void Write_##T##_##N(ALCdevice *device, T *RESTRICT buffer, \
@ -824,6 +828,18 @@ DECL_TEMPLATE(ALfloat, 6, aluF2F)
DECL_TEMPLATE(ALfloat, 7, aluF2F)
DECL_TEMPLATE(ALfloat, 8, aluF2F)
DECL_TEMPLATE(ALuint, 1, aluF2UI)
DECL_TEMPLATE(ALuint, 4, aluF2UI)
DECL_TEMPLATE(ALuint, 6, aluF2UI)
DECL_TEMPLATE(ALuint, 7, aluF2UI)
DECL_TEMPLATE(ALuint, 8, aluF2UI)
DECL_TEMPLATE(ALint, 1, aluF2I)
DECL_TEMPLATE(ALint, 4, aluF2I)
DECL_TEMPLATE(ALint, 6, aluF2I)
DECL_TEMPLATE(ALint, 7, aluF2I)
DECL_TEMPLATE(ALint, 8, aluF2I)
DECL_TEMPLATE(ALushort, 1, aluF2US)
DECL_TEMPLATE(ALushort, 4, aluF2US)
DECL_TEMPLATE(ALushort, 6, aluF2US)
@ -881,6 +897,8 @@ static void Write_##T##_##N(ALCdevice *device, T *RESTRICT buffer, \
}
DECL_TEMPLATE(ALfloat, 2, aluF2F)
DECL_TEMPLATE(ALuint, 2, aluF2UI)
DECL_TEMPLATE(ALint, 2, aluF2I)
DECL_TEMPLATE(ALushort, 2, aluF2US)
DECL_TEMPLATE(ALshort, 2, aluF2S)
DECL_TEMPLATE(ALubyte, 2, aluF2UB)
@ -916,6 +934,8 @@ static void Write_##T(ALCdevice *device, T *buffer, ALuint SamplesToDo) \
}
DECL_TEMPLATE(ALfloat)
DECL_TEMPLATE(ALuint)
DECL_TEMPLATE(ALint)
DECL_TEMPLATE(ALushort)
DECL_TEMPLATE(ALshort)
DECL_TEMPLATE(ALubyte)
@ -1082,6 +1102,12 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
case DevFmtUShort:
Write_ALushort(device, buffer, SamplesToDo);
break;
case DevFmtInt:
Write_ALint(device, buffer, SamplesToDo);
break;
case DevFmtUInt:
Write_ALuint(device, buffer, SamplesToDo);
break;
case DevFmtFloat:
Write_ALfloat(device, buffer, SamplesToDo);
break;

View File

@ -657,6 +657,12 @@ static ALCboolean alsa_reset_playback(ALCdevice *device)
case DevFmtUShort:
format = SND_PCM_FORMAT_U16;
break;
case DevFmtInt:
format = SND_PCM_FORMAT_S32;
break;
case DevFmtUInt:
format = SND_PCM_FORMAT_U32;
break;
case DevFmtFloat:
format = SND_PCM_FORMAT_FLOAT;
break;
@ -692,6 +698,8 @@ static ALCboolean alsa_reset_playback(ALCdevice *device)
enum DevFmtType fmttype;
} formatlist[] = {
{ SND_PCM_FORMAT_FLOAT, DevFmtFloat },
{ SND_PCM_FORMAT_S32, DevFmtInt },
{ SND_PCM_FORMAT_U32, DevFmtUInt },
{ SND_PCM_FORMAT_S16, DevFmtShort },
{ SND_PCM_FORMAT_U16, DevFmtUShort },
{ SND_PCM_FORMAT_S8, DevFmtByte },
@ -908,6 +916,12 @@ static ALCenum alsa_open_capture(ALCdevice *pDevice, const ALCchar *deviceName)
case DevFmtUShort:
format = SND_PCM_FORMAT_U16;
break;
case DevFmtInt:
format = SND_PCM_FORMAT_S32;
break;
case DevFmtUInt:
format = SND_PCM_FORMAT_U32;
break;
case DevFmtFloat:
format = SND_PCM_FORMAT_FLOAT;
break;

View File

@ -296,6 +296,14 @@ static ALCboolean ca_reset_playback(ALCdevice *device)
streamFormat.mBytesPerPacket = 2 * streamFormat.mChannelsPerFrame;
streamFormat.mBytesPerFrame = 2 * streamFormat.mChannelsPerFrame;
break;
case DevFmtUInt:
device->FmtType = DevFmtInt;
/* fall-through */
case DevFmtInt:
streamFormat.mBitsPerChannel = 32;
streamFormat.mBytesPerPacket = 2 * streamFormat.mChannelsPerFrame;
streamFormat.mBytesPerFrame = 2 * streamFormat.mChannelsPerFrame;
break;
}
streamFormat.mFormatID = kAudioFormatLinearPCM;
streamFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger |
@ -455,12 +463,17 @@ static ALCenum ca_open_capture(ALCdevice *device, const ALCchar *deviceName)
requestedFormat.mBitsPerChannel = 16;
requestedFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked;
break;
case DevFmtInt:
requestedFormat.mBitsPerChannel = 32;
requestedFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked;
break;
case DevFmtFloat:
requestedFormat.mBitsPerChannel = 32;
requestedFormat.mFormatFlags = kAudioFormatFlagIsPacked;
break;
case DevFmtByte:
case DevFmtUShort:
case DevFmtUInt:
ERR("%s samples not supported\n", DevFmtTypeString(device->FmtType));
goto error;
}

View File

@ -396,8 +396,12 @@ static ALCboolean DSoundResetPlayback(ALCdevice *device)
case DevFmtUShort:
device->FmtType = DevFmtShort;
break;
case DevFmtUInt:
device->FmtType = DevFmtInt;
break;
case DevFmtUByte:
case DevFmtShort:
case DevFmtInt:
case DevFmtFloat:
break;
}

View File

@ -294,6 +294,14 @@ static HRESULT DoReset(ALCdevice *device)
OutputType.Samples.wValidBitsPerSample = 16;
OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
break;
case DevFmtUInt:
device->FmtType = DevFmtInt;
/* fall-through */
case DevFmtInt:
OutputType.Format.wBitsPerSample = 32;
OutputType.Samples.wValidBitsPerSample = 32;
OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
break;
case DevFmtFloat:
OutputType.Format.wBitsPerSample = 32;
OutputType.Samples.wValidBitsPerSample = 32;
@ -358,6 +366,8 @@ static HRESULT DoReset(ALCdevice *device)
device->FmtType = DevFmtUByte;
else if(OutputType.Format.wBitsPerSample == 16)
device->FmtType = DevFmtShort;
else if(OutputType.Format.wBitsPerSample == 32)
device->FmtType = DevFmtInt;
else
{
device->FmtType = DevFmtShort;

View File

@ -206,6 +206,8 @@ static ALCboolean oss_reset_playback(ALCdevice *device)
ossFormat = AFMT_U8;
break;
case DevFmtUShort:
case DevFmtInt:
case DevFmtUInt:
case DevFmtFloat:
device->FmtType = DevFmtShort;
/* fall-through */
@ -347,6 +349,8 @@ static ALCenum oss_open_capture(ALCdevice *device, const ALCchar *deviceName)
ossFormat = AFMT_S16_NE;
break;
case DevFmtUShort:
case DevFmtInt:
case DevFmtUInt:
case DevFmtFloat:
free(data);
ERR("%s capture samples not supported on OSS\n", DevFmtTypeString(device->FmtType));

View File

@ -192,6 +192,12 @@ retry_open:
case DevFmtShort:
outParams.sampleFormat = paInt16;
break;
case DevFmtUInt:
device->FmtType = DevFmtInt;
/* fall-through */
case DevFmtInt:
outParams.sampleFormat = paInt32;
break;
case DevFmtFloat:
outParams.sampleFormat = paFloat32;
break;
@ -316,11 +322,15 @@ static ALCenum pa_open_capture(ALCdevice *device, const ALCchar *deviceName)
case DevFmtShort:
inParams.sampleFormat = paInt16;
break;
case DevFmtInt:
inParams.sampleFormat = paInt32;
break;
case DevFmtFloat:
inParams.sampleFormat = paFloat32;
break;
case DevFmtUInt:
case DevFmtUShort:
ERR("Unsigned short samples not supported\n");
ERR("%s samples not supported\n", DevFmtTypeString(device->FmtType));
goto error;
}
inParams.channelCount = ChannelsFromDevFmt(device->FmtChans);

View File

@ -953,6 +953,12 @@ static ALCboolean pulse_reset_playback(ALCdevice *device) //{{{
case DevFmtShort:
data->spec.format = PA_SAMPLE_S16NE;
break;
case DevFmtUInt:
device->FmtType = DevFmtInt;
/* fall-through */
case DevFmtInt:
data->spec.format = PA_SAMPLE_S32NE;
break;
case DevFmtFloat:
data->spec.format = PA_SAMPLE_FLOAT32NE;
break;
@ -1150,11 +1156,15 @@ static ALCenum pulse_open_capture(ALCdevice *device, const ALCchar *device_name)
case DevFmtShort:
data->spec.format = PA_SAMPLE_S16NE;
break;
case DevFmtInt:
data->spec.format = PA_SAMPLE_S32NE;
break;
case DevFmtFloat:
data->spec.format = PA_SAMPLE_FLOAT32NE;
break;
case DevFmtByte:
case DevFmtUShort:
case DevFmtUInt:
ERR("Capture format type %#x capture not supported on PulseAudio\n", device->FmtType);
pa_threaded_mainloop_unlock(data->loop);
goto fail;

View File

@ -229,6 +229,14 @@ static ALCboolean sndio_reset_playback(ALCdevice *device)
par.bits = 16;
par.sig = 0;
break;
case DevFmtInt:
par.bits = 32;
par.sig = 1;
break;
case DevFmtUInt:
par.bits = 32;
par.sig = 0;
break;
}
par.le = SIO_LE_NATIVE;
@ -259,6 +267,10 @@ static ALCboolean sndio_reset_playback(ALCdevice *device)
device->FmtType = DevFmtShort;
else if(par.bits == 16 && par.sig == 0)
device->FmtType = DevFmtUShort;
else if(par.bits == 32 && par.sig == 1)
device->FmtType = DevFmtInt;
else if(par.bits == 32 && par.sig == 0)
device->FmtType = DevFmtUInt;
else
{
ERR("Unhandled sample format: %s %u-bit\n", (par.sig?"signed":"unsigned"), par.bits);

View File

@ -156,6 +156,8 @@ static ALCboolean solaris_reset_playback(ALCdevice *device)
info.play.encoding = AUDIO_ENCODING_LINEAR8;
break;
case DevFmtUShort:
case DevFmtInt:
case DevFmtUInt:
case DevFmtFloat:
device->FmtType = DevFmtShort;
/* fall-through */
@ -185,7 +187,9 @@ static ALCboolean solaris_reset_playback(ALCdevice *device)
(info.play.precision == 8 && info.play.encoding == AUDIO_ENCODING_LINEAR8 &&
device->FmtType == DevFmtUByte) ||
(info.play.precision == 16 && info.play.encoding == AUDIO_ENCODING_LINEAR &&
device->FmtType == DevFmtShort)))
device->FmtType == DevFmtShort) ||
(info.play.precision == 32 && info.play.encoding == AUDIO_ENCODING_LINEAR &&
device->FmtType == DevFmtInt)))
{
ERR("Could not set %#x sample type, got %d (%#x)\n",
device->FmtType, info.play.precision, info.play.encoding);

View File

@ -214,8 +214,12 @@ static ALCboolean wave_reset_playback(ALCdevice *device)
case DevFmtUShort:
device->FmtType = DevFmtShort;
break;
case DevFmtUInt:
device->FmtType = DevFmtInt;
break;
case DevFmtUByte:
case DevFmtShort:
case DevFmtInt:
case DevFmtFloat:
break;
}

View File

@ -327,6 +327,8 @@ static ALCenum WinMMOpenPlayback(ALCdevice *pDevice, const ALCchar *deviceName)
case DevFmtByte:
pDevice->FmtType = DevFmtUByte;
break;
case DevFmtInt:
case DevFmtUInt:
case DevFmtUShort:
pDevice->FmtType = DevFmtShort;
break;
@ -518,7 +520,7 @@ static ALCenum WinMMOpenCapture(ALCdevice *pDevice, const ALCchar *deviceName)
if((pDevice->FmtChans != DevFmtMono && pDevice->FmtChans != DevFmtStereo) ||
(pDevice->FmtType != DevFmtUByte && pDevice->FmtType != DevFmtShort &&
pDevice->FmtType != DevFmtFloat))
pDevice->FmtType != DevFmtInt && pDevice->FmtType != DevFmtFloat))
goto failure;
memset(&wfexCaptureFormat, 0, sizeof(WAVEFORMATEX));

View File

@ -507,6 +507,8 @@ enum DevFmtType {
DevFmtUByte = ALC_UNSIGNED_BYTE_SOFT,
DevFmtShort = ALC_SHORT_SOFT,
DevFmtUShort = ALC_UNSIGNED_SHORT_SOFT,
DevFmtInt = ALC_INT_SOFT,
DevFmtUInt = ALC_UNSIGNED_INT_SOFT,
DevFmtFloat = ALC_FLOAT_SOFT
};
enum DevFmtChannels {