在android中从另一个中减去一个音频文件

时间:2017-04-13 17:39:14

标签: java android algorithm audio audio-processing

我录制了一个音频文件 A 并将其保存为testaudio0.gp 然后我录制了一个音频文件 B ,同时音频文件 A 正在播放并保存为testaudio.gp

当然,在音频文件 B 中,我也听到音频文件 A

我在Android中使用普通的MediaPlayer和MediaRecorder类。音频文件长度相同。两者的文件大小为6,81Kb。

这是我的代码:

final MediaRecorder recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile("/sdcard/testaudio.3gp");
try {
    recorder.prepare();
} catch (IOException e) {
    e.printStackTrace();
    Toast.makeText(this, "Error", Toast.LENGTH_SHORT).show();
}

Uri myUri = Uri.parse("/sdcard/testaudio0.3gp"); // initialize Uri here
final MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
    mediaPlayer.setDataSource(getApplicationContext(), myUri);
} catch (IOException e) {
    e.printStackTrace();
}
try {
    mediaPlayer.prepare();
} catch (IOException e) {
    e.printStackTrace();
}
mediaPlayer.start();




recorder.start();   // Recording is now started
new Handler().postDelayed(new Runnable() {
    @Override
    public void run() {
        recorder.stop();
        recorder.reset();   // You can reuse the object by going back to setAudioSource() step
        recorder.release(); // Now the object cannot be reused
        mediaPlayer.stop();
        mediaPlayer.reset();
        mediaPlayer.release();
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(MainActivity.this, "Recording Stopped!", Toast.LENGTH_SHORT).show();
            }
        });

    }
}, 4000);

正如您所看到的,我将recorder.setAudioSource更改为VOICE_COMMUNICATION,因为在对回声消除做了一些研究之后我读到了这应该有所帮助。它似乎有点帮助,但仍然有一个非常好的可存储文件 A 的背景音频。

我想尽可能减去音频文件 A 。我没有找到一个堆栈交换问题来回答如何做到这一点。请耐心等待,我不理解那些复杂的数学运算。代码示例会有很多帮助。

感谢任何帮助。谢谢。

1 个答案:

答案 0 :(得分:1)

从另一个音频文件B中减去一个音频文件A,其中B包含新信号C以及文件A的回放在概念上是简单的......忽略信号A的所有伪像,如文件B中所见,从墙壁等反弹。 ..只需取消音频曲线A的负数并将其覆盖在音频曲线B的顶部...信号A将从音频B中删除,只留下附加信号C

我相信你可以使用音频工作站Audacity来做到这一点......但编写自定义代码来执行相同的转换并不太难......在伪代码中我们会在下面执行此操作

为简单起见,我们将信号A视为从零弧度开始的正弦曲线...我们都看到了这条正弦曲线......如果我们用从0到2 * pi变化的弧度合成这个信号,它将产生一个周期对于下面的演示来说,足够的... ...如果我们同时合成信号A的负值,如果我们使用pi弧度的相移,这个负曲线将是完全相反的形状

for x = 0; x < 2*pi; x += 2*pi/100 {

     A = sin(x)       // your original data of file A
  negA = sin(x + pi)  //  if you plot this negA will == A * (-1)

  new_signal = cos(5*x) // your new signal which go into file B

     B = A + new_signal // your audio data of file B

     C = B + negA  # this is same as following C = B - A == new_signal
     C = B - A     #  desired output : (signal A + new signal) minus A
                   #  this will result in simply new signal which is your goal
                   #   do you now see that C = new_signal
}