Skip to content
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

SDL2 ,clear the queue data? #8485

Closed
MrJokerBoy opened this issue Nov 6, 2023 · 12 comments
Closed

SDL2 ,clear the queue data? #8485

MrJokerBoy opened this issue Nov 6, 2023 · 12 comments
Assignees
Milestone

Comments

@MrJokerBoy
Copy link

In the SDL2 version, when playing through callback, is there a way to clear the queue data?

@slouken
Copy link
Collaborator

slouken commented Nov 6, 2023

No, the callback function is called on demand, there is no queue involved.

@slouken slouken closed this as completed Nov 6, 2023
@MrJokerBoy
Copy link
Author

@slouken Now there is a problem. After the queue data is filled, after pausing and doing some seek operations, the previously stored queue data will be played back when playing again. I hope that the data will be cleared and the new data that is passed in will be played directly. .

@slouken
Copy link
Collaborator

slouken commented Nov 6, 2023

Are you talking about SDL2 or SDL3?

@slouken slouken reopened this Nov 6, 2023
@MrJokerBoy
Copy link
Author

@slouken SDL2 version 2.28.3

@slouken
Copy link
Collaborator

slouken commented Nov 6, 2023

What operating system and SDL audio driver are you using?

@MrJokerBoy
Copy link
Author

iOS version of SDL used

@slouken
Copy link
Collaborator

slouken commented Nov 6, 2023

@icculus, do we have an issue on iOS where we pause the device but don't flush the audio in SDL2?

@icculus
Copy link
Collaborator

icculus commented Nov 6, 2023

As far as I know, it should be requesting audio on demand; it's possible it's buffering a little bit for resampling...?

So to be clear, is the problem:

  • The audio callback runs, you feed it data, then
  • you pause the device with SDL_PauseAudioDevice
  • sometime later you unpause it
  • it then plays old audio from before the pause

?

(And if this is correct, how much old audio does it play?)

icculus added a commit that referenced this issue Nov 6, 2023
This makes sure stuff that was still pending for conversion/resampling doesn't
pop in later when the device is unpaused again.

Fixes #8485.
@icculus
Copy link
Collaborator

icculus commented Nov 6, 2023

Actually, I can see that the comment I made about resampling is obviously going to cause this problem, so I've pushed a fix for that. If this doesn't fix your actual problem, please let me know!

@icculus
Copy link
Collaborator

icculus commented Nov 6, 2023

(This specific fix doesn't need to be cherry-picked to SDL3, since it works differently here and shouldn't have this bug.)

@MrJokerBoy
Copy link
Author

MrJokerBoy commented Nov 7, 2023

@icculus Hello, I have tried it and the problem still exists. I will add the screen recording file. The steps are as follows:

  1. Play normally to a certain position
  2. seek the head
  3. Play again
    Some data at the end of the last queue will be played, and sometimes the sound will be loud.
RPReplay_Final1699323725.MP4

@slouken slouken added this to the 2.30.0 milestone Nov 8, 2023
@icculus
Copy link
Collaborator

icculus commented Nov 28, 2023

This is working here. I modified SDL/test/loopwave.c like this:

diff --git a/test/loopwave.c b/test/loopwave.c
index 18bb0ad74..aec352807 100644
--- a/test/loopwave.c
+++ b/test/loopwave.c
@@ -120,11 +120,13 @@ int main(int argc, char *argv[])
     SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);

     /* Load the SDL library */
-    if (SDL_Init(SDL_INIT_AUDIO | SDL_INIT_EVENTS) < 0) {
+    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_EVENTS) < 0) {
         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
         return 1;
     }

+SDL_CreateWindow("Hello SDL", 100, 100, 100, 100, 0);
+
     filename = GetResourceFilename(argc > 1 ? argv[1] : NULL, "sample.wav");

     if (!filename) {
@@ -166,6 +168,15 @@ int main(int argc, char *argv[])
                 (event.type == SDL_AUDIODEVICEREMOVED && !event.adevice.iscapture && event.adevice.which == device)) {
                 reopen_audio();
             }
+
+            if ((event.type == SDL_KEYDOWN) && (event.key.keysym.sym == SDLK_SPACE)) {
+                if (SDL_GetAudioDeviceStatus(device) == SDL_AUDIO_PAUSED) {
+                    SDL_PauseAudioDevice(device, 0);
+                } else {
+                    SDL_PauseAudioDevice(device, 1);
+                    wave.soundpos = 0;  /* reset to start */
+                }
+            }
         }
         SDL_Delay(100);
     }

So the app starts and you can press the spacebar to pause/unpause. After pausing, it resets the position of the .wav file it's playing to the beginning, so we can hear clearly if an old buffer is still pending. It works.

Granted, this on macOS, not iOS, so it uses the same audio code but it's possible something else is different, but it seems unlikely.

My current assumption is that the app is holding a buffer after pausing and sending it on to SDL, incorrectly, the next time the callback runs after unpausing. If your app has source code available, I can take a look to see if I can debug this further, but at this moment, I don't think there's a further issue in SDL itself.

(Closing this issue, but we can reopen it if necessary!)

@icculus icculus closed this as completed Nov 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants