1,我设置的采样是:
visualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1])
2,因此从回调方法中返回的byte数据长度是1024个字节
@Override
public void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform, int samplingRate) {
//采集波形数据
}
3,而我的项目需求中要绘制的跳动频谱却只有两条,我该从长度为1024的数组中取出哪两个数据来去绘制跳动的频谱呢?下面代码中的方法是我尝试解决的回调函数,其中data就是监听方法中返回的byte数组,只可惜这种方式明显感觉跳动的频率对不上音乐播放的节奏。有大神指点一下吗?万分感谢!
public void onCaptureChanged(byte[] data, boolean isDataVailed, boolean isReverse) {
this.isReverse = isReverse;
if (data != null) {
int leftCentreIndex = data.length / 4 - 1;
int rightCentreIndex = data.length * 3 / 4 - 1;
// 给256临近的数据设置权重,并且进行累加
mData[0] = (int) (data[leftCentreIndex] * 0.4f + data[leftCentreIndex + 1] * 0.3f + data[leftCentreIndex - 1] * 0.3f);
mData[1] = (int) (data[rightCentreIndex] * 0.4f + data[rightCentreIndex + 1] * 0.3f + data[rightCentreIndex - 1] * 0.3f);
} else {
Arrays.fill(this.mData, 0);
}
postInvalidate();
}
结了吧,勉强还能看得过去,主要方法如下:
public void onCaptureChanged(byte[] data, boolean isDataVailed, boolean isReverse) {
this.isReverse = isReverse;
if (data == null || !isDataVailed
|| !EqualizerPreference.getInstance().isShowVisualizer()
|| !EqualizerDataHelper.get().getAudioEffectEnabled()
|| !EqualizerHandler.getInstance().isMusicActive()) {
if (mData == null) {
mData = new int[mCylinderNum];
} else {
Arrays.fill(this.mData, 0);
}
// 用于减少绘制默认背景的次数
if (mDefaultDrawCount <= 3) {
mDefaultDrawCount++;
postInvalidate();
}
return;
}
if (L.isDebug) {
L.e(TAG, "--> onCaptureChanged");
}
mDefaultDrawCount = 0;
Complex[] complexList = new Complex[mCylinderNum];
for (int i = 0; i < mCylinderNum; i++) {
complexList[i] = new Complex(data[i]);
}
fft(complexList, mCylinderNum);
if (this.mData == null) {
this.mData = new int[mCylinderNum];
}
int[] model = new int[mCylinderNum];
float x = mHeight / 255F;
int max = (int) (mHeight * 0.8);
for (int i = 0; i < mCylinderNum; i++) {
// 与上一次数据平分, 减小变化幅度
model[i] = (int) (Math.min(complexList[i].getIntValue() * x, max) / 2f + this.mData[i] / 2f);
}
this.mData = model;
postInvalidate();
}
/**
* 快速傅里叶变换算法(FFT)
*/
public static void fft(Complex[] xin, final int N) {
int f, m, N2, nm, i, k, j, L;// L:运算级数
float p;
int e2, B, ip;
Complex w = new Complex();
Complex t = new Complex();
N2 = N / 2;// 每一级中蝶形的个数,同时也代表m位二进制数最高位的十进制权值
f = N;// f是为了求流程的级数而设立的
for (m = 1; (f = f / 2) != 1; m++)
; // 得到流程图的共几级
nm = N - 2;
j = N2;
/****** 倒序运算(雷德算法)******/
for (i = 1; i <= nm; i++) {
if (i < j) {
// 防止重复交换
t = xin[j];
xin[j] = xin[i];
xin[i] = t;
}
k = N2;
while (j >= k) {
j = j - k;
k = k / 2;
}
j = j + k;
}
/****** 蝶形图计算部分 ******/
for (L = 1; L <= m; L++) {
// 从第1级到第m级
e2 = (int) Math.pow(2, L);
B = e2 / 2;
for (j = 0; j < B; j++) {
// j从0到2^(L-1)-1
p = 2 * PI / e2;
w.real = Math.cos(p * j);
w.image = Math.sin(p * j) * -1;
for (i = j; i < N; i = i + e2) {
// 计算具有相同系数的数据
ip = i + B; // 对应蝶形的数据间隔为2^(L-1)
t = xin[ip].cc(w);
xin[ip] = xin[i].cut(t);
xin[i] = xin[i].sum(t);
}
}
}
}
https://blog.csdn.net/fwt336/article/details/77151049?utm_source=blogxgwz7