windows phone accelerometer jitter - c#

I would like to get accelerometer readings every 10ms from my Windows Phone 8, but instead I observe some jitter: the spacing between readings will be 8,10,12,9, or the like. So approximately 10, but not exactly.
I was wondering whether someone could suggest a way to get more reliable readings.
The core of my code looks like this:
var accelerometer = Windows.Devices.Sensors.Accelerometer.GetDefault();
accelerometer.ReadingChanged += accelerometer_ReadingChanged;
accelerometer.ReportInterval = 10;
The phone reports a MiminumReportingInterval of 10, so that should be fine. My callback just adds the numbers to a list, which I will send over the network at the end.
I am looking at the time in AccelerometerReadingChangedEventArgs.Timestamp, and that's where I see that the interval isn't always 10ms. Here's what the times looked like in the latest measurements: 105,118,128,134,146,157,163,177,187,198,208,213,232,238,245,255,263,279,285,295,303,313,324,334,345,355,363,375,385
So: is there something I can do to get more precisely spaced measurements? Or is this just the best this particular hardware can do?

There is a great article on Windows Phone Developer Blog which covers accelerometer in details.
One of the points of the article is that, yes, the stream of values can and most probably will be 'jittery' so you should implement some method of filtering. One such method is a low pass filter.
The smoother the data after filtering, the bigger the delay will be between the actual change and the reading. In other words, if you used accelerometer in a game as a 'steering wheel', a lot of filtering will result in late turning of a car, but no filtering will probably result in a jittery car. So, the best is to set it somewhere in between, depending on the use case.

Related

C#: How to find the CPU's CURRENT Clock Speed?

Currently working on creating a sorts of "task manager" in c#/wpf. I've searched around but haven't found a solution to my problem.
I am trying to retrieve the CURRENT clock speed of one's CPU (not utilization, base, min/max). I have tried using ManagementObjects, but "CurrentClockSpeed" is always giving a fixed value of 3400, or 3.4GHz, which is the stock max speed of the CPU. I have tried many times and it gives me the same answer, so it isn't just a coincidence i think.
ManagementObject Mo = new ManagementObject("Win32_Processor.DeviceID='CPU0'");
uint sp = (uint)(Mo["CurrentClockSpeed"]);
System.Threading.Thread.Sleep(1000);
sp = (uint)(Mo["CurrentClockSpeed"]);
Mo.Dispose(); //return and such later in the code
Any suggestions on how to fix this issue (I am not bound to using ManagementObjects, I have OpenHardwareMonitor, and can use other packages if need be) are appreciated.
On the WMI object the MaxClockSpeed property gives you the maximum speed of the core, which should be constant. The CurrentClockSpeed property tells you the current clock speed. This may be leess than the MaxClockSpeed dues to cpu throttling.
I believe you can disable throttling at the BIOS level or via the Windows power management control panel applet, so it's possible that *CurrentClockSpeed** will always be the same as MaxClockSpeed.
I had the same question eight years before you did. WMI does not return the real current clock speed, and this appears to still be the case, at least through Windows 10.
For whatever reason, WMI only returns the base clock speed as the value for both maximum and current clock speed. It's not an issue of CPU support; CPU-Z is able to report the correct clock speed, as does Task Manager. It's a piece of data the OS has at its disposal, but doesn't make readily available. There's probably a way to get the exact value from the CPU using C++, but lots of devs aren't fluent in that language.
This awesome answer worked perfectly for me! I finally got this application working properly, after starting (and abandoning) it in 2010.
(P.S. This doesn't work in Windows 7; it seems the perfmon counter used didn't exist back then.)
When running the code at an Intel CPU with access to MSRs then you may evaluate the current CPU frequency from IA32_MPERF (0xE7) TSC Frequency Clock Counter and
IA32_APERF (0xE8) Actual Performance Clock Counter.
aperf_t1 = read_aperf();
mperf_t1 = read_mperf();
sleep(1);
aperf_t2 = read_aperf();
mperf_t2 = read_mperf();
printf("CPU freq: %f [Hz]\n", ((aperf_t2-aperf_t1) / (double)(mperf_t2-mperf_t1)) * nominal_freq);

