-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[audio] Music looping based on FPS issue #2228
Comments
@Kabcorp Yes, I'm aware of this issue, |
Could you tell me if this issue is still being worked on? |
@jdeokkim this issue is open but I'm not working on it right now. Feel free to work on it and send a PR if you wish. |
@raysan5 Oh, I see. Thank you! |
Trying to implement proper looping, independently of frame rate.
@mackron Please, could you take a look to this issue? I tried to review What I tried: If the frames left are less than buffer size, I append to them the required frames from the beginning of the file. As per my understanding it should work but it doesn't. I did many tries and I feel I'm probably missing something... Current implementation seems to kind of work but it's wrong. Here the code I used to test: #include "raylib.h"
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [audio] example - music playing (streaming)");
InitAudioDevice(); // Initialize audio device
Music music = LoadMusicStream("resources/sfx.wav");
music.looping = true;
PlayMusicStream(music);
float timePlayed = 0.0f; // Time played normalized [0.0f..1.0f]
bool pause = false; // Music playing paused
SetTargetFPS(30); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
UpdateMusicStream(music); // Update music buffer with new stream data
// Get normalized time played for current music stream
timePlayed = GetMusicTimePlayed(music)/GetMusicTimeLength(music);
if (timePlayed > 1.0f) timePlayed = 1.0f; // Make sure time played is no longer than music
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
DrawText("MUSIC SHOULD BE PLAYING!", 255, 150, 20, LIGHTGRAY);
DrawRectangle(200, 200, 400, 12, LIGHTGRAY);
DrawRectangle(200, 200, (int)(timePlayed*400.0f), 12, MAROON);
DrawRectangleLines(200, 200, 400, 12, GRAY);
DrawText("PRESS SPACE TO RESTART MUSIC", 215, 250, 20, LIGHTGRAY);
DrawText("PRESS P TO PAUSE/RESUME MUSIC", 208, 280, 20, LIGHTGRAY);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadMusicStream(music); // Unload music stream buffers from RAM
CloseAudioDevice(); // Close audio device (music streaming is automatically stopped)
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
} Here the sound file I use for testing: sfx.zip If you think the implementation cost does not worth it let me know. I can skip this issue. |
I've had a look at this and I'm not actually sure what's going on. When I tried it, I also had another glitch with wav files which I'm not sure is related. I'm strongly of the opinion that the audio system needs a complete overhaul. And by that I mean both the implementation and the public API. Generally, these are the high level things I think you need to change.
If you're willing to do a complete rewrite of the audio system (which I think you should seriously consider), I'd be happy to do a fresh implementation with you. My preference would be to do a complete redesign of the audio API though which would obviously break compatibility, but I have ideas that I think could make the audio system even simpler for the user and at the same time make it more powerful. Happy to talk further about that if you're interested. |
Hi David! Thank you very much for taking a look to this issue! I agree that the audio system needs a review, I know miniaudio has grown a lot in the last years and provides lots of high-level features but redesigning the public API will be a breaking change I prefer to avoid at this moment; at least not intended for the upcoming raylib 4.2 release.
Current implementation discretizes the different file formats loading using
Current approach uses
Agree. That would be a nice improvement. As per my understanding this is mostly an internal change, right?
Sure! At this moment I'm targeting raylib 4.2 release and I'm a bit reticent of API breaking changes but I want to hear your ideas and we can see how we can redesign the API for a future version. |
The way it would work is the context would be a For example, in switch (music.ctxType)
{
#if defined(SUPPORT_FILEFORMAT_WAV)
case MUSIC_AUDIO_WAV:
{
} break;
#endif
#if defined(SUPPORT_FILEFORMAT_OGG)
case MUSIC_AUDIO_OGG:
{
} break;
#endif
#if defined(SUPPORT_FILEFORMAT_FLAC)
case MUSIC_AUDIO_FLAC:
{
} break;
#endif
#if defined(SUPPORT_FILEFORMAT_MP3)
case MUSIC_AUDIO_MP3:
{
} break;
#endif
#if defined(SUPPORT_FILEFORMAT_XM)
case MUSIC_MODULE_XM:
{
} break;
#endif
#if defined(SUPPORT_FILEFORMAT_MOD)
case MUSIC_MODULE_MOD:
{
} break;
#endif
default: break;
} That entire section would be replaced with a call to ma_decoder_read_pcm_frames((ma_decoder*)music.ctxData, frameCountToStream, (float*)AUDIO.System.pcm); It's just so much cleaner. No
Could be possible, but I haven't really looked at the code in enough detail. Certainly if you couldn't make it an alias, you could simplify them a bit. There's something that feels wrong about the double buffering system that's currently being used - I think that needs to be re-written and simplified, and I have an idea for that. I'm suspecting that has something to do with the error in this bug report. But yes, there's still a bunch we could do to improve the code while keeping the same API. They way I would approach it is to first do that unified decoding thing. After then once that's done I would transition away from the low-level API and start using the high level API so you can avoid having to do the mixing yourself.
We can talk on Discord about that if you want. |
Agree. This approximation is more cleaner.
That's nice. I personally never liked the double-buffer approach.
That's sounds good for me. @mackron we can start working on it on the raudio repo if you want and once we have something good enough I will move it into raylib. Currently |
This issue has been fixed but the |
Issue description
Music looping is based on FPS, which is odd in 99% of time.
With this approach, if the music reach the end of its own length, you have to wait the next frame to restart looping.
It was tried of course using WAV pcm file with basic code:
Environment
Windows 10, mingw_w64, GTX1050 3gB
Provide your Platform, Operating System, OpenGL version, GPU details where you experienced the issue.
Issue Screenshot
Code Example
(sfx.wav is downloadable here: http://kabcorp.fr/sendfiles/ray/sfx.wav)
sfx.wav is a pure sine wave with correct repeat sample.
The text was updated successfully, but these errors were encountered: