aboutsummaryrefslogtreecommitdiff
path: root/src/audio.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/audio.c')
-rw-r--r--src/audio.c404
1 files changed, 202 insertions, 202 deletions
diff --git a/src/audio.c b/src/audio.c
index 41ba6fed..a696950e 100644
--- a/src/audio.c
+++ b/src/audio.c
@@ -1,41 +1,41 @@
/*********************************************************************************************
*
-* raylib.audio
+* raylib.audio
*
-* Basic functions to manage Audio: InitAudioDevice, LoadAudioFiles, PlayAudioFiles
-*
-* Uses external lib:
-* OpenAL - Audio device management lib
-* TODO: stb_vorbis - Ogg audio files loading
+* Basic functions to manage Audio: InitAudioDevice, LoadAudioFiles, PlayAudioFiles
+*
+* Uses external lib:
+* OpenAL - Audio device management lib
+* TODO: stb_vorbis - Ogg audio files loading
*
-* Copyright (c) 2013 Ramon Santamaria (Ray San - raysan@raysanweb.com)
-*
-* This software is provided "as-is", without any express or implied warranty. In no event
-* will the authors be held liable for any damages arising from the use of this software.
+* Copyright (c) 2013 Ramon Santamaria (Ray San - raysan@raysanweb.com)
+*
+* This software is provided "as-is", without any express or implied warranty. In no event
+* will the authors be held liable for any damages arising from the use of this software.
*
-* Permission is granted to anyone to use this software for any purpose, including commercial
-* applications, and to alter it and redistribute it freely, subject to the following restrictions:
+* Permission is granted to anyone to use this software for any purpose, including commercial
+* applications, and to alter it and redistribute it freely, subject to the following restrictions:
*
-* 1. The origin of this software must not be misrepresented; you must not claim that you
-* wrote the original software. If you use this software in a product, an acknowledgment
-* in the product documentation would be appreciated but is not required.
+* 1. The origin of this software must not be misrepresented; you must not claim that you
+* wrote the original software. If you use this software in a product, an acknowledgment
+* in the product documentation would be appreciated but is not required.
*
-* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
-* as being the original software.
+* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
+* as being the original software.
*
-* 3. This notice may not be removed or altered from any source distribution.
+* 3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************/
#include "raylib.h"
-#include <AL/al.h> // OpenAL basic header
-#include <AL/alc.h> // OpenAL context header (like OpenGL, OpenAL requires a context to work)
+#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 <stdio.h> // Used for .WAV loading
+#include <stdlib.h> // To use exit() function
+#include <stdio.h> // Used for .WAV loading
-//#include "stb_vorbis.h" // TODO: OGG loading functions
+//#include "stb_vorbis.h" // TODO: OGG loading functions
//----------------------------------------------------------------------------------
// Defines and Macros
@@ -48,11 +48,11 @@
// Wave file data
typedef struct Wave {
- unsigned char *data; // Buffer data pointer
- unsigned int sampleRate;
- unsigned int dataSize;
- short channels;
- short format;
+ unsigned char *data; // Buffer data pointer
+ unsigned int sampleRate;
+ unsigned int dataSize;
+ short channels;
+ short format;
} Wave;
//----------------------------------------------------------------------------------
@@ -74,231 +74,231 @@ static void UnloadWAV(Wave wave);
// Initialize audio device and context
void InitAudioDevice()
{
- // Open and initialize a device with default settings
- ALCdevice *device = alcOpenDevice(NULL);
-
- if(!device)
- {
- fprintf(stderr, "Could not open a device!\n");
- exit(1);
- }
-
- ALCcontext *context = alcCreateContext(device, NULL);
-
- if(context == NULL || alcMakeContextCurrent(context) == ALC_FALSE)
- {
- if(context != NULL) alcDestroyContext(context);
-
- alcCloseDevice(device);
-
- fprintf(stderr, "Could not set a context!\n");
- exit(1);
- }
-
- printf("Opened \"%s\"\n", alcGetString(device, ALC_DEVICE_SPECIFIER));
-
- // Listener definition (just for 2D)
- alListener3f(AL_POSITION, 0, 0, 0);
- alListener3f(AL_VELOCITY, 0, 0, 0);
- alListener3f(AL_ORIENTATION, 0, 0, -1);
+ // Open and initialize a device with default settings
+ ALCdevice *device = alcOpenDevice(NULL);
+
+ if(!device)
+ {
+ fprintf(stderr, "Could not open a device!\n");
+ exit(1);
+ }
+
+ ALCcontext *context = alcCreateContext(device, NULL);
+
+ if(context == NULL || alcMakeContextCurrent(context) == ALC_FALSE)
+ {
+ if(context != NULL) alcDestroyContext(context);
+
+ alcCloseDevice(device);
+
+ fprintf(stderr, "Could not set a context!\n");
+ exit(1);
+ }
+
+ printf("Opened \"%s\"\n", alcGetString(device, ALC_DEVICE_SPECIFIER));
+
+ // Listener definition (just for 2D)
+ alListener3f(AL_POSITION, 0, 0, 0);
+ alListener3f(AL_VELOCITY, 0, 0, 0);
+ alListener3f(AL_ORIENTATION, 0, 0, -1);
}
// Close the audio device for the current context, and destroys the context
void CloseAudioDevice()
{
- ALCdevice *device;
- ALCcontext *context = alcGetCurrentContext();
-
- if (context == NULL) return;
+ ALCdevice *device;
+ ALCcontext *context = alcGetCurrentContext();
+
+ if (context == NULL) return;
- device = alcGetContextsDevice(context);
+ device = alcGetContextsDevice(context);
- alcMakeContextCurrent(NULL);
- alcDestroyContext(context);
- alcCloseDevice(device);
+ alcMakeContextCurrent(NULL);
+ alcDestroyContext(context);
+ alcCloseDevice(device);
}
// Load sound to memory
Sound LoadSound(char *fileName)
{
- Sound sound;
-
- // 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;
- // The OpenAL format is worked out by looking at the number of channels and the bits per sample
- if (wave.channels == 1)
- {
- if (wave.sampleRate == 8 ) format = AL_FORMAT_MONO8;
- else if (wave.sampleRate == 16) format = AL_FORMAT_MONO16;
- }
- else if (wave.channels == 2)
- {
- if (wave.sampleRate == 8 ) format = AL_FORMAT_STEREO8;
- else if (wave.sampleRate == 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, wave.data, wave.dataSize, wave.sampleRate);
-
- // Attach sound buffer to source
- alSourcei(source, AL_BUFFER, buffer);
-
- // Unallocate WAV data
- UnloadWAV(wave);
-
- printf("Sample rate: %i\n", wave.sampleRate);
- printf("Channels: %i\n", wave.channels);
+ Sound sound;
+
+ // 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;
+ // The OpenAL format is worked out by looking at the number of channels and the bits per sample
+ if (wave.channels == 1)
+ {
+ if (wave.sampleRate == 8 ) format = AL_FORMAT_MONO8;
+ else if (wave.sampleRate == 16) format = AL_FORMAT_MONO16;
+ }
+ else if (wave.channels == 2)
+ {
+ if (wave.sampleRate == 8 ) format = AL_FORMAT_STEREO8;
+ else if (wave.sampleRate == 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, wave.data, wave.dataSize, wave.sampleRate);
+
+ // Attach sound buffer to source
+ alSourcei(source, AL_BUFFER, buffer);
+
+ // Unallocate WAV data
+ UnloadWAV(wave);
+
+ printf("Sample rate: %i\n", wave.sampleRate);
+ printf("Channels: %i\n", wave.channels);
printf("Format: %i\n", wave.format);
-
- printf("Audio file loaded...!\n");
-
- sound.source = source;
- sound.buffer = buffer;
-
- return sound;
+
+ printf("Audio file loaded...!\n");
+
+ sound.source = source;
+ sound.buffer = buffer;
+
+ return sound;
}
// Unload sound
void UnloadSound(Sound sound)
{
- alDeleteSources(1, &sound.source);
- alDeleteBuffers(1, &sound.buffer);
+ alDeleteSources(1, &sound.source);
+ alDeleteBuffers(1, &sound.buffer);
}
// Play a sound
void PlaySound(Sound sound)
{
- alSourcePlay(sound.source); // Play the sound
-
- printf("Playing sound!\n");
-
- // Find the current position of the sound being played
- // NOTE: Only work when the entire file is in a single buffer
- //int byteOffset;
- //alGetSourcei(sound.source, AL_BYTE_OFFSET, &byteOffset);
- //float seconds = (float)byteOffset / sampleRate; // Number of seconds since the beginning of the sound
+ alSourcePlay(sound.source); // Play the sound
+
+ printf("Playing sound!\n");
+
+ // Find the current position of the sound being played
+ // NOTE: Only work when the entire file is in a single buffer
+ //int byteOffset;
+ //alGetSourcei(sound.source, AL_BYTE_OFFSET, &byteOffset);
+ //float seconds = (float)byteOffset / sampleRate; // Number of seconds since the beginning of the sound
}
// Play a sound with extended options
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);
+ // 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)
{
- alSourcePause(sound.source);
+ alSourcePause(sound.source);
}
// Stop reproducing a sound
void StopSound(Sound sound)
{
- alSourceStop(sound.source);
+ alSourceStop(sound.source);
}
// Load WAV file into Wave structure
static Wave LoadWAV(char *fileName)
{
- Wave wave;
+ Wave wave;
FILE *wavFile;
wavFile = fopen(fileName, "rb");
-
- if (!wavFile)
- {
- printf("Could not load WAV file.\n");
- exit(1);
- }
-
- unsigned char id[4]; // Four bytes to hold 'RIFF' and 'WAVE' (and other ids)
-
- unsigned int size = 0; // File size (useless)
-
- short format;
- short channels;
- short blockAlign;
- short bitsPerSample;
-
- unsigned int formatLength;
- unsigned int sampleRate;
- unsigned int avgBytesSec;
- unsigned int dataSize;
-
- fread(id, sizeof(unsigned char), 4, wavFile); // Read the first four bytes
-
- if ((id[0] != 'R') || (id[1] != 'I') || (id[2] != 'F') || (id[3] != 'F'))
- {
- printf("Invalid RIFF file.\n"); // If not "RIFF" id, exit
- exit(1);
- }
-
- fread(&size, sizeof(unsigned int), 1, wavFile); // Read file size
- fread(id, sizeof(unsigned char), 4, wavFile); // Read the next id
-
- if ((id[0] != 'W') || (id[1] != 'A') || (id[2] != 'V') || (id[3] != 'E'))
- {
- printf("Invalid WAVE file.\n"); // If not "WAVE" id, exit
- exit(1);
- }
-
- fread(id, sizeof(unsigned char), 4, wavFile); // Read 4 bytes id "fmt "
- fread(&formatLength, sizeof(unsigned int),1,wavFile); // Read format lenght
- fread(&format, sizeof(short), 1, wavFile); // Read format tag
- fread(&channels, sizeof(short), 1, wavFile); // Read num channels (1 mono, 2 stereo)
- fread(&sampleRate, sizeof(unsigned int), 1, wavFile); // Read sample rate (44100, 22050, etc...)
- fread(&avgBytesSec, sizeof(short), 1, wavFile); // Read average bytes per second (probably won't need this)
- fread(&blockAlign, sizeof(short), 1, wavFile); // Read block alignment (probably won't need this)
- fread(&bitsPerSample, sizeof(short), 1, wavFile); // Read bits per sample (8 bit or 16 bit)
-
- fread(id, sizeof(unsigned char), 4, wavFile); // Read 4 bytes id "data"
- fread(&dataSize, sizeof(unsigned int), 1, wavFile); // Read data size (in bytes)
-
- wave.sampleRate = sampleRate;
- wave.dataSize = dataSize;
- wave.channels = channels;
- wave.format = format;
-
- wave.data = (unsigned char *)malloc(sizeof(unsigned char) * dataSize); // Allocate the required bytes to store data
-
- fread(wave.data, sizeof(unsigned char), dataSize, wavFile); // Read the whole sound data chunk
-
- return wave;
+
+ if (!wavFile)
+ {
+ printf("Could not load WAV file.\n");
+ exit(1);
+ }
+
+ unsigned char id[4]; // Four bytes to hold 'RIFF' and 'WAVE' (and other ids)
+
+ unsigned int size = 0; // File size (useless)
+
+ short format;
+ short channels;
+ short blockAlign;
+ short bitsPerSample;
+
+ unsigned int formatLength;
+ unsigned int sampleRate;
+ unsigned int avgBytesSec;
+ unsigned int dataSize;
+
+ fread(id, sizeof(unsigned char), 4, wavFile); // Read the first four bytes
+
+ if ((id[0] != 'R') || (id[1] != 'I') || (id[2] != 'F') || (id[3] != 'F'))
+ {
+ printf("Invalid RIFF file.\n"); // If not "RIFF" id, exit
+ exit(1);
+ }
+
+ fread(&size, sizeof(unsigned int), 1, wavFile); // Read file size
+ fread(id, sizeof(unsigned char), 4, wavFile); // Read the next id
+
+ if ((id[0] != 'W') || (id[1] != 'A') || (id[2] != 'V') || (id[3] != 'E'))
+ {
+ printf("Invalid WAVE file.\n"); // If not "WAVE" id, exit
+ exit(1);
+ }
+
+ fread(id, sizeof(unsigned char), 4, wavFile); // Read 4 bytes id "fmt "
+ fread(&formatLength, sizeof(unsigned int),1,wavFile); // Read format lenght
+ fread(&format, sizeof(short), 1, wavFile); // Read format tag
+ fread(&channels, sizeof(short), 1, wavFile); // Read num channels (1 mono, 2 stereo)
+ fread(&sampleRate, sizeof(unsigned int), 1, wavFile); // Read sample rate (44100, 22050, etc...)
+ fread(&avgBytesSec, sizeof(short), 1, wavFile); // Read average bytes per second (probably won't need this)
+ fread(&blockAlign, sizeof(short), 1, wavFile); // Read block alignment (probably won't need this)
+ fread(&bitsPerSample, sizeof(short), 1, wavFile); // Read bits per sample (8 bit or 16 bit)
+
+ fread(id, sizeof(unsigned char), 4, wavFile); // Read 4 bytes id "data"
+ fread(&dataSize, sizeof(unsigned int), 1, wavFile); // Read data size (in bytes)
+
+ wave.sampleRate = sampleRate;
+ wave.dataSize = dataSize;
+ wave.channels = channels;
+ wave.format = format;
+
+ wave.data = (unsigned char *)malloc(sizeof(unsigned char) * dataSize); // Allocate the required bytes to store data
+
+ fread(wave.data, sizeof(unsigned char), dataSize, wavFile); // Read the whole sound data chunk
+
+ return wave;
}
// Unload WAV file data
static void UnloadWAV(Wave wave)
{
- free(wave.data);
+ free(wave.data);
}
// TODO: Ogg data loading