我昨天刚开始学习Android应用程序开发,并想知道如何解决一个相当重要的问题。我正在尝试创建的是一种迷你卡拉OK播放器,它允许用户在背景歌曲(外部mp3文件)旁边录制他的歌曲(麦克风源)。另一个功能是让用户在唱歌时听到自己的声音 - 近乎实时的反馈。最后,录制的歌曲以及背景音轨应混合并存储在文件中。为避免恶意反馈,假设用户通过耳机收听背景音轨和自己。
到目前为止我能够完成的是让用户使用AudioRecord
记录MediaRecorder.AudioSource.MIC
并将读取的缓冲区直接发送到以下实例:
AudioTrack
AudioTrack.MODE_STREAM
this.isPlaying = true;
this.record = new AudioRecord(MediaRecorder.AudioSource.MIC,
SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT, this.bufferSize);
this.track = new AudioTrack(AudioManager.STREAM_SYSTEM,
SAMPLE_RATE, AudioFormat.CHANNEL_OUT_STEREO,
AudioFormat.ENCODING_PCM_16BIT, this.bufferSize,
AudioTrack.MODE_STREAM);
//..Some customizations with this.track, etc...
FileOutputStream fout = new FileOutputStream(audiofile.getPath());
this.record.startRecording();
this.track.play();
while (isPlaying) {
this.record.read(buffer, 0, this.bufferSize);
fout.write(buffer);
this.track.write(buffer, 0, buffer.length);
}
fout.close();
。我还将缓冲区持久保存到文件中,从而生成原始PCM文件。
它基本上看起来像这样:
{{1}}
该方法在一个单独的线程中运行,到目前为止一切都很好。我正在努力搞清楚的是播放单独的背景音轨并将它们混合成一个流。我知道当两个原始数据相似时(通道,采样频率等),混合只是加性和直接的。因此,一种可能的解决方案可能是将MP3文件转换为具有相同功能的原始PCM,在单独的音轨中播放,然后将它们混合。但我怀疑这里有一些可怕的同步问题,因为涉及的是严重的延迟。我甚至不确定这是否是正确的前进方式。有更简单,更优雅的解决方案吗?您建议使用哪些Android库来执行转换?