Gram w WAV na moim telefonie z Androidem, ładując plik i podając bajty do ścieżki AudioTrack.write() za pomocą metody FileInputStream> BufferedInputStream> DataInputStream. Dźwięk odtwarza się dobrze, a gdy jest, mogę łatwo dostosować częstotliwość próbkowania, głośność itp. W locie z dobrą wydajnością. Jednak odtworzenie ścieżki trwa około dwóch pełnych sekund. Wiem, że AudioTrack ma nieuniknione opóźnienie, ale to niedorzeczne. Za każdym razem, gdy gram utwór, otrzymuję to:Opóźnienie audioTrack: uzyskanie przekroczenia limitu czasu przez Buffera
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
Zauważyłem, że Opóźniony zapis count wzrasta o jeden za każdym razem, gdy gram utwór - nawet w wielu sesjach - od czasu, gdy telefon ma został włączony. Czas blokowania wynosi zawsze 230 - 240 ms, co ma sens biorąc pod uwagę minimalny rozmiar bufora 9600 na tym urządzeniu (9600/44100). Widziałem tę wiadomość w niezliczonych wyszukiwaniach w Internecie, ale zazwyczaj wydaje się, że jest ona związana z brakiem odtwarzania dźwięku lub z pominięciem dźwięku. W moim przypadku jest to tylko opóźniony start.
Uruchomiłem cały mój kod w wątku o wysokim priorytecie. Oto skrócona, ale działająca wersja tego, co robię. To jest wywołanie zwrotne wątku w mojej klasie odtwarzania. Znowu to działa (odtwarzane są teraz tylko 16-bitowe, 44,1 kHz, pliki stereo), po prostu trwa to zawsze, a za każdym razem otrzymujemy komunikat o błędzie/opóźnieniu zapisu.
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
}
}
}
}
Jeśli mogę ominąć sztucznie długim opóźnieniem, mogę łatwo uporać się z opóźnieniami dziedziczyć zaczynając mój zapis w późniejszym, przewidywalnym miejscu (tj pominąć minimalnej długości bufora kiedy rozpocząć odtwarzanie pliku).
mam podobny problem w tej chwili. Czy znalazłeś jakieś rozwiązanie? – sunside
jeszcze niestety. :/ – BTR