Microsoft.CognitiveServices.Speech.SpeechRecognizer-getting time offsets of results in a file with continuous recognition

I'm testing out the new unified speech engine on Azure, and I'm working on a piece where I'm trying to transcribe a 10 minute audio file. I've created a recognizer with CreateSpeechRecognizerWithFileInput, and I've kicked off continuous recognition with StartContinuousRecognitionAsync. I created the recognizer with detailed results enabled.
In the FinalResultsReceived event, there doesn't seem to be a way to access the audio offset in the SpeechRecognitionResult. If I do this though:
string rawResult = ea.Result.ToString(); //can get access to raw value this way.
Regex r=new Regex(#".*Offset"":(\d*),.*");
int offset=Convert.ToInt32(r?.Match(rawResult)?.Groups[1]?.Value);
Then I can extract the offset. The raw result looks something like this:
ResultId:4116b361141446a98f306fdc11c3a5bd Status:Recognized Recognized text:<OK, so what's your think it went well, let's look at number number is 104-828-1198.>. Json:{"Duration":129500000,"NBest":[{"Confidence":0.887861133,"Display":"OK, so what's your think it went well, let's look at number number is 104-828-1198.","ITN":"OK so what's your think it went well let's look at number number is 104-828-1198","Lexical":"OK so what's your think it went well let's look at number number is one zero four eight two eight one one nine eight","MaskedITN":"OK so what's your think it went well let's look at number number is 104-828-1198"}],"Offset":6900000,"RecognitionStatus":"Success"}
The challenge there is that the Offset is sometimes zero, even for cases where it's a nonzero file index, so I'll get zeroes in the middle of a recognition stream.
I also tried submitting the same file through the batch transcription API, which gives me a different result entirely:
{
"RecognitionStatus": "Success",
"Offset": 531700000,
"Duration": 91300000,
"NBest": [{
"Confidence": 0.87579143,
"Lexical": "OK so what's your think it went well let's look at number number is one zero four eight two eight one",
"ITN": "OK so what's your think it went well let's look at number number is 1048281",
"MaskedITN": "OK so what's your think it went well let's look at number number is 1048281",
"Display": "OK, so what's your think it went well, let's look at number number is 1048281."
}
]
},
So I have three questions on this:
Is there a supported method to get the offset of a recognized section of a file in the recognizer API? The SpeechRecognitionResult doesn't expose this, nor does the Best() extension.
Why is the offset coming back as 0 for a segment part way through the file?
What are the units for the offsets in the bulk recognition and file recognition APIs, and why are they different? They don't appear to be ms or frames, at least from what I've found in Audacity. The result I posted was from roughly 59s into the file, which is roughly 800k samples.
Chris,
Thanks for your feedback. To your questions,
1) The offset as well as duration have been added to the API. The next coming release (very soon) will allow you access both properties. Please stay tuned.
2) This is probably due to different recognition mode being used. We will also fix that in the next release.
3) The time unit for both API is 100ns(tick). Please also note that batch transcription uses different model than online recognition, so that the recognition result might be slightly different.
Sorry for the inconvenience!
Thanks,

Using a low pass filter on audio

