2013-02-27 3 views
5

У меня есть два звуковых файла PCM в папке с ресурсами. Я использовал входной поток и преобразовал их в bytearray.Пример кода для Android AudioTrack Mixing

Затем я обработал их путем нормализации и добавления 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 

} 

ответ

9

Я пробовал свой код (подставляя некоторые аудиофайлы). Я инициализирован AudioTrack экземпляр, как это, надеюсь, это подобно тому, как вы сделали это:

AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT, 44100, AudioTrack.MODE_STREAM); 

и попытался запустить его. Это создавало высокий шум, который со временем становился все ниже. Я проверил код, и проблема в том, что вы пишете весь массив байтов вывода в audioTrack на каждой итерации цикла в методе mixSound().

линия

audioTrack.write(output, 0, i); 

потребности перемещаться вне цикла и быть изменен на

audioTrack.write(output, 0, output.length); 

Так вы смешиваете оба файла вместе в выходной массив байт, а затем записать все это сразу.

Поэтому код для рабочего метода mixSound выглядит следующим образом:

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); 

    InputStream in1=getResources().openRawResource(R.raw.track1);  
    InputStream in2=getResources().openRawResource(R.raw.track2); 

    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; 

    } //for loop 
    audioTrack.write(output, 0, output.length); 

} 
+0

Внутри forloop я получил ошибку ArrayIndexOutOfBoundsException –

+1

Это может произойти, если ваш второй звуковой файл короче, чем ваш первый. Выходной массив инициализируется длиной первого аудиофайла, а цикл for выполняет итерацию по длине выходного массива. Таким образом, вы можете закончить чтение в конце второго аудиофайла. Решение было бы добавить защиту вокруг, где вы читаете samplef2. Если i> music2.length, вы должны установить sample2f в 0 (вы достигли конца клипа). – combinatorics

 Смежные вопросы

  • Нет связанных вопросов^_^