Wenn Sie Android AudioTrack zum Kombinieren von Klangbeispielen verwenden, wird Rauschen erzeugt

Ich erstelle eine ziemlich einfache Android-App (SDK-Revision 14: ICS), mit der Benutzer zwei Audioclips gleichzeitig auswählen können (alle im RIFF / WAV-Format, Little Endian, signierte PCM-16-Bit-Codierung) und diese kombinieren können verschiedene Möglichkeiten, um neue Sounds zu erstellen. Die grundlegendste Methode, die ich für diese Kombination verwende, ist wie folgt:

//...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;
}

Das zurückgegebene Byte-Array kann dann folgendermaßen über die AudioTrack-Klasse abgespielt werden:

....
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]);
       }

}

Das Ergebnis einer Kombination und Wiedergabe mit dem obigen Code entspricht ungefähr meinen Vorstellungen (beide Samples sind im resultierenden hybridisierten Sound noch erkennbar), es gibt jedoch auch viele Risse, Knackgeräusche und anderes Rauschen.

Also, drei Fragen: Erstens, verwende ich AudioTrack richtig? Zweitens, wo wird Endianness in der AudioTrack-Konfiguration berücksichtigt? Die Sounds spielen sich von selbst gut und klingen fast so, wie ich es erwarten würde, wenn man sie kombiniert. Die Little-Endian-Natur des RIFF / WAV-Formats scheint also irgendwo kommuniziert zu werden, aber ich bin mir nicht sicher, wo. Was ist der Byte-Wertebereich, den ich für die signierte 16-Bit-PCM-Codierung erwarten sollte? Ich würde in logcat Werte zwischen -32768 und 32767 vom obigen Aufruf von Log.d (...) erwarten, aber stattdessen liegen die Ergebnisse tendenziell im Bereich von -100 bis 100 (mit einigen Ausreißern darüber hinaus). Könnten kombinierte Bytewerte außerhalb des 16-Bit-Bereichs das Rauschen erklären?

Danke, CCJ

UPDATE: Ein großes Dankeschön an Bjorne Roche und William the Coderer! Ich habe jetzt in den Audiodaten zu Short [] Strukturen gelesen, Endianness des DataInputStream wird mit dem EndianInputStream von William (http://stackoverflow.com/questions/8028094/java-datainputstream-replacement-for-endianness) abgerechnet und die Die Kombinationsmethode wurde folgendermaßen geändert:

//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;
}

Die hybride Audio-Ausgabequalität mit diesen Verbesserungen ist fantastisch!

Antworten auf die Frage(1)

Ihre Antwort auf die Frage