Add background updates for music streams

This commit is contained in:
ptarabbia 2021-12-13 20:40:49 -05:00
parent 9238d8e656
commit 551db0281d
4 changed files with 124 additions and 4 deletions

View File

@ -13,6 +13,8 @@
#define MAX_CIRCLES 64
#define AUDIO_THREAD_MUSIC_UPDATE true
typedef struct {
Vector2 position;
float radius;
@ -52,6 +54,7 @@ int main(void)
Music music = LoadMusicStream("resources/mini1111.xm");
music.looping = false;
music.background = AUDIO_THREAD_MUSIC_UPDATE;
float pitch = 1.0f;
PlayMusicStream(music);
@ -67,7 +70,10 @@ int main(void)
{
// Update
//----------------------------------------------------------------------------------
UpdateMusicStream(music); // Update music buffer with new stream data
if (!AUDIO_THREAD_MUSIC_UPDATE)
{
UpdateMusicStream(music); // Update music buffer with new stream data
}
// Restart music playing (stop and play)
if (IsKeyPressed(KEY_SPACE))

View File

@ -11,6 +11,9 @@
#include "raylib.h"
#define AUDIO_THREAD_MUSIC_UPDATE true
int main(void)
{
// Initialization
@ -23,6 +26,7 @@ int main(void)
InitAudioDevice(); // Initialize audio device
Music music = LoadMusicStream("resources/country.mp3");
music.background = AUDIO_THREAD_MUSIC_UPDATE;
PlayMusicStream(music);
@ -37,7 +41,10 @@ int main(void)
{
// Update
//----------------------------------------------------------------------------------
UpdateMusicStream(music); // Update music buffer with new stream data
if (!AUDIO_THREAD_MUSIC_UPDATE)
{
UpdateMusicStream(music); // Update music buffer with new stream data
}
// Restart music playing (stop and play)
if (IsKeyPressed(KEY_SPACE))

View File

@ -651,6 +651,7 @@ void SetAudioBufferCallback(AudioBuffer* buffer, void callback(void*, unsigned i
}
}
// Set volume for an audio buffer
void SetAudioBufferVolume(AudioBuffer *buffer, float volume)
{
@ -1614,6 +1615,63 @@ void UnloadMusicStream(Music music)
}
}
#if defined(SUPPORT_FILEFORMAT_WAV)
static void MusicStreamCallbackWav(void* buffer, unsigned int nframes, void* data)
{
drwav* ctx = (drwav*)data;
// NOTE: Returns the number of samples to process (not required)
if (ctx->bitsPerSample == 16) drwav_read_pcm_frames_s16(ctx, nframes, (short*)buffer);
else if (ctx->bitsPerSample == 32) drwav_read_pcm_frames_f32(ctx, nframes, (short*)buffer);
}
#endif
#if defined(SUPPORT_FILEFORMAT_OGG)
static void MusicStreamCallbackOgg(void* buffer, unsigned int nframes, void* data)
{
stb_vorbis* ctx = (stb_vorbis*)data;
// NOTE: Returns the number of samples to process (be careful! we ask for number of shorts!)
stb_vorbis_get_samples_short_interleaved(ctx, ctx->channels, (short*)buffer, nframes * ctx->channels);
}
#endif
#if defined(SUPPORT_FILEFORMAT_FLAC)
static void MusicStreamCallbackFlac(void* buffer, unsigned int nframes, void* data)
{
drflac* ctx = (drflac*)data;
// NOTE: Returns the number of samples to process (be careful! we ask for number of shorts!)
drflac_read_pcm_frames_s16(ctx, nframes * ctx->channels, (short*)buffer);
}
#endif
#if defined(SUPPORT_FILEFORMAT_MP3)
static void MusicStreamCallbackMp3(void* buffer, unsigned int nframes, void* data)
{
drmp3* ctx = (drmp3*)data;
drmp3_read_pcm_frames_f32(ctx, nframes, (float*)buffer);
}
#endif
#if defined(SUPPORT_FILEFORMAT_XM)
static void MusicStreamCallbackXm(void* buffer, unsigned int nframes, void* data)
{
jar_xm_context_t* ctx = (jar_xm_context_t*)data;
// NOTE: Internally we consider 2 channels generation, so sampleCount/2
if (AUDIO_DEVICE_FORMAT == ma_format_f32) jar_xm_generate_samples(ctx, (float*)buffer, nframes);
else if (AUDIO_DEVICE_FORMAT == ma_format_s16) jar_xm_generate_samples_16bit(ctx, (short*)buffer, nframes);
else if (AUDIO_DEVICE_FORMAT == ma_format_u8) jar_xm_generate_samples_8bit(ctx, (char*)buffer, nframes);
}
#endif
#if defined(SUPPORT_FILEFORMAT_MOD)
static void MusicStreamCallbackMod(void* buffer, unsigned int nframes, void* data)
{
jar_mod_context_t* ctx = (jar_mod_context_t*)data;
// NOTE: 3rd parameter (nbsample) specify the number of stereo 16bits samples you want, so sampleCount/2
jar_mod_fillbuffer(ctx, (short*)buffer, nframes, 0);
}
#endif
// Start music playing (open stream)
void PlayMusicStream(Music music)
{
@ -1626,6 +1684,51 @@ void PlayMusicStream(Music music)
ma_uint32 frameCursorPos = music.stream.buffer->frameCursorPos;
PlayAudioStream(music.stream); // WARNING: This resets the cursor position.
music.stream.buffer->frameCursorPos = frameCursorPos;
if (music.background)
{
switch (music.ctxType)
{
#if defined(SUPPORT_FILEFORMAT_WAV)
case MUSIC_AUDIO_WAV:
{
SetAudioBufferCallback(music.stream.buffer, MusicStreamCallbackWav, music.ctxData);
} break;
#endif
#if defined(SUPPORT_FILEFORMAT_OGG)
case MUSIC_AUDIO_OGG:
{
SetAudioBufferCallback(music.stream.buffer, MusicStreamCallbackOgg, music.ctxData);
} break;
#endif
#if defined(SUPPORT_FILEFORMAT_FLAC)
case MUSIC_AUDIO_FLAC:
{
SetAudioBufferCallback(music.stream.buffer, MusicStreamCallbackFlac, music.ctxData);
} break;
#endif
#if defined(SUPPORT_FILEFORMAT_MP3)
case MUSIC_AUDIO_MP3:
{
SetAudioBufferCallback(music.stream.buffer, MusicStreamCallbackMp3, music.ctxData);
} break;
#endif
#if defined(SUPPORT_FILEFORMAT_XM)
case MUSIC_MODULE_XM:
{
SetAudioBufferCallback(music.stream.buffer, MusicStreamCallbackXm, music.ctxData);
} break;
#endif
#if defined(SUPPORT_FILEFORMAT_MOD)
case MUSIC_MODULE_MOD:
{
SetAudioBufferCallback(music.stream.buffer, MusicStreamCallbackMod, music.ctxData);
} break;
#endif
default: break;
}
}
}
}
@ -2009,7 +2112,11 @@ void SetAudioStreamBufferSizeDefault(int size)
// Audio thread callback to request new data
void SetAudioStreamCallback(AudioStream stream, void callback(void*, unsigned int, void*), void* callbackData)
{
SetAudioBufferCallback(stream.buffer, callback, callbackData);
if (stream.buffer != NULL)
{
stream.buffer->audioCallback = callback;
stream.buffer->audioCallbackData = callbackData;
}
}
//----------------------------------------------------------------------------------

View File

@ -447,7 +447,7 @@ typedef struct Music {
AudioStream stream; // Audio stream
unsigned int frameCount; // Total number of frames (considering channels)
bool looping; // Music looping enable
bool background; // Update in audio thread ?
int ctxType; // Type of music context (audio filetype)
void *ctxData; // Audio context data, depends on type
} Music;