summaryrefslogtreecommitdiffhomepage
path: root/src/audio.c
diff options
context:
space:
mode:
authorraysan5 <[email protected]>2016-10-10 18:22:55 +0200
committerraysan5 <[email protected]>2016-10-10 18:22:55 +0200
commitb1651baea504411dc47ef257094a089c9107dd73 (patch)
tree6afbb793b17ccb9131a27b44581a0483ea31b22b /src/audio.c
parent4c791100cc339e9be09c95b3bcebf09951647e9d (diff)
downloadraylib-b1651baea504411dc47ef257094a089c9107dd73.tar.gz
raylib-b1651baea504411dc47ef257094a089c9107dd73.zip
Added support for FLAC audio loading/streaming
Diffstat (limited to 'src/audio.c')
-rw-r--r--src/audio.c62
1 files changed, 60 insertions, 2 deletions
diff --git a/src/audio.c b/src/audio.c
index 90bf4968..bf66f929 100644
--- a/src/audio.c
+++ b/src/audio.c
@@ -79,6 +79,10 @@
#define JAR_MOD_IMPLEMENTATION
#include "external/jar_mod.h" // MOD loading functions
+#define DR_FLAC_IMPLEMENTATION
+#define DR_FLAC_NO_WIN32_IO
+#include "external/dr_flac.h" // FLAC loading functions
+
#ifdef _MSC_VER
#undef bool
#endif
@@ -98,12 +102,13 @@
// Types and Structures Definition
//----------------------------------------------------------------------------------
-typedef enum { MUSIC_AUDIO_OGG = 0, MUSIC_MODULE_XM, MUSIC_MODULE_MOD } MusicContextType;
+typedef enum { MUSIC_AUDIO_OGG = 0, MUSIC_AUDIO_FLAC, MUSIC_MODULE_XM, MUSIC_MODULE_MOD } MusicContextType;
// Music type (file streaming from memory)
typedef struct MusicData {
MusicContextType ctxType; // Type of music context (OGG, XM, MOD)
stb_vorbis *ctxOgg; // OGG audio context
+ drflac *ctxFlac; // FLAC audio context
jar_xm_context_t *ctxXm; // XM chiptune context
jar_mod_context_t ctxMod; // MOD chiptune context
@@ -128,6 +133,7 @@ typedef enum { INFO = 0, ERROR, WARNING, DEBUG, OTHER } TraceLogType;
//----------------------------------------------------------------------------------
static Wave LoadWAV(const char *fileName); // Load WAV file
static Wave LoadOGG(const char *fileName); // Load OGG file
+static Wave LoadFLAC(const char *fileName); // Load FLAC file
#if defined(AUDIO_STANDALONE)
const char *GetExtension(const char *fileName); // Get the extension for a filename
@@ -212,6 +218,7 @@ Wave LoadWave(const char *fileName)
if (strcmp(GetExtension(fileName), "wav") == 0) wave = LoadWAV(fileName);
else if (strcmp(GetExtension(fileName), "ogg") == 0) wave = LoadOGG(fileName);
+ else if (strcmp(GetExtension(fileName), "flac") == 0) wave = LoadFLAC(fileName);
else TraceLog(WARNING, "[%s] File extension not recognized, it can't be loaded", fileName);
return wave;
@@ -672,7 +679,7 @@ Music LoadMusicStream(const 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
@@ -691,6 +698,24 @@ Music LoadMusicStream(const char *fileName)
}
}
+ else if (strcmp(GetExtension(fileName), "flac") == 0)
+ {
+ music->ctxFlac = drflac_open_file(fileName);
+
+ if (music->ctxFlac == NULL) TraceLog(WARNING, "[%s] FLAC audio file could not be opened", fileName);
+ else
+ {
+ music->stream = InitAudioStream(music->ctxFlac->sampleRate, music->ctxFlac->bitsPerSample, music->ctxFlac->channels);
+ music->totalSamples = music->ctxFlac->totalSampleCount;
+ music->samplesLeft = music->totalSamples;
+ music->ctxType = MUSIC_AUDIO_FLAC;
+ music->loop = true; // We loop by default
+
+ TraceLog(DEBUG, "[%s] FLAC sample rate: %i", fileName, music->ctxFlac->sampleRate);
+ TraceLog(DEBUG, "[%s] FLAC bits per sample: %i", fileName, music->ctxFlac->bitsPerSample);
+ TraceLog(DEBUG, "[%s] FLAC channels: %i", fileName, music->ctxFlac->channels);
+ }
+ }
else if (strcmp(GetExtension(fileName), "xm") == 0)
{
int result = jar_xm_create_context_from_file(&music->ctxXm, 48000, fileName);
@@ -739,6 +764,7 @@ void UnloadMusicStream(Music music)
CloseAudioStream(music->stream);
if (music->ctxType == MUSIC_AUDIO_OGG) stb_vorbis_close(music->ctxOgg);
+ else if (music->ctxType == MUSIC_AUDIO_FLAC) drflac_free(music->ctxFlac);
else if (music->ctxType == MUSIC_MODULE_XM) jar_xm_free_context(music->ctxXm);
else if (music->ctxType == MUSIC_MODULE_MOD) jar_mod_unload(&music->ctxMod);
@@ -819,6 +845,20 @@ void UpdateMusicStream(Music music)
music->samplesLeft -= (numSamplesOgg*music->stream.channels);
} break;
+ case MUSIC_AUDIO_FLAC:
+ {
+ if (music->samplesLeft >= AUDIO_BUFFER_SIZE) numSamples = AUDIO_BUFFER_SIZE;
+ else numSamples = music->samplesLeft;
+
+ int pcmi[AUDIO_BUFFER_SIZE];
+
+ // NOTE: Returns the number of samples to process (should be the same as numSamples)
+ int numSamplesFlac = drflac_read_s32(music->ctxFlac, numSamples, pcmi);
+
+ UpdateAudioStream(music->stream, pcmi, numSamples*music->stream.channels);
+ music->samplesLeft -= (numSamples*music->stream.channels);
+
+ } break;
case MUSIC_MODULE_XM:
{
if (music->samplesLeft >= AUDIO_BUFFER_SIZE/2) numSamples = AUDIO_BUFFER_SIZE/2;
@@ -1214,6 +1254,24 @@ static Wave LoadOGG(const char *fileName)
return wave;
}
+// Load FLAC file into Wave structure
+// NOTE: Using dr_flac library
+static Wave LoadFLAC(const char *fileName)
+{
+ Wave wave;
+
+ // Decode an entire FLAC file in one go
+ uint64_t totalSampleCount;
+ wave.data = drflac_open_and_decode_file_s32(fileName, &wave.channels, &wave.sampleRate, &totalSampleCount);
+
+ wave.sampleCount = (int)totalSampleCount;
+ wave.sampleSize = 32;
+
+ if (wave.data == NULL) TraceLog(WARNING, "[%s] FLAC data could not be loaded", fileName);
+
+ return wave;
+}
+
// Some required functions for audio standalone module version
#if defined(AUDIO_STANDALONE)
// Get the extension for a filename