7
\$\begingroup\$

This is part of the code from a spectral subtraction algorithm. I'm trying to optimize it for Android.

Matlab code:

function Seg=segment(signal,W,SP,Window)
% SEGMENT chops a signal to overlapping windowed segments
% A= SEGMENT(X,W,SP,WIN) returns a matrix which its columns are segmented
% and windowed frames of the input one dimentional signal, X. W is the
% number of samples per window, default value W=256. SP is the shift
% percentage, default value SP=0.4. WIN is the window that is multiplied by
% each segment and its length should be W. the default window is hamming
% window.
% 06-Sep-04
% Esfandiar Zavarehei
if nargin<3
 SP=.4;
end
if nargin<2
 W=256;
end
if nargin<4
 Window=hamming(W);
end
Window=Window(:); %make it a column vector
L=length(signal);
SP=fix(W.*SP);
N=fix((L-W)/SP +1); %number of segments
Index=(repmat(1:W,N,1)+repmat((0:(N-1))'*SP,1,W))';
hw=repmat(Window,1,N);
Seg=signal(Index).*hw;

Java code:

public class MatrixAndSegments 
{
 public int numberOfSegments;
 public double[][] res;
 public MatrixAndSegments(int numberOfSegments,double[][] res)
 {
 this.numberOfSegments = numberOfSegments;
 this.res = res;
 }
}
public MatrixAndSegments segment (double[] signal_in,int samplesPerWindow, double shiftPercentage, double[] window)
{
 //default shiftPercentage = 0.4
 //default samplesPerWindow = 256 //W
 //default window = hanning 
 int L = signal_in.length;
 shiftPercentage = fix(samplesPerWindow * shiftPercentage); //SP
 int numberOfSegments = fix ( (L - samplesPerWindow)/ shiftPercentage + 1); //N
 double[][] reprowMatrix = reprowtrans(samplesPerWindow,numberOfSegments);
 double[][] repcolMatrix = repcoltrans(numberOfSegments, shiftPercentage,samplesPerWindow );
 //Index=(repmat(1:W,N,1)+repmat((0:(N-1))'*SP,1,W))';
 double[][] index = new double[samplesPerWindow+1][numberOfSegments+1];
 for (int x = 1; x < samplesPerWindow+1; x++ )
 {
 for (int y = 1 ; y < numberOfSegments + 1; y++) //numberOfSegments was 3
 {
 index[x][y] = reprowMatrix[x][y] + repcolMatrix[x][y];
 }
 }
 //hamming window
 double[] hammingWindow = this.HammingWindow(samplesPerWindow);
 double[][] HW = repvector(hammingWindow, numberOfSegments);
 double[][] seg = new double[samplesPerWindow][numberOfSegments];
 for (int y = 1 ; y < numberOfSegments + 1; y++)
 {
 for (int x = 1; x < samplesPerWindow+1; x++)
 {
 seg[x-1][y-1] = signal_in[ (int)index[x][y]-1 ] * HW[x-1][y-1]; 
 }
 }
 MatrixAndSegments Matrixseg = new MatrixAndSegments(numberOfSegments,seg);
 return Matrixseg;
}
public int fix(double val) {
 if (val < 0) {
 return (int) Math.ceil(val);
 }
 return (int) Math.floor(val);
}
public double[][] repvector(double[] vec, int replications)
{
 double[][] result = new double[vec.length][replications];
 for (int x = 0; x < vec.length; x++) {
 for (int y = 0; y < replications; y++) {
 result[x][y] = vec[x];
 }
 }
 return result;
}
public double[][] reprowtrans(int end, int replications)
{
 double[][] result = new double[end +1][replications+1];
 for (int x = 1; x <= end; x++) {
 for (int y = 1; y <= replications; y++) {
 result[x][y] = x ;
 }
 }
 return result;
}
 public double[][] repcoltrans(int end, double multiplier, int replications)
{
 double[][] result = new double[replications+1][end+1];
 for (int x = 1; x <= replications; x++) {
 for (int y = 1; y <= end ; y++) {
 result[x][y] = (y-1)*multiplier;
 }
 }
 return result;
}
 public double[] HammingWindow(int size)
{
 double[] window = new double[size];
 for (int i = 0; i < size; i++)
 {
 window[i] = 0.54-0.46 * (Math.cos(2.0 * Math.PI * i / (size-1)));
 }
 return window;
}
rolfl
98.1k17 gold badges219 silver badges419 bronze badges
asked Aug 18, 2012 at 10:21
\$\endgroup\$
2
  • \$\begingroup\$ you could start by flattening your double[][] to double[]. If every little bit counts, there's some RAM and speed you can gain by it. \$\endgroup\$ Commented Aug 24, 2012 at 13:09
  • \$\begingroup\$ does it need optimization for android? have you profiled the code? \$\endgroup\$ Commented Aug 25, 2012 at 13:25

1 Answer 1

5
\$\begingroup\$

I don't have a clue about spectral subtraction, so just some minor, general notes about code:

  1. public int fix(double val) {
     if (val < 0) {
     return (int) Math.ceil(val);
     }
     return (int) Math.floor(val);
    }
    

    It should be called truncate.

  2. A few variables could be renamed to follow the Java code conventions.

    • Variables, parameters:
      • signal_in to inputSignal or signal
      • HW to hw
      • seg maybe to segments or segment (?)
      • Matrixseg to matrixSeg
    • Methods:
      • HammingWindow to calculateHammingWindow

    (Effective Java, 2nd edition, Item 56: Adhere to generally accepted naming conventions and The Java Language Specification, Java SE 7 Edition, 6.1 Declarations).

  3. This comments looks unnecessary:

    // hamming window
    double[] hammingWindow = this.HammingWindow(samplesPerWindow);
    

    (Clean Code by Robert C. Martin: Chapter 4: Comments, Noise Comments)

    The this. prefix also unnecessary.

answered Mar 10, 2014 at 6:31
\$\endgroup\$
1
  • 1
    \$\begingroup\$ hw could have a better name. I don't know why he have hammingWindows and then HW, when it's looks like the same thing but does not represent the same data (double[] vs double[][]). Maybe switch the two name so that the one who is used more often would have a complete name ? \$\endgroup\$ Commented Mar 10, 2014 at 14:35

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.