aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorraysan5 <raysan5@gmail.com>2016-08-01 21:37:45 +0200
committerraysan5 <raysan5@gmail.com>2016-08-01 21:37:45 +0200
commit58d2f70b7e11aadb5eab5f9fa1c081b22a59ef91 (patch)
tree4bdc752c013173a720b0f55850e83d920fe62b39 /src
parent36cf1f7dfd8865310c21b0f78cf1de9976d9197a (diff)
downloadraylib-58d2f70b7e11aadb5eab5f9fa1c081b22a59ef91.tar.gz
raylib-58d2f70b7e11aadb5eab5f9fa1c081b22a59ef91.zip
Review audio module and examples
Diffstat (limited to 'src')
-rw-r--r--src/audio.c179
1 files changed, 63 insertions, 116 deletions
diff --git a/src/audio.c b/src/audio.c
index 2ff56737..d1c425d5 100644
--- a/src/audio.c
+++ b/src/audio.c
@@ -86,13 +86,13 @@
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
-#define MAX_STREAM_BUFFERS 2 // Number of buffers for each audio stream
+#define MAX_STREAM_BUFFERS 2 // Number of buffers for each audio stream
// NOTE: Music buffer size is defined by number of samples, independent of sample size
// After some math, considering a sampleRate of 48000, a buffer refill rate of 1/60 seconds
// and double-buffering system, I concluded that a 4096 samples buffer should be enough
-// In case of music-stalls, just inclease this number
-#define AUDIO_BUFFER_SIZE 4096 // PCM data samples (i.e. short: 32Kb)
+// In case of music-stalls, just increase this number
+#define AUDIO_BUFFER_SIZE 4096 // PCM data samples (i.e. short: 32Kb)
//----------------------------------------------------------------------------------
// Types and Structures Definition
@@ -141,12 +141,12 @@ static Wave LoadWAV(const char *fileName); // Load WAV file
static Wave LoadOGG(char *fileName); // Load OGG file
static void UnloadWave(Wave wave); // Unload wave data
-static AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels);
-static void CloseAudioStream(AudioStream stream); // Frees mix channel
-static int BufferAudioStream(AudioStream stream, void *data, int numberElements); // Pushes more audio data into mix channel
-
static bool BufferMusicStream(Music music, int numBuffersToProcess); // Fill music buffers with data
+static AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels);
+static void BufferAudioStream(AudioStream stream, void *data, int numSamples);
+static void CloseAudioStream(AudioStream stream);
+
#if defined(AUDIO_STANDALONE)
const char *GetExtension(const char *fileName); // Get the extension for a filename
void TraceLog(int msgType, const char *text, ...); // Outputs a trace log message (INFO, ERROR, WARNING)
@@ -492,27 +492,23 @@ Music LoadMusicStream(char *fileName)
// Open ogg audio stream
music->ctxOgg = stb_vorbis_open_filename(fileName, NULL, NULL);
- if (music->ctxOgg == NULL)
- {
- TraceLog(WARNING, "[%s] OGG audio file could not be opened", fileName);
- }
+ if (music->ctxOgg == NULL) TraceLog(WARNING, "[%s] OGG audio file could not be opened", fileName);
else
{
stb_vorbis_info info = stb_vorbis_get_info(music->ctxOgg); // Get Ogg file info
-
- TraceLog(DEBUG, "[%s] Ogg sample rate: %i", fileName, info.sample_rate);
- TraceLog(DEBUG, "[%s] Ogg channels: %i", fileName, info.channels);
- TraceLog(DEBUG, "[%s] Temp memory required: %i", fileName, info.temp_memory_required);
+ //float totalLengthSeconds = stb_vorbis_stream_length_in_seconds(music->ctxOgg);
// TODO: Support 32-bit sampleSize OGGs
music->stream = InitAudioStream(info.sample_rate, 16, info.channels);
-
music->totalSamples = (unsigned int)stb_vorbis_stream_length_in_samples(music->ctxOgg)*info.channels;
music->samplesLeft = music->totalSamples;
- //float totalLengthSeconds = stb_vorbis_stream_length_in_seconds(music->ctxOgg);
-
music->ctxType = MUSIC_AUDIO_OGG;
music->loop = true; // We loop by default
+
+ TraceLog(DEBUG, "[%s] OGG sample rate: %i", fileName, info.sample_rate);
+ TraceLog(DEBUG, "[%s] OGG channels: %i", fileName, info.channels);
+ TraceLog(DEBUG, "[%s] OGG memory required: %i", fileName, info.temp_memory_required);
+
}
}
else if (strcmp(GetExtension(fileName), "xm") == 0)
@@ -523,17 +519,15 @@ Music LoadMusicStream(char *fileName)
{
jar_xm_set_max_loop_count(music->ctxXm, 0); // Set infinite number of loops
- music->totalSamples = (unsigned int)jar_xm_get_remaining_samples(music->ctxXm);
- music->samplesLeft = music->totalSamples;
-
- TraceLog(INFO, "[%s] XM number of samples: %i", fileName, music->totalSamples);
- TraceLog(INFO, "[%s] XM track length: %11.6f sec", fileName, (float)music->totalSamples/48000.0f);
-
// NOTE: Only stereo is supported for XM
music->stream = InitAudioStream(48000, 32, 2);
-
+ music->totalSamples = (unsigned int)jar_xm_get_remaining_samples(music->ctxXm);
+ music->samplesLeft = music->totalSamples;
music->ctxType = MUSIC_MODULE_XM;
music->loop = true;
+
+ TraceLog(DEBUG, "[%s] XM number of samples: %i", fileName, music->totalSamples);
+ TraceLog(DEBUG, "[%s] XM track length: %11.6f sec", fileName, (float)music->totalSamples/48000.0f);
}
else TraceLog(WARNING, "[%s] XM file could not be opened", fileName);
}
@@ -543,16 +537,14 @@ Music LoadMusicStream(char *fileName)
if (jar_mod_load_file(&music->ctxMod, fileName))
{
+ music->stream = InitAudioStream(48000, 16, 2);
music->totalSamples = (unsigned int)jar_mod_max_samples(&music->ctxMod);
music->samplesLeft = music->totalSamples;
+ music->ctxType = MUSIC_MODULE_MOD;
+ music->loop = true;
TraceLog(INFO, "[%s] MOD number of samples: %i", fileName, music->samplesLeft);
TraceLog(INFO, "[%s] MOD track length: %11.6f sec", fileName, (float)music->totalSamples/48000.0f);
-
- music->stream = InitAudioStream(48000, 16, 2);
-
- music->ctxType = MUSIC_MODULE_MOD;
- music->loop = true;
}
else TraceLog(WARNING, "[%s] MOD file could not be opened", fileName);
}
@@ -799,42 +791,18 @@ static void CloseAudioStream(AudioStream stream)
}
// Push more audio data into audio stream, only one buffer per call
-// NOTE: Returns number of samples that were processed
-static int BufferAudioStream(AudioStream stream, void *data, int numberElements)
-{
- if (!data || !numberElements)
- {
- // Pauses audio until data is given
- alSourcePause(stream.source);
- return 0;
- }
-
+static void BufferAudioStream(AudioStream stream, void *data, int numSamples)
+{
ALuint buffer = 0;
alSourceUnqueueBuffers(stream.source, 1, &buffer);
- if (!buffer) return 0;
-
- // Reference
- //void alBufferData(ALuint bufferName, ALenum format, const ALvoid *data, ALsizei size, ALsizei frequency);
-
- // ALuint bufferName: buffer id
- // ALenum format: Valid formats are
- // AL_FORMAT_MONO8, // unsigned char
- // AL_FORMAT_MONO16, // short
- // AL_FORMAT_STEREO8,
- // AL_FORMAT_STEREO16 // stereo data is interleaved: left+right channels sample
- // AL_FORMAT_MONO_FLOAT32 (extension)
- // AL_FORMAT_STEREO_FLOAT32 (extension)
- // ALsizei size: Number of bytes, must be coherent with format
- // ALsizei frequency: sample rate
-
- if (stream.sampleSize == 8) alBufferData(buffer, stream.format, (unsigned char *)data, numberElements*sizeof(unsigned char), stream.sampleRate);
- else if (stream.sampleSize == 16) alBufferData(buffer, stream.format, (short *)data, numberElements*sizeof(short), stream.sampleRate);
- else if (stream.sampleSize == 32) alBufferData(buffer, stream.format, (float *)data, numberElements*sizeof(float), stream.sampleRate);
+ //TraceLog(DEBUG, "Buffer to refill: %i", buffer);
- alSourceQueueBuffers(stream.source, 1, &buffer);
+ if (stream.sampleSize == 8) alBufferData(buffer, stream.format, (unsigned char *)data, numSamples*sizeof(unsigned char), stream.sampleRate);
+ else if (stream.sampleSize == 16) alBufferData(buffer, stream.format, (short *)data, numSamples*sizeof(short), stream.sampleRate);
+ else if (stream.sampleSize == 32) alBufferData(buffer, stream.format, (float *)data, numSamples*sizeof(float), stream.sampleRate);
- return numberElements;
+ alSourceQueueBuffers(stream.source, 1, &buffer);
}
// Fill music buffers with new data from music stream
@@ -845,70 +813,49 @@ static bool BufferMusicStream(Music music, int numBuffersToProcess)
int size = 0; // Total size of data steamed in L+R samples for xm floats, individual L or R for ogg shorts
bool active = true; // We can get more data from stream (not finished)
-
- if (music->ctxType == MUSIC_MODULE_XM) // There is no end of stream for xmfiles, once the end is reached zeros are generated for non looped chiptunes.
+
+ for (int i = 0; i < numBuffersToProcess; i++)
{
- for (int i = 0; i < numBuffersToProcess; i++)
- {
- if (music->samplesLeft >= AUDIO_BUFFER_SIZE) size = AUDIO_BUFFER_SIZE/2;
- else size = music->samplesLeft/2;
-
- // Read 2*shorts and moves them to buffer+size memory location
- jar_xm_generate_samples(music->ctxXm, pcmf, size);
-
- BufferAudioStream(music->stream, pcmf, size*2);
-
- music->samplesLeft -= size;
+ if (music->samplesLeft >= AUDIO_BUFFER_SIZE) size = AUDIO_BUFFER_SIZE;
+ else size = music->samplesLeft;
- if (music->samplesLeft <= 0)
- {
- active = false;
- break;
- }
- }
- }
- else if (music->ctxType == MUSIC_MODULE_MOD)
- {
- for (int i = 0; i < numBuffersToProcess; i++)
+ switch (music->ctxType)
{
- if (music->samplesLeft >= AUDIO_BUFFER_SIZE) size = AUDIO_BUFFER_SIZE/2;
- else size = music->samplesLeft/2;
-
- jar_mod_fillbuffer(&music->ctxMod, pcm, size, 0);
-
- BufferAudioStream(music->stream, pcm, size*2);
-
- music->samplesLeft -= size;
-
- if (music->samplesLeft <= 0)
+ case MUSIC_AUDIO_OGG:
{
- active = false;
- break;
- }
+ // NOTE: Returns the number of samples to process (should be the same as size)
+ int numSamples = stb_vorbis_get_samples_short_interleaved(music->ctxOgg, music->stream.channels, pcm, size);
+
+ BufferAudioStream(music->stream, pcm, numSamples*music->stream.channels);
+ music->samplesLeft -= (numSamples*music->stream.channels);
+
+ } break;
+ case MUSIC_MODULE_XM:
+ {
+ // NOTE: Output buffer is 2*numsamples elements (left and right value for each sample)
+ jar_xm_generate_samples(music->ctxXm, pcmf, size/2);
+ BufferAudioStream(music->stream, pcmf, size); // Using 32bit PCM data
+ music->samplesLeft -= (size/2);
+
+ } break;
+ case MUSIC_MODULE_MOD:
+ {
+ // NOTE: Output buffer size is nbsample*channels (default: 48000Hz, 16bit, Stereo)
+ jar_mod_fillbuffer(&music->ctxMod, pcm, size/2, 0);
+ BufferAudioStream(music->stream, pcm, size);
+ music->samplesLeft -= (size/2);
+
+ } break;
+ default: break;
}
- }
- else if (music->ctxType == MUSIC_AUDIO_OGG)
- {
- if (music->samplesLeft >= AUDIO_BUFFER_SIZE) size = AUDIO_BUFFER_SIZE;
- else size = music->samplesLeft;
- for (int i = 0; i < numBuffersToProcess; i++)
+ if (music->samplesLeft <= 0)
{
- // NOTE: Returns the number of samples stored per channel
- int numSamples = stb_vorbis_get_samples_short_interleaved(music->ctxOgg, music->stream.channels, pcm, size);
-
- BufferAudioStream(music->stream, pcm, numSamples*music->stream.channels);
-
- music->samplesLeft -= (numSamples*music->stream.channels);
-
- if (music->samplesLeft <= 0)
- {
- active = false;
- break;
- }
+ active = false;
+ break;
}
}
-
+
return active;
}