I am VERY new in the world of DSP and filtering. Like I started a week ago. Anyway, I have been looking for ways to use filters (low-pass, high-pass, notch, etc.) on some data I am getting. The data comes in an array of doubles and I can get more than 1 million points in this array. I am trying to filter out sound given a certain cutoff frequency but cannot get any algorithm to work. I have been up and down the internet and tried a bunch of different libraries and methods but I can't get any results. I am partial to the NAudio library because it seems to have everything I need (FFT and filtering by the BiQuadFilter class). I am pretty sure my problem is my extreme lack of the knowledge and math to get the desired output. Judging from what I have read, here is how I believe the process should go:
Insert data into FFT to put data into frequency domain
Pass resulting data into a filter (low, high, notch)
Do IFFT from results in step 2 to get back into time domain
Play sound
Is this the right way to filter audio? Can I shove the entire array into the FFT or do I have to break it up in smaller chunks? What do I do with the complex numbers that I get in the FFT result (ie just use the real part and throw away the imaginary, or use the magnitude and phase)? I really have no idea what the "right way" is.
EDIT
I finally got it working! Here is what I did:
byte[] data = doubleArray.SelectMany(value => BitConverter.GetBytes(value)).ToArray();
wms = new WaveMemoryStream(data, sampleRate, (ushort)audioBitsPerSample, (ushort)channels);
WaveFileReader wfr = new WaveFileReader(wms);
SampleChannel sample = new SampleChannel(wfr, false);
LowPassSampleProvider sampleProvider = new LowPassSampleProvider(sample);
WaveOutEvent player = new WaveOutEvent();
player.Init(sampleProvider);
player.Play();
doubleArray is the array of my accelerometer data, which currently holds 1 million points with each one somewhere around 1.84...
WaveMemoryStream is a class I found on another post here
LowPassSampleProvider is a class I made that implements ISampleProvider and passes the samples to the BiQuadFilter.LowPassFilter function.
The BiQuadFilter in NAudio operates in the time domain. You don't need to use FFT with it. Pass each sample into the Transform method to get the output sample. Use two filters one for left and one for right if you have stereo audio.
I typically make an ISampleProvider implementation that in the Read method reads from a source ISampleProvider (such as an AudioFileReader) and passes the samples through the filter.
Typically you would run the time domain data through a time domain filter. Another method, which is equivalent, is to take the FFT of the data and the FFT of the filter, multiply it in the frequency domain, then take the inverse FFT. For small filters the time domain approach is generally faster. You would typically do this on frames of the data, say 8192 samples passed through a filter. Then repeat for subsequent frames. Without looking at your code I'm unable to provide more help. Also, take a look at these examples using Intel's IPP. There's both time and frequency domain implementations that should help to get you going.

WPF dispatcher performance (100-200 updates/sec)

In a WPF Window, I've got a line chart that plots real-time data (Quinn-Curtis RealTime chart for WPF). In short, for each new value, I call a SetCurrentValue(x, y) method, and then the UpdateDraw() method to update the chart.
The data comes in via a TCP connection in another thread. Every new value that comes in causes an DataReceived event, and its handler should plot the value to the chart and then update it. Logically, I can't call UpdateDraw() directly, since my chart is in the UI thread which is not the same thread as where the data comes in.
So I call Dispatcher.Invoke( new Action (UpdateDraw()) ) - and this works fine, well, as long as I update max. 30 times/sec. When updating more often, the Dispatcher can't keep up and the chart updated slower than the data comes in. I tested this using a single-thread situation with simulated data and without the Dispatcher there are no problems.
So, my conclusion is that the Dispatcher is too slow for this situation. I actually need to update 100-200 times/sec!
Is there a way to put a turbo on the Dispatcher, or are there other ways to solve this? Any suggestions are welcome.
An option would be to use a shared queue to communicate the data.
Where the data comes on, you push the data to the end of the queue:
lock (sharedQueue)
{
sharedQueue.Enqueue(data);
}
On the UI thread, you find a way to read this data, e.g. using a timer:
var incomingData = new List<DataObject>();
lock (sharedQueue)
{
while (sharedQueue.Count > 0)
incomingData.Add(sharedQueue.Dequeue());
}
// Use the data in the incomingData list to plot.
The idea here is that you're not communicating that data is coming in. Because you have a constant stream of data, I suspect that's not a problem. I'm not saying that the exact implementation as give above is the rest, but this is about the general idea.
I'm not sure how you should check for new data, because I do not have enough insight into the details of the application; but this may be a start for you.
Youre requierments are bonkers- You seriously do NOT need 100-200 updates per second, especialyl as teh screen runs at 60 updates per second normally. People wont see them anyway.
Enter new data into a queue.
Trigger a pull event on / for the dispatcher.
Santize data in the queue (thro out doubles, last valid wins) and put them in.l
30 updates per second are enough - people wont see a difference. I had performacne issues on some financial data under high load with a T&S until I did that - now the graph looks better.
Keep Dispatcher moves as few as you can.
I still like to know why you'd want to update a chart 200 times per second when your monitor can't even display it that fast. (Remember, normal flatscreen monitors have an update-rate of 60 fps)
What's the use of updating something 200 times per second when you can only SEE updates 60 times per second ?
You might as well batch incoming data and update the chart at 60 fps since you won't be able to see the difference anyway.
If it's not just about displaying the data but you're doing something else with it - say you are monitoring it to see if it reaches a certain threshold - than I recommend splitting the system in 2 parts : one part monitoring at full speed, the other independently displaying at the maximum speed your monitor can handle : 60 fps.
So please, tell us why you want to update a ui-control more often than it can be displayed to the user.
WPF drawing occurs in a separate thread. Depending on your chart complexity, your PC must have had a mega-descent video card to keep up with 100 frames per second. WPF uses Direct3D to draw everything on screen and optimizing video driver for this has been added in Vista (improved in Windows 7). So, on XP you might have troubles just because of your high data-output rate on poorly designed OS.
Despite all that, I see no reason of printing information to screen with a rate of more than 30-60 frames per second. Come on! Even FPS shooters does not require such a strong reflexes from player. Do you want to tell me, that your poor chart does? :) If by this outputting, you produce some side-effects, which are what you actually need, then it's completely different story. Tell us more about the problem then.

