m_audioEngine->CreateMasteringVoice(
&m_masteringVoice,
XAUDIO2_DEFAULT_CHANNELS,
sampleRate,
0,
NULL
)
);
m_audioEngine->CreateSourceVoice(
&implData->sourceVoice,
format,
0,
XAUDIO2_DEFAULT_FREQ_RATIO,
reinterpret_cast<IXAudio2VoiceCallback*>(&implData->callbackHander),
nullptr,
nullptr
)
);
One of the above code when I have my earphones in seems to always run fine.
If I start my game without earphones in, sometimes (not always) the above function fails. It always throws the same HRESULT: 0x88890017
any ideas?
If I put a breakpoint directly after this, it seems to not throw an error... Does this task run asynchronously?
EDIT---------------------------------
My IXAudio2SourceVoice keeps getting lost randomly
what can cause that to lose itself?
this is why my program crashes...
it only loses itself when earphones are not plugged in (when creating XAudio2 objects)
What does it mean?
This error code is known as "*AUDCLNT_E_CPUUSAGE_EXCEEDED*" and occurs when the audio engine is taking too long to process audio packets. This typically occurs when the CPU-usage of the audio engine exceeds a certain treshold. The audio engine will fail creating new streams if its CPU-usage exceeds this threshold.
Resolving: The User
CPU-usage is subject to various things, like the processing power of your CPU, like the number of channels you're using and like the audio device enhancements you have enabled on a system level. Some possible solutions are to ensure a decent CPU (check the minimum system requirements specification), in the application/game-settings lower the amount of channels in use, or to disable some system-level audio device enhancements in your operating system. For the latter check your task manager for CPU-usage, and if one of the suspicious processes is "audiodg.exe", go into the Sound control panel, double-click each of your playback devices in turn, go to the Enhancements tab, and check the "disable all enhancements" box. This should lower the required CPU-usage and solve your problem.
Resolving: The Coder
Keep in mind that the more your audio code is doing, the more CPU-cycles it will require. If you have an IXAudio2 device created with a ton of effect processors in the chain, 1000 SubmixVoices and hundreds of SourceVoices, that's like asking for trouble. Before you point your fingers to the CPU or to the system-level audio device enhancements, do ensure that it isn't just your code being inefficient.
Your big friend here is IXAudio2::GetPerformanceData, which will query the device and fill in a XAUDIO2_PERFORMANCE_DATA-structure for you. This gives you some information about the CPU-cycles used. Chances are good you can intercept this error before it actually occurs. When you detect a heavy CPU-usage, or when the error actually occurs, it's not necessarily a reason to have things fail in your game/engine/framework. You could retry. Or you could adjust the number of SubmixVoices. Or you could choose to not create a SourceVoice. Or you could temporarily suspend audio/switch to a null-device, and inform the user about all of this.
You could setup an event or callback to inform the user of heavy CPU-usage in the audio engine. This enables the application to inform the user of this heavy CPU-usage, and inform the user to lower the amount of channels in the settings (alternatively you can have your application adjust things automatically) or to turn off some system-level audio device enhancements.
Related
I am trying to write an application in C++ which lists Information obtained from a USB device. I am following USBView (Github) utility's code for it.
When device is in D0 power state (fully powered), I am able to get string descriptors, but when device goes to a low power state (D2), I am not.
The IOCTL IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION returns with the error "A device attached to the system is not functioning." USBView utility shows that string descriptors are not available when device is in a low power state.
This behaviour is odd, and nowhere in the USB spec did I find reference to it.
I have checked with 2 devices, and I get the same behaviour. I am able to get other descriptors such as Device Descriptor, BOS Descriptor, etc. even in D2 state.
Is there a way to get string descriptors when USB device is in low power state?
If not, is there a way to momentarily turn it to D0 power state?
Probably ACPI is the answer, but it is a very low level API which I am finding overwhelming to understand. Does Windows provide any high level API to set power states?
The USB 2.0 specification defines suspend mode, a state where there is no traffic on the bus and devices go to sleep to save power. Since there is no traffic, you cannot request string descriptors from a device in suspend mode. You'd have to wake it up with special signalling before you can do that.
The only thing I can think of that might help you is disabling the "USB selective suspend setting", a feature of Windows that generally puts devices into suspend mode when they are not being used. It's pretty deep in the power settings part of the Control Panel so let me know if you have trouble finding it.
It seems to me that you ought to be able to wake the device up even if it is in selective suspend so that you can get information from it, but I am not sure exactly how to do that and it probably depends on what drivers your device uses.
Is there a way to trigger the USB Device Discovery of Windows, such that removed devices are detected faster?
I have a USB Serial modem that I unplug (the USB plug, not the serial one). I want to detect the DBT_DEVICEREMOVECOMPLETE event which is sent as soon as the unplugging is detected (That's what I assume). The detection of the Event works as desired, it is sent sometimes 1s after removal, sometimes several minutes after removal.
Is there a way to decrease the refresh interval, or another way to make this event getting sent faster?
Well, the problem here is that DBT_DEVICEREMOVECOMPLETE is sent after Windows decides it has detected the removal, and you can't influence that, at least not in the general case. There are various things that make Windows do this faster or slower (type of device, current "data flow" with the device, the device itself), and it also varies between OS versions. What I found helps to some degree in some of cases is to remove, from the Registry, references to USB devices that were plugged into that USB port before (there are various utilities for this).
At the extreme, since this is a Windows Broadcast message (non-queued), there will not be another one sent in until the previous is processed. Thus, you may not receive it at all! To solve that, keep message handling fast and simple and don't set a breakpoint there while debugging.
Also, having a separate Windows and Thread for the specific purpose of handling USB device arrival/removal notifications may help.
But, from my experience, polling will not help, as the main problems seems to be in the criteria Windows uses to detect the removal. The time from that event until you receive the message is small. Of course, in your case this may not be true - to find out, use a tool like SysInternals Process Monitor. Depending on what you see going on there, there may be something you can do to make it faster.
Windows Embedded Compact 7.
Is there a way to test interrupt latency time from user space?
Are there any tools provided as part of platform builder?
I also saw a program called Intrtime.exe - but no examples on how to use it.
How does one test the interrupt latency time?
Reference for Intrtime.exe but how do I implement it?
http://www.ece.ufrgs.br/~cpereira/temporeal_pos/www/WindowsCE2RT.htm
EDIT
Also found:
ILTiming.exe Real-Time Measurement Tool (Compact 2013)
http://msdn.microsoft.com/en-us/library/ee483144.aspx
This really is a test that requires hardware, and there are a couple "latencies" you might measure. Once is the time from the interrupt signal to when the driver ISR reacts and the second is from when the interrupt occurs to when an IST reacts.
I did this back in the CE 3.0/CE 4.0 days by attaching a signal generator to an interruptable input an then having an ISR pulse a second input and an IST pulse a third input when they received the interrupt. I hooked a scope up to the input and outputs and used it to measure time between the input signal and output signals to get not just latency, but also jitter. You could easily add a 4th line for CE 7 so you could check an IST in user space and an IST in kernel space. I'd definitely be interested to see the results.
I don't think you can effectively measure this with software running on the platform, as you get into the problem of the code trying to do the measurement affecting the results. You're also talking time way, way below the system tick resolution so the scheduler is going to be problematic as well. CeLog might be able to get you an idea on these times, but getting it set up and running is probably more work than just hooking up a scope.
What is usually meant by interrupt latency is the time between an interrupt source asserting the interrupt line and a thread (sometimes in user-space) being scheduled and then executing as a result.
Unless your CPU has some accurate way of time-stamping interrupt events as they arrive at the CPU (rather than when an ISR runs), the only truly accurate measurement is one done externally - by measuring the time between a the interrupt line being asserted and some observable signal that the thread responding to the interrupt can control. A DSO or logic analyser is usually used for this purpose.
Software techniques usually rely on storing an accurate time-stamp at the earliest opportunity in an ISR. If you're certain the time between interrupt line becoming asserted and the ISR running is negligible, this might be valid. If, on the other hand, disabling of interrupts is being used to control concurrency, or interrupts are nested, you probably want to be measuring this as well.
In my current project, I have two levels of tasking, in a VxWorks system, a higher priority (100) task for number crunching and other work and then a lower priority (200) task for background data logging to on-board flash memory. Logging is done using the fwrite() call, to a file stored on a TFFS file system. The high priority task runs at a periodic rate and then sleeps to allow background logging to be done.
My expectation was that the background logging task would run when the high priority task sleeps and be preempted as soon as the high priority task wakes.
What appears to be happening is a significant delay in suspending the background logging task once the high priority task is ready to run again, when there is sufficient data to keep the logging task continuously occupied.
What could delay the pre-emption of a lower priority task under VxWorks 6.8 on a Power PC architecture?
You didn't quantify significant, so the following is just speculation...
You mention writing to flash. One of the issue is that writing to flash typically requires the driver to poll the status of the hardware to make sure the operation completes successfully.
It is possible that during certain operations, the file system temporarily disables preemption to insure that no corruption occurs - coupled with having to wait for hardware to complete, this might account for the delay.
If you have access to the System Viewer tool, that would go a long way towards identifying the cause of the delay.
I second the suggestion of using the System Viewer, It'll show all the tasks involved in TFFS stack and you may be surprised how many layers there are. If you're making an fwrite with a large block of data, the flash access may be large (and slow as Benoit said). You may try a bunch of smaller fwrites. I suggest doing a test to see how long fwrites() take for various sizes, and you may see differences from test to test with the same sizea as you cross flash block boundaries.
I am writing to USB disk from a lowest priority thread, using chunked buffer writing and still, from time to time the system in overall lags on this operation. If I disable writing to disk only, everything works fine. I can't use Windows file operations API calls, only C write. So I thought maybe there is a WinAPI function to turn on/off USB disk write caching which I could use in conjunction with FlushBuffers or similar alternatives? The number of drives for operations is undefined.
Ideally I would like to never be lagging using write call and the caching, if it will be performed transparently is ok too.
EDIT: would _O_SEQUENTIAL flag on write only operations be of any use here?
Try to reduce I/O priority for the thread.
See this article: http://msdn.microsoft.com/en-us/library/windows/desktop/ms686277(v=vs.85).aspx
In particular use THREAD_MODE_BACKGROUND_BEGIN for your IO thread.
Warning: this doesn't work in Windows XP
The thread priority won't affect the delay that happens in the process of writing the media, because it's done in the kernel mode by the file system/disk drivers that don't pay attention to the priority of the calling thread.
You might try to use "T" flag (_O_SHORTLIVED) and flush the buffers at the end of the operation, also try to decrease the buffer size.
There are different types of data transfer for USB, for data there are 3:
1.Bulk Transfer,
2.Isochronous Transfer, and
3.Interrupt Transfer.
Bulk Transfers Provides:
Used to transfer large bursty data.
Error detection via CRC, with guarantee of delivery.
No guarantee of bandwidth or minimum latency.
Stream Pipe - Unidirectional
Full & high speed modes only.
Bulk transfer is good for data that does not require delivery in a guaranteed amount of time The USB host controller gives a lower priority to bulk transfer than the other types of transfer.
Isochronous Transfers Provides:
Guaranteed access to USB bandwidth.
Bounded latency.
Stream Pipe - Unidirectional
Error detection via CRC, but no retry or guarantee of delivery.
Full & high speed modes only.
No data toggling.
Isochronous transfers occur continuously and periodically. They typically contain time sensitive information, such as an audio or video stream. If there were a delay or retry of data in an audio stream, then you would expect some erratic audio containing glitches. The beat may no longer be in sync. However if a packet or frame was dropped every now and again, it is less likely to be noticed by the listener.
Interrupt Transfers Provides:
Guaranteed Latency
Stream Pipe - Unidirectional
Error detection and next period retry.
Interrupt transfers are typically non-periodic, small device "initiated" communication requiring bounded latency. An Interrupt request is queued by the device until the host polls the USB device asking for data.
From the above, it seems that you want a Guaranteed Latency, so you should use Isochronous mode. There are some libraries that you can use like libusb, or you can read more in msdn
To find out what is letting your system hang you first need to drill down to the Windows hang. What was Windows doing while you did experience the hang?
To find this out you can take a kernel dump. How to get and analyze a Kernel Dump read here.
Depending on the findings you get there you then need to decide if there is anything under your control you can do about. Since you are using a third party library to to the writing there is little you can do except to set the IO priority, thread priority on thread or process level. If the library you were given links against a specific CRT you could try to build your own customized version of it to e.g. flush after every write to prevent write combining by the OS to write only data in big chunks back to disc.
Edit1
Your best bet would be to flush the device after every write. This could force the OS to flush any pending data and write the current pending writes to disc without caching the writes up to certain amount.
The second best thing would be to simply wait after each write to give the OS the chance to write pending changes though small back to disc after a certain time interval.
If you are deeper into performance you should try out XPerf which has a nice GUI and shows you even the call stack where your process did hang. The Windows Team and many other teams at MS use this tool to troubleshoot hang experiences. The latest edition with many more features comes with the Windows 8 SDK. But beware that Xperf only works on OS > Vista.