aboutsummaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/alhrtf.c75
-rw-r--r--examples/allatency.c87
-rw-r--r--examples/alloopback.c31
-rw-r--r--examples/alreverb.c91
-rw-r--r--examples/alstream.c118
-rw-r--r--examples/common/alhelpers.c243
-rw-r--r--examples/common/alhelpers.h24
-rw-r--r--examples/common/sdl_sound.c164
-rw-r--r--examples/common/sdl_sound.h43
9 files changed, 252 insertions, 624 deletions
diff --git a/examples/alhrtf.c b/examples/alhrtf.c
index 3964a7c6..f9150ae1 100644
--- a/examples/alhrtf.c
+++ b/examples/alhrtf.c
@@ -28,12 +28,13 @@
#include <assert.h>
#include <math.h>
+#include <SDL_sound.h>
+
#include "AL/al.h"
#include "AL/alc.h"
#include "AL/alext.h"
#include "common/alhelpers.h"
-#include "common/sdl_sound.h"
#ifndef M_PI
@@ -44,47 +45,63 @@ static LPALCGETSTRINGISOFT alcGetStringiSOFT;
static LPALCRESETDEVICESOFT alcResetDeviceSOFT;
/* LoadBuffer loads the named audio file into an OpenAL buffer object, and
- * returns the new buffer ID. */
+ * returns the new buffer ID.
+ */
static ALuint LoadSound(const char *filename)
{
- ALenum err, format, type, channels;
- ALuint rate, buffer;
- size_t datalen;
- void *data;
- FilePtr sound;
+ Sound_Sample *sample;
+ ALenum err, format;
+ ALuint buffer;
+ Uint32 slen;
/* Open the audio file */
- sound = openAudioFile(filename, 1000);
- if(!sound)
+ sample = Sound_NewSampleFromFile(filename, NULL, 65536);
+ if(!sample)
{
fprintf(stderr, "Could not open audio in %s\n", filename);
- closeAudioFile(sound);
return 0;
}
/* Get the sound format, and figure out the OpenAL format */
- if(getAudioInfo(sound, &rate, &channels, &type) != 0)
+ if(sample->actual.channels == 1)
{
- fprintf(stderr, "Error getting audio info for %s\n", filename);
- closeAudioFile(sound);
- return 0;
+ if(sample->actual.format == AUDIO_U8)
+ format = AL_FORMAT_MONO8;
+ else if(sample->actual.format == AUDIO_S16SYS)
+ format = AL_FORMAT_MONO16;
+ else
+ {
+ fprintf(stderr, "Unsupported sample format: 0x%04x\n", sample->actual.format);
+ Sound_FreeSample(sample);
+ return 0;
+ }
}
-
- format = GetFormat(channels, type, NULL);
- if(format == AL_NONE)
+ else if(sample->actual.channels == 2)
{
- fprintf(stderr, "Unsupported format (%s, %s) for %s\n",
- ChannelsName(channels), TypeName(type), filename);
- closeAudioFile(sound);
+ if(sample->actual.format == AUDIO_U8)
+ format = AL_FORMAT_STEREO8;
+ else if(sample->actual.format == AUDIO_S16SYS)
+ format = AL_FORMAT_STEREO16;
+ else
+ {
+ fprintf(stderr, "Unsupported sample format: 0x%04x\n", sample->actual.format);
+ Sound_FreeSample(sample);
+ return 0;
+ }
+ }
+ else
+ {
+ fprintf(stderr, "Unsupported channel count: %d\n", sample->actual.channels);
+ Sound_FreeSample(sample);
return 0;
}
/* Decode the whole audio stream to a buffer. */
- data = decodeAudioStream(sound, &datalen);
- if(!data)
+ slen = Sound_DecodeAll(sample);
+ if(!sample->buffer || slen == 0)
{
fprintf(stderr, "Failed to read audio from %s\n", filename);
- closeAudioFile(sound);
+ Sound_FreeSample(sample);
return 0;
}
@@ -92,9 +109,8 @@ static ALuint LoadSound(const char *filename)
* close the file. */
buffer = 0;
alGenBuffers(1, &buffer);
- alBufferData(buffer, format, data, datalen, rate);
- free(data);
- closeAudioFile(sound);
+ alBufferData(buffer, format, sample->buffer, slen, sample->actual.rate);
+ Sound_FreeSample(sample);
/* Check if an error occured, and clean up if so. */
err = alGetError();
@@ -219,10 +235,14 @@ int main(int argc, char **argv)
}
fflush(stdout);
+ /* Initialize SDL_sound. */
+ Sound_Init();
+
/* Load the sound into a buffer. */
buffer = LoadSound(soundname);
if(!buffer)
{
+ Sound_Quit();
CloseAL();
return 1;
}
@@ -263,10 +283,11 @@ int main(int argc, char **argv)
alGetSourcei(source, AL_SOURCE_STATE, &state);
} while(alGetError() == AL_NO_ERROR && state == AL_PLAYING);
- /* All done. Delete resources, and close OpenAL. */
+ /* All done. Delete resources, and close down SDL_sound and OpenAL. */
alDeleteSources(1, &source);
alDeleteBuffers(1, &buffer);
+ Sound_Quit();
CloseAL();
return 0;
diff --git a/examples/allatency.c b/examples/allatency.c
index 56d96b9e..d561373f 100644
--- a/examples/allatency.c
+++ b/examples/allatency.c
@@ -27,16 +27,14 @@
#include <stdio.h>
#include <assert.h>
+#include <SDL_sound.h>
+
#include "AL/al.h"
#include "AL/alc.h"
#include "AL/alext.h"
#include "common/alhelpers.h"
-#include "common/sdl_sound.h"
-
-static LPALBUFFERSAMPLESSOFT alBufferSamplesSOFT = wrap_BufferSamples;
-static LPALISBUFFERFORMATSUPPORTEDSOFT alIsBufferFormatSupportedSOFT;
static LPALSOURCEDSOFT alSourcedSOFT;
static LPALSOURCE3DSOFT alSource3dSOFT;
@@ -52,47 +50,63 @@ static LPALGETSOURCE3I64SOFT alGetSource3i64SOFT;
static LPALGETSOURCEI64VSOFT alGetSourcei64vSOFT;
/* LoadBuffer loads the named audio file into an OpenAL buffer object, and
- * returns the new buffer ID. */
+ * returns the new buffer ID.
+ */
static ALuint LoadSound(const char *filename)
{
- ALenum err, format, type, channels;
- ALuint rate, buffer;
- size_t datalen;
- void *data;
- FilePtr sound;
+ Sound_Sample *sample;
+ ALenum err, format;
+ ALuint buffer;
+ Uint32 slen;
/* Open the audio file */
- sound = openAudioFile(filename, 1000);
- if(!sound)
+ sample = Sound_NewSampleFromFile(filename, NULL, 65536);
+ if(!sample)
{
fprintf(stderr, "Could not open audio in %s\n", filename);
- closeAudioFile(sound);
return 0;
}
/* Get the sound format, and figure out the OpenAL format */
- if(getAudioInfo(sound, &rate, &channels, &type) != 0)
+ if(sample->actual.channels == 1)
{
- fprintf(stderr, "Error getting audio info for %s\n", filename);
- closeAudioFile(sound);
- return 0;
+ if(sample->actual.format == AUDIO_U8)
+ format = AL_FORMAT_MONO8;
+ else if(sample->actual.format == AUDIO_S16SYS)
+ format = AL_FORMAT_MONO16;
+ else
+ {
+ fprintf(stderr, "Unsupported sample format: 0x%04x\n", sample->actual.format);
+ Sound_FreeSample(sample);
+ return 0;
+ }
}
-
- format = GetFormat(channels, type, alIsBufferFormatSupportedSOFT);
- if(format == AL_NONE)
+ else if(sample->actual.channels == 2)
{
- fprintf(stderr, "Unsupported format (%s, %s) for %s\n",
- ChannelsName(channels), TypeName(type), filename);
- closeAudioFile(sound);
+ if(sample->actual.format == AUDIO_U8)
+ format = AL_FORMAT_STEREO8;
+ else if(sample->actual.format == AUDIO_S16SYS)
+ format = AL_FORMAT_STEREO16;
+ else
+ {
+ fprintf(stderr, "Unsupported sample format: 0x%04x\n", sample->actual.format);
+ Sound_FreeSample(sample);
+ return 0;
+ }
+ }
+ else
+ {
+ fprintf(stderr, "Unsupported channel count: %d\n", sample->actual.channels);
+ Sound_FreeSample(sample);
return 0;
}
/* Decode the whole audio stream to a buffer. */
- data = decodeAudioStream(sound, &datalen);
- if(!data)
+ slen = Sound_DecodeAll(sample);
+ if(!sample->buffer || slen == 0)
{
fprintf(stderr, "Failed to read audio from %s\n", filename);
- closeAudioFile(sound);
+ Sound_FreeSample(sample);
return 0;
}
@@ -100,17 +114,15 @@ static ALuint LoadSound(const char *filename)
* close the file. */
buffer = 0;
alGenBuffers(1, &buffer);
- alBufferSamplesSOFT(buffer, rate, format, BytesToFrames(datalen, channels, type),
- channels, type, data);
- free(data);
- closeAudioFile(sound);
+ alBufferData(buffer, format, sample->buffer, slen, sample->actual.rate);
+ Sound_FreeSample(sample);
/* Check if an error occured, and clean up if so. */
err = alGetError();
if(err != AL_NO_ERROR)
{
fprintf(stderr, "OpenAL Error: %s\n", alGetString(err));
- if(alIsBuffer(buffer))
+ if(buffer && alIsBuffer(buffer))
alDeleteBuffers(1, &buffer);
return 0;
}
@@ -158,18 +170,16 @@ int main(int argc, char **argv)
LOAD_PROC(alGetSourcei64SOFT);
LOAD_PROC(alGetSource3i64SOFT);
LOAD_PROC(alGetSourcei64vSOFT);
-
- if(alIsExtensionPresent("AL_SOFT_buffer_samples"))
- {
- LOAD_PROC(alBufferSamplesSOFT);
- LOAD_PROC(alIsBufferFormatSupportedSOFT);
- }
#undef LOAD_PROC
+ /* Initialize SDL_sound. */
+ Sound_Init();
+
/* Load the sound into a buffer. */
buffer = LoadSound(argv[0]);
if(!buffer)
{
+ Sound_Quit();
CloseAL();
return 1;
}
@@ -195,10 +205,11 @@ int main(int argc, char **argv)
} while(alGetError() == AL_NO_ERROR && state == AL_PLAYING);
printf("\n");
- /* All done. Delete resources, and close OpenAL. */
+ /* All done. Delete resources, and close down SDL_sound and OpenAL. */
alDeleteSources(1, &source);
alDeleteBuffers(1, &buffer);
+ Sound_Quit();
CloseAL();
return 0;
diff --git a/examples/alloopback.c b/examples/alloopback.c
index c5dee36d..95ac433f 100644
--- a/examples/alloopback.c
+++ b/examples/alloopback.c
@@ -61,6 +61,35 @@ void SDLCALL RenderSDLSamples(void *userdata, Uint8 *stream, int len)
}
+static const char *ChannelsName(ALCenum chans)
+{
+ switch(chans)
+ {
+ case ALC_MONO_SOFT: return "Mono";
+ case ALC_STEREO_SOFT: return "Stereo";
+ case ALC_QUAD_SOFT: return "Quadraphonic";
+ case ALC_5POINT1_SOFT: return "5.1 Surround";
+ case ALC_6POINT1_SOFT: return "6.1 Surround";
+ case ALC_7POINT1_SOFT: return "7.1 Surround";
+ }
+ return "Unknown Channels";
+}
+
+static const char *TypeName(ALCenum type)
+{
+ switch(type)
+ {
+ case ALC_BYTE_SOFT: return "S8";
+ case ALC_UNSIGNED_BYTE_SOFT: return "U8";
+ case ALC_SHORT_SOFT: return "S16";
+ case ALC_UNSIGNED_SHORT_SOFT: return "U16";
+ case ALC_INT_SOFT: return "S32";
+ case ALC_UNSIGNED_INT_SOFT: return "U32";
+ case ALC_FLOAT_SOFT: return "Float32";
+ }
+ return "Unknown Type";
+}
+
/* Creates a one second buffer containing a sine wave, and returns the new
* buffer ID. */
static ALuint CreateSineWave(void)
@@ -169,7 +198,7 @@ int main(int argc, char *argv[])
attrs[6] = 0; /* end of list */
- playback.FrameSize = FramesToBytes(1, attrs[1], attrs[3]);
+ playback.FrameSize = obtained.channels * SDL_AUDIO_BITSIZE(obtained.format) / 8;
/* Initialize OpenAL loopback device, using our format attributes. */
playback.Device = alcLoopbackOpenDeviceSOFT(NULL);
diff --git a/examples/alreverb.c b/examples/alreverb.c
index ec71f354..e6c9e606 100644
--- a/examples/alreverb.c
+++ b/examples/alreverb.c
@@ -27,17 +27,15 @@
#include <stdio.h>
#include <assert.h>
+#include <SDL_sound.h>
+
#include "AL/al.h"
#include "AL/alc.h"
#include "AL/alext.h"
#include "AL/efx-presets.h"
#include "common/alhelpers.h"
-#include "common/sdl_sound.h"
-
-static LPALBUFFERSAMPLESSOFT alBufferSamplesSOFT = wrap_BufferSamples;
-static LPALISBUFFERFORMATSUPPORTEDSOFT alIsBufferFormatSupportedSOFT;
/* Effect object functions */
static LPALGENEFFECTS alGenEffects;
@@ -145,46 +143,63 @@ static ALuint LoadEffect(const EFXEAXREVERBPROPERTIES *reverb)
/* LoadBuffer loads the named audio file into an OpenAL buffer object, and
- * returns the new buffer ID. */
+ * returns the new buffer ID.
+ */
static ALuint LoadSound(const char *filename)
{
- ALenum err, format, type, channels;
- ALuint rate, buffer;
- size_t datalen;
- void *data;
- FilePtr sound;
-
- /* Open the file and get the first stream from it */
- sound = openAudioFile(filename, 1000);
- if(!sound)
+ Sound_Sample *sample;
+ ALenum err, format;
+ ALuint buffer;
+ Uint32 slen;
+
+ /* Open the audio file */
+ sample = Sound_NewSampleFromFile(filename, NULL, 65536);
+ if(!sample)
{
fprintf(stderr, "Could not open audio in %s\n", filename);
return 0;
}
/* Get the sound format, and figure out the OpenAL format */
- if(getAudioInfo(sound, &rate, &channels, &type) != 0)
+ if(sample->actual.channels == 1)
{
- fprintf(stderr, "Error getting audio info for %s\n", filename);
- closeAudioFile(sound);
- return 0;
+ if(sample->actual.format == AUDIO_U8)
+ format = AL_FORMAT_MONO8;
+ else if(sample->actual.format == AUDIO_S16SYS)
+ format = AL_FORMAT_MONO16;
+ else
+ {
+ fprintf(stderr, "Unsupported sample format: 0x%04x\n", sample->actual.format);
+ Sound_FreeSample(sample);
+ return 0;
+ }
}
-
- format = GetFormat(channels, type, alIsBufferFormatSupportedSOFT);
- if(format == AL_NONE)
+ else if(sample->actual.channels == 2)
+ {
+ if(sample->actual.format == AUDIO_U8)
+ format = AL_FORMAT_STEREO8;
+ else if(sample->actual.format == AUDIO_S16SYS)
+ format = AL_FORMAT_STEREO16;
+ else
+ {
+ fprintf(stderr, "Unsupported sample format: 0x%04x\n", sample->actual.format);
+ Sound_FreeSample(sample);
+ return 0;
+ }
+ }
+ else
{
- fprintf(stderr, "Unsupported format (%s, %s) for %s\n",
- ChannelsName(channels), TypeName(type), filename);
- closeAudioFile(sound);
+ fprintf(stderr, "Unsupported channel count: %d\n", sample->actual.channels);
+ Sound_FreeSample(sample);
return 0;
}
/* Decode the whole audio stream to a buffer. */
- data = decodeAudioStream(sound, &datalen);
- if(!data)
+ slen = Sound_DecodeAll(sample);
+ if(!sample->buffer || slen == 0)
{
fprintf(stderr, "Failed to read audio from %s\n", filename);
- closeAudioFile(sound);
+ Sound_FreeSample(sample);
return 0;
}
@@ -192,17 +207,15 @@ static ALuint LoadSound(const char *filename)
* close the file. */
buffer = 0;
alGenBuffers(1, &buffer);
- alBufferSamplesSOFT(buffer, rate, format, BytesToFrames(datalen, channels, type),
- channels, type, data);
- free(data);
- closeAudioFile(sound);
+ alBufferData(buffer, format, sample->buffer, slen, sample->actual.rate);
+ Sound_FreeSample(sample);
/* Check if an error occured, and clean up if so. */
err = alGetError();
if(err != AL_NO_ERROR)
{
fprintf(stderr, "OpenAL Error: %s\n", alGetString(err));
- if(alIsBuffer(buffer))
+ if(buffer && alIsBuffer(buffer))
alDeleteBuffers(1, &buffer);
return 0;
}
@@ -261,19 +274,17 @@ int main(int argc, char **argv)
LOAD_PROC(alGetAuxiliaryEffectSlotiv);
LOAD_PROC(alGetAuxiliaryEffectSlotf);
LOAD_PROC(alGetAuxiliaryEffectSlotfv);
-
- if(alIsExtensionPresent("AL_SOFT_buffer_samples"))
- {
- LOAD_PROC(alBufferSamplesSOFT);
- LOAD_PROC(alIsBufferFormatSupportedSOFT);
- }
#undef LOAD_PROC
+ /* Initialize SDL_sound. */
+ Sound_Init();
+
/* Load the sound into a buffer. */
buffer = LoadSound(argv[0]);
if(!buffer)
{
CloseAL();
+ Sound_Quit();
return 1;
}
@@ -282,6 +293,7 @@ int main(int argc, char **argv)
if(!effect)
{
alDeleteBuffers(1, &buffer);
+ Sound_Quit();
CloseAL();
return 1;
}
@@ -316,12 +328,13 @@ int main(int argc, char **argv)
alGetSourcei(source, AL_SOURCE_STATE, &state);
} while(alGetError() == AL_NO_ERROR && state == AL_PLAYING);
- /* All done. Delete resources, and close OpenAL. */
+ /* All done. Delete resources, and close down SDL_sound and OpenAL. */
alDeleteSources(1, &source);
alDeleteAuxiliaryEffectSlots(1, &slot);
alDeleteEffects(1, &effect);
alDeleteBuffers(1, &buffer);
+ Sound_Quit();
CloseAL();
return 0;
diff --git a/examples/alstream.c b/examples/alstream.c
index 65a04475..d13899d0 100644
--- a/examples/alstream.c
+++ b/examples/alstream.c
@@ -30,16 +30,13 @@
#include <signal.h>
#include <assert.h>
+#include <SDL_sound.h>
+
#include "AL/al.h"
#include "AL/alc.h"
#include "AL/alext.h"
#include "common/alhelpers.h"
-#include "common/sdl_sound.h"
-
-
-static LPALBUFFERSAMPLESSOFT alBufferSamplesSOFT = wrap_BufferSamples;
-static LPALISBUFFERFORMATSUPPORTEDSOFT alIsBufferFormatSupportedSOFT;
/* Define the number of buffers and buffer size (in milliseconds) to use. 4
@@ -54,13 +51,11 @@ typedef struct StreamPlayer {
ALuint source;
/* Handle for the audio file */
- FilePtr file;
+ Sound_Sample *sample;
/* The format of the output stream */
ALenum format;
- ALenum channels;
- ALenum type;
- ALuint rate;
+ ALsizei srate;
} StreamPlayer;
static StreamPlayer *NewPlayer(void);
@@ -77,11 +72,9 @@ static StreamPlayer *NewPlayer(void)
{
StreamPlayer *player;
- player = malloc(sizeof(*player));
+ player = calloc(1, sizeof(*player));
assert(player != NULL);
- memset(player, 0, sizeof(*player));
-
/* Generate the buffers and source */
alGenBuffers(NUM_BUFFERS, player->buffers);
assert(alGetError() == AL_NO_ERROR && "Could not create buffers");
@@ -119,37 +112,63 @@ static void DeletePlayer(StreamPlayer *player)
* it will be closed first. */
static int OpenPlayerFile(StreamPlayer *player, const char *filename)
{
+ Uint32 frame_size;
+
ClosePlayerFile(player);
/* Open the file and get the first stream from it */
- player->file = openAudioFile(filename, BUFFER_TIME_MS);
- if(!player->file)
+ player->sample = Sound_NewSampleFromFile(filename, NULL, 0);
+ if(!player->sample)
{
fprintf(stderr, "Could not open audio in %s\n", filename);
goto error;
}
/* Get the stream format, and figure out the OpenAL format */
- if(getAudioInfo(player->file, &player->rate, &player->channels, &player->type) != 0)
+ if(player->sample->actual.channels == 1)
{
- fprintf(stderr, "Error getting audio info for %s\n", filename);
- goto error;
+ if(player->sample->actual.format == AUDIO_U8)
+ player->format = AL_FORMAT_MONO8;
+ else if(player->sample->actual.format == AUDIO_S16SYS)
+ player->format = AL_FORMAT_MONO16;
+ else
+ {
+ fprintf(stderr, "Unsupported sample format: 0x%04x\n", player->sample->actual.format);
+ goto error;
+ }
}
-
- player->format = GetFormat(player->channels, player->type, alIsBufferFormatSupportedSOFT);
- if(player->format == 0)
+ else if(player->sample->actual.channels == 2)
{
- fprintf(stderr, "Unsupported format (%s, %s) for %s\n",
- ChannelsName(player->channels), TypeName(player->type),
- filename);
+ if(player->sample->actual.format == AUDIO_U8)
+ player->format = AL_FORMAT_STEREO8;
+ else if(player->sample->actual.format == AUDIO_S16SYS)
+ player->format = AL_FORMAT_STEREO16;
+ else
+ {
+ fprintf(stderr, "Unsupported sample format: 0x%04x\n", player->sample->actual.format);
+ goto error;
+ }
+ }
+ else
+ {
+ fprintf(stderr, "Unsupported channel count: %d\n", player->sample->actual.channels);
goto error;
}
+ player->srate = player->sample->actual.rate;
+
+ frame_size = player->sample->actual.channels *
+ SDL_AUDIO_BITSIZE(player->sample->actual.format) / 8;
+
+ /* Set the buffer size, given the desired millisecond length. */
+ Sound_SetBufferSize(player->sample, (Uint32)((Uint64)player->srate*BUFFER_TIME_MS/1000) *
+ frame_size);
return 1;
error:
- closeAudioFile(player->file);
- player->file = NULL;
+ if(player->sample)
+ Sound_FreeSample(player->sample);
+ player->sample = NULL;
return 0;
}
@@ -157,8 +176,9 @@ error:
/* Closes the audio file stream */
static void ClosePlayerFile(StreamPlayer *player)
{
- closeAudioFile(player->file);
- player->file = NULL;
+ if(player->sample)
+ Sound_FreeSample(player->sample);
+ player->sample = NULL;
}
@@ -174,16 +194,12 @@ static int StartPlayer(StreamPlayer *player)
/* Fill the buffer queue */
for(i = 0;i < NUM_BUFFERS;i++)
{
- uint8_t *data;
- size_t got;
-
/* Get some data to give it to the buffer */
- data = getAudioData(player->file, &got);
- if(!data) break;
+ Uint32 slen = Sound_Decode(player->sample);
+ if(slen == 0) break;
- alBufferSamplesSOFT(player->buffers[i], player->rate, player->format,
- BytesToFrames(got, player->channels, player->type),
- player->channels, player->type, data);
+ alBufferData(player->buffers[i], player->format,
+ player->sample->buffer, slen, player->srate);
}
if(alGetError() != AL_NO_ERROR)
{
@@ -220,20 +236,21 @@ static int UpdatePlayer(StreamPlayer *player)
while(processed > 0)
{
ALuint bufid;
- uint8_t *data;
- size_t got;
+ Uint32 slen;
alSourceUnqueueBuffers(player->source, 1, &bufid);
processed--;
+ if((player->sample->flags&(SOUND_SAMPLEFLAG_EOF|SOUND_SAMPLEFLAG_ERROR)))
+ continue;
+
/* Read the next chunk of data, refill the buffer, and queue it
* back on the source */
- data = getAudioData(player->file, &got);
- if(data != NULL)
+ slen = Sound_Decode(player->sample);
+ if(slen > 0)
{
- alBufferSamplesSOFT(bufid, player->rate, player->format,
- BytesToFrames(got, player->channels, player->type),
- player->channels, player->type, data);
+ alBufferData(bufid, player->format, player->sample->buffer, slen,
+ player->srate);
alSourceQueueBuffers(player->source, 1, &bufid);
}
if(alGetError() != AL_NO_ERROR)
@@ -281,14 +298,7 @@ int main(int argc, char **argv)
if(InitAL(&argv, &argc) != 0)
return 1;
- if(alIsExtensionPresent("AL_SOFT_buffer_samples"))
- {
- printf("AL_SOFT_buffer_samples supported!\n");
- alBufferSamplesSOFT = alGetProcAddress("alBufferSamplesSOFT");
- alIsBufferFormatSupportedSOFT = alGetProcAddress("alIsBufferFormatSupportedSOFT");
- }
- else
- printf("AL_SOFT_buffer_samples not supported\n");
+ Sound_Init();
player = NewPlayer();
@@ -307,9 +317,8 @@ int main(int argc, char **argv)
else
namepart = argv[i];
- printf("Playing: %s (%s, %s, %dhz)\n", namepart,
- TypeName(player->type), ChannelsName(player->channels),
- player->rate);
+ printf("Playing: %s (%s, %dhz)\n", namepart, FormatName(player->format),
+ player->srate);
fflush(stdout);
if(!StartPlayer(player))
@@ -326,10 +335,11 @@ int main(int argc, char **argv)
}
printf("Done.\n");
- /* All files done. Delete the player, and close OpenAL */
+ /* All files done. Delete the player, and close down SDL_sound and OpenAL */
DeletePlayer(player);
player = NULL;
+ Sound_Quit();
CloseAL();
return 0;
diff --git a/examples/common/alhelpers.c b/examples/common/alhelpers.c
index 43548b5c..fab039e9 100644
--- a/examples/common/alhelpers.c
+++ b/examples/common/alhelpers.c
@@ -103,243 +103,14 @@ void CloseAL(void)
}
-/* GetFormat retrieves a compatible buffer format given the channel config and
- * sample type. If an alIsBufferFormatSupportedSOFT-compatible function is
- * provided, it will be called to find the closest-matching format from
- * AL_SOFT_buffer_samples. Returns AL_NONE (0) if no supported format can be
- * found. */
-ALenum GetFormat(ALenum channels, ALenum type, LPALISBUFFERFORMATSUPPORTEDSOFT palIsBufferFormatSupportedSOFT)
+const char *FormatName(ALenum format)
{
- ALenum format = AL_NONE;
-
- /* If using AL_SOFT_buffer_samples, try looking through its formats */
- if(palIsBufferFormatSupportedSOFT)
- {
- /* AL_SOFT_buffer_samples is more lenient with matching formats. The
- * specified sample type does not need to match the returned format,
- * but it is nice to try to get something close. */
- if(type == AL_UNSIGNED_BYTE_SOFT || type == AL_BYTE_SOFT)
- {
- if(channels == AL_MONO_SOFT) format = AL_MONO8_SOFT;
- else if(channels == AL_STEREO_SOFT) format = AL_STEREO8_SOFT;
- else if(channels == AL_QUAD_SOFT) format = AL_QUAD8_SOFT;
- else if(channels == AL_5POINT1_SOFT) format = AL_5POINT1_8_SOFT;
- else if(channels == AL_6POINT1_SOFT) format = AL_6POINT1_8_SOFT;
- else if(channels == AL_7POINT1_SOFT) format = AL_7POINT1_8_SOFT;
- }
- else if(type == AL_UNSIGNED_SHORT_SOFT || type == AL_SHORT_SOFT)
- {
- if(channels == AL_MONO_SOFT) format = AL_MONO16_SOFT;
- else if(channels == AL_STEREO_SOFT) format = AL_STEREO16_SOFT;
- else if(channels == AL_QUAD_SOFT) format = AL_QUAD16_SOFT;
- else if(channels == AL_5POINT1_SOFT) format = AL_5POINT1_16_SOFT;
- else if(channels == AL_6POINT1_SOFT) format = AL_6POINT1_16_SOFT;
- else if(channels == AL_7POINT1_SOFT) format = AL_7POINT1_16_SOFT;
- }
- else if(type == AL_UNSIGNED_BYTE3_SOFT || type == AL_BYTE3_SOFT ||
- type == AL_UNSIGNED_INT_SOFT || type == AL_INT_SOFT ||
- type == AL_FLOAT_SOFT || type == AL_DOUBLE_SOFT)
- {
- if(channels == AL_MONO_SOFT) format = AL_MONO32F_SOFT;
- else if(channels == AL_STEREO_SOFT) format = AL_STEREO32F_SOFT;
- else if(channels == AL_QUAD_SOFT) format = AL_QUAD32F_SOFT;
- else if(channels == AL_5POINT1_SOFT) format = AL_5POINT1_32F_SOFT;
- else if(channels == AL_6POINT1_SOFT) format = AL_6POINT1_32F_SOFT;
- else if(channels == AL_7POINT1_SOFT) format = AL_7POINT1_32F_SOFT;
- }
-
- if(format != AL_NONE && !palIsBufferFormatSupportedSOFT(format))
- format = AL_NONE;
-
- /* A matching format was not found or supported. Try 32-bit float. */
- if(format == AL_NONE)
- {
- if(channels == AL_MONO_SOFT) format = AL_MONO32F_SOFT;
- else if(channels == AL_STEREO_SOFT) format = AL_STEREO32F_SOFT;
- else if(channels == AL_QUAD_SOFT) format = AL_QUAD32F_SOFT;
- else if(channels == AL_5POINT1_SOFT) format = AL_5POINT1_32F_SOFT;
- else if(channels == AL_6POINT1_SOFT) format = AL_6POINT1_32F_SOFT;
- else if(channels == AL_7POINT1_SOFT) format = AL_7POINT1_32F_SOFT;
-
- if(format != AL_NONE && !palIsBufferFormatSupportedSOFT(format))
- format = AL_NONE;
- }
- /* 32-bit float not supported. Try 16-bit int. */
- if(format == AL_NONE)
- {
- if(channels == AL_MONO_SOFT) format = AL_MONO16_SOFT;
- else if(channels == AL_STEREO_SOFT) format = AL_STEREO16_SOFT;
- else if(channels == AL_QUAD_SOFT) format = AL_QUAD16_SOFT;
- else if(channels == AL_5POINT1_SOFT) format = AL_5POINT1_16_SOFT;
- else if(channels == AL_6POINT1_SOFT) format = AL_6POINT1_16_SOFT;
- else if(channels == AL_7POINT1_SOFT) format = AL_7POINT1_16_SOFT;
-
- if(format != AL_NONE && !palIsBufferFormatSupportedSOFT(format))
- format = AL_NONE;
- }
- /* 16-bit int not supported. Try 8-bit int. */
- if(format == AL_NONE)
- {
- if(channels == AL_MONO_SOFT) format = AL_MONO8_SOFT;
- else if(channels == AL_STEREO_SOFT) format = AL_STEREO8_SOFT;
- else if(channels == AL_QUAD_SOFT) format = AL_QUAD8_SOFT;
- else if(channels == AL_5POINT1_SOFT) format = AL_5POINT1_8_SOFT;
- else if(channels == AL_6POINT1_SOFT) format = AL_6POINT1_8_SOFT;
- else if(channels == AL_7POINT1_SOFT) format = AL_7POINT1_8_SOFT;
-
- if(format != AL_NONE && !palIsBufferFormatSupportedSOFT(format))
- format = AL_NONE;
- }
-
- return format;
- }
-
- /* We use the AL_EXT_MCFORMATS extension to provide output of Quad, 5.1,
- * and 7.1 channel configs, AL_EXT_FLOAT32 for 32-bit float samples, and
- * AL_EXT_DOUBLE for 64-bit float samples. */
- if(type == AL_UNSIGNED_BYTE_SOFT)
- {
- if(channels == AL_MONO_SOFT)
- format = AL_FORMAT_MONO8;
- else if(channels == AL_STEREO_SOFT)
- format = AL_FORMAT_STEREO8;
- else if(alIsExtensionPresent("AL_EXT_MCFORMATS"))
- {
- if(channels == AL_QUAD_SOFT)
- format = alGetEnumValue("AL_FORMAT_QUAD8");
- else if(channels == AL_5POINT1_SOFT)
- format = alGetEnumValue("AL_FORMAT_51CHN8");
- else if(channels == AL_6POINT1_SOFT)
- format = alGetEnumValue("AL_FORMAT_61CHN8");
- else if(channels == AL_7POINT1_SOFT)
- format = alGetEnumValue("AL_FORMAT_71CHN8");
- }
- }
- else if(type == AL_SHORT_SOFT)
- {
- if(channels == AL_MONO_SOFT)
- format = AL_FORMAT_MONO16;
- else if(channels == AL_STEREO_SOFT)
- format = AL_FORMAT_STEREO16;
- else if(alIsExtensionPresent("AL_EXT_MCFORMATS"))
- {
- if(channels == AL_QUAD_SOFT)
- format = alGetEnumValue("AL_FORMAT_QUAD16");
- else if(channels == AL_5POINT1_SOFT)
- format = alGetEnumValue("AL_FORMAT_51CHN16");
- else if(channels == AL_6POINT1_SOFT)
- format = alGetEnumValue("AL_FORMAT_61CHN16");
- else if(channels == AL_7POINT1_SOFT)
- format = alGetEnumValue("AL_FORMAT_71CHN16");
- }
- }
- else if(type == AL_FLOAT_SOFT && alIsExtensionPresent("AL_EXT_FLOAT32"))
- {
- if(channels == AL_MONO_SOFT)
- format = alGetEnumValue("AL_FORMAT_MONO_FLOAT32");
- else if(channels == AL_STEREO_SOFT)
- format = alGetEnumValue("AL_FORMAT_STEREO_FLOAT32");
- else if(alIsExtensionPresent("AL_EXT_MCFORMATS"))
- {
- if(channels == AL_QUAD_SOFT)
- format = alGetEnumValue("AL_FORMAT_QUAD32");
- else if(channels == AL_5POINT1_SOFT)
- format = alGetEnumValue("AL_FORMAT_51CHN32");
- else if(channels == AL_6POINT1_SOFT)
- format = alGetEnumValue("AL_FORMAT_61CHN32");
- else if(channels == AL_7POINT1_SOFT)
- format = alGetEnumValue("AL_FORMAT_71CHN32");
- }
- }
- else if(type == AL_DOUBLE_SOFT && alIsExtensionPresent("AL_EXT_DOUBLE"))
- {
- if(channels == AL_MONO_SOFT)
- format = alGetEnumValue("AL_FORMAT_MONO_DOUBLE");
- else if(channels == AL_STEREO_SOFT)
- format = alGetEnumValue("AL_FORMAT_STEREO_DOUBLE");
- }
-
- /* NOTE: It seems OSX returns -1 from alGetEnumValue for unknown enums, as
- * opposed to 0. Correct it. */
- if(format == -1)
- format = 0;
-
- return format;
-}
-
-
-void AL_APIENTRY wrap_BufferSamples(ALuint buffer, ALuint samplerate,
- ALenum internalformat, ALsizei samples,
- ALenum channels, ALenum type,
- const ALvoid *data)
-{
- alBufferData(buffer, internalformat, data,
- FramesToBytes(samples, channels, type),
- samplerate);
-}
-
-
-const char *ChannelsName(ALenum chans)
-{
- switch(chans)
- {
- case AL_MONO_SOFT: return "Mono";
- case AL_STEREO_SOFT: return "Stereo";
- case AL_REAR_SOFT: return "Rear";
- case AL_QUAD_SOFT: return "Quadraphonic";
- case AL_5POINT1_SOFT: return "5.1 Surround";
- case AL_6POINT1_SOFT: return "6.1 Surround";
- case AL_7POINT1_SOFT: return "7.1 Surround";
- }
- return "Unknown Channels";
-}
-
-const char *TypeName(ALenum type)
-{
- switch(type)
+ switch(format)
{
- case AL_BYTE_SOFT: return "S8";
- case AL_UNSIGNED_BYTE_SOFT: return "U8";
- case AL_SHORT_SOFT: return "S16";
- case AL_UNSIGNED_SHORT_SOFT: return "U16";
- case AL_INT_SOFT: return "S32";
- case AL_UNSIGNED_INT_SOFT: return "U32";
- case AL_FLOAT_SOFT: return "Float32";
- case AL_DOUBLE_SOFT: return "Float64";
+ case AL_FORMAT_MONO8: return "Mono, U8";
+ case AL_FORMAT_MONO16: return "Mono, S16";
+ case AL_FORMAT_STEREO8: return "Stereo, U8";
+ case AL_FORMAT_STEREO16: return "Stereo, S16";
}
- return "Unknown Type";
-}
-
-
-ALsizei FramesToBytes(ALsizei size, ALenum channels, ALenum type)
-{
- switch(channels)
- {
- case AL_MONO_SOFT: size *= 1; break;
- case AL_STEREO_SOFT: size *= 2; break;
- case AL_REAR_SOFT: size *= 2; break;
- case AL_QUAD_SOFT: size *= 4; break;
- case AL_5POINT1_SOFT: size *= 6; break;
- case AL_6POINT1_SOFT: size *= 7; break;
- case AL_7POINT1_SOFT: size *= 8; break;
- }
-
- switch(type)
- {
- case AL_BYTE_SOFT: size *= sizeof(ALbyte); break;
- case AL_UNSIGNED_BYTE_SOFT: size *= sizeof(ALubyte); break;
- case AL_SHORT_SOFT: size *= sizeof(ALshort); break;
- case AL_UNSIGNED_SHORT_SOFT: size *= sizeof(ALushort); break;
- case AL_INT_SOFT: size *= sizeof(ALint); break;
- case AL_UNSIGNED_INT_SOFT: size *= sizeof(ALuint); break;
- case AL_FLOAT_SOFT: size *= sizeof(ALfloat); break;
- case AL_DOUBLE_SOFT: size *= sizeof(ALdouble); break;
- }
-
- return size;
-}
-
-ALsizei BytesToFrames(ALsizei size, ALenum channels, ALenum type)
-{
- return size / FramesToBytes(1, channels, type);
+ return "Unknown Format";
}
diff --git a/examples/common/alhelpers.h b/examples/common/alhelpers.h
index 9f60df2a..41a7ce58 100644
--- a/examples/common/alhelpers.h
+++ b/examples/common/alhelpers.h
@@ -11,28 +11,8 @@
extern "C" {
#endif /* __cplusplus */
-/* Some helper functions to get the name from the channel and type enums. */
-const char *ChannelsName(ALenum chans);
-const char *TypeName(ALenum type);
-
-/* Helpers to convert frame counts and byte lengths. */
-ALsizei FramesToBytes(ALsizei size, ALenum channels, ALenum type);
-ALsizei BytesToFrames(ALsizei size, ALenum channels, ALenum type);
-
-/* Retrieves a compatible buffer format given the channel configuration and
- * sample type. If an alIsBufferFormatSupportedSOFT-compatible function is
- * provided, it will be called to find the closest-matching format from
- * AL_SOFT_buffer_samples. Returns AL_NONE (0) if no supported format can be
- * found. */
-ALenum GetFormat(ALenum channels, ALenum type, LPALISBUFFERFORMATSUPPORTEDSOFT palIsBufferFormatSupportedSOFT);
-
-/* Loads samples into a buffer using the standard alBufferData call, but with a
- * LPALBUFFERSAMPLESSOFT-compatible prototype. Assumes internalformat is valid
- * for alBufferData, and that channels and type match it. */
-void AL_APIENTRY wrap_BufferSamples(ALuint buffer, ALuint samplerate,
- ALenum internalformat, ALsizei samples,
- ALenum channels, ALenum type,
- const ALvoid *data);
+/* Some helper functions to get the name from the format enums. */
+const char *FormatName(ALenum type);
/* Easy device init/deinit functions. InitAL returns 0 on success. */
int InitAL(char ***argv, int *argc);
diff --git a/examples/common/sdl_sound.c b/examples/common/sdl_sound.c
deleted file mode 100644
index 79a5bf32..00000000
--- a/examples/common/sdl_sound.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * SDL_sound Decoder Helpers
- *
- * Copyright (c) 2013 by Chris Robinson <[email protected]>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/* This file contains routines for helping to decode audio using SDL_sound.
- * There's very little OpenAL-specific code here.
- */
-#include "sdl_sound.h"
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <signal.h>
-#include <assert.h>
-
-#include <SDL_sound.h>
-
-#include "AL/al.h"
-#include "AL/alc.h"
-#include "AL/alext.h"
-
-#include "alhelpers.h"
-
-
-static int done_init = 0;
-
-FilePtr openAudioFile(const char *fname, size_t buftime_ms)
-{
- FilePtr file;
- ALuint rate;
- Uint32 bufsize;
- ALenum chans, type;
-
- /* We need to make sure SDL_sound is initialized. */
- if(!done_init)
- {
- Sound_Init();
- done_init = 1;
- }
-
- file = Sound_NewSampleFromFile(fname, NULL, 0);
- if(!file)
- {
- fprintf(stderr, "Failed to open %s: %s\n", fname, Sound_GetError());
- return NULL;
- }
-
- if(getAudioInfo(file, &rate, &chans, &type) != 0)
- {
- Sound_FreeSample(file);
- return NULL;
- }
-
- bufsize = FramesToBytes((ALsizei)(buftime_ms/1000.0*rate), chans, type);
- if(Sound_SetBufferSize(file, bufsize) == 0)
- {
- fprintf(stderr, "Failed to set buffer size to %u bytes: %s\n", bufsize, Sound_GetError());
- Sound_FreeSample(file);
- return NULL;
- }
-
- return file;
-}
-
-void closeAudioFile(FilePtr file)
-{
- if(file)
- Sound_FreeSample(file);
-}
-
-
-int getAudioInfo(FilePtr file, ALuint *rate, ALenum *channels, ALenum *type)
-{
- if(file->actual.channels == 1)
- *channels = AL_MONO_SOFT;
- else if(file->actual.channels == 2)
- *channels = AL_STEREO_SOFT;
- else
- {
- fprintf(stderr, "Unsupported channel count: %d\n", file->actual.channels);
- return 1;
- }
-
- if(file->actual.format == AUDIO_U8)
- *type = AL_UNSIGNED_BYTE_SOFT;
- else if(file->actual.format == AUDIO_S8)
- *type = AL_BYTE_SOFT;
- else if(file->actual.format == AUDIO_U16LSB || file->actual.format == AUDIO_U16MSB)
- *type = AL_UNSIGNED_SHORT_SOFT;
- else if(file->actual.format == AUDIO_S16LSB || file->actual.format == AUDIO_S16MSB)
- *type = AL_SHORT_SOFT;
- else
- {
- fprintf(stderr, "Unsupported sample format: 0x%04x\n", file->actual.format);
- return 1;
- }
-
- *rate = file->actual.rate;
-
- return 0;
-}
-
-
-uint8_t *getAudioData(FilePtr file, size_t *length)
-{
- *length = Sound_Decode(file);
- if(*length == 0)
- return NULL;
- if((file->actual.format == AUDIO_U16LSB && AUDIO_U16LSB != AUDIO_U16SYS) ||
- (file->actual.format == AUDIO_U16MSB && AUDIO_U16MSB != AUDIO_U16SYS) ||
- (file->actual.format == AUDIO_S16LSB && AUDIO_S16LSB != AUDIO_S16SYS) ||
- (file->actual.format == AUDIO_S16MSB && AUDIO_S16MSB != AUDIO_S16SYS))
- {
- /* Swap bytes if the decoded endianness doesn't match the system. */
- char *buffer = file->buffer;
- size_t i;
- for(i = 0;i < *length;i+=2)
- {
- char b = buffer[i];
- buffer[i] = buffer[i+1];
- buffer[i+1] = b;
- }
- }
- return file->buffer;
-}
-
-void *decodeAudioStream(FilePtr file, size_t *length)
-{
- Uint32 got;
- char *mem;
-
- got = Sound_DecodeAll(file);
- if(got == 0)
- {
- *length = 0;
- return NULL;
- }
-
- mem = malloc(got);
- memcpy(mem, file->buffer, got);
-
- *length = got;
- return mem;
-}
diff --git a/examples/common/sdl_sound.h b/examples/common/sdl_sound.h
deleted file mode 100644
index e93ab92b..00000000
--- a/examples/common/sdl_sound.h
+++ /dev/null
@@ -1,43 +0,0 @@
-#ifndef EXAMPLES_SDL_SOUND_H
-#define EXAMPLES_SDL_SOUND_H
-
-#include "AL/al.h"
-
-#include <SDL_sound.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-/* Opaque handles to files and streams. Apps don't need to concern themselves
- * with the internals */
-typedef Sound_Sample *FilePtr;
-
-/* Opens a file with SDL_sound, and specifies the size of the sample buffer in
- * milliseconds. */
-FilePtr openAudioFile(const char *fname, size_t buftime_ms);
-
-/* Closes/frees an opened file */
-void closeAudioFile(FilePtr file);
-
-/* Returns information about the given audio stream. Returns 0 on success. */
-int getAudioInfo(FilePtr file, ALuint *rate, ALenum *channels, ALenum *type);
-
-/* Returns a pointer to the next available chunk of decoded audio. The size (in
- * bytes) of the returned data buffer is stored in 'length', and the returned
- * pointer is only valid until the next call to getAudioData. */
-uint8_t *getAudioData(FilePtr file, size_t *length);
-
-/* Decodes all remaining data from the stream and returns a buffer containing
- * the audio data, with the size stored in 'length'. The returned pointer must
- * be freed with a call to free(). Note that since this decodes the whole
- * stream, using it on lengthy streams (eg, music) will use a lot of memory.
- * Such streams are better handled using getAudioData to keep smaller chunks in
- * memory at any given time. */
-void *decodeAudioStream(FilePtr, size_t *length);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* EXAMPLES_SDL_SOUND_H */
l kwd">VECTOR(Generator) gens; VECTOR(Modulator) mods; } GenModList; static void GenModList_Construct(GenModList *self) { VECTOR_INIT(self->gens); VECTOR_INIT(self->mods); } static void GenModList_Destruct(GenModList *self) { VECTOR_DEINIT(self->mods); VECTOR_DEINIT(self->gens); } static GenModList GenModList_clone(const GenModList *self) { GenModList ret; GenModList_Construct(&ret); VECTOR_INSERT(ret.gens, VECTOR_ITER_END(ret.gens), VECTOR_ITER_BEGIN(self->gens), VECTOR_ITER_END(self->gens) ); VECTOR_INSERT(ret.mods, VECTOR_ITER_END(ret.mods), VECTOR_ITER_BEGIN(self->mods), VECTOR_ITER_END(self->mods) ); return ret; } static void GenModList_insertGen(GenModList *self, const Generator *gen, ALboolean ispreset) { Generator *i; #define MATCH_GENERATOR(i) ((i)->mGenerator == gen->mGenerator) VECTOR_FIND_IF(i, Generator, self->gens, MATCH_GENERATOR); if(i != VECTOR_ITER_END(self->gens)) { i->mAmount = gen->mAmount; return; } #undef MATCH_GENERATOR if(ispreset && (gen->mGenerator == 0 || gen->mGenerator == 1 || gen->mGenerator == 2 || gen->mGenerator == 3 || gen->mGenerator == 4 || gen->mGenerator == 12 || gen->mGenerator == 45 || gen->mGenerator == 46 || gen->mGenerator == 47 || gen->mGenerator == 50 || gen->mGenerator == 54 || gen->mGenerator == 57 || gen->mGenerator == 58)) return; if(VECTOR_PUSH_BACK(self->gens, *gen) == AL_FALSE) { ERR("Failed to insert generator (from %zu elements)\n", VECTOR_SIZE(self->gens)); return; } } static void GenModList_accumGen(GenModList *self, const Generator *gen) { Generator *i; #define MATCH_GENERATOR(i) ((i)->mGenerator == gen->mGenerator) VECTOR_FIND_IF(i, Generator, self->gens, MATCH_GENERATOR); if(i != VECTOR_ITER_END(self->gens)) { if(gen->mGenerator == 43 || gen->mGenerator == 44) { /* Range generators accumulate by taking the intersection of the * two ranges. */ ALushort low = maxu(i->mAmount&0x00ff, gen->mAmount&0x00ff); ALushort high = minu(i->mAmount&0xff00, gen->mAmount&0xff00); i->mAmount = low | high; } else i->mAmount += gen->mAmount; return; } #undef MATCH_GENERATOR if(VECTOR_PUSH_BACK(self->gens, *gen) == AL_FALSE) { ERR("Failed to insert generator (from %zu elements)\n", VECTOR_SIZE(self->gens)); return; } if(gen->mGenerator < 60) VECTOR_BACK(self->gens).mAmount += DefaultGenValue[gen->mGenerator]; } static void GenModList_insertMod(GenModList *self, const Modulator *mod) { Modulator *i; #define MATCH_MODULATOR(i) ((i)->mDstOp == mod->mDstOp && (i)->mSrcOp == mod->mSrcOp && \ (i)->mAmtSrcOp == mod->mAmtSrcOp && (i)->mTransOp == mod->mTransOp) VECTOR_FIND_IF(i, Modulator, self->mods, MATCH_MODULATOR); if(i != VECTOR_ITER_END(self->mods)) { i->mAmount = mod->mAmount; return; } #undef MATCH_MODULATOR if(VECTOR_PUSH_BACK(self->mods, *mod) == AL_FALSE) { ERR("Failed to insert modulator (from %zu elements)\n", VECTOR_SIZE(self->mods)); return; } } static void GenModList_accumMod(GenModList *self, const Modulator *mod) { Modulator *i; #define MATCH_MODULATOR(i) ((i)->mDstOp == mod->mDstOp && (i)->mSrcOp == mod->mSrcOp && \ (i)->mAmtSrcOp == mod->mAmtSrcOp && (i)->mTransOp == mod->mTransOp) VECTOR_FIND_IF(i, Modulator, self->mods, MATCH_MODULATOR); if(i != VECTOR_ITER_END(self->mods)) { i->mAmount += mod->mAmount; return; } #undef MATCH_MODULATOR if(VECTOR_PUSH_BACK(self->mods, *mod) == AL_FALSE) { ERR("Failed to insert modulator (from %zu elements)\n", VECTOR_SIZE(self->mods)); return; } if(mod->mSrcOp == 0x0502 && mod->mDstOp == 48 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0) VECTOR_BACK(self->mods).mAmount += 960; else if(mod->mSrcOp == 0x0102 && mod->mDstOp == 8 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0) VECTOR_BACK(self->mods).mAmount += -2400; else if(mod->mSrcOp == 0x000D && mod->mDstOp == 6 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0) VECTOR_BACK(self->mods).mAmount += 50; else if(mod->mSrcOp == 0x0081 && mod->mDstOp == 6 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0) VECTOR_BACK(self->mods).mAmount += 50; else if(mod->mSrcOp == 0x0582 && mod->mDstOp == 48 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0) VECTOR_BACK(self->mods).mAmount += 960; else if(mod->mSrcOp == 0x028A && mod->mDstOp == 17 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0) VECTOR_BACK(self->mods).mAmount += 1000; else if(mod->mSrcOp == 0x058B && mod->mDstOp == 48 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0) VECTOR_BACK(self->mods).mAmount += 960; else if(mod->mSrcOp == 0x00DB && mod->mDstOp == 16 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0) VECTOR_BACK(self->mods).mAmount += 200; else if(mod->mSrcOp == 0x00DD && mod->mDstOp == 15 && mod->mAmtSrcOp == 0 && mod->mTransOp == 0) VECTOR_BACK(self->mods).mAmount += 200; /*else if(mod->mSrcOp == 0x020E && mod->mDstOp == ?initialpitch? && mod->mAmtSrcOp == 0x0010 && mod->mTransOp == 0) VECTOR_BACK(self->mods).mAmount += 12700;*/ } #define ERROR_GOTO(lbl_, ...) do { \ ERR(__VA_ARGS__); \ goto lbl_; \ } while(0) static ALboolean ensureFontSanity(const Soundfont *sfont) { ALsizei i; for(i = 0;i < sfont->phdr_size;i++) { if(sfont->phdr[i].mZoneIdx >= sfont->pbag_size) { WARN("Preset %d has invalid zone index %d (max: %d)\n", i, sfont->phdr[i].mZoneIdx, sfont->pbag_size); return AL_FALSE; } if(i+1 < sfont->phdr_size && sfont->phdr[i+1].mZoneIdx < sfont->phdr[i].mZoneIdx) { WARN("Preset %d has invalid zone index (%d does not follow %d)\n", i+1, sfont->phdr[i+1].mZoneIdx, sfont->phdr[i].mZoneIdx); return AL_FALSE; } } for(i = 0;i < sfont->pbag_size;i++) { if(sfont->pbag[i].mGenIdx >= sfont->pgen_size) { WARN("Preset zone %d has invalid generator index %d (max: %d)\n", i, sfont->pbag[i].mGenIdx, sfont->pgen_size); return AL_FALSE; } if(i+1 < sfont->pbag_size && sfont->pbag[i+1].mGenIdx < sfont->pbag[i].mGenIdx) { WARN("Preset zone %d has invalid generator index (%d does not follow %d)\n", i+1, sfont->pbag[i+1].mGenIdx, sfont->pbag[i].mGenIdx); return AL_FALSE; } if(sfont->pbag[i].mModIdx >= sfont->pmod_size) { WARN("Preset zone %d has invalid modulator index %d (max: %d)\n", i, sfont->pbag[i].mModIdx, sfont->pmod_size); return AL_FALSE; } if(i+1 < sfont->pbag_size && sfont->pbag[i+1].mModIdx < sfont->pbag[i].mModIdx) { WARN("Preset zone %d has invalid modulator index (%d does not follow %d)\n", i+1, sfont->pbag[i+1].mModIdx, sfont->pbag[i].mModIdx); return AL_FALSE; } } for(i = 0;i < sfont->inst_size;i++) { if(sfont->inst[i].mZoneIdx >= sfont->ibag_size) { WARN("Instrument %d has invalid zone index %d (max: %d)\n", i, sfont->inst[i].mZoneIdx, sfont->ibag_size); return AL_FALSE; } if(i+1 < sfont->inst_size && sfont->inst[i+1].mZoneIdx < sfont->inst[i].mZoneIdx) { WARN("Instrument %d has invalid zone index (%d does not follow %d)\n", i+1, sfont->inst[i+1].mZoneIdx, sfont->inst[i].mZoneIdx); return AL_FALSE; } } for(i = 0;i < sfont->ibag_size;i++) { if(sfont->ibag[i].mGenIdx >= sfont->igen_size) { WARN("Instrument zone %d has invalid generator index %d (max: %d)\n", i, sfont->ibag[i].mGenIdx, sfont->igen_size); return AL_FALSE; } if(i+1 < sfont->ibag_size && sfont->ibag[i+1].mGenIdx < sfont->ibag[i].mGenIdx) { WARN("Instrument zone %d has invalid generator index (%d does not follow %d)\n", i+1, sfont->ibag[i+1].mGenIdx, sfont->ibag[i].mGenIdx); return AL_FALSE; } if(sfont->ibag[i].mModIdx >= sfont->imod_size) { WARN("Instrument zone %d has invalid modulator index %d (max: %d)\n", i, sfont->ibag[i].mModIdx, sfont->imod_size); return AL_FALSE; } if(i+1 < sfont->ibag_size && sfont->ibag[i+1].mModIdx < sfont->ibag[i].mModIdx) { WARN("Instrument zone %d has invalid modulator index (%d does not follow %d)\n", i+1, sfont->ibag[i+1].mModIdx, sfont->ibag[i].mModIdx); return AL_FALSE; } } for(i = 0;i < sfont->shdr_size-1;i++) { if((sfont->shdr[i].mSampleType&0x8000) && sfont->irom == NULL) { WARN("Sample header %d has ROM sample type without an irom sub-chunk\n", i); return AL_FALSE; } } return AL_TRUE; } static ALboolean checkZone(const GenModList *zone, const PresetHeader *preset, const InstrumentHeader *inst, const SampleHeader *samp) { Generator *gen = VECTOR_ITER_BEGIN(zone->gens); Generator *gen_end = VECTOR_ITER_END(zone->gens); for(;gen != gen_end;gen++) { if(gen->mGenerator == 43 || gen->mGenerator == 44) { int high = gen->mAmount>>8; int low = gen->mAmount&0xff; if(!(low >= 0 && high <= 127 && high >= low)) { TRACE("Preset \"%s\", inst \"%s\", sample \"%s\": invalid %s range %d...%d\n", preset->mName, inst->mName, samp->mName, (gen->mGenerator == 43) ? "key" : (gen->mGenerator == 44) ? "velocity" : "(unknown)", low, high); return AL_FALSE; } } } return AL_TRUE; } static ALenum getModSrcInput(int input) { if(input == 0) return AL_ONE_SOFT; if(input == 2) return AL_NOTEON_VELOCITY_SOFT; if(input == 3) return AL_NOTEON_KEY_SOFT; if(input == 10) return AL_KEYPRESSURE_SOFT; if(input == 13) return AL_CHANNELPRESSURE_SOFT; if(input == 14) return AL_PITCHBEND_SOFT; if(input == 16) return AL_PITCHBEND_SENSITIVITY_SOFT; if((input&0x80)) { if(IsValidCtrlInput(input^0x80)) return input^0x80; } ERR("Unhandled modulator source input: 0x%02x\n", input); return AL_INVALID; } static ALenum getModSrcType(int type) { if(type == 0x0000) return AL_UNORM_SOFT; if(type == 0x0100) return AL_UNORM_REV_SOFT; if(type == 0x0200) return AL_SNORM_SOFT; if(type == 0x0300) return AL_SNORM_REV_SOFT; ERR("Unhandled modulator source type: 0x%04x\n", type); return AL_INVALID; } static ALenum getModSrcForm(int form) { if(form == 0x0000) return AL_LINEAR_SOFT; if(form == 0x0400) return AL_CONCAVE_SOFT; if(form == 0x0800) return AL_CONVEX_SOFT; if(form == 0x0C00) return AL_SWITCH_SOFT; ERR("Unhandled modulator source form: 0x%04x\n", form); return AL_INVALID; } static ALenum getModTransOp(int op) { if(op == 0) return AL_LINEAR_SOFT; if(op == 2) return AL_ABSOLUTE_SOFT; ERR("Unhandled modulator transform op: 0x%04x\n", op); return AL_INVALID; } static ALenum getLoopMode(int mode) { if(mode == 0) return AL_NONE; if(mode == 1) return AL_LOOP_CONTINUOUS_SOFT; if(mode == 3) return AL_LOOP_UNTIL_RELEASE_SOFT; ERR("Unhandled loop mode: %d\n", mode); return AL_NONE; } static ALenum getSampleType(int type) { if(type == 1) return AL_MONO_SOFT; if(type == 2) return AL_RIGHT_SOFT; if(type == 4) return AL_LEFT_SOFT; if(type == 8) { WARN("Sample type \"linked\" ignored; pretending mono\n"); return AL_MONO_SOFT; } ERR("Unhandled sample type: 0x%04x\n", type); return AL_MONO_SOFT; } static void fillZone(ALfontsound *sound, ALCcontext *context, const GenModList *zone) { static const ALenum Gen2Param[60] = { 0, /* 0 - startAddrOffset */ 0, /* 1 - endAddrOffset */ 0, /* 2 - startloopAddrOffset */ 0, /* 3 - endloopAddrOffset */ 0, /* 4 - startAddrCoarseOffset */ AL_MOD_LFO_TO_PITCH_SOFT, /* 5 - modLfoToPitch */ AL_VIBRATO_LFO_TO_PITCH_SOFT, /* 6 - vibLfoToPitch */ AL_MOD_ENV_TO_PITCH_SOFT, /* 7 - modEnvToPitch */ AL_FILTER_CUTOFF_SOFT, /* 8 - initialFilterFc */ AL_FILTER_RESONANCE_SOFT, /* 9 - initialFilterQ */ AL_MOD_LFO_TO_FILTER_CUTOFF_SOFT, /* 10 - modLfoToFilterFc */ AL_MOD_ENV_TO_FILTER_CUTOFF_SOFT, /* 11 - modEnvToFilterFc */ 0, /* 12 - endAddrCoarseOffset */ AL_MOD_LFO_TO_VOLUME_SOFT, /* 13 - modLfoToVolume */ 0, /* 14 - */ AL_CHORUS_SEND_SOFT, /* 15 - chorusEffectsSend */ AL_REVERB_SEND_SOFT, /* 16 - reverbEffectsSend */ AL_PAN_SOFT, /* 17 - pan */ 0, /* 18 - */ 0, /* 19 - */ 0, /* 20 - */ AL_MOD_LFO_DELAY_SOFT, /* 21 - delayModLFO */ AL_MOD_LFO_FREQUENCY_SOFT, /* 22 - freqModLFO */ AL_VIBRATO_LFO_DELAY_SOFT, /* 23 - delayVibLFO */ AL_VIBRATO_LFO_FREQUENCY_SOFT, /* 24 - freqVibLFO */ AL_MOD_ENV_DELAYTIME_SOFT, /* 25 - delayModEnv */ AL_MOD_ENV_ATTACKTIME_SOFT, /* 26 - attackModEnv */ AL_MOD_ENV_HOLDTIME_SOFT, /* 27 - holdModEnv */ AL_MOD_ENV_DECAYTIME_SOFT, /* 28 - decayModEnv */ AL_MOD_ENV_SUSTAINVOLUME_SOFT, /* 29 - sustainModEnv */ AL_MOD_ENV_RELEASETIME_SOFT, /* 30 - releaseModEnv */ AL_MOD_ENV_KEY_TO_HOLDTIME_SOFT, /* 31 - keynumToModEnvHold */ AL_MOD_ENV_KEY_TO_DECAYTIME_SOFT, /* 32 - keynumToModEnvDecay */ AL_VOLUME_ENV_DELAYTIME_SOFT, /* 33 - delayVolEnv */ AL_VOLUME_ENV_ATTACKTIME_SOFT, /* 34 - attackVolEnv */ AL_VOLUME_ENV_HOLDTIME_SOFT, /* 35 - holdVolEnv */ AL_VOLUME_ENV_DECAYTIME_SOFT, /* 36 - decayVolEnv */ AL_VOLUME_ENV_SUSTAINVOLUME_SOFT, /* 37 - sustainVolEnv */ AL_VOLUME_ENV_RELEASETIME_SOFT, /* 38 - releaseVolEnv */ AL_VOLUME_ENV_KEY_TO_HOLDTIME_SOFT, /* 39 - keynumToVolEnvHold */ AL_VOLUME_ENV_KEY_TO_DECAYTIME_SOFT, /* 40 - keynumToVolEnvDecay */ 0, /* 41 - */ 0, /* 42 - */ AL_KEY_RANGE_SOFT, /* 43 - keyRange */ AL_VELOCITY_RANGE_SOFT, /* 44 - velRange */ 0, /* 45 - startloopAddrCoarseOffset */ 0, /* 46 - keynum */ 0, /* 47 - velocity */ AL_ATTENUATION_SOFT, /* 48 - initialAttenuation */ 0, /* 49 - */ 0, /* 50 - endloopAddrCoarseOffset */ AL_TUNING_COARSE_SOFT, /* 51 - corseTune */ AL_TUNING_FINE_SOFT, /* 52 - fineTune */ 0, /* 53 - */ AL_LOOP_MODE_SOFT, /* 54 - sampleModes */ 0, /* 55 - */ AL_TUNING_SCALE_SOFT, /* 56 - scaleTuning */