【问题标题】:Subtracting one audio file from another in android在android中从另一个音频文件中减去一个音频文件
【发布时间】:2017-04-14 07:13:30
【问题描述】:

我录制了一个音频文件 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 。我没有找到回答如何执行此操作的堆栈交换问题。请耐心等待,我不明白那些复杂的数学运算要做。一个代码示例会很有帮助。

感谢任何帮助。谢谢。

【问题讨论】:

  • 您想要的内容需要深入了解数字信号处理,尤其是与音频数据和编解码器相关的知识。这比堆栈溢出问题更接近“写一本书”的长度知识。
  • 所以这是一个糟糕的问题,因为您没有足够的知识来提供帮助?
  • 不,这是一个糟糕的问题,因为它需要几十页才能完成基础知识。你想要的真的很难。这个网站的范围太大了。
  • 请记住我不想要一本书。相反,我正在寻找代码的解决方案。如果有人有这方面的知识,他也许可以编写一些代码并解释一下。这就是为什么我说:我需要代码。
  • 你录制的不仅仅是a+b,而是a转换为模拟,穿过扬声器,从墙上反弹,穿过麦克风,然后转换为数字+ b。这样做的结果将与原来的 a 大不相同。取消这一点是一门完整的科学。您可能会在 dsp.stackexchange.com 上获得实用的答案,但请在发布之前先检查您的问题是否与该主题相关。

标签: java android algorithm audio audio-processing


【解决方案1】:

从另一个音频文件 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
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-08
    • 1970-01-01
    相关资源
    最近更新 更多