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

标签 java android algorithm audio audio-processing

我录制了一个音频文件 A 并将其保存为 testaudio0.gp 然后我在播放音频文件A的同时录制了一个音频文件B并保存为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 。我没有找到回答如何执行此操作的堆栈交换问题。请耐心等待,我不明白那些复杂的数学运算。一个代码示例会有很大帮助。

感谢任何帮助。谢谢。

最佳答案

要从另一个音频文件 B 中减去一个音频文件 A,其中 B 包含新信号 C 以及文件 A 的播放在概念上很简单......忽略文件 B 中发现的信号 A 从墙壁等处反弹的所有伪像。 .. 只需取音频曲线 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
}

关于java - 在android中从另一个音频文件中减去一个音频文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43398539/

相关文章:

android - 有没有办法将 3D 模型导入 Android?

java - 选择排序算法

algorithm - 为什么 Dijkstra 算法中的 decreasekey 需要 O(logN) 时间?

algorithm - 给定二进制字符串中不同数字的数量及其总和

java - 正则表达式如何获取子字符串?

java - 仅在 Chrome 浏览器中无法在 Iframe 标记下找到元素 (html)

java - 庞大的数字列表中最常重复的数字

java - Gradle中的错误

android ffmpeg 错误的视频输出

android - getInt() SharedPreferences 安卓错误