一些特殊的情况迫使我做那种变态的事情.
是否可以在不同的频道上播放2个不同的音频流.想象一下耳机,我需要同时播放左扬声器的第一首歌和右扬声器的第二首歌.
经过一些研究,我发现可以在某个单一频道播放.甚至可以关闭其中一个.但我没有找到任何有关如何同时播放2个音频流的信息.
它甚至可能吗?如何?一些代码示例和链接赞赏!
研究结果.
1)AudioTrack能够在不同的频道上播放
// only play sound on left
for(int i = 0; i < count; i += 2){
short sample = (short)(Math.sin(2 * Math.PI * i / (44100.0 / freqHz)) * 0x7FFF);
samples[i + 0] = sample;
samples[i + 1] = 0;
}
// only play sound on right
for(int i = 0; i < count; i += 2){
short sample = (short)(Math.sin(2 * Math.PI * i / (44100.0 / freqHz)) * 0x7FFF);
samples[i + 0] = 0;
samples[i + 1] = sample;
}
Run Code Online (Sandbox Code Playgroud)
2) SoundPool能够分别设置左右声道的音量.因此从技术上讲,可以启动2个流,并设置为0左侧音量,100个右侧音量,反之亦然,为第2个流.对?
setVolume(int streamID, float leftVolume, float rightVolume)
Run Code Online (Sandbox Code Playgroud)
样品:
SoundPool pool = new SoundPool(1, AudioManager.STREAM_NOTIFICATION, 0);
pool.play(
pool.load(this, R.raw.my_sound_effect, 1), // The sound effect to play
0, // The volume for the left channel (0.0 - 1.0)
1.0f, // The volume for the right channel (0.0 - 1.0)
0, // Default priority
0, // Do not loop
1.0f); // Playback rate (1.0f == normal)
Run Code Online (Sandbox Code Playgroud)
Perhabs有这样的解决方案使用MediaPlayer,这将是更好的!
解决方案:似乎最简单的解决方案就是使用SoundPool.我测试它的方式.
//SDK Version
public CustomSoundPool() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
AudioAttributes attributes = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_GAME)
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.build();
soundPool = new SoundPool.Builder()
.setAudioAttributes(attributes)
.build();
} else {
soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
}
soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
@Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
soundPool.play(sampleId, 1.0f, 0, 0, 0, 1.0f); //left channel
//soundPool.play(sampleId, 0, 1.0f, 0, 0, 1.0f); //right channel
}
});
}
public void playSound(String path) {
if (soundPool != null) {
soundPool.load(path, 1);
}
}
public void release(){
if (soundPool != null) {
soundPool.release();
}
}
Run Code Online (Sandbox Code Playgroud)
虽然缺乏像这样的功能MediaPlayer.OnCompletionListener().现在确定如何实现这一点但无论如何..问题解决了.
任何一种方法 1) 2) 都应该像你说的那样工作。
关于方法 1),如果您想同时播放不同的流,您可以在同一个循环中写入具有不同数据的两个通道,而无需使用两个循环。为了设置每个通道的音量,您可以使用AudioTrack的方法setStereoVolume(float leftGain, float rightGain)。
由于MediaPlayer它是一个高级 API,因此它不提供这种级别的特异性;解决方法可能是将音频数据保存到文件(使左/右通道静音)并使用MediaPlayer.
更新:
将音频数据保存到文件(使左/右通道静音)
为此,假设您的音频数据采用 AudioTrack 兼容格式 (PCM),您只需按照您所说的方式处理数据(通过重置数组的一部分来静音一个通道),然后将数组/缓冲区保存到WAV/PCM 格式的文件。请查看此处,了解有关如何保存 WAV 文件的更多详细信息和代码。
| 归档时间: |
|
| 查看次数: |
2648 次 |
| 最近记录: |