XAudio2 delayed sound - when playing multiple voices - c++

I am using XAudio2 to play sounds in my game. I have about 16 source voices out of which 3 are looping effects which need to be played just like a background music. I have another background music which starts playing at regular intervals(once completed it waits for 1 minute and restarts). Whenever another effect has to be played like button click, gun shot etc, I search for an available source and attach the buffer to it and starts playing.
My problem is once the background music has started playing, just the looping effects will get played and other effects which need to be played on game actions(such as button click) do not get played. And all of these delayed effects get played once the background music is stopped. Also if I use one looping effect(instead of 3) all these get played in the right order.
I am using a submix voice for effects and background music is submitted directly to the mastering voice.
Can someone please help me as I am stuck here

Whenever one intends to play different sounds in the same time, he or she should make sure that these sounds are not in a queue, displayed in a sequential order, but they are displayed using different threads.
In Milsim's case the problem was exactly this, apparently, he used tasks to display the sounds, but they were not issued in different threads. He solved his problem using IAsyncAction.

Related

Do not show Desktop between 2 videos

I´m working with OMXPlayer on Raspberry.
Right now I have a loop(with Python2.7) to show videos and it works correctly.
But I have two problems:
1. When one video is finished, the Desktop will be shown for one second. And I don't want it. How can I change quickly to another video without showing the Desktop?
2. Another problem is that I wanna show some pictures too.. I know that OMXPlayer does not show images... Can I use another program in my code? But the user should not notice the change.
Thanks.
I was trying to figure this out too but I'm afraid it's not possible. It seams to me that omxplayer is only able to play a single video at a time and to play another video you have to run a new instance of the program. It takes a while to initialize, hence the gap between the videos.
That said, I figured a nasty way to get around it. When playing a video, you can extract it's last frame into a PNG file with ffmpeg. Then, you can play the video with omxplayer and use whatever graphical tools you have to display the picture fullscreen in the background. When the video ends, it disappears but the picture stays there and since it's the last frame of the video, it appears to just freeze at the end for a second, before the next video starts. Then, you just repeat the process. Hope it helps.

Force QMediaPlayer to update position accurately for video scrubbing application?

