Audio module reviewed for standalone usage
This commit is contained in:
parent
6e4cfa5ecf
commit
e8fa630c28
2 changed files with 100 additions and 30 deletions
125
src/audio.c
125
src/audio.c
|
@ -42,8 +42,12 @@
|
||||||
#include <string.h> // Required for strcmp()
|
#include <string.h> // Required for strcmp()
|
||||||
#include <stdio.h> // Used for .WAV loading
|
#include <stdio.h> // Used for .WAV loading
|
||||||
|
|
||||||
#include "utils.h" // rRES data decompression utility function
|
#if defined(AUDIO_STANDALONE)
|
||||||
|
#include <stdarg.h> // Used for functions with variable number of parameters (TraceLog())
|
||||||
|
#else
|
||||||
|
#include "utils.h" // rRES data decompression utility function
|
||||||
// NOTE: Includes Android fopen function map
|
// NOTE: Includes Android fopen function map
|
||||||
|
#endif
|
||||||
|
|
||||||
//#define STB_VORBIS_HEADER_ONLY
|
//#define STB_VORBIS_HEADER_ONLY
|
||||||
#include "stb_vorbis.h" // OGG loading functions
|
#include "stb_vorbis.h" // OGG loading functions
|
||||||
|
@ -81,6 +85,10 @@ typedef struct Music {
|
||||||
|
|
||||||
} Music;
|
} Music;
|
||||||
|
|
||||||
|
#if defined(AUDIO_STANDALONE)
|
||||||
|
typedef enum { INFO = 0, ERROR, WARNING, DEBUG, OTHER } TraceLogType;
|
||||||
|
#endif
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Global Variables Definition
|
// Global Variables Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
@ -91,13 +99,18 @@ static Music currentMusic; // Current music loaded
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module specific Functions Declaration
|
// Module specific Functions Declaration
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
static Wave LoadWAV(const char *fileName); // Load WAV file
|
static Wave LoadWAV(const char *fileName); // Load WAV file
|
||||||
static Wave LoadOGG(char *fileName); // Load OGG file
|
static Wave LoadOGG(char *fileName); // Load OGG file
|
||||||
static void UnloadWave(Wave wave); // Unload wave data
|
static void UnloadWave(Wave wave); // Unload wave data
|
||||||
|
|
||||||
static bool BufferMusicStream(ALuint buffer); // Fill music buffers with data
|
static bool BufferMusicStream(ALuint buffer); // Fill music buffers with data
|
||||||
static void EmptyMusicStream(void); // Empty music buffers
|
static void EmptyMusicStream(void); // Empty music buffers
|
||||||
extern void UpdateMusicStream(void); // Updates buffers (refill) for music streaming
|
extern void UpdateMusicStream(void); // Updates buffers (refill) for music streaming
|
||||||
|
|
||||||
|
#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)
|
||||||
|
#endif
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module Functions Definition - Audio Device initialization and Closing
|
// Module Functions Definition - Audio Device initialization and Closing
|
||||||
|
@ -279,6 +292,11 @@ Sound LoadSoundFromRES(const char *rresName, int resId)
|
||||||
{
|
{
|
||||||
// NOTE: rresName could be directly a char array with all the data!!! --> TODO
|
// NOTE: rresName could be directly a char array with all the data!!! --> TODO
|
||||||
Sound sound;
|
Sound sound;
|
||||||
|
|
||||||
|
#if defined(AUDIO_STANDALONE)
|
||||||
|
TraceLog(WARNING, "Sound loading from rRES resource file not supported on standalone mode");
|
||||||
|
#else
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
char id[4]; // rRES file identifier
|
char id[4]; // rRES file identifier
|
||||||
|
@ -422,7 +440,7 @@ Sound LoadSoundFromRES(const char *rresName, int resId)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found) TraceLog(WARNING, "[%s] Required resource id [%i] could not be found in the raylib resource file", rresName, resId);
|
if (!found) TraceLog(WARNING, "[%s] Required resource id [%i] could not be found in the raylib resource file", rresName, resId);
|
||||||
|
#endif
|
||||||
return sound;
|
return sound;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -783,6 +801,7 @@ static Wave LoadWAV(const char *fileName)
|
||||||
if (wavFile == NULL)
|
if (wavFile == NULL)
|
||||||
{
|
{
|
||||||
TraceLog(WARNING, "[%s] WAV file could not be opened", fileName);
|
TraceLog(WARNING, "[%s] WAV file could not be opened", fileName);
|
||||||
|
wave.data = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -852,40 +871,49 @@ static Wave LoadOGG(char *fileName)
|
||||||
Wave wave;
|
Wave wave;
|
||||||
|
|
||||||
stb_vorbis *oggFile = 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);
|
|
||||||
|
|
||||||
wave.sampleRate = info.sample_rate;
|
if (oggFile == NULL)
|
||||||
wave.bitsPerSample = 16;
|
{
|
||||||
wave.channels = info.channels;
|
TraceLog(WARNING, "[%s] OGG file could not be opened", fileName);
|
||||||
|
wave.data = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stb_vorbis_info info = stb_vorbis_get_info(oggFile);
|
||||||
|
|
||||||
TraceLog(DEBUG, "[%s] Ogg sample rate: %i", fileName, info.sample_rate);
|
wave.sampleRate = info.sample_rate;
|
||||||
TraceLog(DEBUG, "[%s] Ogg channels: %i", fileName, info.channels);
|
wave.bitsPerSample = 16;
|
||||||
|
wave.channels = info.channels;
|
||||||
|
|
||||||
int totalSamplesLength = (stb_vorbis_stream_length_in_samples(oggFile) * info.channels);
|
TraceLog(DEBUG, "[%s] Ogg sample rate: %i", fileName, info.sample_rate);
|
||||||
|
TraceLog(DEBUG, "[%s] Ogg channels: %i", fileName, info.channels);
|
||||||
|
|
||||||
wave.dataSize = totalSamplesLength*sizeof(short); // Size must be in bytes
|
int totalSamplesLength = (stb_vorbis_stream_length_in_samples(oggFile) * info.channels);
|
||||||
|
|
||||||
TraceLog(DEBUG, "[%s] Samples length: %i", fileName, totalSamplesLength);
|
wave.dataSize = totalSamplesLength*sizeof(short); // Size must be in bytes
|
||||||
|
|
||||||
float totalSeconds = stb_vorbis_stream_length_in_seconds(oggFile);
|
TraceLog(DEBUG, "[%s] Samples length: %i", fileName, totalSamplesLength);
|
||||||
|
|
||||||
TraceLog(DEBUG, "[%s] Total seconds: %f", fileName, totalSeconds);
|
float totalSeconds = stb_vorbis_stream_length_in_seconds(oggFile);
|
||||||
|
|
||||||
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);
|
TraceLog(DEBUG, "[%s] Total seconds: %f", fileName, totalSeconds);
|
||||||
|
|
||||||
int totalSamples = totalSeconds*info.sample_rate*info.channels;
|
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);
|
||||||
|
|
||||||
TraceLog(DEBUG, "[%s] Total samples calculated: %i", fileName, totalSamples);
|
int totalSamples = totalSeconds*info.sample_rate*info.channels;
|
||||||
|
|
||||||
wave.data = malloc(sizeof(short)*totalSamplesLength);
|
TraceLog(DEBUG, "[%s] Total samples calculated: %i", fileName, totalSamples);
|
||||||
|
|
||||||
int samplesObtained = stb_vorbis_get_samples_short_interleaved(oggFile, info.channels, wave.data, totalSamplesLength);
|
wave.data = malloc(sizeof(short)*totalSamplesLength);
|
||||||
|
|
||||||
TraceLog(DEBUG, "[%s] Samples obtained: %i", fileName, samplesObtained);
|
int samplesObtained = stb_vorbis_get_samples_short_interleaved(oggFile, info.channels, wave.data, totalSamplesLength);
|
||||||
|
|
||||||
TraceLog(INFO, "[%s] OGG file loaded successfully (SampleRate: %i, BitRate: %i, Channels: %i)", fileName, wave.sampleRate, wave.bitsPerSample, wave.channels);
|
TraceLog(DEBUG, "[%s] Samples obtained: %i", fileName, samplesObtained);
|
||||||
|
|
||||||
stb_vorbis_close(oggFile);
|
TraceLog(INFO, "[%s] OGG file loaded successfully (SampleRate: %i, BitRate: %i, Channels: %i)", fileName, wave.sampleRate, wave.bitsPerSample, wave.channels);
|
||||||
|
|
||||||
|
stb_vorbis_close(oggFile);
|
||||||
|
}
|
||||||
|
|
||||||
return wave;
|
return wave;
|
||||||
}
|
}
|
||||||
|
@ -895,3 +923,46 @@ static void UnloadWave(Wave wave)
|
||||||
{
|
{
|
||||||
free(wave.data);
|
free(wave.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Some required functions for audio standalone module version
|
||||||
|
#if defined(AUDIO_STANDALONE)
|
||||||
|
// Get the extension for a filename
|
||||||
|
const char *GetExtension(const char *fileName)
|
||||||
|
{
|
||||||
|
const char *dot = strrchr(fileName, '.');
|
||||||
|
if(!dot || dot == fileName) return "";
|
||||||
|
return (dot + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Outputs a trace log message (INFO, ERROR, WARNING)
|
||||||
|
// NOTE: If a file has been init, output log is written there
|
||||||
|
void TraceLog(int msgType, const char *text, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
int traceDebugMsgs = 0;
|
||||||
|
|
||||||
|
#ifdef DO_NOT_TRACE_DEBUG_MSGS
|
||||||
|
traceDebugMsgs = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch(msgType)
|
||||||
|
{
|
||||||
|
case INFO: fprintf(stdout, "INFO: "); break;
|
||||||
|
case ERROR: fprintf(stdout, "ERROR: "); break;
|
||||||
|
case WARNING: fprintf(stdout, "WARNING: "); break;
|
||||||
|
case DEBUG: if (traceDebugMsgs) fprintf(stdout, "DEBUG: "); break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((msgType != DEBUG) || ((msgType == DEBUG) && (traceDebugMsgs)))
|
||||||
|
{
|
||||||
|
va_start(args, text);
|
||||||
|
vfprintf(stdout, text, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
fprintf(stdout, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msgType == ERROR) exit(1); // If ERROR message, exit program
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -95,7 +95,6 @@ void SetMusicVolume(float volume); // Set volume fo
|
||||||
float GetMusicTimeLength(void); // Get current music time length (in seconds)
|
float GetMusicTimeLength(void); // Get current music time length (in seconds)
|
||||||
float GetMusicTimePlayed(void); // Get current music time played (in seconds)
|
float GetMusicTimePlayed(void); // Get current music time played (in seconds)
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue