używanie AudioTrack systemu Android do łączenia bajtów próbek dźwięku generuje szum

Buduję dość prostą aplikację na Androida (sdk revision 14: ICS), która pozwala użytkownikom wybrać dwa klipy audio naraz (wszystkie są w formacie RIFF / WAV, little-endian, podpisane kodowanie PCM-16-bitowe) i połączyć je różne sposoby tworzenia nowych dźwięków. Najbardziej podstawowa metoda, której używam dla tej kombinacji, jest następująca:

//...sound samples are read in to memory as raw byte arrays elsewhere
//...offset is currently set to 45 so as to skip the 44 byte header of basic
//RIFF/WAV files
...
//Actual combination method
public byte[] makeChimeraAll(int offset){
    for(int i=offset;i<bigData.length;i++){
        if(i < littleData.length){
            bigData[i] = (byte) (bigData[i] + littleData[i]);
        }
        else{
            //leave bigData alone
        }
    } 
    return bigData;
}

zwrócona tablica bajtów może być następnie odtwarzana przez klasę AudioTrack:

....
hMain.setBigData(hMain.getAudioTransmutation().getBigData()); //set the shared bigData
// to the bigData in AudioTransmutation object
hMain.getAudioProc().playWavFromByteArray(hMain.getBigData(), 22050 + (22050*
(freqSeekSB.getProgress()/100)), 1024); //a SeekBar allows the user to adjust the freq
//ranging from 22050 hz to 44100 hz
....
public void playWavFromByteArray(byte[] audio,int sampleRate, int bufferSize){
    int minBufferSize = AudioTrack.getMinBufferSize(sampleRate, 
            AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT);
        AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, 
            AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT,
            minBufferSize, AudioTrack.MODE_STREAM);

        int i = 0;

        at.play();
        at.write(audio, 0, audio.length);     
        at.stop();
        at.release();

       for(i=0;i<audio.length;i++){
           Log.d("me","the byte value at audio index " + i + " is " + audio[i]);
       }

}

Wynik kombinacji i odtwarzania przy użyciu powyższego kodu jest zbliżony do tego, czego chcę (obie próbki są nadal dostrzegalne w wynikowym zhybrydyzowanym dźwięku), ale jest też wiele pęknięć, trzasków i innych szumów.

Tak więc trzy pytania: Po pierwsze, czy używam AudioTrack poprawnie? Po drugie, gdzie jest endianness w konfiguracji AudioTrack? Dźwięki grają dobrze same w sobie i brzmią prawie tak, jak bym się spodziewał po połączeniu, więc wydaje się, że przekazywany jest gdzieś mały endianowy format RIFF / WAV, ale nie jestem pewien, gdzie. Na koniec, jaki jest zakres wartości bajtów, którego powinienem oczekiwać dla podpisanego 16-bitowego kodowania PCM? Oczekuję, że zobaczymy wartości w zakresie od -32768 do 32767 w logcat z wywołania Log.d (...) powyżej, ale zamiast tego wyniki będą się mieścić w przedziale od -100 do 100 (z niektórymi wartościami odstającymi poza tym). Czy łączne wartości bajtów poza zakresem 16-bitowym mogą być przyczyną szumu?

dzięki, CCJ

AKTUALIZACJA: wielkie podziękowania dla Bjorne'a Roche'a i Williama the Coderer! Teraz czytam dane audio do struktur short [], endianness DataInputStream jest uwzględniany przy użyciu EndianInputStream z Williama (http://stackoverflow.com/questions/8028094/java-datainputstream-replacement-for-endianness) i zmieniono metodę łączenia na to:

//Audio Chimera methods!
public short[] makeChimeraAll(int offset){
    //bigData and littleData are each short arrays, populated elsewhere
    int intBucket = 0;
    for(int i=offset;i<bigData.length;i++){
        if(i < littleData.length){
            intBucket = bigData[i] + littleData[i];
            if(intBucket > SIGNED_SHORT_MAX){
                intBucket = SIGNED_SHORT_MAX;
            }
            else if (intBucket < SIGNED_SHORT_MIN){
                intBucket = SIGNED_SHORT_MIN;
            }
            bigData[i] = (short) intBucket;
        }
        else{
            //leave bigData alone
        }
    } 
    return bigData;
}

Jakość dźwięku hybrydowego z tymi ulepszeniami jest niesamowita!

questionAnswers(1)

yourAnswerToTheQuestion