我正在嘗試將音頻輸入的低音增強爲12 dB。下面是代碼Java中的低音增強
public class BassBoost {
double xn1, xn2, yn1, yn2;
double omega, sn, cs, a, shape, beta, b0, b1, b2, a0, a1, a2;
public BassBoost(int frequency, int dB_boost, int sampleRate) {
xn1 = 0;
xn2 = 0;
yn1 = 0;
yn2 = 0;
omega = 2 * Utils.pi * frequency/sampleRate;
sn = Math.sin(omega);
cs = Math.cos(omega);
a = Math.exp(Math.log(10.0) * dB_boost/40);
shape = 1.0;
beta = Math.sqrt((a * a + 1)/shape - (Math.pow((a - 1), 2)));
/* Coefficients */
b0 = a * ((a + 1) - (a - 1) * cs + beta * sn);
b1 = 2 * a * ((a - 1) - (a + 1) * cs);
b2 = a * ((a + 1) - (a - 1) * cs - beta * sn);
a0 = ((a + 1) + (a - 1) * cs + beta * sn);
a1 = -2 * ((a - 1) + (a + 1) * cs);
a2 = (a + 1) + (a - 1) * cs - beta * sn;
}
public void process(double[] buffer, int length) {
double out, in = 0;
for (int i = 0; i < length; i++) {
in = buffer[i];
out = (b0 * in + b1 * xn1 + b2 * xn2 - a1 * yn1 - a2 * yn2)/a0;
xn2 = xn1;
xn1 = in;
yn2 = yn1;
yn1 = out;
if (out < -1.0)
out = -1.0;
else if (out > 1.0)
out = 1.0; // Prevents clipping
buffer[i] = out;
}
}
}
,這裏是它調用過程
音頻被記錄並存儲在緩衝區短的僞代碼。 將緩衝區分成小陣列並複製到雙陣列以進行濾波處理。如果我不分,我正在嘗試在Android手機上使用OutofMemory。 應用濾波(LPF,HPF) 在寫入字節數組之前,使用以下代碼對輸出雙緩衝區進行放大。
void doOutput(int outlen, boolean maxGain) {
int qi;
int i, i2;
while (true) {
int max = 0;
i = outbp;
for (i2 = 0; i2 < outlen; i2 += 4) {
qi = (int) (leftBuffer[i] * outputGain);
if (qi > max)
max = qi;
if (qi < -max)
max = -qi;
ob[i2 + 1] = (byte) (qi >> 8);
ob[i2] = (byte) qi;
i = (i + 1) & fbufmask;
}
i = outbp;
for (i2 = 2; i2 < outlen; i2 += 4) {
qi = (int) (rightBuffer[i] * outputGain);
if (qi > max)
max = qi;
if (qi < -max)
max = -qi;
ob[i2 + 1] = (byte) (qi >> 8);
ob[i2] = (byte) qi;
i = (i + 1) & fbufmask;
}
// if we're getting overflow, adjust the gain
if (max > 32767) {
outputGain *= 30000./max;
if (outputGain < 1e-8 || Double.isInfinite(outputGain)) {
unstable = true;
break;
}
continue;
} else if (maxGain && max < 24000) {
if (max == 0) {
if (outputGain == 1)
break;
outputGain = 1;
} else
outputGain *= 30000./max;
continue;
}
break;
}
if (unstable)
return;
outbp = i;
out.write(ob, 0, outlen);
}
此代碼是爲android,因此它必須是有效的內存。我嘗試了使用Arraylist,但那也是內存不足。
問題是 要通過緩衝區應用一致的outputGain,我正在應用兩次過濾並寫入byteOutputStream一次。我嘗試使用Arraylist在應用單個outputGain之前存儲輸出緩衝區,但是該內存需要存儲整個Double緩衝區(1分鐘記錄)。同樣對於BassBoost,我想將它應用於整個輸出。有沒有內存有效的方法來做到這一點。使用ArrayList是沒有問題的。爲了獲得一致的outputGain,我必須通過整個輸出緩衝區並將其應用於單個outputGain。
想要使上面的示例代碼有效,以便我不必通過緩衝區兩次。如果我將其應用於大塊,也會降低連續聲音。
由於
所以,你認爲使用ArrayList是個問題,在你發佈的大量代碼中,我沒有看到任何相關的代碼。你能編輯你的問題來包含代碼段嗎? – marko
這些double []有多大?爲什麼你不使用float []?在我所有的音頻編碼中,我總是使用float [](在java中)。 – Nick