mirror of
https://github.com/openmoh/openmohaa.git
synced 2025-04-28 13:47:58 +03:00
Add support for IMA-ADPCM sounds (4-bit)
Sounds such as sea waves (mohaa m3l1a) and subpen (mohaas flughafen) will be played accordingly. This uses OpenAL extensions such as AL_EXT_IMA4 and SOFT features such as AL_SOFT_block_alignment
This commit is contained in:
parent
459e13dc76
commit
1e9decf193
8 changed files with 135 additions and 78 deletions
|
@ -81,6 +81,7 @@ LPALGENBUFFERS qalGenBuffers;
|
|||
LPALDELETEBUFFERS qalDeleteBuffers;
|
||||
LPALISBUFFER qalIsBuffer;
|
||||
LPALBUFFERDATA qalBufferData;
|
||||
LPALBUFFERI qalBufferi;
|
||||
LPALGETBUFFERF qalGetBufferf;
|
||||
LPALGETBUFFERFV qalGetBufferfv;
|
||||
LPALGETBUFFERI qalGetBufferi;
|
||||
|
@ -201,6 +202,7 @@ qboolean QAL_Init(const char *libname)
|
|||
qalDeleteBuffers = GPA("alDeleteBuffers");
|
||||
qalIsBuffer = GPA("alIsBuffer");
|
||||
qalBufferData = GPA("alBufferData");
|
||||
qalBufferi = GPA("alBufferi");
|
||||
qalGetBufferf = GPA("alGetBufferf");
|
||||
qalGetBufferfv = GPA("alGetBufferfv");
|
||||
qalGetBufferi = GPA("alGetBufferi");
|
||||
|
|
|
@ -120,7 +120,7 @@ extern LPALBUFFERDATA qalBufferData;
|
|||
extern LPALBUFFERF qalBufferf;
|
||||
extern LPALBUFFER3F qalBuffer3f;
|
||||
extern LPALBUFFERFV qalBufferfv;
|
||||
extern LPALBUFFERF qalBufferi;
|
||||
extern LPALBUFFERI qalBufferi;
|
||||
extern LPALBUFFER3F qalBuffer3i;
|
||||
extern LPALBUFFERFV qalBufferiv;
|
||||
extern LPALGETBUFFERF qalGetBufferf;
|
||||
|
|
|
@ -34,11 +34,12 @@ extern "C" {
|
|||
typedef struct snd_info_s
|
||||
{
|
||||
int rate;
|
||||
int width;
|
||||
float width;
|
||||
int channels;
|
||||
int samples;
|
||||
int size;
|
||||
int dataofs;
|
||||
int dataalign;
|
||||
} snd_info_t;
|
||||
|
||||
typedef struct snd_codec_s snd_codec_t;
|
||||
|
|
|
@ -622,7 +622,7 @@ int S_MP3_CodecReadStream(snd_stream_t* stream, int bytes, void* buffer)
|
|||
mp3info = stream->ptr;
|
||||
|
||||
// Make sure we get complete frames all the way through.
|
||||
bytes -= bytes % (stream->info.channels * stream->info.width);
|
||||
bytes -= fmod(bytes, (stream->info.channels * stream->info.width));
|
||||
|
||||
if (mp3info->buflen)
|
||||
{
|
||||
|
|
|
@ -133,6 +133,7 @@ static qboolean S_ReadRIFFHeader(fileHandle_t file, snd_info_t *info)
|
|||
char dump[16];
|
||||
int bits;
|
||||
int fmtlen = 0;
|
||||
int bytealign;
|
||||
|
||||
// skip the riff wav header
|
||||
FS_Read(dump, 12, file);
|
||||
|
@ -149,17 +150,22 @@ static qboolean S_ReadRIFFHeader(fileHandle_t file, snd_info_t *info)
|
|||
info->channels = FGetLittleShort(file);
|
||||
info->rate = FGetLittleLong(file);
|
||||
FGetLittleLong(file);
|
||||
FGetLittleShort(file);
|
||||
bytealign = FGetLittleShort(file);
|
||||
bits = FGetLittleShort(file);
|
||||
|
||||
if( bits < 8 )
|
||||
{
|
||||
Com_Printf( S_COLOR_RED "ERROR: Less than 8 bit sound is not supported\n");
|
||||
return qfalse;
|
||||
}
|
||||
//if( bits < 8 )
|
||||
//{
|
||||
// Com_Printf( S_COLOR_RED "ERROR: Less than 8 bit sound is not supported\n");
|
||||
// return qfalse;
|
||||
//}
|
||||
|
||||
info->width = bits / 8;
|
||||
info->width = bits / 8.0;
|
||||
info->dataofs = 0;
|
||||
if (bits == 16) {
|
||||
info->dataalign = 1;
|
||||
} else {
|
||||
info->dataalign = (bytealign / info->channels - 4) / 4 * 8 + 1;
|
||||
}
|
||||
|
||||
// Skip the rest of the format chunk if required
|
||||
if(fmtlen > 16)
|
||||
|
|
|
@ -62,6 +62,7 @@ typedef struct {
|
|||
|
||||
int dataofs;
|
||||
int datasize;
|
||||
int dataalign;
|
||||
} wavinfo_t;
|
||||
|
||||
typedef struct sfx_s {
|
||||
|
|
|
@ -43,13 +43,13 @@ short int GetLittleShort()
|
|||
byte bytes[2];
|
||||
} val;
|
||||
|
||||
# ifdef Q3_LITTLE_ENDIAN
|
||||
#ifdef Q3_LITTLE_ENDIAN
|
||||
val.bytes[0] = data_p[0];
|
||||
val.bytes[1] = data_p[1];
|
||||
# else
|
||||
#else
|
||||
val.bytes[0] = data_p[1];
|
||||
val.bytes[1] = data_p[0];
|
||||
# endif
|
||||
#endif
|
||||
|
||||
data_p += sizeof(short);
|
||||
return val.value;
|
||||
|
@ -67,17 +67,17 @@ int GetLittleLong()
|
|||
byte bytes[4];
|
||||
} val;
|
||||
|
||||
# ifdef Q3_LITTLE_ENDIAN
|
||||
#ifdef Q3_LITTLE_ENDIAN
|
||||
val.bytes[0] = data_p[0];
|
||||
val.bytes[1] = data_p[1];
|
||||
val.bytes[2] = data_p[2];
|
||||
val.bytes[3] = data_p[3];
|
||||
# else
|
||||
#else
|
||||
val.bytes[0] = data_p[3];
|
||||
val.bytes[1] = data_p[2];
|
||||
val.bytes[2] = data_p[1];
|
||||
val.bytes[3] = data_p[0];
|
||||
# endif
|
||||
#endif
|
||||
|
||||
data_p += sizeof(int);
|
||||
return val.value;
|
||||
|
@ -97,13 +97,13 @@ void SetLittleShort(int i)
|
|||
|
||||
val.value = i;
|
||||
|
||||
# ifdef Q3_LITTLE_ENDIAN
|
||||
#ifdef Q3_LITTLE_ENDIAN
|
||||
data_p[0] = val.bytes[0];
|
||||
data_p[1] = val.bytes[1];
|
||||
# else
|
||||
#else
|
||||
data_p[0] = val.bytes[1];
|
||||
data_p[1] = val.bytes[0];
|
||||
# endif
|
||||
#endif
|
||||
|
||||
data_p += sizeof(short);
|
||||
}
|
||||
|
@ -122,17 +122,17 @@ void SetLittleLong(int i)
|
|||
|
||||
val.value = i;
|
||||
|
||||
# ifdef Q3_LITTLE_ENDIAN
|
||||
#ifdef Q3_LITTLE_ENDIAN
|
||||
data_p[0] = val.bytes[0];
|
||||
data_p[1] = val.bytes[1];
|
||||
data_p[2] = val.bytes[2];
|
||||
data_p[3] = val.bytes[3];
|
||||
# else
|
||||
#else
|
||||
data_p[0] = val.bytes[3];
|
||||
data_p[1] = val.bytes[2];
|
||||
data_p[2] = val.bytes[1];
|
||||
data_p[3] = val.bytes[0];
|
||||
# endif
|
||||
#endif
|
||||
|
||||
data_p += sizeof(int);
|
||||
}
|
||||
|
@ -218,6 +218,7 @@ wavinfo_t GetWavinfo(const char *name, byte *wav, int wavlength)
|
|||
{
|
||||
wavinfo_t info;
|
||||
int samples;
|
||||
short bytealign;
|
||||
|
||||
memset(&info, 0, sizeof(wavinfo_t));
|
||||
|
||||
|
@ -247,7 +248,9 @@ wavinfo_t GetWavinfo(const char *name, byte *wav, int wavlength)
|
|||
if (info.format == 17) {
|
||||
info.channels = GetLittleShort();
|
||||
info.rate = (float)GetLittleLong();
|
||||
data_p += 6;
|
||||
data_p += 4;
|
||||
|
||||
bytealign = GetLittleShort();
|
||||
info.width = (float)GetLittleShort() / 8.f;
|
||||
data_p += 2;
|
||||
|
||||
|
@ -270,12 +273,16 @@ wavinfo_t GetWavinfo(const char *name, byte *wav, int wavlength)
|
|||
Com_Error(ERR_DROP, "Sound %s has a bad loop length", name);
|
||||
}
|
||||
|
||||
info.dataofs = 0;
|
||||
info.dataofs = data_p - wav;
|
||||
info.datasize = iff_chunk_len - bytealign + info.dataofs;
|
||||
info.dataalign = (bytealign / info.channels - 4) / 4 * 8 + 1;
|
||||
} else if (info.format == 1) {
|
||||
info.channels = GetLittleShort();
|
||||
info.rate = (float)GetLittleLong();
|
||||
data_p += 6;
|
||||
info.width = (float)(GetLittleShort() / 8);
|
||||
data_p += 4;
|
||||
|
||||
bytealign = GetLittleShort();
|
||||
info.width = (float)GetLittleShort() / 8.f;
|
||||
|
||||
FindChunk("data");
|
||||
if (!data_p) {
|
||||
|
@ -292,14 +299,16 @@ wavinfo_t GetWavinfo(const char *name, byte *wav, int wavlength)
|
|||
Com_Error(ERR_DROP, "Sound %s has a bad loop length", name);
|
||||
}
|
||||
|
||||
info.dataofs = data_p - wav;
|
||||
info.dataofs = data_p - wav;
|
||||
info.datasize = iff_chunk_len;
|
||||
info.dataalign = (bytealign / info.channels - 4) / 4 * 8 + 1;
|
||||
// dataalign should always be 1
|
||||
assert(info.dataalign == 1);
|
||||
} else {
|
||||
Com_Printf("Microsoft PCM format only\n");
|
||||
return info;
|
||||
}
|
||||
|
||||
info.datasize = iff_chunk_len;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
|
@ -310,26 +319,24 @@ DownSampleWav
|
|||
*/
|
||||
qboolean DownSampleWav(wavinfo_t *info, byte *wav, int wavlength, int newkhz, byte **newdata)
|
||||
{
|
||||
int newdatasize;
|
||||
byte* datap;
|
||||
int i;
|
||||
int ii;
|
||||
int error;
|
||||
int width;
|
||||
int oldsamples;
|
||||
int oldrate;
|
||||
int newdatasize;
|
||||
byte *datap;
|
||||
int i;
|
||||
int ii;
|
||||
int error;
|
||||
int width;
|
||||
int oldsamples;
|
||||
int oldrate;
|
||||
|
||||
newdatasize = 0;
|
||||
datap = &wav[info->dataofs];
|
||||
datap = &wav[info->dataofs];
|
||||
|
||||
if (info->channels > 1)
|
||||
{
|
||||
if (info->channels > 1) {
|
||||
Com_DPrintf("Could not downsample WAV file. Stereo WAVs not supported!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (info->format != 1 || !info->dataofs)
|
||||
{
|
||||
if (info->format != 1 || !info->dataofs) {
|
||||
Com_DPrintf("Could not downsample WAV file. Not PCM format!\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -348,29 +355,27 @@ qboolean DownSampleWav(wavinfo_t *info, byte *wav, int wavlength, int newkhz, by
|
|||
}
|
||||
}
|
||||
|
||||
oldsamples = info->samples;
|
||||
oldrate = info->rate;
|
||||
oldsamples = info->samples;
|
||||
oldrate = info->rate;
|
||||
info->samples = newdatasize / width;
|
||||
info->rate = (float)newkhz;
|
||||
info->rate = (float)newkhz;
|
||||
newdatasize += info->dataofs;
|
||||
|
||||
*newdata = (byte*)Z_TagMalloc(newdatasize, TAG_SOUND);
|
||||
*newdata = (byte *)Z_TagMalloc(newdatasize, TAG_SOUND);
|
||||
memcpy(*newdata, wav, info->dataofs);
|
||||
|
||||
iff_data = *newdata;
|
||||
iff_end = *newdata + newdatasize;
|
||||
iff_end = *newdata + newdatasize;
|
||||
FindChunk("RIFF");
|
||||
|
||||
if (!data_p || strncmp((const char*)data_p + 8, "WAVE", 4u))
|
||||
{
|
||||
if (!data_p || strncmp((const char *)data_p + 8, "WAVE", 4u)) {
|
||||
Com_DPrintf("Missing RIFF/WAVE chunks\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
iff_data = data_p + 12;
|
||||
FindChunk("fmt ");
|
||||
if (!data_p)
|
||||
{
|
||||
if (!data_p) {
|
||||
Com_DPrintf("Missing fmt chunk\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -380,8 +385,7 @@ qboolean DownSampleWav(wavinfo_t *info, byte *wav, int wavlength, int newkhz, by
|
|||
data_p += 8;
|
||||
|
||||
FindChunk("data");
|
||||
if (!data_p)
|
||||
{
|
||||
if (!data_p) {
|
||||
Com_DPrintf("Missing data chunk\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -427,10 +431,10 @@ S_LoadSound
|
|||
*/
|
||||
qboolean S_LoadSound(const char *fileName, sfx_t *sfx, int streamed, qboolean force_load)
|
||||
{
|
||||
int size;
|
||||
int size;
|
||||
fileHandle_t file_handle;
|
||||
char tempName[MAX_RES_NAME + 1];
|
||||
int realKhz;
|
||||
char tempName[MAX_RES_NAME + 1];
|
||||
int realKhz;
|
||||
|
||||
sfx->buffer = 0;
|
||||
|
||||
|
@ -440,10 +444,10 @@ qboolean S_LoadSound(const char *fileName, sfx_t *sfx, int streamed, qboolean fo
|
|||
|
||||
if (streamed) {
|
||||
sfx->length = 5000;
|
||||
sfx->width = 1;
|
||||
sfx->width = 1;
|
||||
sfx->iFlags |= SFX_FLAG_STREAMED;
|
||||
sfx->time_length = 5000.0;
|
||||
sfx->data = NULL;
|
||||
sfx->data = NULL;
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
|
@ -456,22 +460,20 @@ qboolean S_LoadSound(const char *fileName, sfx_t *sfx, int streamed, qboolean fo
|
|||
}
|
||||
|
||||
size = FS_FOpenFileRead(fileName, &file_handle, qfalse, qtrue);
|
||||
if (size <= 0)
|
||||
{
|
||||
if (size <= 0) {
|
||||
if (file_handle) {
|
||||
FS_FCloseFile(file_handle);
|
||||
}
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
sfx->data = (byte*)Z_TagMalloc(size, TAG_SOUND);
|
||||
sfx->data = (byte *)Z_TagMalloc(size, TAG_SOUND);
|
||||
|
||||
FS_Read(sfx->data, size, file_handle);
|
||||
FS_FCloseFile(file_handle);
|
||||
sfx->info = GetWavinfo(fileName, sfx->data, size);
|
||||
|
||||
if (sfx->info.channels != 1 && !streamed)
|
||||
{
|
||||
if (sfx->info.channels != 1 && !streamed) {
|
||||
Com_Printf("%s is a stereo wav file\n", fileName);
|
||||
Z_Free(sfx->data);
|
||||
sfx->data = NULL;
|
||||
|
@ -496,8 +498,8 @@ qboolean S_LoadSound(const char *fileName, sfx_t *sfx, int streamed, qboolean fo
|
|||
}
|
||||
|
||||
if (!(sfx->iFlags & SFX_FLAG_STREAMED) && realKhz < sfx->info.rate) {
|
||||
byte* newdata;
|
||||
int newdatasize;
|
||||
byte *newdata;
|
||||
int newdatasize;
|
||||
|
||||
newdata = NULL;
|
||||
if (sfx->iFlags & SFX_FLAG_NO_OFFSET) {
|
||||
|
@ -508,13 +510,13 @@ qboolean S_LoadSound(const char *fileName, sfx_t *sfx, int streamed, qboolean fo
|
|||
|
||||
if (newdatasize) {
|
||||
Z_Free(sfx->data);
|
||||
sfx->data = newdata;
|
||||
sfx->data = newdata;
|
||||
sfx->info.datasize = newdatasize;
|
||||
}
|
||||
}
|
||||
|
||||
sfx->length = sfx->info.samples;
|
||||
sfx->width = sfx->info.width;
|
||||
sfx->length = sfx->info.samples;
|
||||
sfx->width = sfx->info.width;
|
||||
sfx->time_length = sfx->info.samples / sfx->info.rate * 1000.f;
|
||||
|
||||
if (sfx->iFlags & SFX_FLAG_STREAMED) {
|
||||
|
@ -540,7 +542,7 @@ S_LoadMP3
|
|||
*/
|
||||
qboolean S_LoadMP3(const char *fileName, sfx_t *sfx)
|
||||
{
|
||||
int length;
|
||||
int length;
|
||||
fileHandle_t file_handle;
|
||||
|
||||
length = FS_FOpenFileRead(fileName, &file_handle, 0, 1);
|
||||
|
@ -552,9 +554,9 @@ qboolean S_LoadMP3(const char *fileName, sfx_t *sfx)
|
|||
}
|
||||
|
||||
memset(&sfx->info, 0, sizeof(sfx->info));
|
||||
sfx->data = (byte*)Z_TagMalloc(length, TAG_SOUND);
|
||||
sfx->data = (byte *)Z_TagMalloc(length, TAG_SOUND);
|
||||
sfx->length = length;
|
||||
sfx->width = 1;
|
||||
sfx->width = 1;
|
||||
FS_Read(sfx->data, length, file_handle);
|
||||
FS_FCloseFile(file_handle);
|
||||
|
||||
|
|
|
@ -100,6 +100,9 @@ int music_currentsong = 0;
|
|||
static qboolean enumeration_ext = qfalse;
|
||||
static qboolean enumeration_all_ext = qfalse;
|
||||
|
||||
static qboolean ima4_ext = qfalse;
|
||||
static qboolean soft_block_align = qfalse;
|
||||
|
||||
song_t music_songs[MAX_MUSIC_SONGS];
|
||||
openal_internal_t openal;
|
||||
static float s_fFadeStartTime;
|
||||
|
@ -113,7 +116,7 @@ static int
|
|||
S_OPENAL_SpatializeStereoSound(const vec3_t listener_origin, const vec3_t listener_left, const vec3_t origin);
|
||||
static void S_OPENAL_reverb(int iChannel, int iReverbType, float fReverbLevel);
|
||||
static bool S_OPENAL_LoadMP3_Codec(const char *_path, sfx_t *pSfx);
|
||||
static ALuint S_OPENAL_Format(int width, int channels);
|
||||
static ALuint S_OPENAL_Format(float width, int channels);
|
||||
|
||||
#define alDieIfError() __alDieIfError(__FILE__, __LINE__)
|
||||
|
||||
|
@ -449,7 +452,9 @@ S_OPENAL_InitExtensions
|
|||
*/
|
||||
static bool S_OPENAL_InitExtensions()
|
||||
{
|
||||
Com_Printf("AL extensions ignored\n");
|
||||
ima4_ext = qalIsExtensionPresent("AL_EXT_IMA4");
|
||||
soft_block_align = qalIsExtensionPresent("AL_SOFT_block_alignment");
|
||||
|
||||
return true;
|
||||
|
||||
extensions_table_t extensions_table[4] = {
|
||||
|
@ -612,7 +617,9 @@ qboolean S_OPENAL_Init()
|
|||
}
|
||||
|
||||
for (i = 0; i < MAX_SOUNDSYSTEM_CHANNELS_2D_STREAM; i++) {
|
||||
if (!S_OPENAL_InitChannel(i + MAX_SOUNDSYSTEM_CHANNELS_3D + MAX_SOUNDSYSTEM_CHANNELS_2D, &openal.chan_2D_stream[i])) {
|
||||
if (!S_OPENAL_InitChannel(
|
||||
i + MAX_SOUNDSYSTEM_CHANNELS_3D + MAX_SOUNDSYSTEM_CHANNELS_2D, &openal.chan_2D_stream[i]
|
||||
)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -827,7 +834,8 @@ void S_DumpInfo()
|
|||
S_DumpStatus(
|
||||
"Misc",
|
||||
i,
|
||||
openal.channel[MAX_SOUNDSYSTEM_CHANNELS_3D + MAX_SOUNDSYSTEM_CHANNELS_2D + MAX_SOUNDSYSTEM_CHANNELS_2D_STREAM + i]
|
||||
openal.channel
|
||||
[MAX_SOUNDSYSTEM_CHANNELS_3D + MAX_SOUNDSYSTEM_CHANNELS_2D + MAX_SOUNDSYSTEM_CHANNELS_2D_STREAM + i]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1818,7 +1826,9 @@ static int S_OPENAL_Start2DLoopSound(
|
|||
pChannel->set_gain(fVolumeToPlay);
|
||||
pChannel->start_sample();
|
||||
if (s_show_sounds->integer > 0) {
|
||||
Com_DPrintf("OpenAL: %d (#%i) - %s (vol %f)\n", cl.serverTime, pLoopSound->iChannel, pLoopSound->pSfx->name, fVolume);
|
||||
Com_DPrintf(
|
||||
"OpenAL: %d (#%i) - %s (vol %f)\n", cl.serverTime, pLoopSound->iChannel, pLoopSound->pSfx->name, fVolume
|
||||
);
|
||||
}
|
||||
|
||||
return iChannel;
|
||||
|
@ -2138,7 +2148,9 @@ void S_OPENAL_AddLoopSounds(const vec3_t vTempAxis)
|
|||
}
|
||||
|
||||
if (s_show_sounds->integer > 0) {
|
||||
Com_DPrintf("OpenAL: %d (#%i) - started loop - %s\n", cl.serverTime, pLoopSound->iChannel, pLoopSound->pSfx->name);
|
||||
Com_DPrintf(
|
||||
"OpenAL: %d (#%i) - started loop - %s\n", cl.serverTime, pLoopSound->iChannel, pLoopSound->pSfx->name
|
||||
);
|
||||
}
|
||||
|
||||
if (pLoopSound->pSfx->iFlags & (SFX_FLAG_NO_OFFSET)
|
||||
|
@ -2991,9 +3003,21 @@ bool openal_channel::set_sfx(sfx_t *pSfx)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (pSfx->info.dataalign > 1 && !soft_block_align) {
|
||||
Com_DPrintf(
|
||||
"OpenAL: Alignment specified but AL doesn't support block alignment (%d).", pSfx->info.dataalign
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
qalGenBuffers(1, &pSfx->buffer);
|
||||
alDieIfError();
|
||||
|
||||
if (pSfx->info.dataalign > 1) {
|
||||
qalBufferi(pSfx->buffer, AL_UNPACK_BLOCK_ALIGNMENT_SOFT, pSfx->info.dataalign);
|
||||
alDieIfError();
|
||||
}
|
||||
|
||||
qalBufferData(
|
||||
pSfx->buffer,
|
||||
fmt,
|
||||
|
@ -4216,7 +4240,7 @@ int S_CurrentMoviePosition()
|
|||
S_AL_Format
|
||||
=================
|
||||
*/
|
||||
static ALuint S_OPENAL_Format(int width, int channels)
|
||||
static ALuint S_OPENAL_Format(float width, int channels)
|
||||
{
|
||||
ALuint format = AL_FORMAT_MONO16;
|
||||
|
||||
|
@ -4233,6 +4257,17 @@ static ALuint S_OPENAL_Format(int width, int channels)
|
|||
} else if (channels == 2) {
|
||||
format = AL_FORMAT_STEREO16;
|
||||
}
|
||||
} else if (width == 0.5) {
|
||||
if (ima4_ext && soft_block_align) {
|
||||
if (channels == 1) {
|
||||
format = AL_FORMAT_MONO_IMA4;
|
||||
} else if (channels == 2) {
|
||||
format = AL_FORMAT_STEREO_IMA4;
|
||||
}
|
||||
} else {
|
||||
// unsupported
|
||||
format = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return format;
|
||||
|
@ -4360,6 +4395,11 @@ bool openal_channel_two_d_stream::set_sfx(sfx_t *pSfx)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (stream->info.dataalign > 1 && soft_block_align) {
|
||||
qalBufferi(buffers[currentBuf], AL_UNPACK_BLOCK_ALIGNMENT_SOFT, stream->info.dataalign);
|
||||
alDieIfError();
|
||||
}
|
||||
|
||||
qalBufferData(buffers[currentBuf], pSfx->info.format, rawData, bytesRead, stream->info.rate);
|
||||
alDieIfError();
|
||||
|
||||
|
@ -4499,6 +4539,11 @@ void openal_channel_two_d_stream::update()
|
|||
}
|
||||
}
|
||||
|
||||
if (stream->info.dataalign > 1 && soft_block_align) {
|
||||
qalBufferi(buffers[currentBuf], AL_UNPACK_BLOCK_ALIGNMENT_SOFT, stream->info.dataalign);
|
||||
alDieIfError();
|
||||
}
|
||||
|
||||
qalBufferData(buffers[currentBuf], format, rawData, bytesRead, stream->info.rate);
|
||||
alDieIfError();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue