我试图做我的音频输入到12 dB的低音增强。这是代码
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;
}
}
}下面是调用进程的伪代码
音频记录并存储在短缓冲器中。缓冲区分为小数组,复制到双数组进行滤波处理。如果我不分裂,我得到的是OutofMemory,因为我在安卓手机上尝试这一点。应用滤波(LPF,HPF),在写入Byte数组之前,用以下代码放大输出双缓冲区。
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一次。在应用单个outputGain之前,我尝试使用Arraylist来存储输出缓冲区,但这是为了存储整个双缓冲区(1分钟记录)。另外,对于BassBoost,我想将它应用于整个输出。有没有有效的记忆方法。使用ArrayList是不可能的。要获得一致的outputGain,我必须遍历整个输出缓冲区,并将其应用于单个outputGain。
希望使上面的示例代码高效,这样我就不必通过缓冲区两次了。另外,如果我把它应用到块上,就会使我在连续的声音中中断。
谢谢
发布于 2013-08-05 21:14:25
一个short[]一分钟的44.1千赫立体声音响需要44100 * 2 * 2 * 60 = 10584000,或大约10 or的内存。
这只是为了一个简单的短缓冲区。
由于您使用的是ArrayList<Double>,根据您的评论,它会变得更大。Java为每个Object增加了一些开销,这个数组将有大约500万个对象。我很确定VM的开销是不同的。
但是,我相信开销是每个Object的at least 8 bytes。用你的500万Shorts,这个(8 + 8) * 5M = 80MB是最低限度的。
看看这是怎么回事?
我不认为你想要创建500万个物体。我给出的只是样本本身的数字。如果在处理阶段使用额外的内存,情况会更糟。这就是为什么基本上每个音频应用程序都是以块的形式处理的。那里有大量的数据,即使是相对“短”的剪辑也是如此。
https://stackoverflow.com/questions/18067415
复制相似问题