前一段实习,本来打算做c++,到了公司发现没啥项目,于是乎转行做了android,写的第一个程序竟然要我处理信号,咱可是一心搞计算机的,没接触过信号的东西,什么都没接触过,于是乎, 找各种朋友,各种熟人,现在想想,专注语言是不对的,语言就是一工具,关键还是业务,算法。好了,废话不多说,上程序,注释都很详细,应该能看懂。
分析声音,其实很简单,就是运用傅里叶变换,将声音信号由时域转化到频域(程序用的是快速傅里叶变换,比较简单),为啥要这样,好处多多,不细讲,公司里的用处是为了检测手机发出声音的信号所在的频率集中范围。
第一个类,复数的计算,用到加减乘,很简单。
package com.mobao360.sunshine;
//复数的加减乘运算
public class Complex {
public double real;
public double image;
//三个构造函数
public Complex() {
// TODO Auto-generated constructor stub
this.real = 0;
this.image = 0;
}
public Complex(double real, double image){
this.real = real;
this.image = image;
}
public Complex(int real, int image) {
Integer integer = real;
this.real = integer.floatValue();
integer = image;
this.image = integer.floatValue();
}
public Complex(double real) {
this.real = real;
this.image = 0;
}
//乘法
public Complex cc(Complex complex) {
Complex tmpComplex = new Complex();
tmpComplex.real = this.real * complex.real - this.image * complex.image;
tmpComplex.image = this.real * complex.image + this.image * complex.real;
return tmpComplex;
}
//加法
public Complex sum(Complex complex) {
Complex tmpComplex = new Complex();
tmpComplex.real = this.real + complex.real;
tmpComplex.image = this.image + complex.image;
return tmpComplex;
}
//减法
public Complex cut(Complex complex) {
Complex tmpComplex = new Complex();
tmpComplex.real = this.real - complex.real;
tmpComplex.image = this.image - complex.image;
return tmpComplex;
}
//获得一个复数的值
public int getIntValue(){
int ret = 0;
ret = (int) Math.round(Math.sqrt(this.real*this.real - this.image*this.image));
return ret;
}
}
这个类是有三个功能,第一,采集数据;第二,进行快速傅里叶计算;第三,绘图。
采集数据用AudioRecord类,网上讲解这个类的蛮多的,搞清楚构造类的各个参数就可以。
绘图用的是SurfaceView Paint Canvas三个类,本人也是参考网络达人的代码
package com.mobao360.sunshine;
import java.util.ArrayList;
import java.lang.Short;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathEffect;
import android.graphics.Rect;
import android.media.AudioRecord;
import android.util.Log;
import android.view.SurfaceView;
public class AudioProcess {
public static final float pi= (float) 3.1415926;
//应该把处理前后处理后的普线都显示出来
private ArrayList<short[]> inBuf = new ArrayList<short[]>();//原始录入数据
private ArrayList<int[]> outBuf = new ArrayList<int[]>();//处理后的数据
pri