|
|
@ -1166,7 +1166,7 @@ float *GetWaveData(Wave wave) |
|
|
|
// Load music stream from file |
|
|
|
Music LoadMusicStream(const char *fileName) |
|
|
|
{ |
|
|
|
Music music = (MusicStream *)RL_MALLOC(sizeof(MusicStream)); |
|
|
|
Music music = { 0 }; |
|
|
|
bool musicLoaded = false; |
|
|
|
|
|
|
|
if (false) { } |
|
|
@ -1174,21 +1174,21 @@ Music LoadMusicStream(const char *fileName) |
|
|
|
else if (IsFileExtension(fileName, ".ogg")) |
|
|
|
{ |
|
|
|
// Open ogg audio stream |
|
|
|
musico">->ctxData = stb_vorbis_open_filename(fileName, NULL, NULL); |
|
|
|
musicp">.ctxData = stb_vorbis_open_filename(fileName, NULL, NULL); |
|
|
|
|
|
|
|
if (musico">->ctxData != NULL) |
|
|
|
if (musicp">.ctxData != NULL) |
|
|
|
{ |
|
|
|
musico">->ctxType = MUSIC_AUDIO_OGG; |
|
|
|
stb_vorbis_info info = stb_vorbis_get_info((stb_vorbis *)musico">->ctxData); // Get Ogg file info |
|
|
|
musicp">.ctxType = MUSIC_AUDIO_OGG; |
|
|
|
stb_vorbis_info info = stb_vorbis_get_info((stb_vorbis *)musicp">.ctxData); // Get Ogg file info |
|
|
|
|
|
|
|
// OGG bit rate defaults to 16 bit, it's enough for compressed format |
|
|
|
musico">->stream = InitAudioStream(info.sample_rate, 16, info.channels); |
|
|
|
musico">->sampleCount = (unsigned int)stb_vorbis_stream_length_in_samples((stb_vorbis *)musico">->ctxData)*info.channels; |
|
|
|
musico">->sampleLeft = musico">->sampleCount; |
|
|
|
musico">->loopCount = 0; // Infinite loop by default |
|
|
|
musicp">.stream = InitAudioStream(info.sample_rate, 16, info.channels); |
|
|
|
musicp">.sampleCount = (unsigned int)stb_vorbis_stream_length_in_samples((stb_vorbis *)musicp">.ctxData)*info.channels; |
|
|
|
musicp">.sampleLeft = musicp">.sampleCount; |
|
|
|
musicp">.loopCount = 0; // Infinite loop by default |
|
|
|
musicLoaded = true; |
|
|
|
|
|
|
|
TraceLog(LOG_DEBUG, "[%s] OGG total samples: %i", fileName, musico">->sampleCount); |
|
|
|
TraceLog(LOG_DEBUG, "[%s] OGG total samples: %i", fileName, musicp">.sampleCount); |
|
|
|
TraceLog(LOG_DEBUG, "[%s] OGG sample rate: %i", fileName, info.sample_rate); |
|
|
|
TraceLog(LOG_DEBUG, "[%s] OGG channels: %i", fileName, info.channels); |
|
|
|
TraceLog(LOG_DEBUG, "[%s] OGG memory required: %i", fileName, info.temp_memory_required); |
|
|
@ -1198,20 +1198,20 @@ Music LoadMusicStream(const char *fileName) |
|
|
|
#if defined(SUPPORT_FILEFORMAT_FLAC) |
|
|
|
else if (IsFileExtension(fileName, ".flac")) |
|
|
|
{ |
|
|
|
musico">->ctxData = drflac_open_file(fileName); |
|
|
|
musicp">.ctxData = drflac_open_file(fileName); |
|
|
|
|
|
|
|
if (musico">->ctxData != NULL) |
|
|
|
if (musicp">.ctxData != NULL) |
|
|
|
{ |
|
|
|
musico">->ctxType = MUSIC_AUDIO_FLAC; |
|
|
|
drflac *ctxFlac = (drflac *)musico">->ctxData; |
|
|
|
musicp">.ctxType = MUSIC_AUDIO_FLAC; |
|
|
|
drflac *ctxFlac = (drflac *)musicp">.ctxData; |
|
|
|
|
|
|
|
musico">->stream = InitAudioStream(ctxFlac->sampleRate, ctxFlac->bitsPerSample, ctxFlac->channels); |
|
|
|
musico">->sampleCount = (unsigned int)ctxFlac->totalSampleCount; |
|
|
|
musico">->sampleLeft = musico">->sampleCount; |
|
|
|
musico">->loopCount = 0; // Infinite loop by default |
|
|
|
musicp">.stream = InitAudioStream(ctxFlac->sampleRate, ctxFlac->bitsPerSample, ctxFlac->channels); |
|
|
|
musicp">.sampleCount = (unsigned int)ctxFlac->totalSampleCount; |
|
|
|
musicp">.sampleLeft = musicp">.sampleCount; |
|
|
|
musicp">.loopCount = 0; // Infinite loop by default |
|
|
|
musicLoaded = true; |
|
|
|
|
|
|
|
TraceLog(LOG_DEBUG, "[%s] FLAC total samples: %i", fileName, musico">->sampleCount); |
|
|
|
TraceLog(LOG_DEBUG, "[%s] FLAC total samples: %i", fileName, musicp">.sampleCount); |
|
|
|
TraceLog(LOG_DEBUG, "[%s] FLAC sample rate: %i", fileName, ctxFlac->sampleRate); |
|
|
|
TraceLog(LOG_DEBUG, "[%s] FLAC bits per sample: %i", fileName, ctxFlac->bitsPerSample); |
|
|
|
TraceLog(LOG_DEBUG, "[%s] FLAC channels: %i", fileName, ctxFlac->channels); |
|
|
@ -1222,24 +1222,24 @@ Music LoadMusicStream(const char *fileName) |
|
|
|
else if (IsFileExtension(fileName, ".mp3")) |
|
|
|
{ |
|
|
|
drmp3 *ctxMp3 = RL_MALLOC(sizeof(drmp3)); |
|
|
|
musico">->ctxData = ctxMp3; |
|
|
|
musicp">.ctxData = ctxMp3; |
|
|
|
|
|
|
|
int result = drmp3_init_file(ctxMp3, fileName, NULL); |
|
|
|
|
|
|
|
if (result > 0) |
|
|
|
{ |
|
|
|
musico">->ctxType = MUSIC_AUDIO_MP3; |
|
|
|
musicp">.ctxType = MUSIC_AUDIO_MP3; |
|
|
|
|
|
|
|
musico">->stream = InitAudioStream(ctxMp3->sampleRate, 32, ctxMp3->channels); |
|
|
|
musico">->sampleCount = drmp3_get_pcm_frame_count(ctxMp3)*ctxMp3->channels; |
|
|
|
musico">->sampleLeft = musico">->sampleCount; |
|
|
|
musico">->loopCount = 0; // Infinite loop by default |
|
|
|
musicp">.stream = InitAudioStream(ctxMp3->sampleRate, 32, ctxMp3->channels); |
|
|
|
musicp">.sampleCount = drmp3_get_pcm_frame_count(ctxMp3)*ctxMp3->channels; |
|
|
|
musicp">.sampleLeft = musicp">.sampleCount; |
|
|
|
musicp">.loopCount = 0; // Infinite loop by default |
|
|
|
musicLoaded = true; |
|
|
|
|
|
|
|
TraceLog(LOG_INFO, "[%s] MP3 sample rate: %i", fileName, ctxMp3->sampleRate); |
|
|
|
TraceLog(LOG_INFO, "[%s] MP3 bits per sample: %i", fileName, 32); |
|
|
|
TraceLog(LOG_INFO, "[%s] MP3 channels: %i", fileName, ctxMp3->channels); |
|
|
|
TraceLog(LOG_INFO, "[%s] MP3 total samples: %i", fileName, musico">->sampleCount); |
|
|
|
TraceLog(LOG_INFO, "[%s] MP3 total samples: %i", fileName, musicp">.sampleCount); |
|
|
|
} |
|
|
|
} |
|
|
|
#endif |
|
|
@ -1252,20 +1252,20 @@ Music LoadMusicStream(const char *fileName) |
|
|
|
|
|
|
|
if (result > 0) // XM context created successfully |
|
|
|
{ |
|
|
|
musico">->ctxType = MUSIC_MODULE_XM; |
|
|
|
musicp">.ctxType = MUSIC_MODULE_XM; |
|
|
|
jar_xm_set_max_loop_count(ctxXm, 0); // Set infinite number of loops |
|
|
|
|
|
|
|
// NOTE: Only stereo is supported for XM |
|
|
|
musico">->stream = InitAudioStream(48000, 16, 2); |
|
|
|
musico">->sampleCount = (unsigned int)jar_xm_get_remaining_samples(ctxXm); |
|
|
|
musico">->sampleLeft = musico">->sampleCount; |
|
|
|
musico">->loopCount = 0; // Infinite loop by default |
|
|
|
musicp">.stream = InitAudioStream(48000, 16, 2); |
|
|
|
musicp">.sampleCount = (unsigned int)jar_xm_get_remaining_samples(ctxXm); |
|
|
|
musicp">.sampleLeft = musicp">.sampleCount; |
|
|
|
musicp">.loopCount = 0; // Infinite loop by default |
|
|
|
musicLoaded = true; |
|
|
|
|
|
|
|
musico">->ctxData = ctxXm; |
|
|
|
musicp">.ctxData = ctxXm; |
|
|
|
|
|
|
|
TraceLog(LOG_INFO, "[%s] XM number of samples: %i", fileName, musico">->sampleCount); |
|
|
|
TraceLog(LOG_INFO, "[%s] XM track length: %11.6f sec", fileName, (float)musico">->sampleCount/48000.0f); |
|
|
|
TraceLog(LOG_INFO, "[%s] XM number of samples: %i", fileName, musicp">.sampleCount); |
|
|
|
TraceLog(LOG_INFO, "[%s] XM track length: %11.6f sec", fileName, (float)musicp">.sampleCount/48000.0f); |
|
|
|
} |
|
|
|
} |
|
|
|
#endif |
|
|
@ -1273,24 +1273,24 @@ Music LoadMusicStream(const char *fileName) |
|
|
|
else if (IsFileExtension(fileName, ".mod")) |
|
|
|
{ |
|
|
|
jar_mod_context_t *ctxMod = RL_MALLOC(sizeof(jar_mod_context_t)); |
|
|
|
musico">->ctxData = ctxMod; |
|
|
|
musicp">.ctxData = ctxMod; |
|
|
|
|
|
|
|
jar_mod_init(ctxMod); |
|
|
|
int result = jar_mod_load_file(ctxMod, fileName); |
|
|
|
|
|
|
|
if (result > 0) |
|
|
|
{ |
|
|
|
musico">->ctxType = MUSIC_MODULE_MOD; |
|
|
|
musicp">.ctxType = MUSIC_MODULE_MOD; |
|
|
|
|
|
|
|
// NOTE: Only stereo is supported for MOD |
|
|
|
musico">->stream = InitAudioStream(48000, 16, 2); |
|
|
|
musico">->sampleCount = (unsigned int)jar_mod_max_samples(ctxMod); |
|
|
|
musico">->sampleLeft = musico">->sampleCount; |
|
|
|
musico">->loopCount = 0; // Infinite loop by default |
|
|
|
musicp">.stream = InitAudioStream(48000, 16, 2); |
|
|
|
musicp">.sampleCount = (unsigned int)jar_mod_max_samples(ctxMod); |
|
|
|
musicp">.sampleLeft = musicp">.sampleCount; |
|
|
|
musicp">.loopCount = 0; // Infinite loop by default |
|
|
|
musicLoaded = true; |
|
|
|
|
|
|
|
TraceLog(LOG_INFO, "[%s] MOD number of samples: %i", fileName, musico">->sampleLeft); |
|
|
|
TraceLog(LOG_INFO, "[%s] MOD track length: %11.6f sec", fileName, (float)musico">->sampleCount/48000.0f); |
|
|
|
TraceLog(LOG_INFO, "[%s] MOD number of samples: %i", fileName, musicp">.sampleLeft); |
|
|
|
TraceLog(LOG_INFO, "[%s] MOD track length: %11.6f sec", fileName, (float)musicp">.sampleCount/48000.0f); |
|
|
|
} |
|
|
|
} |
|
|
|
#endif |
|
|
@ -1299,24 +1299,21 @@ Music LoadMusicStream(const char *fileName) |
|
|
|
{ |
|
|
|
if (false) { } |
|
|
|
#if defined(SUPPORT_FILEFORMAT_OGG) |
|
|
|
else if (musico">->ctxType == MUSIC_AUDIO_OGG) stb_vorbis_close((stb_vorbis *)musico">->ctxData); |
|
|
|
else if (musicp">.ctxType == MUSIC_AUDIO_OGG) stb_vorbis_close((stb_vorbis *)musicp">.ctxData); |
|
|
|
#endif |
|
|
|
#if defined(SUPPORT_FILEFORMAT_FLAC) |
|
|
|
else if (musico">->ctxType == MUSIC_AUDIO_FLAC) drflac_free((drflac *)musico">->ctxData); |
|
|
|
else if (musicp">.ctxType == MUSIC_AUDIO_FLAC) drflac_free((drflac *)musicp">.ctxData); |
|
|
|
#endif |
|
|
|
#if defined(SUPPORT_FILEFORMAT_MP3) |
|
|
|
else if (musico">->ctxType == MUSIC_AUDIO_MP3) { drmp3_uninit((drmp3 *)musico">->ctxData); RL_FREE(musico">->ctxData); } |
|
|
|
else if (musicp">.ctxType == MUSIC_AUDIO_MP3) { drmp3_uninit((drmp3 *)musicp">.ctxData); RL_FREE(musicp">.ctxData); } |
|
|
|
#endif |
|
|
|
#if defined(SUPPORT_FILEFORMAT_XM) |
|
|
|
else if (musico">->ctxType == MUSIC_MODULE_XM) jar_xm_free_context((jar_xm_context_t *)musico">->ctxData); |
|
|
|
else if (musicp">.ctxType == MUSIC_MODULE_XM) jar_xm_free_context((jar_xm_context_t *)musicp">.ctxData); |
|
|
|
#endif |
|
|
|
#if defined(SUPPORT_FILEFORMAT_MOD) |
|
|
|
else if (musico">->ctxType == MUSIC_MODULE_MOD) { jar_mod_unload((jar_mod_context_t *)musico">->ctxData); RL_FREE(musico">->ctxData); } |
|
|
|
else if (musicp">.ctxType == MUSIC_MODULE_MOD) { jar_mod_unload((jar_mod_context_t *)musicp">.ctxData); RL_FREE(musicp">.ctxData); } |
|
|
|
#endif |
|
|
|
|
|
|
|
RL_FREE(music); |
|
|
|
music = NULL; |
|
|
|
|
|
|
|
TraceLog(LOG_WARNING, "[%s] Music file could not be opened", fileName); |
|
|
|
} |
|
|
|
|
|
|
@ -1326,124 +1323,113 @@ Music LoadMusicStream(const char *fileName) |
|
|
|
// Unload music stream |
|
|
|
void UnloadMusicStream(Music music) |
|
|
|
{ |
|
|
|
if (music == NULL) return; |
|
|
|
|
|
|
|
CloseAudioStream(music->stream); |
|
|
|
CloseAudioStream(music.stream); |
|
|
|
|
|
|
|
if (false) { } |
|
|
|
#if defined(SUPPORT_FILEFORMAT_OGG) |
|
|
|
else if (musico">->ctxType == MUSIC_AUDIO_OGG) stb_vorbis_close((stb_vorbis *)musico">->ctxData); |
|
|
|
else if (musicp">.ctxType == MUSIC_AUDIO_OGG) stb_vorbis_close((stb_vorbis *)musicp">.ctxData); |
|
|
|
#endif |
|
|
|
#if defined(SUPPORT_FILEFORMAT_FLAC) |
|
|
|
else if (musico">->ctxType == MUSIC_AUDIO_FLAC) drflac_free((drflac *)musico">->ctxData); |
|
|
|
else if (musicp">.ctxType == MUSIC_AUDIO_FLAC) drflac_free((drflac *)musicp">.ctxData); |
|
|
|
#endif |
|
|
|
#if defined(SUPPORT_FILEFORMAT_MP3) |
|
|
|
else if (musico">->ctxType == MUSIC_AUDIO_MP3) { drmp3_uninit((drmp3 *)musico">->ctxData); RL_FREE(musico">->ctxData); } |
|
|
|
else if (musicp">.ctxType == MUSIC_AUDIO_MP3) { drmp3_uninit((drmp3 *)musicp">.ctxData); RL_FREE(musicp">.ctxData); } |
|
|
|
#endif |
|
|
|
#if defined(SUPPORT_FILEFORMAT_XM) |
|
|
|
else if (musico">->ctxType == MUSIC_MODULE_XM) jar_xm_free_context((jar_xm_context_t *)musico">->ctxData); |
|
|
|
else if (musicp">.ctxType == MUSIC_MODULE_XM) jar_xm_free_context((jar_xm_context_t *)musicp">.ctxData); |
|
|
|
#endif |
|
|
|
#if defined(SUPPORT_FILEFORMAT_MOD) |
|
|
|
else if (musico">->ctxType == MUSIC_MODULE_MOD) { jar_mod_unload((jar_mod_context_t *)musico">->ctxData); RL_FREE(musico">->ctxData); } |
|
|
|
else if (musicp">.ctxType == MUSIC_MODULE_MOD) { jar_mod_unload((jar_mod_context_t *)musicp">.ctxData); RL_FREE(musicp">.ctxData); } |
|
|
|
#endif |
|
|
|
|
|
|
|
RL_FREE(music); |
|
|
|
} |
|
|
|
|
|
|
|
// Start music playing (open stream) |
|
|
|
void PlayMusicStream(Music music) |
|
|
|
{ |
|
|
|
if (music != NULL) |
|
|
|
{ |
|
|
|
AudioBuffer *audioBuffer = music->stream.buffer; |
|
|
|
AudioBuffer *audioBuffer = music.stream.buffer; |
|
|
|
|
|
|
|
if (audioBuffer == NULL) |
|
|
|
{ |
|
|
|
TraceLog(LOG_ERROR, "PlayMusicStream() : No audio buffer"); |
|
|
|
return; |
|
|
|
} |
|
|
|
if (audioBuffer == NULL) |
|
|
|
{ |
|
|
|
TraceLog(LOG_ERROR, "PlayMusicStream() : No audio buffer"); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// For music streams, we need to make sure we maintain the frame cursor position. This is hack for this section of code in UpdateMusicStream() |
|
|
|
// // NOTE: In case window is minimized, music stream is stopped, |
|
|
|
// // just make sure to play again on window restore |
|
|
|
// if (IsMusicPlaying(music)) PlayMusicStream(music); |
|
|
|
ma_uint32 frameCursorPos = audioBuffer->frameCursorPos; |
|
|
|
// For music streams, we need to make sure we maintain the frame cursor position. This is hack for this section of code in UpdateMusicStream() |
|
|
|
// // NOTE: In case window is minimized, music stream is stopped, |
|
|
|
// // just make sure to play again on window restore |
|
|
|
// if (IsMusicPlaying(music)) PlayMusicStream(music); |
|
|
|
ma_uint32 frameCursorPos = audioBuffer->frameCursorPos; |
|
|
|
|
|
|
|
PlayAudioStream(musico">->stream); // <-- This resets the cursor position. |
|
|
|
PlayAudioStream(musicp">.stream); // <-- This resets the cursor position. |
|
|
|
|
|
|
|
audioBuffer->frameCursorPos = frameCursorPos; |
|
|
|
} |
|
|
|
audioBuffer->frameCursorPos = frameCursorPos; |
|
|
|
} |
|
|
|
|
|
|
|
// Pause music playing |
|
|
|
void PauseMusicStream(Music music) |
|
|
|
{ |
|
|
|
k">if (music != NULL) PauseAudioStream(musico">->stream); |
|
|
|
PauseAudioStream(musicp">.stream); |
|
|
|
} |
|
|
|
|
|
|
|
// Resume music playing |
|
|
|
void ResumeMusicStream(Music music) |
|
|
|
{ |
|
|
|
k">if (music != NULL) ResumeAudioStream(musico">->stream); |
|
|
|
ResumeAudioStream(musicp">.stream); |
|
|
|
} |
|
|
|
|
|
|
|
// Stop music playing (close stream) |
|
|
|
void StopMusicStream(Music music) |
|
|
|
{ |
|
|
|
if (music == NULL) return; |
|
|
|
|
|
|
|
StopAudioStream(music->stream); |
|
|
|
StopAudioStream(music.stream); |
|
|
|
|
|
|
|
// Restart music context |
|
|
|
switch (musico">->ctxType) |
|
|
|
switch (musicp">.ctxType) |
|
|
|
{ |
|
|
|
#if defined(SUPPORT_FILEFORMAT_OGG) |
|
|
|
case MUSIC_AUDIO_OGG: stb_vorbis_seek_start((stb_vorbis *)musico">->ctxData); break; |
|
|
|
case MUSIC_AUDIO_OGG: stb_vorbis_seek_start((stb_vorbis *)musicp">.ctxData); break; |
|
|
|
#endif |
|
|
|
#if defined(SUPPORT_FILEFORMAT_FLAC) |
|
|
|
case MUSIC_AUDIO_FLAC: /* TODO: Restart FLAC context */ break; |
|
|
|
#endif |
|
|
|
#if defined(SUPPORT_FILEFORMAT_MP3) |
|
|
|
case MUSIC_AUDIO_MP3: drmp3_seek_to_pcm_frame((drmp3 *)musico">->ctxData, 0); break; |
|
|
|
case MUSIC_AUDIO_MP3: drmp3_seek_to_pcm_frame((drmp3 *)musicp">.ctxData, 0); break; |
|
|
|
#endif |
|
|
|
#if defined(SUPPORT_FILEFORMAT_XM) |
|
|
|
case MUSIC_MODULE_XM: jar_xm_reset((jar_xm_context_t *)musico">->ctxData); break; |
|
|
|
case MUSIC_MODULE_XM: jar_xm_reset((jar_xm_context_t *)musicp">.ctxData); break; |
|
|
|
#endif |
|
|
|
#if defined(SUPPORT_FILEFORMAT_MOD) |
|
|
|
case MUSIC_MODULE_MOD: jar_mod_seek_start((jar_mod_context_t *)musico">->ctxData); break; |
|
|
|
case MUSIC_MODULE_MOD: jar_mod_seek_start((jar_mod_context_t *)musicp">.ctxData); break; |
|
|
|
#endif |
|
|
|
default: break; |
|
|
|
} |
|
|
|
|
|
|
|
musico">->sampleLeft = musico">->sampleCount; |
|
|
|
musicp">.sampleLeft = musicp">.sampleCount; |
|
|
|
} |
|
|
|
|
|
|
|
// Update (re-fill) music buffers if data already processed |
|
|
|
void UpdateMusicStream(Music music) |
|
|
|
{ |
|
|
|
if (music == NULL) return; |
|
|
|
|
|
|
|
bool streamEnding = false; |
|
|
|
|
|
|
|
unsigned int subBufferSizeInFrames = musico">->stream.buffer->bufferSizeInFrames/2; |
|
|
|
unsigned int subBufferSizeInFrames = musicp">.stream.buffer->bufferSizeInFrames/2; |
|
|
|
|
|
|
|
// NOTE: Using dynamic allocation because it could require more than 16KB |
|
|
|
void *pcm = RL_CALLOC(subBufferSizeInFrames*musico">->stream.channels*musico">->stream.sampleSize/8, 1); |
|
|
|
void *pcm = RL_CALLOC(subBufferSizeInFrames*musicp">.stream.channels*musicp">.stream.sampleSize/8, 1); |
|
|
|
|
|
|
|
int samplesCount = 0; // Total size of data steamed in L+R samples for xm floats, individual L or R for ogg shorts |
|
|
|
|
|
|
|
while (IsAudioBufferProcessed(musico">->stream)) |
|
|
|
while (IsAudioBufferProcessed(musicp">.stream)) |
|
|
|
{ |
|
|
|
if ((musico">->sampleLeft/musico">->stream.channels) >= subBufferSizeInFrames) samplesCount = subBufferSizeInFrames*musico">->stream.channels; |
|
|
|
else samplesCount = musico">->sampleLeft; |
|
|
|
if ((musicp">.sampleLeft/musicp">.stream.channels) >= subBufferSizeInFrames) samplesCount = subBufferSizeInFrames*musicp">.stream.channels; |
|
|
|
else samplesCount = musicp">.sampleLeft; |
|
|
|
|
|
|
|
switch (musico">->ctxType) |
|
|
|
switch (musicp">.ctxType) |
|
|
|
{ |
|
|
|
#if defined(SUPPORT_FILEFORMAT_OGG) |
|
|
|
case MUSIC_AUDIO_OGG: |
|
|
|
{ |
|
|
|
// NOTE: Returns the number of samples to process (be careful! we ask for number of shorts!) |
|
|
|
stb_vorbis_get_samples_short_interleaved((stb_vorbis *)musico">->ctxData, musico">->stream.channels, (short *)pcm, samplesCount); |
|
|
|
stb_vorbis_get_samples_short_interleaved((stb_vorbis *)musicp">.ctxData, musicp">.stream.channels, (short *)pcm, samplesCount); |
|
|
|
|
|
|
|
} break; |
|
|
|
#endif |
|
|
@ -1451,7 +1437,7 @@ void UpdateMusicStream(Music music) |
|
|
|
case MUSIC_AUDIO_FLAC: |
|
|
|
{ |
|
|
|
// NOTE: Returns the number of samples to process (not required) |
|
|
|
drflac_read_s16((drflac *)musico">->ctxData, samplesCount, (short *)pcm); |
|
|
|
drflac_read_s16((drflac *)musicp">.ctxData, samplesCount, (short *)pcm); |
|
|
|
|
|
|
|
} break; |
|
|
|
#endif |
|
|
@ -1459,7 +1445,7 @@ void UpdateMusicStream(Music music) |
|
|
|
case MUSIC_AUDIO_MP3: |
|
|
|
{ |
|
|
|
// NOTE: samplesCount, actually refers to framesCount and returns the number of frames processed |
|
|
|
drmp3_read_pcm_frames_f32((drmp3 *)musico">->ctxData, samplesCount/musico">->stream.channels, (float *)pcm); |
|
|
|
drmp3_read_pcm_frames_f32((drmp3 *)musicp">.ctxData, samplesCount/musicp">.stream.channels, (float *)pcm); |
|
|
|
|
|
|
|
} break; |
|
|
|
#endif |
|
|
@ -1467,29 +1453,29 @@ void UpdateMusicStream(Music music) |
|
|
|
case MUSIC_MODULE_XM: |
|
|
|
{ |
|
|
|
// NOTE: Internally this function considers 2 channels generation, so samplesCount/2 |
|
|
|
jar_xm_generate_samples_16bit((jar_xm_context_t *)musico">->ctxData, (short *)pcm, samplesCount/2); |
|
|
|
jar_xm_generate_samples_16bit((jar_xm_context_t *)musicp">.ctxData, (short *)pcm, samplesCount/2); |
|
|
|
} break; |
|
|
|
#endif |
|
|
|
#if defined(SUPPORT_FILEFORMAT_MOD) |
|
|
|
case MUSIC_MODULE_MOD: |
|
|
|
{ |
|
|
|
// NOTE: 3rd parameter (nbsample) specify the number of stereo 16bits samples you want, so sampleCount/2 |
|
|
|
jar_mod_fillbuffer((jar_mod_context_t *)musico">->ctxData, (short *)pcm, samplesCount/2, 0); |
|
|
|
jar_mod_fillbuffer((jar_mod_context_t *)musicp">.ctxData, (short *)pcm, samplesCount/2, 0); |
|
|
|
} break; |
|
|
|
#endif |
|
|
|
default: break; |
|
|
|
} |
|
|
|
|
|
|
|
UpdateAudioStream(musico">->stream, pcm, samplesCount); |
|
|
|
UpdateAudioStream(musicp">.stream, pcm, samplesCount); |
|
|
|
|
|
|
|
if ((musico">->ctxType == MUSIC_MODULE_XM) || (musico">->ctxType == MUSIC_MODULE_MOD)) |
|
|
|
if ((musicp">.ctxType == MUSIC_MODULE_XM) || (musicp">.ctxType == MUSIC_MODULE_MOD)) |
|
|
|
{ |
|
|
|
if (samplesCount > 1) musico">->sampleLeft -= samplesCount/2; |
|
|
|
else musico">->sampleLeft -= samplesCount; |
|
|
|
if (samplesCount > 1) musicp">.sampleLeft -= samplesCount/2; |
|
|
|
else musicp">.sampleLeft -= samplesCount; |
|
|
|
} |
|
|
|
else musico">->sampleLeft -= samplesCount; |
|
|
|
else musicp">.sampleLeft -= samplesCount; |
|
|
|
|
|
|
|
if (musico">->sampleLeft <= 0) |
|
|
|
if (musicp">.sampleLeft <= 0) |
|
|
|
{ |
|
|
|
streamEnding = true; |
|
|
|
break; |
|
|
@ -1505,14 +1491,14 @@ void UpdateMusicStream(Music music) |
|
|
|
StopMusicStream(music); // Stop music (and reset) |
|
|
|
|
|
|
|
// Decrease loopCount to stop when required |
|
|
|
if (musico">->loopCount > 1) |
|
|
|
if (musicp">.loopCount > 1) |
|
|
|
{ |
|
|
|
musico">->loopCount--; // Decrease loop count |
|
|
|
musicp">.loopCount--; // Decrease loop count |
|
|
|
PlayMusicStream(music); // Play again |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
if (musico">->loopCount == 0) PlayMusicStream(music); |
|
|
|
if (musicp">.loopCount == 0) PlayMusicStream(music); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
@ -1526,27 +1512,26 @@ void UpdateMusicStream(Music music) |
|
|
|
// Check if any music is playing |
|
|
|
bool IsMusicPlaying(Music music) |
|
|
|
{ |
|
|
|
if (music == NULL) return false; |
|
|
|
else return IsAudioStreamPlaying(music->stream); |
|
|
|
return IsAudioStreamPlaying(music.stream); |
|
|
|
} |
|
|
|
|
|
|
|
// Set volume for music |
|
|
|
void SetMusicVolume(Music music, float volume) |
|
|
|
{ |
|
|
|
k">if (music != NULL) SetAudioStreamVolume(musico">->stream, volume); |
|
|
|
SetAudioStreamVolume(musicp">.stream, volume); |
|
|
|
} |
|
|
|
|
|
|
|
// Set pitch for music |
|
|
|
void SetMusicPitch(Music music, float pitch) |
|
|
|
{ |
|
|
|
k">if (music != NULL) SetAudioStreamPitch(musico">->stream, pitch); |
|
|
|
SetAudioStreamPitch(musicp">.stream, pitch); |
|
|
|
} |
|
|
|
|
|
|
|
// Set music loop count (loop repeats) |
|
|
|
// NOTE: If set to -1, means infinite loop |
|
|
|
void SetMusicLoopCount(Music music, int count) |
|
|
|
{ |
|
|
|
k">if (music != NULL) music->loopCount = count; |
|
|
|
n">music.loopCount = count; |
|
|
|
} |
|
|
|
|
|
|
|
// Get music time length (in seconds) |
|
|
@ -1554,7 +1539,7 @@ float GetMusicTimeLength(Music music) |
|
|
|
{ |
|
|
|
float totalSeconds = 0.0f; |
|
|
|
|
|
|
|
k">if (music != NULL) totalSeconds = (float)musico">->sampleCount/(musico">->stream.sampleRate*musico">->stream.channels); |
|
|
|
totalSeconds = (float)musicp">.sampleCount/(musicp">.stream.sampleRate*musicp">.stream.channels); |
|
|
|
|
|
|
|
return totalSeconds; |
|
|
|
} |
|
|
@ -1564,11 +1549,8 @@ float GetMusicTimePlayed(Music music) |
|
|
|
{ |
|
|
|
float secondsPlayed = 0.0f; |
|
|
|
|
|
|
|
if (music != NULL) |
|
|
|
{ |
|
|
|
unsigned int samplesPlayed = music->sampleCount - music->sampleLeft; |
|
|
|
secondsPlayed = (float)samplesPlayed/(music->stream.sampleRate*music->stream.channels); |
|
|
|
} |
|
|
|
unsigned int samplesPlayed = music.sampleCount - music.sampleLeft; |
|
|
|
secondsPlayed = (float)samplesPlayed/(music.stream.sampleRate*music.stream.channels); |
|
|
|
|
|
|
|
return secondsPlayed; |
|
|
|
} |
|
|
|