Smoothing signal from microphone - Hearthbeat - java

I'm working on project using oximeter.I want to smooth it out so I can use it for calculating hearthbeat. I'm gathering raw data from microphone , I put them in new array, lets say, sData[].
Signal is really crazy and jumps all over the plot as expected, so i tried smoothing it using moving average. So my main code looks something like this.
writeAudioDataToFile();
for (int a = 0; a < sData.length; a++) {
tempAvg += Math.abs(sData[a]);
if (a % numberOfSamplesAveraged == 0) { //Average from x samples
if (myIndex > SAMPLE_SIZE - 1) {
myIndex = 0;
}
tempAvg = tempAvg / numberOfSamplesAveraged;
if (tempAvg > 500) {
newDataArray[myIndex] = 500;
}else{
newDataArray[myIndex] = tempAvg;
} //This is suppose to clear the high peaks.
Log.d("isRecording - Average from " + numberOfSamplesAveraged + " numbers.", "newDataArray[" + myIndex + "] = " + newDataArray[myIndex]);
tempAvg = 0;
myIndex++;
}
}
notifier.notifyObservers();
Log.d("Notifier", "Notifier Fired!");
Thread.sleep(20); //Still experimenting with this value
It looks so messy, but the plot (I'm using AndroidPlot btw) looks good but it is so inaccurate so I can't calculate the hearthrate from it. It has so much "Bounce" in "high" state. I found on internet that some kind of filter (Maybe IIR filter) will do the job. So i just wanna ask you guys how can i achieve a nice smooth chart? Is IIR filter the way to go? Is there any free applet/lib to smoothen it out?
This is my first question here so I'm really sorry if it is badly written.
If you will need any more information to help me, just ask.
Here is a picture how my chart looks like now.
http://oi62.tinypic.com/2uf7yoy.jpg // Cant post images im new here.
This is a lucky one though.
I need smoother output.

Noises, which occur at measurement, have high frequency. You should filter your signal, that is you should retain low frequency part of signal and suppress high frquency part of signal. You can do it, making a low-pass filter. It could be, for example, first-order inertial model. I suggest make a pass-band till ~~10 kHz, since people hear sound from 2 kHz to 20 kHz. Then appriopriate sample time is 0,0001 sec (0,1 ms). Discrete model has following equation:
y[k] = 0.9048*y[k-1] + 0.09516*u[k-1],
where u is a measured vector (directly from microphone, input in our filter),
and y is a vector you want to analyze (so output from our filter).
As you can see,, you can calculate a sample number 1, and you can just assign 0 to the sample number 0. After all, you can try to plot y vector.

Related

how to get the speed of the process in android

I know the API "long getUidRxBytes (int uid)",but this interface could not get the network speed with each process. Is there someone who konws a simple way to get the speed of the prcocess.
my english is not very well.
Basically, to measure speed of anything, you need 2 parameters: time and amount.
Here, I assume you are calculating byte/s, you need to measure how many bytes transfered every second.
Almost time, you will need a algorithm such as
totalTimeSpent = 0
bytesSent = 0
do
beforeSendingTime = getCurrentMilisecond
send n bytes to desination via network
bytesSent = bytesSent + n
afterSendingTime = getCurrentMilisecond
timeSpent = afterSendingTime - beforeSendingTime
totalTimeSpent = totalTimeSpent + timeSpent
say: currentSpeed = n/timeSpent
say: averageSpeed = bytesSent/totalTimeSpent
loop until no data remaining to send
Hope it help, you need to implement that algorithm in your own development language

Minimization of number of itererations by adjusting input parameters in Java

I was inspired by this question XOR Neural Network in Java
Briefly, a XOR neural network is trained and the number of iterations required to complete the training depends on seven parameters (alpha, gamma3_min_cutoff, gamma3_max_cutoff, gamma4_min_cutoff, gamma4_max_cutoff, gamma4_min_cutoff, gamma4_max_cutoff). I would like to minimize number of iterations required for training by tweaking these parameters.
So, I want to rewrite program from
private static double alpha=0.1, g3min=0.2, g3max=0.8;
int iteration= 0;
loop {
do_something;
iteration++;
if (error < threshold){break}
}
System.out.println( "iterations: " + iteration)
to
for (double alpha = 0.01; alpha < 10; alpha+=0.01){
for (double g3min = 0.01; g3min < 0.4; g3min += 0.01){
//Add five more loops to optimize other parameters
int iteration = 1;
loop {
do_something;
iteration++;
if (error < threshold){break}
}
System.out.println( inputs );
//number of iterations, alpha, cutoffs,etc
//Close five more loops here
}
}
But this brute forcing method is not going to be efficient. Given 7 parameters and hundreds of iterations for each calculation even with 10 points for each parameter translates in billions of operations. Nonlinear fit should do, but those typically require partial derivatives which I wouldn't have in this case.
Is there a Java package for this sort of optimizations?
Thank you in advance,
Stepan
You have some alternatives - depending on the equations that govern the error parameter.
Pick a point in parameter space and use an iterative process to walk towards a minimum. Essentially, add a delta to each parameter and pick whichever reduces the error by the most - rince - repeat.
Pick each pareameter and perform a binary-chop search between its limits to find it's minimum. Will only work if the parameter's effect is linear.
Solve the system using some form of Operations-Research technique to track down a minimum.

Wrong values in calculating Frequency using FFT

I'm getting wrong frequency, I don't understand why i'm getting wrong values.since i have calculating as per instructions followed by stackoverflow.
I've used FFT from
http://introcs.cs.princeton.edu/java/97data/FFT.java.html
and complex from
http://introcs.cs.princeton.edu/java/97data/Complex.java.html
audioRec.startRecording();
audioRec.read(bufferByte, 0,bufferSize);
for(int i=0;i<bufferSize;i++){
bufferDouble[i]=(double)bufferByte[i];
}
Complex[] fftArray = new Complex[bufferSize];
for(int i=0;i<bufferSize;i++){
fftArray[i]=new Complex(bufferDouble[i],0);
}
FFT.fft(fftArray);
double[] magnitude=new double[bufferSize];
for(int i=0;i<bufferSize;i++){
magnitude[i] = Math.sqrt((fftArray[i].re()*fftArray[i].re()) + (fftArray[i].im()*fftArray[i].im()));
}
double max = 0.0;
int index = -1;
for(int j=0;j<bufferSize;j++){
if(max < magnitude[j]){
max = magnitude[j];
index = j;
}
}
final int peak=index * sampleRate/bufferSize;
Log.v(TAG2, "Peak Frequency = " + index * sampleRate/bufferSize);
handler.post(new Runnable() {
public void run() {
textView.append("---"+peak+"---");
}
});
i'm getting values like 21000,18976,40222,30283 etc...
Please help me.....
Thank you..
Your source code is almost fine. The only problem is that you search for the peaks through the full spectrum, i.e. from 0 via Fs/2 to Fs.
For any real-valued input signal (which you have) the spectrum between Fs/2 and Fs (=sample frequency) is an exact mirror of the spectrum between 0 and Fs/2 (I found this nice background explanation). Thus, for each frequency there exist two peaks with almost identical amplitude. I'm writing 'almost' because due to limited machine precision they are not necessarily exactly identical. So, you randomly find the peak in the first half of the spectrum which contains the frequencies below the Nyquist frequency (=Fs/2) or in the second half of the spectrum with the frequencies above the Nyquist frequency.
If you want to correct the mistake yourself, stop reading here. Otherwise continue:
Just replace
for(int j=0;j<bufferSize;j++){
with
for(int j=0;j<=bufferSize/2;j++){
in the source code you presented.
P.S.: Typically, it is better to apply a window function to the analysis buffer (e.g. a Hamming window) but for your application of peak picking it won't change results very much.

An efficient algorithm to move ostrichs along a line at a constant speed

Problem: move an object along a straight line at a constant speed in the Cartesian coordinate system (x,y only). The rate of update is unstable. The movement speed must be close to exact and the object must arrive very close to the destination. The line's source and destination may be anywhere.
Given: the source and destination addresses (x0,x1,y0, y1), and a speed of arbitrary value.
An asside: There is an answer on the SO regarding this, and it's good, however it presumes that total time spend traveling is given.
Here's what I've got:
x0 = 127;
y0 = 127;
x1 = 257;
y1 = 188;
speed = 127;
ostrich.x=x0 //plus some distance along the line;
ostrich.y=y0 // plus some distance along the line;
//An arbitrarily large value so that each iteration increments the distance a minute amount
SPEED_VAR = 1000;
xDistPerIteration = (x1 - x0) / SPEED_VAR;
yDistPerIteration = (y1 - y0) / SPEED_VAR;
distanceToTravel = ;//Pythagorean theorum
limitX = limit1 = 0; //determines when to stop the while loop
//get called 40-60 times per second
void update(){
//Keep incrementing the ostrich' location
while (limitX < speed && limitY < speed) {
limitX += Math.abs(xDistPerIteration);
limitY += Math.abs(yDistPerIteration);
ostrich.x += xDistPerIteration;
ostrich.y += yDistPerIteration;
}
distanceTraveled -= Math.sqrt(Math.pow(limitX, 2) + Math.pow(limitY, 2));
if (distanceTraveled <=0)
//ostrich arrived safely at the factory
}
This code gets the job done, however it takes up exclusively 18% of program time in a CPU intensive program. It's garbage, programatically and in terms of performance. Any ideas on what to do here?
An asside: There is an answer on the
SO regarding this, and it's good,
however it presumes that total time
spend traveling is given.
basic physics to the rescue
total time spent traveling = distance/speed
btw Math.hypot(limitX,limitY) is faster than Math.sqrt(Math.pow(limitX, 2) + Math.pow(limitY, 2))
though really it's that while loop you should refactor out
One thing to improve is:
There is no need to compute the square root in each call to the update function. You may use the squared distanceTraveled instead.
Similarly, Math.abs(xDistPerIteration) and Math.abs(yDistPerIteration) do not change at each call to update, you may save those values and get rid of the calls to the absolute value function in order to bit a save a bit more computing time.
Update gets called 40-60 times per second, right? In other words, once per frame. So why is there a while loop inside it?
Also, doing sqrt once, and pow twice, per frame is unnecessary.
Just let d2 be the distance squared, and stop when limitX*limitX+limitY*limitY exceeds it.

Java audio effects - Distortion algorithm on Android

I'm working on an application for android that does some real-time processing of audio from the mic. The sampling and playback is working effectively, but I am having difficulty with implementing the first audio effect - distortion. The audio comes in buffers of shorts, so each time one of these is received I attempt to map the values to the full size of a signed short, and then essentially clip these values if they are above a certain level. The audio that comes from this is certainly distorted, but not in a desirable way. I've included my code for accomplishing this. Can anyone see an error here?
public void onMarkerReached(AudioRecord recorder) {
// TODO Auto-generated method stub
short max = maxValue(buffers[ix]);
short multiplier;
if(max!=0)
multiplier = (short) (0x7fff/max);
else
multiplier = 0x7fff;
double distLvl =.8;
short distLvlSho = 31000;
short max2 =100;
for(int i=0;i<buffers[ix].length;i++){
buffers[ix][i]=(short) (buffers[ix][i]*multiplier);
if(buffers[ix][i]>distLvlSho)
buffers[ix][i]=distLvlSho;
else if(buffers[ix][i]<-distLvlSho)
buffers[ix][i]=(short)-distLvlSho;
buffers[ix][i]=(short) (buffers[ix][i]/multiplier);
}
The buffers array is a 2D array of shorts, and the processing is to be done on just one of the array-within-arrays, here buffers[ix].
As far as I see in the end what you get is just a clipping of the source with a clip threshold which follows the proportion clipThr/max(input)=distLvlSho/0x7fff. most of the input this way is basically unchanged.
If you actually wanted to distort the signal you should apply some kind nonlinear function to the whole signal (plus eventually clipping near sample max to simulate the analog saturation)
A few simple models for distortion are listed in this book : http://books.google.it/books?id=h90HIV0uwVsC&printsec=frontcover#v=onepage&q&f=false
The simplest is a simmetrical soft clipping (see page 118). Here's your method modified with that soft clip function, see if it fits your needs for distorted sound (I tested it by making up a few sinusoids on input and using excel to plot the output)
In the same chapter you'll find a simple tube modeling and a fuzz filter modeling (there are a few exponentials on those so if performance is an issue you might want to approximate those).
public void onMarkerReachedSoftClip(short[] buffer) {
double th=1.0/3.0;
double multiplier = 1.0/0x7fff; // normalize input to double -1,1
double out = 0.0;
for(int i=0;i<buffer.length;i++){
double in = multiplier*(double)buffer[i];
double absIn = java.lang.Math.abs(in);
if(absIn<th){
out=(buffer[i]*2*multiplier);
}
else if(absIn<2*th){
if(in>0)out= (3-(2-in*3)*(2-in*3))/3;
else if(in<0)out=-(3-(2-absIn*3)*(2-absIn*3))/3;
}
else if(absIn>=2*th){
if(in>0)out=1;
else if(in<0)out=-1;
}
buffer[i] = (short)(out/multiplier);
}
}
If you multiply 2 short integers, the result requires a long integer or the result can overflow.
e.g. 1000 * 1000 = 1000000 , which is too big for a 16-bit short integer.
So you need to perform a scaling operation (divide or right shift) before you convert the multiplication result to a short value for storage. Something like:
result_short = (short)( ( short_op_1 * short_op_2 ) >> 16 );

Categories

Resources