当我运行以下代码时,我没有声音作为输出,而是给了我噪音。
我的资源文件夹中有两个音频文件,使用1个输入流,这些文件被转换为bytearray。如果我添加了mp3,那么应用程序就会关闭。
private void mixSound() throws IOException {
AudioTrack audioTrack =new AudioTrack(AudioManager.STREAM_MUSIC,44100,AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT, 44100, AudioTrack.MODE_STREAM);
Log.i(tag,"inside mixSound");
InputStream in1=getResources().openRawResource(R.raw.cut1); s
InputStream in2=getResources().openRawResource(R.raw.cut2);
byte[] music1 = null;
music1= new byte[in1.available()];
Log.i(tag,"in1");
music1=convertStreamToByteArray(in1);
in1.close();
byte[] music2 = null;
music2= new byte[in2.available()];
music2=convertStreamToByteArray(in2);
in2.close();
byte[] output = new byte[music1.length];
audioTrack.play();
for(int i=0; i < output.length; i++){
float samplef1 = music1[i] / 128.0f; // 2^7=128
float samplef2 = music2[i] / 128.0f;
float mixed = samplef1 + samplef2;
// reduce the volume a bit:
mixed *= 0.8;
// hard clipping
if (mixed > 1.0f) mixed = 1.0f;
if (mixed < -1.0f) mixed = -1.0f;
byte outputSample = (byte)(mixed * 128.0f);
output[i] = outputSample;
} //for loop
audioTrack.write(output, 0, output.length);
}
public static byte[] convertStreamToByteArray(InputStream is) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buff = new byte[10240];
int i = Integer.MAX_VALUE;
Log.i(tag,"in csb");
while ((i = is.read(buff, 0, buff.length)) > 0) {
baos.write(buff, 0, i);
}
return baos.toByteArray();
}
提前感谢您的帮助。
答案 0 :(得分:0)
这里有一些问题......
如果您正在处理16位PCM音频(通过初始化AudioTrack
看起来很合适),那么您应该访问源音频并写入AudioTrack
in short
s(16位)而不是byte
s(8位)。如果你必须从你的来源阅读byte
,你需要在你的循环中一次阅读其中两个,并做类似的事情
short curSample = (myByteArr[i] << 8) | myByteArr[i+1];
然后将结果写入存储的缓冲区。这假设您在读取的文件中存储了16位短路,您应该这样做。不过,最好还是将它们视为它们的内容。
使用AudioTrack.MODE_STREAM
表示您将在播放音频时连续写入缓冲区。你在这里完成它的方式填充整个缓冲区,然后将其写入AudioTrack
。如果这是一次性播放,您应该使用AudioTrack.MODE_STATIC
。
这是一个极端情况,但请考虑mixed == 1.0f
会发生什么。如果将其乘以128.0f并截断为byte
,则会得到128,这实际上超出了有符号byte
的范围(因为0,范围是[-128,127] )。
我相信问题#1是噪音的来源。您需要保持16位PCM数据的完整性,而不是将其拆分。