我正在开发一个 Android 应用程序,它可以实时处理来自麦克风的音频。采样和播放工作正常,但我在实现第一个音频效果 - 失真时遇到困难。音频位于短片缓冲区中,因此每次收到其中一个音频时,我都会尝试将这些值映射到签名短片的完整大小,然后在这些值高于特定级别时对它们进行实质上的剪辑。由此产生的音频肯定会失真,但不是以理想的方式失真。我已经包含了完成此操作的代码。有人能看到这里有错误吗?
public void onMarkerReached(AudioRecord recorder) {
// TODO Auto-generated method stub
short max = maxValue(buffers[ix]);
short multiplier;
if(max!=0)
multiplier = (short) (0x7fff/max);
else
multiplier = 0x7fff;
double distLvl =.8;
short distLvlSho = 31000;
short max2 =100;
for(int i=0;i<buffers[ix].length;i++){
buffers[ix][i]=(short) (buffers[ix][i]*multiplier);
if(buffers[ix][i]>distLvlSho)
buffers[ix][i]=distLvlSho;
else if(buffers[ix][i]<-distLvlSho)
buffers[ix][i]=(short)-distLvlSho;
buffers[ix][i]=(short) (buffers[ix][i]/multiplier);
}
buffers 数组是一个 2D 数组,处理仅在数组中的数组之一上完成,此处为 buffers[ix]。
最佳答案
据我所知,最终您得到的只是源的剪辑,其剪辑阈值遵循比例clipThr/max(input)=distLvlSho/0x7fff。这种方式大部分输入基本不变。
如果您确实想要扭曲信号,您应该对整个信号应用某种非线性函数(加上最终在样本最大值附近进行削波以模拟模拟饱和)
本书列出了一些简单的失真模型:http://books.google.it/books?id=h90HIV0uwVsC&printsec=frontcover#v=onepage&q&f=false
最简单的是对称软剪裁(参见第 118 页)。这是用软剪辑功能修改的方法,看看它是否适合您对失真声音的需求(我通过在输入上组成一些正弦曲线并使用 Excel 绘制输出来测试它)
在同一章中,您将找到一个简单的管建模和模糊滤波器建模(这些建模有一些指数,因此如果性能是一个问题,您可能需要近似这些)。
public void onMarkerReachedSoftClip(short[] buffer) {
double th=1.0/3.0;
double multiplier = 1.0/0x7fff; // normalize input to double -1,1
double out = 0.0;
for(int i=0;i<buffer.length;i++){
double in = multiplier*(double)buffer[i];
double absIn = java.lang.Math.abs(in);
if(absIn<th){
out=(buffer[i]*2*multiplier);
}
else if(absIn<2*th){
if(in>0)out= (3-(2-in*3)*(2-in*3))/3;
else if(in<0)out=-(3-(2-absIn*3)*(2-absIn*3))/3;
}
else if(absIn>=2*th){
if(in>0)out=1;
else if(in<0)out=-1;
}
buffer[i] = (short)(out/multiplier);
}
}
关于Java 音频效果 - Android 上的失真算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5083088/