How to use the playsound function multiple times? - c++

PlaySound works perfectly fine if i need a single beep. The following illustrates my code snippet:
PlaySound(TEXT("C:\\Test1.wav"), NULL, SND_ASYNC);
My question is, how to use this function twice or more than twice, since it plays only once regardless of the amount of repetition I put together. I have also tried this:
PlaySound(TEXT("C:\\Test1.wav"), NULL,SND_FILENAME|SND_LOOP|SND_ASYNC);
which plays the beep in a continuous loop. How to play this twice or thrice etc.?
Using a loop doesn't help either.

You have two options with that API. Either play synchronous, or asynchronous.
If you play synchronous, then your thread will block until the sound has finished playing. You can put it in a loop and call it as many times as you like, but then your thread will block whilst the sound is being played.
If you play asynchronous, then your thread will not block but you don't have any reliable way of controlling the number of repetitions.
I see two solutions for you: either create a new sound from the original, with the correct number of repeats added and play that once, or create a background thread to play the sound the specified number of times - in this background thread you can safely use the synchronous play method as described above.

The problem is the SND_ASYNC flag. It says that you want this call to return immediately and play the sound in background.
If you do this in a loop, since it will return with the sound still playing, it will overlap with the next call and do nothing, because IIRC, an application can only do one call to PlaySound at the same time.
The solution is to replace SND_ASYNC with SND_SYNC (or remove it, since it is the default). If you need the call to be asynchronous, you can create a thread and equeue the sounds you want to play. The thread will play synchronously, but your other threads won't notice.

Related

mciSendString doesn't pause sound played from a thread

