Load soundfont samples into an ALbuffer
Also remove ALsoundfont's now-unneeded sample storage functions and struct fields.
This commit is contained in:
@@ -293,10 +293,6 @@ static const ALCfunction alcFunctions[] = {
|
||||
DECL(alGenSoundfontsSOFT),
|
||||
DECL(alDeleteSoundfontsSOFT),
|
||||
DECL(alIsSoundfontSOFT),
|
||||
DECL(alSoundfontSamplesSOFT),
|
||||
DECL(alGetSoundfontSamplesSOFT),
|
||||
DECL(alSoundfontMapSamplesSOFT),
|
||||
DECL(alSoundfontUnmapSamplesSOFT),
|
||||
DECL(alGetSoundfontivSOFT),
|
||||
DECL(alSoundfontPresetsSOFT),
|
||||
DECL(alGenPresetsSOFT),
|
||||
|
||||
@@ -218,7 +218,7 @@ static int FPreset_getPreset(fluid_preset_t *preset);
|
||||
static int FPreset_getBank(fluid_preset_t *preset);
|
||||
static int FPreset_noteOn(fluid_preset_t *preset, fluid_synth_t *synth, int channel, int key, int velocity);
|
||||
|
||||
static void FPreset_Construct(FPreset *self, ALsfpreset *preset, fluid_sfont_t *parent, ALsoundfont *sfont)
|
||||
static void FPreset_Construct(FPreset *self, ALsfpreset *preset, fluid_sfont_t *parent)
|
||||
{
|
||||
STATIC_CAST(fluid_preset_t, self)->data = self;
|
||||
STATIC_CAST(fluid_preset_t, self)->sfont = parent;
|
||||
@@ -386,7 +386,7 @@ static void FSfont_Construct(FSfont *self, ALsoundfont *sfont)
|
||||
ALsizei i;
|
||||
self->NumPresets = sfont->NumPresets;
|
||||
for(i = 0;i < self->NumPresets;i++)
|
||||
FPreset_Construct(&self->Presets[i], sfont->Presets[i], STATIC_CAST(fluid_sfont_t, self), sfont);
|
||||
FPreset_Construct(&self->Presets[i], sfont->Presets[i], STATIC_CAST(fluid_sfont_t, self));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+19
-6
@@ -897,7 +897,7 @@ static void fillZone(ALfontsound *sound, ALCcontext *context, const GenModList *
|
||||
}
|
||||
}
|
||||
|
||||
static void processInstrument(ALfontsound ***sounds, ALsizei *sounds_size, ALCcontext *context, InstrumentHeader *inst, const PresetHeader *preset, const Soundfont *sfont, const GenModList *pzone)
|
||||
static void processInstrument(ALfontsound ***sounds, ALsizei *sounds_size, ALCcontext *context, ALbuffer *buffer, InstrumentHeader *inst, const PresetHeader *preset, const Soundfont *sfont, const GenModList *pzone)
|
||||
{
|
||||
const Generator *gen, *gen_end;
|
||||
const Modulator *mod, *mod_end;
|
||||
@@ -990,6 +990,7 @@ static void processInstrument(ALfontsound ***sounds, ALsizei *sounds_size, ALCco
|
||||
|
||||
sound = NewFontsound(context);
|
||||
(*sounds)[(*sounds_size)++] = sound;
|
||||
ALfontsound_setPropi(sound, context, AL_BUFFER, buffer->id);
|
||||
ALfontsound_setPropi(sound, context, AL_SAMPLE_START_SOFT, samp->mStart);
|
||||
ALfontsound_setPropi(sound, context, AL_SAMPLE_END_SOFT, samp->mEnd);
|
||||
ALfontsound_setPropi(sound, context, AL_SAMPLE_LOOP_START_SOFT, samp->mStartloop);
|
||||
@@ -1015,6 +1016,7 @@ ALboolean loadSf2(Reader *stream, ALsoundfont *soundfont, ALCcontext *context)
|
||||
{
|
||||
ALsfpreset **presets = NULL;
|
||||
ALsizei presets_size = 0;
|
||||
ALbuffer *buffer = NULL;
|
||||
ALuint ltype;
|
||||
Soundfont sfont;
|
||||
RiffHdr riff;
|
||||
@@ -1099,6 +1101,7 @@ ALboolean loadSf2(Reader *stream, ALsoundfont *soundfont, ALCcontext *context)
|
||||
{
|
||||
ALbyte *ptr;
|
||||
RiffHdr smpl;
|
||||
ALenum err;
|
||||
|
||||
RiffHdr_read(&smpl, stream);
|
||||
if(smpl.mCode != FOURCC('s','m','p','l'))
|
||||
@@ -1108,11 +1111,14 @@ ALboolean loadSf2(Reader *stream, ALsoundfont *soundfont, ALCcontext *context)
|
||||
if(smpl.mSize > list.mSize)
|
||||
ERROR_GOTO(error, "Invalid Format, sample chunk size mismatch\n");
|
||||
|
||||
if(!(ptr=realloc(soundfont->Samples, smpl.mSize)))
|
||||
buffer = NewBuffer(context);
|
||||
if(!buffer)
|
||||
SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, error);
|
||||
soundfont->Samples = (ALshort*)ptr;
|
||||
soundfont->NumSamples = smpl.mSize/2;
|
||||
/* Sample rate it unimportant, the individual fontsounds will specify it. */
|
||||
if((err=LoadData(buffer, 22050, AL_MONO16_SOFT, smpl.mSize/2, UserFmtMono, UserFmtShort, NULL, 1, AL_FALSE)) != AL_NO_ERROR)
|
||||
SET_ERROR_AND_GOTO(context, err, error);
|
||||
|
||||
ptr = buffer->data;
|
||||
if(IS_LITTLE_ENDIAN)
|
||||
READ(stream, ptr, smpl.mSize);
|
||||
else
|
||||
@@ -1310,8 +1316,10 @@ ALboolean loadSf2(Reader *stream, ALsoundfont *soundfont, ALCcontext *context)
|
||||
ERR("Generator %ld has invalid instrument ID (%d of %d)\n",
|
||||
(long)(gen-sfont.pgen), gen->mAmount, sfont.inst_size-1);
|
||||
else
|
||||
processInstrument(&sounds, &sounds_size, context,
|
||||
&sfont.inst[gen->mAmount], &sfont.phdr[i], &sfont, &lzone);
|
||||
processInstrument(
|
||||
&sounds, &sounds_size, context, buffer, &sfont.inst[gen->mAmount],
|
||||
&sfont.phdr[i], &sfont, &lzone
|
||||
);
|
||||
break;
|
||||
}
|
||||
GenModList_insertGen(&lzone, gen, AL_TRUE);
|
||||
@@ -1346,6 +1354,9 @@ ALboolean loadSf2(Reader *stream, ALsoundfont *soundfont, ALCcontext *context)
|
||||
free(presets);
|
||||
|
||||
Soundfont_Destruct(&sfont);
|
||||
/* If the buffer ends up unused, delete it. */
|
||||
if(ReadRef(&buffer->ref) == 0)
|
||||
DeleteBuffer(context->Device, buffer->id);
|
||||
|
||||
return AL_TRUE;
|
||||
|
||||
@@ -1359,6 +1370,8 @@ error:
|
||||
}
|
||||
|
||||
Soundfont_Destruct(&sfont);
|
||||
if(buffer)
|
||||
DeleteBuffer(context->Device, buffer->id);
|
||||
|
||||
return AL_FALSE;
|
||||
}
|
||||
|
||||
+15
-15
@@ -121,7 +121,7 @@ DECL_TEMPLATE(ALfloat)
|
||||
|
||||
#undef DECL_TEMPLATE
|
||||
|
||||
static void LoadData(ALfloat *dst, const ALvoid *src, ALuint srcstep, enum FmtType srctype, ALuint samples)
|
||||
static void LoadSamples(ALfloat *dst, const ALvoid *src, ALuint srcstep, enum FmtType srctype, ALuint samples)
|
||||
{
|
||||
switch(srctype)
|
||||
{
|
||||
@@ -137,7 +137,7 @@ static void LoadData(ALfloat *dst, const ALvoid *src, ALuint srcstep, enum FmtTy
|
||||
}
|
||||
}
|
||||
|
||||
static void SilenceData(ALfloat *dst, ALuint samples)
|
||||
static void SilenceSamples(ALfloat *dst, ALuint samples)
|
||||
{
|
||||
ALuint i;
|
||||
for(i = 0;i < samples;i++)
|
||||
@@ -265,7 +265,7 @@ ALvoid MixSource(ALactivesource *src, ALCdevice *Device, ALuint SamplesToDo)
|
||||
DataSize = BufferPrePadding - DataPosInt;
|
||||
DataSize = minu(SrcBufferSize - SrcDataSize, DataSize);
|
||||
|
||||
SilenceData(&SrcData[SrcDataSize], DataSize);
|
||||
SilenceSamples(&SrcData[SrcDataSize], DataSize);
|
||||
SrcDataSize += DataSize;
|
||||
|
||||
pos = 0;
|
||||
@@ -275,11 +275,11 @@ ALvoid MixSource(ALactivesource *src, ALCdevice *Device, ALuint SamplesToDo)
|
||||
* rest of the temp buffer */
|
||||
DataSize = minu(SrcBufferSize - SrcDataSize, ALBuffer->SampleLen - pos);
|
||||
|
||||
LoadData(&SrcData[SrcDataSize], &Data[(pos*NumChannels + chan)*SampleSize],
|
||||
NumChannels, ALBuffer->FmtType, DataSize);
|
||||
LoadSamples(&SrcData[SrcDataSize], &Data[(pos*NumChannels + chan)*SampleSize],
|
||||
NumChannels, ALBuffer->FmtType, DataSize);
|
||||
SrcDataSize += DataSize;
|
||||
|
||||
SilenceData(&SrcData[SrcDataSize], SrcBufferSize - SrcDataSize);
|
||||
SilenceSamples(&SrcData[SrcDataSize], SrcBufferSize - SrcDataSize);
|
||||
SrcDataSize += SrcBufferSize - SrcDataSize;
|
||||
}
|
||||
else
|
||||
@@ -302,7 +302,7 @@ ALvoid MixSource(ALactivesource *src, ALCdevice *Device, ALuint SamplesToDo)
|
||||
DataSize = BufferPrePadding - DataPosInt;
|
||||
DataSize = minu(SrcBufferSize - SrcDataSize, DataSize);
|
||||
|
||||
SilenceData(&SrcData[SrcDataSize], DataSize);
|
||||
SilenceSamples(&SrcData[SrcDataSize], DataSize);
|
||||
SrcDataSize += DataSize;
|
||||
|
||||
pos = 0;
|
||||
@@ -313,8 +313,8 @@ ALvoid MixSource(ALactivesource *src, ALCdevice *Device, ALuint SamplesToDo)
|
||||
DataSize = LoopEnd - pos;
|
||||
DataSize = minu(SrcBufferSize - SrcDataSize, DataSize);
|
||||
|
||||
LoadData(&SrcData[SrcDataSize], &Data[(pos*NumChannels + chan)*SampleSize],
|
||||
NumChannels, ALBuffer->FmtType, DataSize);
|
||||
LoadSamples(&SrcData[SrcDataSize], &Data[(pos*NumChannels + chan)*SampleSize],
|
||||
NumChannels, ALBuffer->FmtType, DataSize);
|
||||
SrcDataSize += DataSize;
|
||||
|
||||
DataSize = LoopEnd-LoopStart;
|
||||
@@ -322,8 +322,8 @@ ALvoid MixSource(ALactivesource *src, ALCdevice *Device, ALuint SamplesToDo)
|
||||
{
|
||||
DataSize = minu(SrcBufferSize - SrcDataSize, DataSize);
|
||||
|
||||
LoadData(&SrcData[SrcDataSize], &Data[(LoopStart*NumChannels + chan)*SampleSize],
|
||||
NumChannels, ALBuffer->FmtType, DataSize);
|
||||
LoadSamples(&SrcData[SrcDataSize], &Data[(LoopStart*NumChannels + chan)*SampleSize],
|
||||
NumChannels, ALBuffer->FmtType, DataSize);
|
||||
SrcDataSize += DataSize;
|
||||
}
|
||||
}
|
||||
@@ -353,7 +353,7 @@ ALvoid MixSource(ALactivesource *src, ALCdevice *Device, ALuint SamplesToDo)
|
||||
{
|
||||
ALuint DataSize = minu(SrcBufferSize - SrcDataSize, pos);
|
||||
|
||||
SilenceData(&SrcData[SrcDataSize], DataSize);
|
||||
SilenceSamples(&SrcData[SrcDataSize], DataSize);
|
||||
SrcDataSize += DataSize;
|
||||
|
||||
pos = 0;
|
||||
@@ -390,8 +390,8 @@ ALvoid MixSource(ALactivesource *src, ALCdevice *Device, ALuint SamplesToDo)
|
||||
pos -= pos;
|
||||
|
||||
DataSize = minu(SrcBufferSize - SrcDataSize, DataSize);
|
||||
LoadData(&SrcData[SrcDataSize], Data, NumChannels,
|
||||
ALBuffer->FmtType, DataSize);
|
||||
LoadSamples(&SrcData[SrcDataSize], Data, NumChannels,
|
||||
ALBuffer->FmtType, DataSize);
|
||||
SrcDataSize += DataSize;
|
||||
}
|
||||
}
|
||||
@@ -400,7 +400,7 @@ ALvoid MixSource(ALactivesource *src, ALCdevice *Device, ALuint SamplesToDo)
|
||||
tmpiter = Source->queue;
|
||||
else if(!tmpiter)
|
||||
{
|
||||
SilenceData(&SrcData[SrcDataSize], SrcBufferSize - SrcDataSize);
|
||||
SilenceSamples(&SrcData[SrcDataSize], SrcBufferSize - SrcDataSize);
|
||||
SrcDataSize += SrcBufferSize - SrcDataSize;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,6 +97,11 @@ typedef struct ALbuffer {
|
||||
ALuint id;
|
||||
} ALbuffer;
|
||||
|
||||
ALbuffer *NewBuffer(ALCcontext *context);
|
||||
void DeleteBuffer(ALCdevice *device, ALuint bufid);
|
||||
|
||||
ALenum LoadData(ALbuffer *buffer, ALuint freq, ALenum NewFormat, ALsizei frames, enum UserFmtChannels SrcChannels, enum UserFmtType SrcType, const ALvoid *data, ALsizei align, ALboolean storesrc);
|
||||
|
||||
inline struct ALbuffer *LookupBuffer(ALCdevice *device, ALuint id)
|
||||
{ return (struct ALbuffer*)LookupUIntMapKey(&device->BufferMap, id); }
|
||||
inline struct ALbuffer *RemoveBuffer(ALCdevice *device, ALuint id)
|
||||
|
||||
@@ -155,10 +155,6 @@
|
||||
typedef void (AL_APIENTRY*LPALGENSOUNDFONTSSOFT)(ALsizei n, ALuint *ids);
|
||||
typedef void (AL_APIENTRY*LPALDELETESOUNDFONTSSOFT)(ALsizei n, const ALuint *ids);
|
||||
typedef ALboolean (AL_APIENTRY*LPALISSOUNDFONTSOFT)(ALuint id);
|
||||
typedef void (AL_APIENTRY*LPALSOUNDFONTSAMPLESSOFT)(ALuint sfid, ALenum type, ALsizei count, const ALvoid *samples);
|
||||
typedef void (AL_APIENTRY*LPALGETSOUNDFONTSAMPLESSOFT)(ALuint id, ALsizei offset, ALsizei count, ALenum type, ALvoid *samples);
|
||||
typedef ALvoid* (AL_APIENTRY*LPALSOUNDFONTMAPSAMPLESSOFT)(ALuint sfid, ALsizei offset, ALsizei length);
|
||||
typedef void (AL_APIENTRY*LPALSOUNDFONTUNMAPSAMPLESSOFT)(ALuint sfid);
|
||||
typedef void (AL_APIENTRY*LPALGETSOUNDFONTIVSOFT)(ALuint id, ALenum param, ALint *values);
|
||||
typedef void (AL_APIENTRY*LPALSOUNDFONTPRESETSSOFT)(ALuint id, ALsizei count, const ALuint *pids);
|
||||
typedef void (AL_APIENTRY*LPALGENPRESETSSOFT)(ALsizei n, ALuint *ids);
|
||||
@@ -193,10 +189,6 @@ typedef void (AL_APIENTRY*LPALLOADSOUNDFONTSOFT)(ALuint id, size_t(*cb)(ALvoid*,
|
||||
AL_API void AL_APIENTRY alGenSoundfontsSOFT(ALsizei n, ALuint *ids);
|
||||
AL_API void AL_APIENTRY alDeleteSoundfontsSOFT(ALsizei n, const ALuint *ids);
|
||||
AL_API ALboolean AL_APIENTRY alIsSoundfontSOFT(ALuint id);
|
||||
AL_API void AL_APIENTRY alSoundfontSamplesSOFT(ALuint sfid, ALenum type, ALsizei count, const ALvoid *samples);
|
||||
AL_API void AL_APIENTRY alGetSoundfontSamplesSOFT(ALuint id, ALsizei offset, ALsizei count, ALenum type, ALvoid *samples);
|
||||
AL_API ALvoid* AL_APIENTRY alSoundfontMapSamplesSOFT(ALuint sfid, ALsizei offset, ALsizei length);
|
||||
AL_API void AL_APIENTRY alSoundfontUnmapSamplesSOFT(ALuint sfid);
|
||||
AL_API void AL_APIENTRY alGetSoundfontivSOFT(ALuint id, ALenum param, ALint *values);
|
||||
AL_API void AL_APIENTRY alSoundfontPresetsSOFT(ALuint id, ALsizei count, const ALuint *pids);
|
||||
|
||||
|
||||
@@ -140,11 +140,7 @@ typedef struct ALsoundfont {
|
||||
ALsfpreset **Presets;
|
||||
ALsizei NumPresets;
|
||||
|
||||
ALshort *Samples;
|
||||
ALint NumSamples;
|
||||
|
||||
RWLock Lock;
|
||||
volatile ALenum Mapped;
|
||||
|
||||
ALuint id;
|
||||
} ALsoundfont;
|
||||
|
||||
+45
-29
@@ -41,7 +41,6 @@ extern inline struct ALbuffer *RemoveBuffer(ALCdevice *device, ALuint id);
|
||||
extern inline ALuint FrameSizeFromUserFmt(enum UserFmtChannels chans, enum UserFmtType type);
|
||||
extern inline ALuint FrameSizeFromFmt(enum FmtChannels chans, enum FmtType type);
|
||||
|
||||
static ALenum LoadData(ALbuffer *ALBuf, ALuint freq, ALenum NewFormat, ALsizei frames, enum UserFmtChannels chans, enum UserFmtType type, const ALvoid *data, ALsizei align, ALboolean storesrc);
|
||||
static ALboolean IsValidType(ALenum type) DECL_CONST;
|
||||
static ALboolean IsValidChannels(ALenum channels) DECL_CONST;
|
||||
static ALboolean DecomposeUserFormat(ALenum format, enum UserFmtChannels *chans, enum UserFmtType *type) DECL_CONST;
|
||||
@@ -54,7 +53,6 @@ AL_API ALvoid AL_APIENTRY alGenBuffers(ALsizei n, ALuint *buffers)
|
||||
ALCdevice *device;
|
||||
ALCcontext *context;
|
||||
ALsizei cur = 0;
|
||||
ALenum err;
|
||||
|
||||
context = GetContextRef();
|
||||
if(!context) return;
|
||||
@@ -65,25 +63,11 @@ AL_API ALvoid AL_APIENTRY alGenBuffers(ALsizei n, ALuint *buffers)
|
||||
device = context->Device;
|
||||
for(cur = 0;cur < n;cur++)
|
||||
{
|
||||
ALbuffer *buffer = calloc(1, sizeof(ALbuffer));
|
||||
ALbuffer *buffer = NewBuffer(context);
|
||||
if(!buffer)
|
||||
{
|
||||
alDeleteBuffers(cur, buffers);
|
||||
SET_ERROR_AND_GOTO(context, AL_OUT_OF_MEMORY, done);
|
||||
}
|
||||
RWLockInit(&buffer->lock);
|
||||
|
||||
err = NewThunkEntry(&buffer->id);
|
||||
if(err == AL_NO_ERROR)
|
||||
err = InsertUIntMapEntry(&device->BufferMap, buffer->id, buffer);
|
||||
if(err != AL_NO_ERROR)
|
||||
{
|
||||
FreeThunkEntry(buffer->id);
|
||||
memset(buffer, 0, sizeof(ALbuffer));
|
||||
free(buffer);
|
||||
|
||||
alDeleteBuffers(cur, buffers);
|
||||
SET_ERROR_AND_GOTO(context, err, done);
|
||||
break;
|
||||
}
|
||||
|
||||
buffers[cur] = buffer->id;
|
||||
@@ -120,16 +104,7 @@ AL_API ALvoid AL_APIENTRY alDeleteBuffers(ALsizei n, const ALuint *buffers)
|
||||
}
|
||||
|
||||
for(i = 0;i < n;i++)
|
||||
{
|
||||
if((ALBuf=RemoveBuffer(device, buffers[i])) == NULL)
|
||||
continue;
|
||||
FreeThunkEntry(ALBuf->id);
|
||||
|
||||
free(ALBuf->data);
|
||||
|
||||
memset(ALBuf, 0, sizeof(*ALBuf));
|
||||
free(ALBuf);
|
||||
}
|
||||
DeleteBuffer(device, buffers[i]);
|
||||
|
||||
done:
|
||||
ALCcontext_DecRef(context);
|
||||
@@ -954,7 +929,7 @@ done:
|
||||
* Currently, the new format must have the same channel configuration as the
|
||||
* original format.
|
||||
*/
|
||||
static ALenum LoadData(ALbuffer *ALBuf, ALuint freq, ALenum NewFormat, ALsizei frames, enum UserFmtChannels SrcChannels, enum UserFmtType SrcType, const ALvoid *data, ALsizei align, ALboolean storesrc)
|
||||
ALenum LoadData(ALbuffer *ALBuf, ALuint freq, ALenum NewFormat, ALsizei frames, enum UserFmtChannels SrcChannels, enum UserFmtType SrcType, const ALvoid *data, ALsizei align, ALboolean storesrc)
|
||||
{
|
||||
ALuint NewChannels, NewBytes;
|
||||
enum FmtChannels DstChannels;
|
||||
@@ -1293,6 +1268,47 @@ static ALboolean IsValidChannels(ALenum channels)
|
||||
}
|
||||
|
||||
|
||||
ALbuffer *NewBuffer(ALCcontext *context)
|
||||
{
|
||||
ALCdevice *device = context->Device;
|
||||
ALbuffer *buffer;
|
||||
ALenum err;
|
||||
|
||||
buffer = calloc(1, sizeof(ALbuffer));
|
||||
if(!buffer)
|
||||
SET_ERROR_AND_RETURN_VALUE(context, AL_OUT_OF_MEMORY, NULL);
|
||||
RWLockInit(&buffer->lock);
|
||||
|
||||
err = NewThunkEntry(&buffer->id);
|
||||
if(err == AL_NO_ERROR)
|
||||
err = InsertUIntMapEntry(&device->BufferMap, buffer->id, buffer);
|
||||
if(err != AL_NO_ERROR)
|
||||
{
|
||||
FreeThunkEntry(buffer->id);
|
||||
memset(buffer, 0, sizeof(ALbuffer));
|
||||
free(buffer);
|
||||
|
||||
SET_ERROR_AND_RETURN_VALUE(context, err, NULL);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void DeleteBuffer(ALCdevice *device, ALuint bufid)
|
||||
{
|
||||
ALbuffer *buffer;
|
||||
|
||||
if((buffer=RemoveBuffer(device, bufid)) == NULL)
|
||||
return;
|
||||
FreeThunkEntry(buffer->id);
|
||||
|
||||
free(buffer->data);
|
||||
|
||||
memset(buffer, 0, sizeof(*buffer));
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ReleaseALBuffers()
|
||||
*
|
||||
|
||||
+13
-153
@@ -9,6 +9,7 @@
|
||||
#include "alMidi.h"
|
||||
#include "alThunk.h"
|
||||
#include "alError.h"
|
||||
#include <alBuffer.h>
|
||||
|
||||
#include "midi/base.h"
|
||||
|
||||
@@ -91,7 +92,7 @@ AL_API ALvoid AL_APIENTRY alDeleteSoundfontsSOFT(ALsizei n, const ALuint *ids)
|
||||
}
|
||||
else if((sfont=LookupSfont(device, ids[i])) == NULL)
|
||||
SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
|
||||
if(sfont->Mapped != AL_FALSE || ReadRef(&sfont->ref) != 0)
|
||||
if(ReadRef(&sfont->ref) != 0)
|
||||
SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
|
||||
}
|
||||
|
||||
@@ -136,137 +137,6 @@ AL_API ALboolean AL_APIENTRY alIsSoundfontSOFT(ALuint id)
|
||||
return ret;
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alSoundfontSamplesSOFT(ALuint id, ALenum type, ALsizei count, const ALvoid *samples)
|
||||
{
|
||||
ALCdevice *device;
|
||||
ALCcontext *context;
|
||||
ALsoundfont *sfont;
|
||||
void *ptr;
|
||||
|
||||
context = GetContextRef();
|
||||
if(!context) return;
|
||||
|
||||
device = context->Device;
|
||||
if(id == 0)
|
||||
SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
|
||||
if(!(sfont=LookupSfont(device, id)))
|
||||
SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
|
||||
if(type != AL_SHORT_SOFT)
|
||||
SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
|
||||
if(count <= 0)
|
||||
SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
|
||||
|
||||
WriteLock(&sfont->Lock);
|
||||
if(ReadRef(&sfont->ref) != 0)
|
||||
alSetError(context, AL_INVALID_OPERATION);
|
||||
else if(sfont->Mapped)
|
||||
alSetError(context, AL_INVALID_OPERATION);
|
||||
else if(!(ptr=realloc(sfont->Samples, count * sizeof(ALshort))))
|
||||
alSetError(context, AL_OUT_OF_MEMORY);
|
||||
else
|
||||
{
|
||||
sfont->Samples = ptr;
|
||||
sfont->NumSamples = count;
|
||||
if(samples != NULL)
|
||||
memcpy(sfont->Samples, samples, count * sizeof(ALshort));
|
||||
}
|
||||
WriteUnlock(&sfont->Lock);
|
||||
|
||||
done:
|
||||
ALCcontext_DecRef(context);
|
||||
}
|
||||
|
||||
AL_API void AL_APIENTRY alGetSoundfontSamplesSOFT(ALuint id, ALsizei offset, ALsizei count, ALenum type, ALvoid *samples)
|
||||
{
|
||||
ALCdevice *device;
|
||||
ALCcontext *context;
|
||||
ALsoundfont *sfont;
|
||||
|
||||
context = GetContextRef();
|
||||
if(!context) return;
|
||||
|
||||
device = context->Device;
|
||||
if(id == 0)
|
||||
sfont = ALsoundfont_getDefSoundfont(context);
|
||||
else if(!(sfont=LookupSfont(device, id)))
|
||||
SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
|
||||
if(type != AL_SHORT_SOFT)
|
||||
SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
|
||||
if(offset < 0 || count <= 0)
|
||||
SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
|
||||
|
||||
ReadLock(&sfont->Lock);
|
||||
if(offset >= sfont->NumSamples || count > (sfont->NumSamples-offset))
|
||||
alSetError(context, AL_INVALID_VALUE);
|
||||
else if(sfont->Mapped)
|
||||
alSetError(context, AL_INVALID_OPERATION);
|
||||
else
|
||||
{
|
||||
/* TODO: Allow conversion. */
|
||||
memcpy(samples, sfont->Samples + offset*sizeof(ALshort), count * sizeof(ALshort));
|
||||
}
|
||||
ReadUnlock(&sfont->Lock);
|
||||
|
||||
done:
|
||||
ALCcontext_DecRef(context);
|
||||
}
|
||||
|
||||
AL_API ALvoid* AL_APIENTRY alSoundfontMapSamplesSOFT(ALuint id, ALsizei offset, ALsizei length)
|
||||
{
|
||||
ALCdevice *device;
|
||||
ALCcontext *context;
|
||||
ALsoundfont *sfont;
|
||||
ALvoid *ptr = NULL;
|
||||
|
||||
context = GetContextRef();
|
||||
if(!context) return NULL;
|
||||
|
||||
device = context->Device;
|
||||
if(id == 0)
|
||||
SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
|
||||
if(!(sfont=LookupSfont(device, id)))
|
||||
SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
|
||||
if(offset < 0 || (ALuint)offset > sfont->NumSamples*sizeof(ALshort))
|
||||
SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
|
||||
if(length <= 0 || (ALuint)length > (sfont->NumSamples*sizeof(ALshort) - offset))
|
||||
SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
|
||||
|
||||
ReadLock(&sfont->Lock);
|
||||
if(ReadRef(&sfont->ref) != 0)
|
||||
alSetError(context, AL_INVALID_OPERATION);
|
||||
else if(ExchangeInt(&sfont->Mapped, AL_TRUE) == AL_TRUE)
|
||||
alSetError(context, AL_INVALID_OPERATION);
|
||||
else
|
||||
ptr = (ALbyte*)sfont->Samples + offset;
|
||||
ReadUnlock(&sfont->Lock);
|
||||
|
||||
done:
|
||||
ALCcontext_DecRef(context);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
AL_API ALvoid AL_APIENTRY alSoundfontUnmapSamplesSOFT(ALuint id)
|
||||
{
|
||||
ALCdevice *device;
|
||||
ALCcontext *context;
|
||||
ALsoundfont *sfont;
|
||||
|
||||
context = GetContextRef();
|
||||
if(!context) return;
|
||||
|
||||
device = context->Device;
|
||||
if(id == 0)
|
||||
SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
|
||||
if(!(sfont=LookupSfont(device, id)))
|
||||
SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
|
||||
if(ExchangeInt(&sfont->Mapped, AL_FALSE) == AL_FALSE)
|
||||
SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
|
||||
|
||||
done:
|
||||
ALCcontext_DecRef(context);
|
||||
}
|
||||
|
||||
AL_API void AL_APIENTRY alGetSoundfontivSOFT(ALuint id, ALenum param, ALint *values)
|
||||
{
|
||||
ALCdevice *device;
|
||||
@@ -293,14 +163,6 @@ AL_API void AL_APIENTRY alGetSoundfontivSOFT(ALuint id, ALenum param, ALint *val
|
||||
values[i] = sfont->Presets[i]->id;
|
||||
break;
|
||||
|
||||
case AL_SAMPLE_LENGTH_SOFT:
|
||||
values[0] = sfont->NumSamples;
|
||||
break;
|
||||
|
||||
case AL_FORMAT_TYPE_SOFT:
|
||||
values[0] = AL_SHORT_SOFT;
|
||||
break;
|
||||
|
||||
default:
|
||||
SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
|
||||
}
|
||||
@@ -395,11 +257,6 @@ AL_API void AL_APIENTRY alLoadSoundfontSOFT(ALuint id, size_t(*cb)(ALvoid*,size_
|
||||
WriteUnlock(&sfont->Lock);
|
||||
SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
|
||||
}
|
||||
if(sfont->Mapped)
|
||||
{
|
||||
WriteUnlock(&sfont->Lock);
|
||||
SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
|
||||
}
|
||||
if(sfont->NumPresets > 0)
|
||||
{
|
||||
WriteUnlock(&sfont->Lock);
|
||||
@@ -424,11 +281,7 @@ void ALsoundfont_Construct(ALsoundfont *self)
|
||||
self->Presets = NULL;
|
||||
self->NumPresets = 0;
|
||||
|
||||
self->Samples = NULL;
|
||||
self->NumSamples = 0;
|
||||
|
||||
RWLockInit(&self->Lock);
|
||||
self->Mapped = AL_FALSE;
|
||||
|
||||
self->id = 0;
|
||||
}
|
||||
@@ -448,10 +301,6 @@ void ALsoundfont_Destruct(ALsoundfont *self)
|
||||
free(self->Presets);
|
||||
self->Presets = NULL;
|
||||
self->NumPresets = 0;
|
||||
|
||||
free(self->Samples);
|
||||
self->Samples = NULL;
|
||||
self->NumSamples = 0;
|
||||
}
|
||||
|
||||
ALsoundfont *ALsoundfont_getDefSoundfont(ALCcontext *context)
|
||||
@@ -492,6 +341,7 @@ void ALsoundfont_deleteSoundfont(ALsoundfont *self, ALCdevice *device)
|
||||
{
|
||||
ALsfpreset **presets;
|
||||
ALsizei num_presets;
|
||||
ALbuffer *buffer = NULL;
|
||||
ALsizei i;
|
||||
|
||||
presets = ExchangePtr((XchgPtr*)&self->Presets, NULL);
|
||||
@@ -523,6 +373,10 @@ void ALsoundfont_deleteSoundfont(ALsoundfont *self, ALCdevice *device)
|
||||
if(sounds[j] && ReadRef(&sounds[j]->ref) == 0)
|
||||
{
|
||||
deleting = AL_TRUE;
|
||||
if(!buffer)
|
||||
buffer = sounds[j]->Buffer;
|
||||
else if(sounds[j]->Buffer)
|
||||
assert(sounds[j]->Buffer == buffer);
|
||||
RemoveFontsound(device, sounds[j]->id);
|
||||
ALfontsound_Destruct(sounds[j]);
|
||||
free(sounds[j]);
|
||||
@@ -535,6 +389,12 @@ void ALsoundfont_deleteSoundfont(ALsoundfont *self, ALCdevice *device)
|
||||
|
||||
ALsoundfont_Destruct(self);
|
||||
free(self);
|
||||
|
||||
if(buffer)
|
||||
{
|
||||
assert(ReadRef(&buffer->ref) == 0);
|
||||
DeleteBuffer(device, buffer->id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user