aboutsummaryrefslogtreecommitdiff
path: root/src/audio.c
diff options
context:
space:
mode:
authorraysan5 <raysan5@gmail.com>2014-04-19 16:36:49 +0200
committerraysan5 <raysan5@gmail.com>2014-04-19 16:36:49 +0200
commitf06a15ac8b3fe92d101ae795225fbf56fa670dba (patch)
treecdfba90ee24fd078a15c89d8753ee3e11d8e229b /src/audio.c
parent650a8f7f159d3ce2addb1b0fdb31c3f460005391 (diff)
downloadraylib-f06a15ac8b3fe92d101ae795225fbf56fa670dba.tar.gz
raylib-f06a15ac8b3fe92d101ae795225fbf56fa670dba.zip
raylib 1.1
View CHANGELOG for a detailed list of changes
Diffstat (limited to 'src/audio.c')
-rw-r--r--src/audio.c630
1 files changed, 346 insertions, 284 deletions
diff --git a/src/audio.c b/src/audio.c
index 35874b59..c32b9f6e 100644
--- a/src/audio.c
+++ b/src/audio.c
@@ -6,7 +6,7 @@
*
* Uses external lib:
* OpenAL - Audio device management lib
-* TODO: stb_vorbis - Ogg audio files loading
+* stb_vorbis - Ogg audio files loading
*
* Copyright (c) 2013 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
@@ -32,50 +32,45 @@
#include <AL/al.h> // OpenAL basic header
#include <AL/alc.h> // OpenAL context header (like OpenGL, OpenAL requires a context to work)
-#include <stdlib.h> // To use exit() function
+#include <stdlib.h> // Declares malloc() and free() for memory management
+#include <string.h> // Required for strcmp()
#include <stdio.h> // Used for .WAV loading
#include "utils.h" // rRES data decompression utility function
-//#include "stb_vorbis.h" // OGG loading functions
+#include "stb_vorbis.h" // OGG loading functions
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
-// Nop...
+#define MUSIC_STREAM_BUFFERS 2
+#define MUSIC_BUFFER_SIZE 4096*8 //4096*32
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
-// Sound source type (all file loaded in memory)
-/*
-struct Sound {
- unsigned int source;
- unsigned int buffer;
-};
-
-// Music type (file streamming from memory)
-// NOTE: Anything longer than ~10 seconds should be Music...
-struct Music {
- stb_vorbis* stream;
- stb_vorbis_info info;
-
- ALuint id;
- ALuint buffers[2];
+
+// Music type (file streaming from memory)
+// NOTE: Anything longer than ~10 seconds should be streamed...
+typedef struct Music {
+ stb_vorbis *stream;
+
+ ALuint buffers[MUSIC_STREAM_BUFFERS];
ALuint source;
ALenum format;
- int bufferSize;
+ int channels;
+ int sampleRate;
int totalSamplesLeft;
bool loop;
-};
-*/
+
+} Music;
// Wave file data
typedef struct Wave {
- unsigned char *data; // Buffer data pointer
+ void *data; // Buffer data pointer
+ unsigned int dataSize; // Data size in bytes
unsigned int sampleRate;
- unsigned int dataSize;
short bitsPerSample;
short channels;
} Wave;
@@ -83,22 +78,23 @@ typedef struct Wave {
//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
-static bool musicIsPlaying;
-static Music *currentMusic;
+bool musicEnabled = false;
+static Music currentMusic; // Current music loaded
+ // NOTE: Only one music file playing at a time
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
//----------------------------------------------------------------------------------
-static Wave LoadWAV(char *fileName);
-static void UnloadWAV(Wave wave);
-//static Ogg LoadOGG(char *fileName);
-static bool MusicStream(Music music, ALuint buffer);
+static Wave LoadWAV(const char *fileName);
+static Wave LoadOGG(char *fileName);
+static void UnloadWave(Wave wave);
-extern bool MusicStreamUpdate();
-extern void PlayCurrentMusic();
+static bool BufferMusicStream(ALuint buffer); // Fill music buffers with data
+static void EmptyMusicStream(); // Empty music buffers
+extern void UpdateMusicStream(); // Updates buffers (refill) for music streaming
//----------------------------------------------------------------------------------
-// Module Functions Definition - Window and OpenGL Context Functions
+// Module Functions Definition - Audio Device initialization and Closing
//----------------------------------------------------------------------------------
// Initialize audio device and context
@@ -126,13 +122,13 @@ void InitAudioDevice()
alListener3f(AL_POSITION, 0, 0, 0);
alListener3f(AL_VELOCITY, 0, 0, 0);
alListener3f(AL_ORIENTATION, 0, 0, -1);
-
- musicIsPlaying = false;
}
// Close the audio device for the current context, and destroys the context
void CloseAudioDevice()
{
+ StopMusicStream(); // Stop music streaming and close current stream
+
ALCdevice *device;
ALCcontext *context = alcGetCurrentContext();
@@ -145,60 +141,70 @@ void CloseAudioDevice()
alcCloseDevice(device);
}
+//----------------------------------------------------------------------------------
+// Module Functions Definition - Sounds loading and playing (.WAV)
+//----------------------------------------------------------------------------------
+
// Load sound to memory
Sound LoadSound(char *fileName)
{
Sound sound;
+ Wave wave;
// NOTE: The entire file is loaded to memory to play it all at once (no-streaming)
- // WAV file loading
- // NOTE: Buffer space is allocated inside LoadWAV, Wave must be freed
- Wave wave = LoadWAV(fileName);
-
- ALenum format = 0;
- // The OpenAL format is worked out by looking at the number of channels and the bits per sample
- if (wave.channels == 1)
- {
- if (wave.bitsPerSample == 8 ) format = AL_FORMAT_MONO8;
- else if (wave.bitsPerSample == 16) format = AL_FORMAT_MONO16;
- }
- else if (wave.channels == 2)
- {
- if (wave.bitsPerSample == 8 ) format = AL_FORMAT_STEREO8;
- else if (wave.bitsPerSample == 16) format = AL_FORMAT_STEREO16;
- }
-
+ // Audio file loading
+ // NOTE: Buffer space is allocated inside function, Wave must be freed
- // Create an audio source
- ALuint source;
- alGenSources(1, &source); // Generate pointer to audio source
-
- alSourcef(source, AL_PITCH, 1);
- alSourcef(source, AL_GAIN, 1);
- alSource3f(source, AL_POSITION, 0, 0, 0);
- alSource3f(source, AL_VELOCITY, 0, 0, 0);
- alSourcei(source, AL_LOOPING, AL_FALSE);
+ if (strcmp(GetExtension(fileName),"wav") == 0) wave = LoadWAV(fileName);
+ else if (strcmp(GetExtension(fileName),"ogg") == 0) wave = LoadOGG(fileName);
+ else TraceLog(WARNING, "[%s] Sound extension not recognized, it can't be loaded", fileName);
- // Convert loaded data to OpenAL buffer
- //----------------------------------------
- ALuint buffer;
- alGenBuffers(1, &buffer); // Generate pointer to buffer
+ if (wave.data != NULL)
+ {
+ ALenum format = 0;
+ // The OpenAL format is worked out by looking at the number of channels and the bits per sample
+ if (wave.channels == 1)
+ {
+ if (wave.bitsPerSample == 8 ) format = AL_FORMAT_MONO8;
+ else if (wave.bitsPerSample == 16) format = AL_FORMAT_MONO16;
+ }
+ else if (wave.channels == 2)
+ {
+ if (wave.bitsPerSample == 8 ) format = AL_FORMAT_STEREO8;
+ else if (wave.bitsPerSample == 16) format = AL_FORMAT_STEREO16;
+ }
+
+ // Create an audio source
+ ALuint source;
+ alGenSources(1, &source); // Generate pointer to audio source
+
+ alSourcef(source, AL_PITCH, 1);
+ alSourcef(source, AL_GAIN, 1);
+ alSource3f(source, AL_POSITION, 0, 0, 0);
+ alSource3f(source, AL_VELOCITY, 0, 0, 0);
+ alSourcei(source, AL_LOOPING, AL_FALSE);
+
+ // Convert loaded data to OpenAL buffer
+ //----------------------------------------
+ ALuint buffer;
+ alGenBuffers(1, &buffer); // Generate pointer to buffer
- // Upload sound data to buffer
- alBufferData(buffer, format, (void*)wave.data, wave.dataSize, wave.sampleRate);
+ // Upload sound data to buffer
+ alBufferData(buffer, format, wave.data, wave.dataSize, wave.sampleRate);
- // Attach sound buffer to source
- alSourcei(source, AL_BUFFER, buffer);
-
- // Unallocate WAV data
- UnloadWAV(wave);
-
- TraceLog(INFO, "[%s] Sound file loaded successfully", fileName);
- TraceLog(INFO, "[%s] Sample rate: %i - Channels: %i", fileName, wave.sampleRate, wave.channels);
-
- sound.source = source;
- sound.buffer = buffer;
+ // Attach sound buffer to source
+ alSourcei(source, AL_BUFFER, buffer);
+
+ // Unallocate WAV data
+ UnloadWave(wave);
+
+ TraceLog(INFO, "[%s] Sound file loaded successfully", fileName);
+ TraceLog(INFO, "[%s] Sample rate: %i - Channels: %i", fileName, wave.sampleRate, wave.channels);
+
+ sound.source = source;
+ sound.buffer = buffer;
+ }
return sound;
}
@@ -314,7 +320,7 @@ Sound LoadSoundFromRES(const char *rresName, int resId)
alSourcei(source, AL_BUFFER, buffer);
// Unallocate WAV data
- UnloadWAV(wave);
+ UnloadWave(wave);
TraceLog(INFO, "[%s] Sound loaded successfully from resource, sample rate: %i", rresName, (int)sampleRate);
@@ -381,22 +387,6 @@ void PlaySound(Sound sound)
//alGetSourcef(sound.source, AL_SEC_OFFSET, &result); // AL_SAMPLE_OFFSET
}
-// Play a sound with extended options
-// TODO: This function should be reviewed...
-void PlaySoundEx(Sound sound, float timePosition, bool loop)
-{
- // TODO: Review
-
- // Change the current position (e.g. skip some part of the sound)
- // NOTE: Only work when the entire file is in a single buffer
- //alSourcei(sound.source, AL_BYTE_OFFSET, int(position * sampleRate));
-
- alSourcePlay(sound.source); // Play the sound
-
- if (loop) alSourcei(sound.source, AL_LOOPING, AL_TRUE);
- else alSourcei(sound.source, AL_LOOPING, AL_FALSE);
-}
-
// Pause a sound
void PauseSound(Sound sound)
{
@@ -421,30 +411,250 @@ bool SoundIsPlaying(Sound sound)
return playing;
}
+// Set volume for a sound
+void SetSoundVolume(Sound sound, float volume)
+{
+ alSourcef(sound.source, AL_GAIN, volume);
+}
+
+// Set pitch for a sound
+void SetSoundPitch(Sound sound, float pitch)
+{
+ alSourcef(sound.source, AL_PITCH, pitch);
+}
+
+//----------------------------------------------------------------------------------
+// Module Functions Definition - Music loading and stream playing (.OGG)
+//----------------------------------------------------------------------------------
+
+// Start music playing (open stream)
+void PlayMusicStream(char *fileName)
+{
+ if (strcmp(GetExtension(fileName),"ogg") == 0)
+ {
+ // Stop current music, clean buffers, unload current stream
+ StopMusicStream();
+
+ // Open audio stream
+ currentMusic.stream = stb_vorbis_open_filename(fileName, NULL, NULL);
+
+ if (currentMusic.stream == NULL) TraceLog(WARNING, "[%s] Could not open ogg audio file", fileName);
+ else
+ {
+ // Get file info
+ stb_vorbis_info info = stb_vorbis_get_info(currentMusic.stream);
+
+ currentMusic.channels = info.channels;
+ currentMusic.sampleRate = info.sample_rate;
+
+ TraceLog(INFO, "[%s] Ogg sample rate: %i", fileName, info.sample_rate);
+ TraceLog(INFO, "[%s] Ogg channels: %i", fileName, info.channels);
+ TraceLog(INFO, "[%s] Temp memory required: %i", fileName, info.temp_memory_required);
+
+ if (info.channels == 2) currentMusic.format = AL_FORMAT_STEREO16;
+ else currentMusic.format = AL_FORMAT_MONO16;
+
+ currentMusic.loop = true; // We loop by default
+ musicEnabled = true;
+
+ // Create an audio source
+ alGenSources(1, &currentMusic.source); // Generate pointer to audio source
+
+ alSourcef(currentMusic.source, AL_PITCH, 1);
+ alSourcef(currentMusic.source, AL_GAIN, 1);
+ alSource3f(currentMusic.source, AL_POSITION, 0, 0, 0);
+ alSource3f(currentMusic.source, AL_VELOCITY, 0, 0, 0);
+ //alSourcei(currentMusic.source, AL_LOOPING, AL_TRUE); // ERROR: Buffers do not queue!
+
+ // Generate two OpenAL buffers
+ alGenBuffers(2, currentMusic.buffers);
+
+ // Fill buffers with music...
+ BufferMusicStream(currentMusic.buffers[0]);
+ BufferMusicStream(currentMusic.buffers[1]);
+
+ // Queue buffers and start playing
+ alSourceQueueBuffers(currentMusic.source, 2, currentMusic.buffers);
+ alSourcePlay(currentMusic.source);
+
+ // NOTE: Regularly, we must check if a buffer has been processed and refill it: MusicStreamUpdate()
+
+ currentMusic.totalSamplesLeft = stb_vorbis_stream_length_in_samples(currentMusic.stream) * currentMusic.channels;
+ }
+ }
+ else TraceLog(WARNING, "[%s] Music extension not recognized, it can't be loaded", fileName);
+}
+
+// Stop music playing (close stream)
+void StopMusicStream()
+{
+ if (musicEnabled)
+ {
+ alSourceStop(currentMusic.source);
+
+ EmptyMusicStream(); // Empty music buffers
+
+ alDeleteSources(1, &currentMusic.source);
+ alDeleteBuffers(2, currentMusic.buffers);
+
+ stb_vorbis_close(currentMusic.stream);
+ }
+
+ musicEnabled = false;
+}
+
+// Pause music playing
+void PauseMusicStream()
+{
+ // TODO: Record music is paused or check if music available!
+ alSourcePause(currentMusic.source);
+}
+
// Check if music is playing
-bool MusicIsPlaying(Music music)
+bool MusicIsPlaying()
{
ALenum state;
- alGetSourcei(music.source, AL_SOURCE_STATE, &state);
+ alGetSourcei(currentMusic.source, AL_SOURCE_STATE, &state);
return (state == AL_PLAYING);
}
-// Set volume for a sound
-void SetVolume(Sound sound, float volume)
+// Set volume for music
+void SetMusicVolume(float volume)
{
- alSourcef(sound.source, AL_GAIN, volume);
+ alSourcef(currentMusic.source, AL_GAIN, volume);
}
-// Set pitch for a sound
-void SetPitch(Sound sound, float pitch)
+// Get current music time length (in seconds)
+float GetMusicTimeLength()
{
- alSourcef(sound.source, AL_PITCH, pitch);
+ float totalSeconds = stb_vorbis_stream_length_in_seconds(currentMusic.stream);
+
+ return totalSeconds;
+}
+
+// Get current music time played (in seconds)
+float GetMusicTimePlayed()
+{
+ int totalSamples = stb_vorbis_stream_length_in_samples(currentMusic.stream) * currentMusic.channels;
+
+ int samplesPlayed = totalSamples - currentMusic.totalSamplesLeft;
+
+ float secondsPlayed = (float)samplesPlayed / (currentMusic.sampleRate * currentMusic.channels);
+
+ return secondsPlayed;
+}
+
+//----------------------------------------------------------------------------------
+// Module specific Functions Definition
+//----------------------------------------------------------------------------------
+
+// Fill music buffers with new data from music stream
+static bool BufferMusicStream(ALuint buffer)
+{
+ short pcm[MUSIC_BUFFER_SIZE];
+
+ int size = 0; // Total size of data steamed (in bytes)
+ int streamedBytes = 0; // Bytes of data obtained in one samples get
+
+ bool active = true; // We can get more data from stream (not finished)
+
+ if (musicEnabled)
+ {
+ while (size < MUSIC_BUFFER_SIZE)
+ {
+ streamedBytes = stb_vorbis_get_samples_short_interleaved(currentMusic.stream, currentMusic.channels, pcm + size, MUSIC_BUFFER_SIZE - size);
+
+ if (streamedBytes > 0) size += (streamedBytes*currentMusic.channels);
+ else break;
+ }
+
+ TraceLog(DEBUG, "Streaming music data to buffer. Bytes streamed: %i", size);
+ }
+
+ if (size > 0)
+ {
+ alBufferData(buffer, currentMusic.format, pcm, size*sizeof(short), currentMusic.sampleRate);
+
+ currentMusic.totalSamplesLeft -= size;
+ }
+ else
+ {
+ active = false;
+ TraceLog(WARNING, "No more data obtained from stream");
+ }
+
+ return active;
+}
+
+// Empty music buffers
+static void EmptyMusicStream()
+{
+ ALuint buffer = 0;
+ int queued = 0;
+
+ alGetSourcei(currentMusic.source, AL_BUFFERS_QUEUED, &queued);
+
+ while(queued > 0)
+ {
+ alSourceUnqueueBuffers(currentMusic.source, 1, &buffer);
+
+ queued--;
+ }
+}
+
+// Update (re-fill) music buffers if data already processed
+extern void UpdateMusicStream()
+{
+ ALuint buffer = 0;
+ ALint processed = 0;
+ bool active = true;
+
+ if (musicEnabled)
+ {
+ // Get the number of already processed buffers (if any)
+ alGetSourcei(currentMusic.source, AL_BUFFERS_PROCESSED, &processed);
+
+ while (processed > 0)
+ {
+ // Recover processed buffer for refill
+ alSourceUnqueueBuffers(currentMusic.source, 1, &buffer);
+
+ // Refill buffer
+ active = BufferMusicStream(buffer);
+
+ // If no more data to stream, restart music (if loop)
+ if ((!active) && (currentMusic.loop))
+ {
+ if (currentMusic.loop)
+ {
+ stb_vorbis_seek_start(currentMusic.stream);
+ currentMusic.totalSamplesLeft = stb_vorbis_stream_length_in_samples(currentMusic.stream) * currentMusic.channels;
+
+ active = BufferMusicStream(buffer);
+ }
+ }
+
+ // Add refilled buffer to queue again... don't let the music stop!
+ alSourceQueueBuffers(currentMusic.source, 1, &buffer);
+
+ if(alGetError() != AL_NO_ERROR) TraceLog(WARNING, "Ogg playing, error buffering data...");
+
+ processed--;
+ }
+
+ ALenum state;
+ alGetSourcei(currentMusic.source, AL_SOURCE_STATE, &state);
+
+ if ((state != AL_PLAYING) && active) alSourcePlay(currentMusic.source);
+
+ if (!active) StopMusicStream();
+ }
}
// Load WAV file into Wave structure
-static Wave LoadWAV(char *fileName)
+static Wave LoadWAV(const char *fileName)
{
// Basic WAV headers structs
typedef struct {
@@ -543,199 +753,51 @@ static Wave LoadWAV(char *fileName)
return wave;
}
-// Unload WAV file data
-static void UnloadWAV(Wave wave)
+// Load OGG file into Wave structure
+static Wave LoadOGG(char *fileName)
{
- free(wave.data);
-}
-
-// TODO: Ogg data loading
-Music LoadMusic(char *fileName)
-{
- Music music;
+ Wave wave;
- // Open audio stream
- music.stream = stb_vorbis_open_filename(fileName, NULL, NULL);
+ stb_vorbis *oggFile = stb_vorbis_open_filename(fileName, NULL, NULL);
+ stb_vorbis_info info = stb_vorbis_get_info(oggFile);
- if (music.stream == NULL) TraceLog(WARNING, "Could not open ogg audio file");
- else
- {
- // Get file info
- music.info = stb_vorbis_get_info(music.stream);
-
- printf("Ogg sample rate: %i\n", music.info.sample_rate);
- printf("Ogg channels: %i\n", music.info.channels);
- printf("Temp memory required: %i\n", music.info.temp_memory_required);
-
- if (music.info.channels == 2) music.format = AL_FORMAT_STEREO16;
- else music.format = AL_FORMAT_MONO16;
-
- music.bufferSize = 4096*8;
- music.loop = true; // We loop by default
-
- // Create an audio source
- alGenSources(1, &music.source); // Generate pointer to audio source
-
- alSourcef(music.source, AL_PITCH, 1);
- alSourcef(music.source, AL_GAIN, 1);
- alSource3f(music.source, AL_POSITION, 0, 0, 0);
- alSource3f(music.source, AL_VELOCITY, 0, 0, 0);
- alSourcei(music.source, AL_LOOPING, AL_TRUE); // We loop by default
-
- // Convert loaded data to OpenAL buffers
- alGenBuffers(2, music.buffers);
- /*
- if (!MusicStream(music, music.buffers[0])) exit(1);
- if (!MusicStream(music, music.buffers[1])) exit(1);
-
- alSourceQueueBuffers(music.source, 2, music.buffers);
-
- PlayMusic(music);
- */
- music.totalSamplesLeft = stb_vorbis_stream_length_in_samples(music.stream) * music.info.channels;
-
- currentMusic = &music;
- }
+ wave.sampleRate = info.sample_rate;
+ wave.bitsPerSample = 16;
+ wave.channels = info.channels;
- return music;
-}
+ TraceLog(DEBUG, "[%s] Ogg sample rate: %i", fileName, info.sample_rate);
+ TraceLog(DEBUG, "[%s] Ogg channels: %i", fileName, info.channels);
-void UnloadMusic(Music music)
-{
- StopMusic(music);
-
- alDeleteSources(1, &music.source);
- alDeleteBuffers(2, music.buffers);
+ int totalSamplesLength = (stb_vorbis_stream_length_in_samples(oggFile) * info.channels);
- stb_vorbis_close(music.stream);
-}
-
-void PlayMusic(Music music)
-{
- //if (MusicIsPlaying(music)) return true;
-
- if (!MusicStream(music, music.buffers[0])) TraceLog(WARNING, "MusicStream returned 0");
- if (!MusicStream(music, music.buffers[1])) TraceLog(WARNING, "MusicStream returned 0");
+ wave.dataSize = totalSamplesLength*sizeof(short); // Size must be in bytes
- alSourceQueueBuffers(music.source, 2, music.buffers);
- alSourcePlay(music.source);
-
- TraceLog(INFO, "Playing music");
-}
-
-extern void PlayCurrentMusic()
-{
- if (!MusicStream(*currentMusic, currentMusic->buffers[0])) TraceLog(WARNING, "MusicStream returned 0");
- if (!MusicStream(*currentMusic, currentMusic->buffers[1])) TraceLog(WARNING, "MusicStream returned 0");
+ TraceLog(DEBUG, "[%s] Samples length: %i", fileName, totalSamplesLength);
- alSourceQueueBuffers(currentMusic->source, 2, currentMusic->buffers);
- alSourcePlay(currentMusic->source);
-}
-
-// Stop reproducing music
-void StopMusic(Music music)
-{
- alSourceStop(music.source);
+ float totalSeconds = stb_vorbis_stream_length_in_seconds(oggFile);
- musicIsPlaying = false;
-}
-
-static bool MusicStream(Music music, ALuint buffer)
-{
- //Uncomment this to avoid VLAs
- //#define BUFFER_SIZE 4096*32
- #ifndef BUFFER_SIZE//VLAs ftw
- #define BUFFER_SIZE (music.bufferSize)
- #endif
- ALshort pcm[BUFFER_SIZE];
-
- int size = 0;
- int result = 0;
-
- while (size < BUFFER_SIZE)
- {
- result = stb_vorbis_get_samples_short_interleaved(music.stream, music.info.channels, pcm+size, BUFFER_SIZE-size);
-
- if (result > 0) size += (result*music.info.channels);
- else break;
- }
-
- if (size == 0) return false;
-
- alBufferData(buffer, music.format, pcm, size*sizeof(ALshort), music.info.sample_rate);
+ TraceLog(DEBUG, "[%s] Total seconds: %f", fileName, totalSeconds);
- music.totalSamplesLeft -= size;
-
- #undef BUFFER_SIZE
-
- return true;
-}
-/*
-extern bool MusicStreamUpdate()
-{
- ALint processed = 0;
-
- alGetSourcei(currentMusic->source, AL_BUFFERS_PROCESSED, &processed);
-
- while (processed--)
- {
- ALuint buffer = 0;
-
- alSourceUnqueueBuffers(currentMusic->source, 1, &buffer);
-
- if (!MusicStream(*currentMusic, buffer))
- {
- bool shouldExit = true;
-
- if (currentMusic->loop)
- {
- stb_vorbis_seek_start(currentMusic->stream);
- currentMusic->totalSamplesLeft = stb_vorbis_stream_length_in_samples(currentMusic->stream) * currentMusic->info.channels;
-
- shouldExit = !MusicStream(*currentMusic, buffer);
- }
-
- if (shouldExit) return false;
- }
-
- alSourceQueueBuffers(currentMusic->source, 1, &buffer);
- }
-
- return true;
-}
-*/
-extern bool MusicStreamUpdate()
-{
- int processed;
- bool active = true;
-
- alGetSourcei(currentMusic->source, AL_BUFFERS_PROCESSED, &processed);
+ if (totalSeconds > 10) TraceLog(WARNING, "[%s] Ogg audio lenght is larger than 10 seconds (%f), that's a big file in memory, consider music streaming", fileName, totalSeconds);
- printf("Data processed: %i\n", processed);
-
- while (processed--)
- {
- ALuint buffer = 0;
-
- alSourceUnqueueBuffers(currentMusic->source, 1, &buffer);
+ int totalSamples = totalSeconds*info.sample_rate*info.channels;
+
+ TraceLog(DEBUG, "[%s] Total samples calculated: %i", fileName, totalSamples);
+
+ //short *data
+ wave.data = malloc(sizeof(short)*totalSamplesLength);
- active = MusicStream(*currentMusic, buffer);
-
- alSourceQueueBuffers(currentMusic->source, 1, &buffer);
- }
-
- return active;
+ int samplesObtained = stb_vorbis_get_samples_short_interleaved(oggFile, info.channels, wave.data, totalSamplesLength);
+
+ TraceLog(DEBUG, "[%s] Samples obtained: %i", fileName, samplesObtained);
+
+ stb_vorbis_close(oggFile);
+
+ return wave;
}
-void MusicStreamEmpty()
+// Unload Wave data
+static void UnloadWave(Wave wave)
{
- int queued;
-
- alGetSourcei(currentMusic->source, AL_BUFFERS_QUEUED, &queued);
-
- while(queued--)
- {
- ALuint buffer;
- alSourceUnqueueBuffers(currentMusic->source, 1, &buffer);
- }
+ free(wave.data);
} \ No newline at end of file