Recently I already asked for a solution similar to this questions:
Is there a way to pause/stop a mp3 file playing with mcisendstring with the "wait" option?
I want to implement a function in my audio player which allows people to have sound playing continuosly, while a slider moves according to the current second the track is running in, and also with the functionality to go to the next track after the current track is over
After (as you can read in the link) trying to do it with
mciSendString("play mp3 wait", NULL, 0, NULL);
which failed due to the problem that the track can't be paused or stopped until it is finished, I am now trying to implement it another way. Currently, when I start to play the track, I also start another thread, which is starting a counter. The counter is getting the length of the track in seconds, and is counting down the time, also offering a mutex for pausing/resuming the counter. In order to stop my MusicCycle from simply looping uncontrolled, I am joining the thread, therefore waiting for its termination.
void Music::MusicCycle(std::wstring trackPath)
{
while (true)
{
OpenMP3(trackPath);
mciSendString("play mp3", NULL, 0, NULL);
m_counterThread = boost::thread(boost::bind(&Counter::StartCount, m_counter, <length of track in seconds>));
m_counterThread.join();
//... Get new track here
}
}
Note that this whole method is created in a thread as well:
m_cycleThread = boost::thread(boost::bind(&Music::MusicCycle, this, trackPath));
The thread started by the MusicCycle function is looking like this:
void Counter::StartCount(int seconds)
{
boost::mutex::scoped_lock lock(m_mutex);
for (int i = 0; i < seconds; i++)
{
while (m_counterLock)
{
m_condVar.wait(lock);
}
boost::this_thread::sleep(boost::posix_time::seconds(1));
}
}
Also, I added another functionality to lock/unlock the mutex here with my Pause/Resume methods, which also call the corresponding mciSendString functions
mciSendString("resume mp3", NULL, 0, NULL);
mciSendString("pause mp3", NULL, 0, NULL);
When I would call pause now, mciSendString would pause the track, and also lock the counter so it won't keep on counting down.
However, the problem is that it still doesn't work. The pause simply doesn't affect the playing of music, despite my efforts to think up a solution without using the wait option in the mciSendString
Any advice?
EDIT: Turns out this is actually happening due to threading. I've been doing some C# for a good amount of time and you could use Invokes to work around thread problems. Maybe this is possible here as well?
EDIT2: I read up a bit and it seems like there is an option to Post a method in the message queue of another thread via PostMessage WinAPI call. Is this a possiblity here? If yes, could anyone provide a good example? I read up a bit but I don't really understand alot so far
Is there something like this in C++ as well?
EDIT: Turns out this is actually happening due to threading. I've been doing some C# for a good amount of time and you could use Invokes to work around thread problems.
Yes. Ifff you need a user-land thread for the asynchronous events then a queued message is your course of action (like C#'s (or Java's etc.) invoke-on-UI-thread). That's hard work.
EDIT2: I read up a bit and it seems like there is an option to Post a method in the message queue of another thread via PostMessage WinAPI call. Is this a possiblity here? If yes, could anyone provide a good example? I read up a bit but I don't really understand alot so far
Is there something like this in C++ as well?
What you're referring to is just the general message-pump/event-loop that underlies almost¹ all UI frameworks. C++ doesn't "have" GUI natively, but certainly libraries exist that have similar facilities.
Boost Asio was one mentionable. If you already have a GUI framework, it'll have it's own event loop (Qt, MFC etc. have it).
Regardless of what is used, all Win32 GUI applications end up using the message pump you referred to which does indeed allow messages to be posted.
This is almost always the wrong level of abstraction, unless you're actively developing your GUI framework².
You can always build your own. Just have some kind of (priority) queue to receive messages and have a main loop processing these. Call them events and pronto: event-driven design.
¹ there's a wave back at the moment with new-fangled back-to-basics like https://github.com/ocornut/imgui
² the fact that this question exists tells me you are not doing that

C++ - Execute function every X milliseconds

I can't seem to find a good answer to this:
I'm making a game, and I want the logic loop to be separate from the graphics loop. In other words I want the game to go through a loop every X milliseconds regardless of how many frames/second it is displaying.
Obviously they will both be sharing a lot of variables, so I can't have a thread/timer passing one variable back and forth... I'm basically just looking for a way to have a timer in the background that every X milliseconds sends out a flag to execute the logic loop, regardless of where the graphics loop is.
I'm open to any suggestions. It seems like the best option is to have 2 threads, but I'm not sure what the best way to communicate between them is, without constantly synchronizing large amounts of data.
You can very well do multithreading by having your "world view" exchanged every tick. So here is how it works:
Your current world view is pointed to by a single smart pointer and is read only, so no locking is necessary.
Your logic creates your (first) world view, publishes it and schedules the renderer.
Your renderer grabs a copy of the pointer to your world view and renders it (remember, read-only)
In the meantime, your logic creates a new, slightly different world view.
When it's done it exchanges the pointer to the current world view, publishing it as the current one.
Even if the renderer is still busy with the old world view there is no locking necessary.
Eventually the renderer finishes rendering the (old) world. It grabs the new world view and starts another run.
In the meantime, ... (goto step 4)
The only locking you need is for the time when you publish or grab the pointer to the world. As an alternative you can do atomic exchange but then you have to make sure you use smart pointers that can do that.
Most toolkits have an event loop (built above some multiplexing syscall like poll(2) -or the obsolete select-...), e.g. GTK has g_application_run (which is above:) gtk_main which is built above Glib main event loop (which in fact does a poll or something similar). Likewise, Qt has QApplication and its exec methods.
Very often, you can register timers within the event loop. For GTK, use GTimers, g_timeout_add etc. For Qt learn about its timers.
Very often, you can also register some idle or background processing, which is one of your function which is started by the event loop after other events and timeouts have been processed. Your idle function is expected to run quickly (usually it does a small step of some computation in a few milliseconds, to keep the GUI responsive). For GTK, use g_idle_add etc. IIRC, in Qt you can use a timer with a 0 delay.
So you could code even a (conceptually) single threaded application, using timeouts and idle processing.
Of course, you could use multi-threading: generally the main thread is running the event loop, and other threads can do other things. You have synchronization issues. On POSIX systems, a nice synchronization trick could be to use a pipe(7) to self: you set up a pipe before running the event loop, and your computation threads may write a few bytes on it, while the main event loop is "listening" on it (with GTK, using g_source_add_poll or async IO or GUnixInputStream etc.., with Qt, using QSocketNotifier etc....). Then, in the input handler running in the main loop for that pipe, you could access traditional global data with mutexes etc...
Conceptually, read about continuations. It is a relevant notion.
You could have a Draw and Update Method attached to all your game components. That way you can set it that while your game is running the update is called and the draw is ignored or any combination of the two. It also has the benefit of keeping logic and graphics completely separate.
Couldn't you just have a draw method for each object that needs to be drawn and make them globals. Then just run your rendering thread with a sleep delay in it. As long as your rendering thread doesn't write any information to the globals you should be fine. Look up sfml to see an example of it in action.
If you are running on a unix system you could use usleep() however that is not available on windows so you might want to look here for alternatives.

SDL_PollEvent vs SDL_WaitEvent

So I was reading this article which contains 'Tips and Advice for Multithreaded Programming in SDL' - https://vilimpoc.org/research/portmonitorg/sdl-tips-and-tricks.html
It talks about SDL_PollEvent being inefficient as it can cause excessive CPU usage and so recommends using SDL_WaitEvent instead.
It shows an example of both loops but I can't see how this would work with a game loop. Is it the case that SDL_WaitEvent should only be used by things which don't require constant updates ie if you had a game running you would perform game logic each frame.
The only things I can think it could be used for are programs like a paint program where there is only action required on user input.
Am I correct in thinking I should continue to use SDL_PollEvent for generic game programming?
If your game only updates/repaints on user input, then you could use SDL_WaitEvent. However, most games have animation/physics going on even when there is no user input. So I think SDL_PollEvent would be best for most games.
One case in which SDL_WaitEvent might be useful is if you have it in one thread and your animation/logic on another thread. That way even if SDL_WaitEvent waits for a long time, your game will continue painting/updating. (EDIT: This may not actually work. See Henrik's comment below)
As for SDL_PollEvent using 100% CPU as the article indicated, you could mitigate that by adding a sleep in your loop when you detect that your game is running more than the required frames-per-second.
If you don't need sub-frame precision in your input, and your game is constantly animating, then SDL_PollEvent is appropriate.
Sub-frame precision can be important for, eg. games where the player might want very small increments in movement - quickly tapping and releasing a key has unpredictable behavior if you use the classic lazy method of keydown to mean "velocity = 1" and keyup to mean "velocity = 0" and then you only update position once per frame. If your tap happens to overlap with the frame render then you get one frame-duration of movement, if it does not you get no movement, where what you really want is an amount of movement smaller than the length of a frame based on the timestamps at which the events occurred.
Unfortunately SDL's events don't include the actual event timestamps from the operating system, only the timestamp of the PumpEvents call, and WaitEvent effectively polls at 10ms intervals, so even with WaitEvent running in a separate thread, the most precision you'll get is 10ms (you could maybe approximate smaller by saying if you get a keydown and keyup in the same poll cycle then it's ~5ms).
So if you really want precision timing on your input, you might actually need to write your own version of SDL_WaitEventTimeout with a smaller SDL_Delay, and run that in a separate thread from your main game loop.
Further unfortunately, SDL_PumpEvents must be run on the thread that initialized the video subsystem (per https://wiki.libsdl.org/SDL_PumpEvents ), so the whole idea of running your input loop on another thread to get sub-frame timing is nixed by the SDL framework.
In conclusion, for SDL applications with animation there is no reason to use anything other than SDL_PollEvents. The best you can do for sub-framerate input precision is, if you have time to burn between frames, you have the option of being precise during that time, but then you'll get weird render-duration windows each frame where your input loses precision, so you end up with a different kind of inconsistency.
In general, you should use SDL_WaitEvent rather than SDL_PollEvent to release the CPU to the operating system to handle other tasks, like processing user input. This will manifest to you users as sluggish reaction to user input, since this can cause a delay between when they enter a command and when your application processes the event. By using SDL_WaitEvent instead, the OS can post events to your application more quickly, which improves the perceived performance.
As a side benefit, users on battery powered systems, like laptops and portable devices should see slightly less battery usage since the OS has the opportunity to reduce overall CPU usage since your game isn't using it 100% of the time - it would only be using it when an event actually occurs.
This is a very late response, I know. But this is the thread that tops a Google search on this, so it seems the place to add an alternative suggestion to dealing with this that some might find useful.
You could write your code using SDL_WaitEvent, so that, when your application is not actively animating anything, it'll block and hand the CPU back to the OS.
But then you can send a user-defined message to the queue, from another thread (e.g. the game logic thread), to wake up the main rendering thread with that message. And then it goes through the loop to render a frame, swap and returns back to SDL_WaitEvent again. Where another of these user-defined messages can be waiting to be picked up, to tell it to loop once more.
This sort of structure might be good for an application (or game) where there's a "burst" of animation, but otherwise it's best for it to block and go idle (and save battery on laptops).
For example, a GUI where it animates when you open or close or move windows or hover over buttons, but it's otherwise static content most of the time.
(Or, for a game, though it's animating all the time in-game, it might not need to do that for the pause screen or the game menus. So, you could send the "SDL_ANIMATEEVENT" user-defined message during gameplay, but then, in the game menus and pause screen, just wait for mouse / keyboard events and actually allow the CPU to idle and cool down.)
Indeed, you could have self-triggering animation events. In that the rendering thread is woken up by a "SDL_ANIMATEEVENT" and then one more frame of animation is done. But because the animation is not complete, the rendering thread itself posts a "SDL_ANIMATEEVENT" to its own queue, that'll trigger it to wake up again, when it reaches SDL_WaitEvent.
And another idea there is that SDL events can carry data too. So you could supply, say, an animation ID in "data1" and a "current frame" counter in "data2" with the event. So that when the thread picks up the "SDL_ANIMATEEVENT", the event itself tells it which animation to do and what frame we're currently on.
This is a "best of both worlds" solution, I feel. It can behave like SDL_WaitEvent or SDL_PollEvent at the application's discretion by just sending messages to itself.
For a game, this might not be worth it, as you're updating frames constantly, so there's no big advantage to this and maybe it's not worth bothering with (though even games could benefit from going to 0% CPU usage in the pause screen or in-game menus, to let the CPU cool down and use less laptop battery).
But for something like a GUI - which has more "burst-y" animation - then a mouse event can trigger an animation (e.g. opening a new window, which zooms or slides into view) that sends "SDL_ANIMATEEVENT" back to the queue. And it keeps doing that until the animation is complete, then falls back to normal SDL_WaitEvent behaviour again.
It's an idea that might fit what some people need, so I thought I'd float it here for general consumption.
You could actually initialise the SDL and the window in the main thread and then create 2 more threads for updates(Just updates game states and variables as time passes) and rendering(renders the surfaces accordingly).
Then after all that is done, use SDL_WaitEvent in your main thread to manage SDL_Events. This way you could ensure that event is managed in the same thread that called the sdl_init.
I have been using this method for long to make my games work in windows and linux and have been able to successfully run 3 threads at the same time as mentioned above.
I had to use mutex to make sure that textures/surfaces can be transformed/changed in the update thread as well by pausing the render thread, and the lock is called every once 60 frames, so its not going to cause major perf issues.
This model works best to create event driven games, run time games, or both.

Some questions on Multithreading and Background worker threads in windows form

I have encountered the need to use multithreading in my windows form GUI application using C++. From my research on the topic it seems background worker threads are the way to go for my purposes. According to example code I have
System::Void backgroundWorker1_DoWork(System::Object^ sender, System::ComponentModel::DoWorkEventArgs^ e)
{
BackgroundWorker^ worker = dynamic_cast<BackgroundWorker^>(sender);
e->Result = SomeCPUHungryFunction( safe_cast<Int32>(e->Argument), worker, e );
}
However there are a few things I need to get straight and figure out
Will a background worker thread make my multithreading life easier?
Why do I need e->Result?
What are the arguments passed into the backgroundWorker1_DoWork function for?
What is the purpose of the parameter safe_cast(e->Argument)?
What things should I do in my CPUHungryFunction()?
What if my CPUHungryFunction() has a while loop that loops indefinitely?
Do I have control over the processor time my worker thread gets?
Can more specifically control the number of times the loop loops within a set period? I don’t want to be using up cpu looping 1000s of times a second when I only need to loop 30 times a second.
*Is it necessary to control the rate at which the GUI is updated?
Will a background worker thread make my multithreading life easier?
Yes, very much so. It helps you deal with the fact that you cannot update the UI from a worker thread. Particularly the ProgressChanged event lets you show progress and the RunWorkerCompleted event lets you use the results of the worker thread to update the UI without you having to deal with the cross-threading problem.
Why do I need e->Result?
To pass back the result of the work you did to the UI thread. You get the value back in your RunWorkerCompleted event handler, e->Result property. From which you then update the UI with the result.
What are the arguments passed into the function for?
To tell the worker thread what to do, it is optional. Otherwise identical to passing arguments to any method, just more awkward since you don't get to chose the arguments. You typically pass some kind of value from your UI for example, use a little helper class if you need to pass more than one. Always favor this over trying to obtain UI values in the worker, that's very troublesome.
What things should I do in my CPUHungryFunction()?
Burn CPU cycles of course. Or in general do something that takes a long time, like a dbase query. Which doesn't burn CPU cycles but takes too long to allow the UI thread to go dead while waiting for the result. Roughly, whenever you need to do something that takes more than a second then you should execute it on a worker thread instead of the UI thread.
What if my CPUHungryFunction() has a while loop that loops indefinitely?
Then your worker never completes and never produces a result. This may be useful but it isn't common. You would not typically use a BGW for this, just a regular Thread that has its IsBackground property set to true.
Do I have control over the processor time my worker thread gets?
You have some by artificially slowing it down by calling Thread.Sleep(). This is not a common thing to do, the point of starting a worker thread is to do work. A thread that sleeps is using an expensive resource in a non-productive way.
Can more specifically control the number of times the loop loops within a set period? I don’t want to be using up cpu looping 1000s of times a second when I only need to loop 30 times a second.
Same as above, you'd have to sleep. Do so by executing the loop 30 times and then sleep for a second.
Is it necessary to control the rate at which the GUI is updated?
Yes, that's very important. ReportProgress() can be a fire-hose, generating many thousands of UI updates per second. You can easily get into a problem with this when the UI thread just can't keep up with that rate. You'll notice, the UI thread stops taking care of its regular duties, like painting the UI and responding to input. Because it keeps having to deal with another invoke request to run the ProgressChanged event handler. The side-effect is that the UI looks frozen, you've got the exact problem back you were trying to solve with a worker. It isn't actually frozen, it just looks that way, it is still running the event handler. But your user won't see the difference.
The one thing to keep in mind is that ReportProgress() only needs to keep human eyes happy. Which cannot see updates that happen more frequently than 20 times per second. Beyond that, it just turns into an unreadable blur. So don't waste time on UI updates that just are not useful anyway. You'll automatically also avoid the fire-hose problem. Tuning the update rate is something you have to program, it isn't built into BGW.
I will try to answer you question by question
Yes
DoWork is a void method (and need to be so). Also DoWork executes
in a different thread from the calling one, so you need to have a
way to return something to the calling thread. The e->Result
parameter will be passed to the RunWorkerCompleted event inside
the RunWorkerCompletedEventArgs
The sender argument is the backgroundworker itself that you can use
to raise events for the UI thread, the DoWorkEventArgs eventually
contains parameters passed from the calling thread (the one who has
called RunWorkerAsync(Object))
Whatever you have need to do. Paying attention to the userinterface
elements that are not accessible from the DoWork thread. Usually, one
calculate the percentage of work done and update the UI (a progress
bar or something alike) and call ReportProgress to communicate with
the UI thread. (Need to have WorkerReportProgress property set to
True)
Nothing runs indefinitely. You can always unplug the cord.
Seriously, it is just another thread, the OS takes care of it and
destroys everything when your app ends.
Not sure what do you mean with this, but it is probably related
to the next question
You can use the Thread.Sleep or Thread.Join methods to release the
CPU time after one loop. The exact timing to sleep should be fine
tuned depending on what you are doing, the workload of the current
system and the raw speed of your processor
Please refer to MSDN docs on BackgroundWorker and Thread classes

How to play sound at the same time as the program?

I want to play sound while the program is running in c++. I am using the code:
void fighterplanesound()
{PlaySound(TEXT("bombdrop.wav"), NULL, SND_FILENAME|SND_ASYNC);}
I thought the SND_ASYNC flag would fix this problem but it did not. What is happening is the program will pause or control will not move on until the sound is done playing. How can I play the sound while the program continues to run. To clarify, the program is a Windows console program that operates in an MS-DOS window.
How about playing the sound in a different thread?
Ok. What I figured out was that you can't include the PlaySound method in the function because even though the ASYNC flag was there, control had to fully execute the PlaySound method before returning, so don't put it in the function unless there is more code in the function(in which case the sound will play while that code is executing) or in other words, control will not return from the function until PlaySound is finished executing and because there is no other code in the function to execute, control waits until PlaySound method is finished and then moves on.
Actually i had the same problem on my iOS app. You know the time that how long does it take to play your .wav file. You can create a Timer that calls your fighterplanesound() method each period of ending time of your file. Not the best solution but it works for me.