src/multimedia/audio/qaudioinput_alsa_p.cpp
changeset 19 fcece45ef507
parent 18 2f34d5167611
child 22 79de32ba3296
--- a/src/multimedia/audio/qaudioinput_alsa_p.cpp	Fri Apr 16 15:50:13 2010 +0300
+++ b/src/multimedia/audio/qaudioinput_alsa_p.cpp	Mon May 03 13:17:34 2010 +0300
@@ -121,6 +121,11 @@
         err = snd_pcm_prepare(handle);
         if(err < 0)
             reset = true;
+        else {
+            bytesAvailable = bytesReady();
+            if (bytesAvailable <= 0)
+                reset = true;
+        }
 
     } else if((err == -ESTRPIPE)||(err == -EIO)) {
         errorState = QAudio::IOError;
@@ -443,6 +448,7 @@
     if(deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState)
         return 0;
     int frames = snd_pcm_avail_update(handle);
+    if (frames < 0) return frames;
     if((int)frames > (int)buffer_frames)
         frames = buffer_frames;
 
@@ -459,6 +465,20 @@
 
     bytesAvailable = bytesReady();
 
+    if (bytesAvailable < 0) {
+        // bytesAvailable as negative is error code, try to recover from it.
+        xrun_recovery(bytesAvailable);
+        bytesAvailable = bytesReady();
+        if (bytesAvailable < 0) {
+            // recovery failed must stop and set error.
+            close();
+            errorState = QAudio::IOError;
+            deviceState = QAudio::StoppedState;
+            emit stateChanged(deviceState);
+            return 0;
+        }
+    }
+
     int count=0, err = 0;
     while(count < 5) {
         int chunks = bytesAvailable/period_size;
@@ -588,7 +608,11 @@
 
 qint64 QAudioInputPrivate::processedUSecs() const
 {
-    return qint64(1000000) * totalTimeValue / settings.frequency();
+    qint64 result = qint64(1000000) * totalTimeValue /
+        (settings.channels()*(settings.sampleSize()/8)) /
+        settings.frequency();
+
+    return result;
 }
 
 void QAudioInputPrivate::suspend()