2016-07-10 16 views
0

Ich verwende AudioTrack Klasse einen Strom von rohen Tondaten zu spielen:Android Audiotrack Schreibblocks für die gesamte Dauer der Wiedergabe

AudioTrack audioTrack; 
int sampleRate = 11025; 
int channelConfigIn = AudioFormat.CHANNEL_IN_MONO; 
int channelConfigOut = AudioFormat.CHANNEL_OUT_STEREO; 
int audioFormat = AudioFormat.ENCODING_PCM_16BIT; 
..... 
int bufferSize = AudioTrack.getMinBufferSize(sampleRate,channelConfigOut,audioFormat); 
audioTrack = new AudioTrack(AudioManager.STREAM_VOICE_CALL,sampleRate,channelConfigOut,audioFormat,bufferSize,AudioTrack.MODE_STREAM); 
    audioTrack.play(); 

Dann auf einem separaten Thread:

while(true) 
{ 
    short [] buffer = new short[14500]; 
    //fill buffer with sound data 
    long time = System.currentTimeMillis(); 
    audioTrack.write(buffer,0,14500); 
    Log.i("time",(System.currentTimeMillis() - time) + ""); 
} 

Mein Problem ist, dass das Protokoll zeigt immer, dass die write Methode für etwa 0,6 Sekunden blockiert, das ist die gleiche wie die wiedergegebene Klanglänge (14500 Samples), außerdem reagiert das Telefon während der Wiedergabe nicht, der Haupttritt kann fast nichts tun, jemand kann helfen ...

+1

[dies] (http://pastebin.com/tz2Mvh5G) funktioniert einfach ok – pskink

Antwort

0

Sie verwenden die Blockierungsversion der write()-Methode. Sie können stattdessen write(float[],int,int,int) verwenden und WRITE_NON_BLOCKING als vierten Parameter übergeben, aber das würde nur so viele Daten schreiben, wie in den Wiedergabepuffer passen. Ich bevorzuge generell den Ansatz, den Sie bereits haben (einen Thread dem Schreiben widmen). Sie sollten erwarten, dass jeder Anruf blockiert wird. Schließlich kann der Wiedergabepuffer nur so viele Daten aufnehmen, und um mehr Platz zu schaffen, muss der Sound abgespielt werden (was Zeit braucht). 14500 Samples sind ~ 1,3 Sekunden Sound bei der gewählten Sample-Rate, also nehme ich an, dass Sie etwa 0,7 Sekunden brauchen, um jedes Mal buffer zu füllen.

Ich kann nicht anhand des angezeigten Codes feststellen, warum Ihr UI-Thread nicht reagiert.

+0

Vielen Dank für die Antwort, zuerst die Methode, die Sie vorgeschlagen, benötigt apk 23, also habe ich es nicht verwendet, obwohl ich weiß, dass es existiert, zweitens habe ich benutze 'HandlerThread', um es zu lösen, scheint die Priorität des Threads die Ursache dafür zu sein. Wie auch immer, es scheint, dass es eine akkumulierte Latenz gibt, die dazu führt, dass die Wiedergabe im Laufe der Zeit etwas später wird – ammcom