리소스 폴더에 두 개의 PCM 사운드 파일이 있습니다. 나는 inputstream을 사용하여 bytearray로 변환했다.Android AudioTrack 믹싱 샘플 코드
그런 다음 정규화 된 다음 music1 및 music2를 추가하고 출력을 바이트 배열 출력으로 처리했습니다. 마지막으로 출력 배열을 AudioTrack에 공급합니다.
분명히, 나는 아무것도 듣지 못하고 뭔가 잘못되었습니다.
private void mixSound() throws IOException {
InputStream in1=getResources().openRawResource(R.raw.cheerapp2);
InputStream in2=getResources().openRawResource(R.raw.buzzer2);
byte[] music1 = null;
music1= new byte[in1.available()];
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;
audioTrack.write(output, 0, i);
} //for loop
public static byte[] convertStreamToByteArray(InputStream is) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buff = new byte[10240];
int i = Integer.MAX_VALUE;
while ((i = is.read(buff, 0, buff.length)) > 0) {
baos.write(buff, 0, i);
}
return baos.toByteArray(); // be sure to close InputStream in calling function
}
를 내가 두 번째 오디오 파일을 첫 번째보다 짧은 경우 발생할 수는 ArrayIndexOutOfBoundsException –
의 오류를받은 forloop 내부. 출력 배열은 첫 번째 오디오 파일의 길이로 초기화되고 for 루프는 출력 배열의 길이를 반복합니다. 따라서 두 번째 오디오 파일의 마지막 부분을 읽는 것으로 끝날 수도 있습니다. 해결책은 samplef2를 읽는 위치 주변에 보호 기능을 추가하는 것입니다. i> music2.length 인 경우 sample2f를 0으로 설정해야합니다 (클립의 끝까지 도달했습니다). – combinatorics