I am writing an application which will allow the user to scrub through an open video. Developing on Windows 7/8 with Qt 5.3, I have been using QMediaPlayer and QVideoWidget following the qvideowidget example project. The result has been pretty good, except that the QVideoWidget seems only to update during idle time. Still, it's a good start and it's usable.
However, when I build on Mac OS 10.10 (again with Qt 5.3), scrubbing behaves as though there were only one frame per second in the video. As I drag the "position" slider, the video jumps from one frame to the frame one second later, then one second after that, even though I am calling QMediaPlayer::setPosition several times with positions between those two frames.
The problem can be reproduced using the videowidget example that ships with Qt 5.3 here: Qt\Examples\Qt-5.3\multimediawidgets\videowidget. When the slider is dragged on a Windows machine, the QVideoWidget moves between frames that are spaced fairly close together. When the slider is dragged on a Mac (at least on mine), the QVideoWidget jumps between frames spaced about one second apart. No matter how long I wait for an "in between" frame to render, it won't happen unless I hit the "play" button.
I've tried calling QMediaPlayer::play() and QMediaPlayer::pause() one after the other to force an update, but this doesn't seem to work--QMediaPlayer works asynchronously, so the update doesn't have time to take effect.
If I check the value of QMediaPlayer::position, I find that it actually doesn't change between these jumps. It appears that when I call QMediaPlayer::setPosition, it is actually rounding the position to one second increments on a Mac and finer increments on a Windows machine.
Ideally, I would like to jump to a particular position in the video and render that frame immediately on the QVideoWidget. Is there any way to force QMediaPlayer to set the position accurately and update the associated QVideoWidget? Is there a better way to implement smooth scrubbing in a video?
Thanks for your help!
In case anyone else has a similar problem...
My best guess is that the issue stems from limitations in the codec used by QMediaPlayer, since this seems to be the main difference between the two platforms. Rather than deal with the codec issues directly, I looked around for other options.
MLT (http://www.mltframework.org/) seemed promising, but it is a major pain to compile and the primary author seems to have settled on offering SDK support to commercial users only.
libVLC (https://wiki.videolan.org/LibVLC/) looks a lot better. In particular, I’ve been using vlc-qt (https://github.com/ntadej/vlc-qt). The latter has an interface that will look quite familiar to users of QMediaPlayer and QVideoWidget. It was an easy replacement in my own application, and the result was much smoother video scrubbing on both Windows and Mac.
Hope this helps someone else!

OpenGL Window Overlay

What I need to do is create a program that overlays the whole screen and every 30 seconds the screen needs to flash black once.
the program just needs to be on top of everything, doesn't have to work over the top of games, but wouldn't say no if it did!
But i've got no idea where to start. Ideally the solution would be cross-platform for both windows and osx.
Does anybody have any ideas about where I should start or could whip up a quick demo?
OpenGL (you tagged it as such) will not help you with this.
Create a program, that overlays the whole screen,
The canonical way to do this is by creating a decorationless, borderless top level window with some stay-on-top property being set.
and every 30 seconds the screen needs to flash black once.
How do you define "flash back once"? You mean you want the display become visible for one single vertical retrace period or a given amount of time? Being the electronics tinkerer I am, honestly, I'd do this using a handfull of transistors, resistors and capacitors, blanking the analog VGA signal.
Anyway, if you want to do this using software, this is going to be hard work. If you'd do this using the aforementioned stay-on-top window, when you "flash" it away, all the programs with visible output would receive redraw events, which to process would take some time. In the best case scenario the system uses a compositing window manager which can practically immediately show the desktop. Without a compositor its going to be impossible to "flash" the screen.
Ideally the solution would be cross-platform for both windows and osx
A task like this can not be solved cross plattform. There's too much OS dependent work to do for this.
I presume this is for some kind of nerological or psychological experiment. I think doing this using some VGA intercepting circurity would be actually the easier, quicker to implement solution. I can help you with that. But I think there's another StackExchange better suited for this. Unfortunately digital display interfaces (DVI, HDMI and Display Port) use a complex line code scheme, which can not be blanked as easily as VGA, so you must have a computer capable of analog (=VGA) output and a display with a VGA input.

cocos2d-iphone games stop playing background music sometimes

cocos2d-iphone 1.0.1.
I have noticed this with other cocos2d-iphone games installed in my device, like Kingdom Rush.
Basically, most of the times, the audio is fine (almost always). But suddenly, at an unexpected moment, the background music stops playing and only the sound effects work. Sometimes, killing the application will not be enough to fix it.
With my cocos2d-iphone game this happens as well, with no hint in the console. I use SimpleAudioEngine to play background music and sound effects.
Killing my application, restarting Xcode will not fix it. I usually just ignore the problem and, in the near future, it is suddenly gone. I suspect that rebooting the device tends to fix this, but that's beyond the point: I should know why is it happening.
I also tried preloading my background music. Doesn't change a thing.
I believe I have experienced this problem with both .mp3 and .wav formats.
Why might this be happening?
No idea to the exact reason, but I can think of a few:
memory warning causes audio stream to be interrupted
audio interruptions (calendar notification, incoming SMS/call) not handled properly by CocosDenshion
other streaming music is played (ie perhaps videoplayer, iPod music player)
music isn't streamed but buffered, which means music is fighting over audio buffers with all other effects - eventually so many audio effects are played that older buffers have to cancel playback (which might be the music) in order to allow the new effect to play
defective device (since it happens in other apps …)
bug in CocosDenshion (check the cocos2d issue tracker and forum for any unresolved audio bugs)
I think you can exclude the latter if you're using the playBackgroundMusic API to stream music instead of buffering it.

Large number of Sound Effects with SimpleAudioEngine

Background:
My background music is being played as a sound effect because I want to change the pitch between each repetition of the tune.
The Issue:
While the background music is playing there's a lot of other short sound effects happening. After a certain number of sound effects play, my background music (also a sound effect) cuts out. The queue seems to cycle so that after say 50 sound effects have played, when the 51st plays, the 1st will be released whether it has completed or not.
Request for direction:
There are two directions I can see possibly going with this issue.
1. Not play the background music as an effect and figure out how to change the pitch as background music instead of an effect
2. Some how make sure that the effect will be retained until it has completed.
Thanks
The SimpleAudioEngine doesn't allow you to control channels, so it'll just play your sound effects in one of the channels it has allocated internally. Eventually all channels are playing audio. In that case, when a new audio file is to be played and all channels are already playing, SimpleAudioEngine will cancel one of the existing audio files. On occasion this will be your background music. Dang.
What you normally do to fix this is to assign (allocate) one audio channel specifically for the background music. No other audio will ever attempt to play audio on that channel. You will have to use the "regular" CocosDenshion API. It looks like you either need to use CDAudioManager or CDSoundEngine, but I have no experience with using channels with CocosDenshion.
Personally I never used CocosDenshion, whenever I needed more control I found the ObjectAL API to be easier to understand and it has excellent documentation. I made the following helper function for ObjectAL that plays a sound on a particular channel. I simply instantiated a ALChannelSource for my background music, and only played background music through that channel. The returned ALSoundSource even allows you to change pitch, pan, etc. while the audio is playing.
+(id<ALSoundSource>) playEffect:(NSString*)effect channel:(ALChannelSource*)channel loop:(bool)loop
{
id<ALSoundSource> soundSource = nil;
if (channel)
{
ALBuffer* buffer = [[OALAudioSupport sharedInstance] bufferFromFile:effect];
soundSource = [channel play:buffer loop:loop];
}
return soundSource;
}
All other audio files I'm playing through the OALSimpleAudio class.