Je joue des fichiers WAV sur mon téléphone Android en chargeant le fichier et en introduisant les octets dans AudioTrack.write() via la méthode FileInputStream> BufferedInputStream> DataInputStream. L'audio joue bien et quand il est, je peux facilement ajuster la fréquence d'échantillonnage, le volume, etc à la volée avec de bonnes performances. Cependant, il faut environ deux secondes pour qu'une piste commence à jouer. Je sais que AudioTrack a un délai inévitable, mais c'est ridicule. Chaque fois que je joue une piste, je reçois ceci:AudioTrack lag: gettingBuffer a expiré
03-13 14:55:57.100: WARN/AudioTrack(3454): obtainBuffer timed out (is the CPU pegged?) 0x2e9348 user=00000960, server=00000000
03-13 14:55:57.340: WARN/AudioFlinger(72): write blocked for 233 msecs, 9 delayed writes, thread 0xba28
J'ai remarqué que le nombre écriture retardées augmente d'un à chaque fois que je joue une piste - même à travers plusieurs sessions - à partir du moment où le téléphone a été allumé. Le temps de blocage est toujours de 230 à 240 ms, ce qui est logique si l'on considère une taille de tampon minimale de 9600 sur cet appareil (9600/44100). J'ai vu ce message dans d'innombrables recherches sur Internet, mais il semble généralement lié à ne pas jouer du tout ou sauter de l'audio. Dans mon cas, c'est juste un départ différé.
Je cours tout mon code dans un fil de haute priorité. Voici une version tronquée et fonctionnelle de ce que je fais. C'est le rappel de thread dans ma classe de lecture. Encore une fois, cela fonctionne (en ne jouant que des fichiers stéréo 16 bits, 44,1 kHz en ce moment), il faut juste une éternité pour commencer et a ce message writeBuffer/delay write à chaque fois.
public void run() {
// Load file
FileInputStream mFileInputStream;
try {
// mFile is instance of custom file class -- this is correct,
// so don't sweat this line
mFileInputStream = new FileInputStream(mFile.path());
} catch (FileNotFoundException e) {
// log
}
BufferedInputStream mBufferedInputStream = new BufferedInputStream(mFileInputStream, mBufferLength);
DataInputStream mDataInputStream = new DataInputStream(mBufferedInputStream);
// Skip header
try {
if (mDataInputStream.available() > 44) {
mDataInputStream.skipBytes(44);
}
} catch (IOException e) {
// log
}
// Initialize device
mAudioTrack = new AudioTrack(
AudioManager.STREAM_MUSIC,
ConfigManager.SAMPLE_RATE,
AudioFormat.CHANNEL_CONFIGURATION_STEREO,
AudioFormat.ENCODING_PCM_16BIT,
ConfigManager.AUDIO_BUFFER_LENGTH,
AudioTrack.MODE_STREAM
);
mAudioTrack.play();
// Initialize buffer
byte[] mByteArray = new byte[mBufferLength];
int mBytesToWrite = 0;
int mBytesWritten = 0;
// Loop to keep thread running
while (mRun) {
// This flag is turned on when the user presses "play"
while (mPlaying) {
try {
// Check if data is available
if (mDataInputStream.available() > 0) {
// Read data from file and write to audio device
mBytesToWrite = mDataInputStream.read(mByteArray, 0, mBufferLength);
mBytesWritten += mAudioTrack.write(mByteArray, 0, mBytesToWrite);
}
}
catch (IOException e){
// log
}
}
}
}
Si je peux passer le retard artificiellement long, je peux facilement faire face à la latence de Hériter en démarrant mon écriture à une position plus tard, prévisible (c.-à-sauter-delà de la longueur minimale de tampon lorsque je commence à jouer un fichier).
J'ai un problème similaire au moment. Avez-vous trouvé une solution? – sunside
pas encore, malheureusement. :/ – BTR