I have a question regarding the UI Thread in Android:
My activity extends AsyncTask to do some calculations on wave file. If I run the application once, it takes around 15 min to finish. This is not problem for me. I want to start the process multiple times(for example 4 times, because I have 4 wave files) so I expect the time to be 1 h (15 min* 4= 1h), but this is not the case, it lasts for about 3 hours !
In order to start the process multiple times, I created a function that calls "new ProcessTask().execute();" 4 times, and I call this function within the "onPostExecute"
Do u have any ide why it requires more time when I run it multiple times?
Thanks in advance for your help
public void processingRespiratoryFiles() {
if(p<=MainActivity.count)
{
filePath = Environment.getExternalStorageDirectory() + "/external_sd/AudioRecorder/audio"+p+".wav";
File filein = new File(filePath);
if (filein.exists())
new ProcessTask().execute();
}
else
{
RespiratoryHandling(ODI_Sum,0);
Index.setText(Double.toString(ODI_Sum));
message2=ODI_Sum;
}
}
private class ProcessTask extends AsyncTask<Void, Void, Integer> {
ProgressDialog dialog;
@Override
protected Integer doInBackground(Void... params) {
return process(filePath);
}
@Override
protected void onPostExecute(Integer result) {////////////////////////////////////////////////////////
dialog.dismiss();
if (result > -1)
{
p++;
ODI=(double)result/NumberOfHours;
ODI_Sum+=ODI;
processingRespiratoryFiles();
}
}
@Override
protected void onPreExecute() {
dialog = ProgressDialog.show(
Diagnose.this, "Diagnosing, please wait",
"Processing...");
}
}
/**
* Reset ring buffer for filter process before filtering signal
* @param alength number of a coefficients
* @param blength number of a coefficients
*/
public void resetRingBuffer(int alength, int blength) {
xv = new double[blength + 1];
yv = new double[alength + 1];
px = 0;
py = 0;
}
/**
* Filter each second of signal and then compute the energy of output
* @param din input stream of audio file
* @param length number of read samples
* @param numChannels number of channels of signal
* @return energy value of 1 second filtered signal
*/
public double readEnergyFiltered(DataInputStream din, int length,
int numChannels) {
double energy = 0.0;
try {
byte[] byteBuffer = new byte[length * 2 * numChannels]; // 16 bit
// read length samples from file's stream
int r = din.read(byteBuffer); // bytes read
// if reach to end of file
if (r == -1)
return -1.0;
r = r / (2 * numChannels); // samples read
// apply the filter
for (int i = 0; i < r; ++i) {
// get the new sample
short sample = (short) ((byteBuffer[2 * numChannels * i] & 0xff) | (byteBuffer[2
* numChannels * i + 1] & 0xff) << 8);
xv[px] = (double) sample / 32768.0;
// compute the output
double y = bcoef[0] * xv[px];
for (int j = 1; j < bcoef.length; ++j)
y += bcoef[j] * xv[(px - j + xv.length) % xv.length];
for (int j = 1; j < acoef.length; ++j)
y -= acoef[j] * yv[(py - j + yv.length) % yv.length];
// save the result
yv[py] = y;
// update energy
energy += y * y;
// increment the index of the ring buffer
px = (px + 1) % xv.length;
py = (py + 1) % yv.length;
}
return energy;
} catch (Exception e) {
e.printStackTrace();
}
return -1.0;
}
/**
* Process the filtering, computing energy and estimating number of events
* @param filePath path to audio file on sd card
* @return number of events
*/
private int process(String filePath) {
try {
int event = 0;
double sum =0.0;
byte[] header = new byte[44];
File filein = new File(filePath);
FileInputStream fin = new FileInputStream(filein);
BufferedInputStream bin = new BufferedInputStream(fin);
DataInputStream din = new DataInputStream(bin);
din.read(header);
// Sample Rate
int fs = (header[24] & 0xff) | (header[25] & 0xff) << 8
| (header[26] & 0xff) << 16 | (header[27] & 0xff) << 24;
double Ts = 1.0 / fs;
Log.v("PERM", "Sample Rate: " + String.valueOf(fs));
// Num Channels
int numChannels = (header[22] & 0xff) | (header[23] & 0xff) << 8;
Log.v("PERM", "Num Channel: " + String.valueOf(numChannels));
// Bits Per Sample
int bitsPerSample = (header[34] & 0xff) | (header[35] & 0xff) << 8;
Log.v("PERM", "Bits per sample: " + String.valueOf(bitsPerSample));
// Sample Rate
int numBytes = (header[40] & 0xff) | (header[41] & 0xff) << 8
| (header[42] & 0xff) << 16 | (header[43] & 0xff) << 24;
int N = numBytes / numChannels / (bitsPerSample / 8);
Log.v("PERM", "Data Length: " + String.valueOf(N));
// Calibration phase
// Find average energy for the first 180 seconds
double energy = 0.0;
resetRingBuffer(acoef.length, bcoef.length);
for (int i = 0; i < 30; i++) {
sum = readEnergyFiltered(din, fs, numChannels);
energy += sum * Ts;
}
if(MainActivity.count==1)
{
mean_energy = energy / 30.0;
ThresholdR = 0.8 * mean_energy;
}
Log.v("PERM", "Threshold: " + String.valueOf(ThresholdR));
// process hold file
resetRingBuffer(acoef.length, bcoef.length);
din.close();
bin.close();
fin.close();
fin = new FileInputStream(filein);
bin = new BufferedInputStream(fin);
din = new DataInputStream(bin);
din.read(header);
N = N / fs;
int j = 1;
while (j <= N) {
int counter = 0;
//int trigger = 0;
energy = readEnergyFiltered(din, fs, numChannels) * Ts;
if (energy >= 0.) {
Log.v("PERM", "Energy " + String.valueOf(energy));
//while ((energy <= Threshold) || (trigger < 4))
while ((energy < ThresholdR)) {
counter++;
energy = readEnergyFiltered(din, fs, numChannels) * Ts;
Log.v("PERM", "Inner Energy " + String.valueOf(energy));
if (energy < 0)
break;
//trigger++;
}
}
if (counter > 10)
event++;
if (counter > 0)
j += counter;
else
j++;
}
Log.v("PERM", "Event: " + String.valueOf(event));
din.close();
bin.close();
fin.close();
return event;
} catch (Exception e) {
e.printStackTrace();
}
return -1;
}