Greater time resolution using .NET Micro Framework on Netduino board (for dimming an LED)?

I'm programming a Netduino board using the .NET Micro Framework 4.1 and want to get a higher time resolution than milliseconds. This is because I'm attempting to dim an LED by blinking it really fast.
The issue is that the sample code uses Thread.Sleep(..) which takes a number of milliseconds.
Sample code from http://netduino.com/projects/ showing the issue in question:
OutputPort ledOnboard = new OutputPort(Pins.ONBOARD_LED, false);
while (true)
{
ledOnboard.Write(true);
Thread.Sleep(1); // << PROBLEM: Can only get as low as 1 millisecond
Even if there's another way to accomplish dimming by not using a greater time resolution, I'm game.
This doesn't answer your question about getting a better time resolution, but it does solve your problem with changing the brightness on an LED. You should be using the PWM module for the Netduino.
Netduino Basics: Using Pulse Width Modulation (PWM) is a great article on how to use it.
I have had a similar problem in the past and used the following method to time in the microsecond range. The first line determines how many ticks are in a millisecond (its been a while since I used this, but I think 1 tick was 10 microseconds). The second line gets the amount of time the system has been on (in ticks). I hope this helps.
public const Int64 ticks_per_millisecond = System.TimeSpan.TicksPerMillisecond;
public static long GetCurrentTimeInTicks()
{
return Microsoft.SPOT.Hardware.Utility.GetMachineTime().Ticks;
}
You can use a timer to raise an event instead of using sleep.
The Interval property on a timer is a double so you can have less than a millisecond on it.
http://msdn.microsoft.com/en-us/library/0tcs6ww8(v=VS.90).aspx
In his comment to Seidleroni's answer BrainSlugs83 suggests "sit in a busy loop and wait for the desired number of ticks to elapse. See the function I added in the edit". But I cannot see the function added to the edit. I assume it would be something like this:
using System;
using Microsoft.SPOT.Hardware;
private static long _TicksPerMicroSecond = TimeSpan.TicksPerMillisecond/1000;
private void Wait(long microseconds)
{
var then = Utility.GetMachineTime().Ticks;
var ticksToWait = microseconds * _TicksPerNanoSecond;
while (true)
{
var now = Utility.GetMachineTime().Ticks;
if ((now - then) > ticksToWait) break;
}
}
A point that you might not be thinking about is that your code is relying on the .NET System namespace, which is based on the real time clock in your PC. Notice that the answers rely on the timer in the device.
Moving forward, I would suggest that you take a moment to qualify the source of the information you are using in your code -- is it .NET proper (Which is fundamentally based on your PC), or the device the code is running on (Which will have a namespace other than System, for example)?
PWM is a good way to control DC current artificially (by varying the pulse width), but varying the PWM frequency will still be a function of time at the end of the day.
Rather than use delays....like Sleep....you might want to spawn a thread and have it manage the brightness. Using Sleep is still basically a straight line procedural method and your code will only be able to do this one thing if you use a single thread.

Categories