|
|
@ -1219,6 +1219,8 @@ Music LoadMusicStream(const char *fileName) |
|
|
|
// Unload music stream |
|
|
|
void UnloadMusicStream(Music music) |
|
|
|
{ |
|
|
|
if (music == NULL) return; |
|
|
|
|
|
|
|
CloseAudioStream(music->stream); |
|
|
|
|
|
|
|
if (music->ctxType == MUSIC_AUDIO_OGG) stb_vorbis_close(music->ctxOgg); |
|
|
@ -1241,41 +1243,46 @@ void UnloadMusicStream(Music music) |
|
|
|
// Start music playing (open stream) |
|
|
|
void PlayMusicStream(Music music) |
|
|
|
{ |
|
|
|
AudioBuffer *audioBuffer = (AudioBuffer *)music->stream.audioBuffer; |
|
|
|
|
|
|
|
if (audioBuffer == NULL) |
|
|
|
if (music != NULL) |
|
|
|
{ |
|
|
|
TraceLog(LOG_ERROR, "PlayMusicStream() : No audio buffer"); |
|
|
|
return; |
|
|
|
} |
|
|
|
AudioBuffer *audioBuffer = (AudioBuffer *)music->stream.audioBuffer; |
|
|
|
|
|
|
|
// 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); |
|
|
|
mal_uint32 frameCursorPos = audioBuffer->frameCursorPos; |
|
|
|
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); |
|
|
|
mal_uint32 frameCursorPos = audioBuffer->frameCursorPos; |
|
|
|
|
|
|
|
PlayAudioStream(music->stream); // <-- This resets the cursor position. |
|
|
|
PlayAudioStream(music->stream); // <-- This resets the cursor position. |
|
|
|
|
|
|
|
audioBuffer->frameCursorPos = frameCursorPos; |
|
|
|
audioBuffer->frameCursorPos = frameCursorPos; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Pause music playing |
|
|
|
void PauseMusicStream(Music music) |
|
|
|
{ |
|
|
|
PauseAudioStream(music->stream); |
|
|
|
k">if (music != NULL) PauseAudioStream(music->stream); |
|
|
|
} |
|
|
|
|
|
|
|
// Resume music playing |
|
|
|
void ResumeMusicStream(Music music) |
|
|
|
{ |
|
|
|
ResumeAudioStream(music->stream); |
|
|
|
k">if (music != NULL) ResumeAudioStream(music->stream); |
|
|
|
} |
|
|
|
|
|
|
|
// Stop music playing (close stream) |
|
|
|
// TODO: To clear a buffer, make sure they have been already processed! |
|
|
|
void StopMusicStream(Music music) |
|
|
|
{ |
|
|
|
if (music == NULL) return; |
|
|
|
|
|
|
|
StopAudioStream(music->stream); |
|
|
|
|
|
|
|
// Restart music context |
|
|
@ -1304,6 +1311,8 @@ void StopMusicStream(Music music) |
|
|
|
// TODO: Make sure buffers are ready for update... check music state |
|
|
|
void UpdateMusicStream(Music music) |
|
|
|
{ |
|
|
|
if (music == NULL) return; |
|
|
|
|
|
|
|
bool streamEnding = false; |
|
|
|
|
|
|
|
unsigned int subBufferSizeInFrames = ((AudioBuffer *)music->stream.audioBuffer)->bufferSizeInFrames/2; |
|
|
@ -1406,32 +1415,35 @@ void UpdateMusicStream(Music music) |
|
|
|
// Check if any music is playing |
|
|
|
bool IsMusicPlaying(Music music) |
|
|
|
{ |
|
|
|
return IsAudioStreamPlaying(music->stream); |
|
|
|
if (music == NULL) return false; |
|
|
|
else return IsAudioStreamPlaying(music->stream); |
|
|
|
} |
|
|
|
|
|
|
|
// Set volume for music |
|
|
|
void SetMusicVolume(Music music, float volume) |
|
|
|
{ |
|
|
|
SetAudioStreamVolume(music->stream, volume); |
|
|
|
k">if (music != NULL) SetAudioStreamVolume(music->stream, volume); |
|
|
|
} |
|
|
|
|
|
|
|
// Set pitch for music |
|
|
|
void SetMusicPitch(Music music, float pitch) |
|
|
|
{ |
|
|
|
SetAudioStreamPitch(music->stream, pitch); |
|
|
|
k">if (music != NULL) SetAudioStreamPitch(music->stream, pitch); |
|
|
|
} |
|
|
|
|
|
|
|
// Set music loop count (loop repeats) |
|
|
|
// NOTE: If set to -1, means infinite loop |
|
|
|
void SetMusicLoopCount(Music music, int count) |
|
|
|
{ |
|
|
|
music->loopCount = count; |
|
|
|
k">if (music != NULL) music->loopCount = count; |
|
|
|
} |
|
|
|
|
|
|
|
// Get music time length (in seconds) |
|
|
|
float GetMusicTimeLength(Music music) |
|
|
|
{ |
|
|
|
float totalSeconds = (float)music->totalSamples/(music->stream.sampleRate*music->stream.channels); |
|
|
|
float totalSeconds = 0.0f; |
|
|
|
|
|
|
|
if (music != NULL) totalSeconds = (float)music->totalSamples/(music->stream.sampleRate*music->stream.channels); |
|
|
|
|
|
|
|
return totalSeconds; |
|
|
|
} |
|
|
@ -1441,8 +1453,11 @@ float GetMusicTimePlayed(Music music) |
|
|
|
{ |
|
|
|
float secondsPlayed = 0.0f; |
|
|
|
|
|
|
|
unsigned int samplesPlayed = music->totalSamples - music->samplesLeft; |
|
|
|
secondsPlayed = (float)samplesPlayed/(music->stream.sampleRate*music->stream.channels); |
|
|
|
if (music != NULL) |
|
|
|
{ |
|
|
|
unsigned int samplesPlayed = music->totalSamples - music->samplesLeft; |
|
|
|
secondsPlayed = (float)samplesPlayed/(music->stream.sampleRate*music->stream.channels); |
|
|
|
} |
|
|
|
|
|
|
|
return secondsPlayed; |
|
|
|
} |
|
|
|