src/multimedia/audio/qaudiooutput_alsa_p.cpp
changeset 18 2f34d5167611
parent 3 41300fa6a67c
child 19 fcece45ef507
--- a/src/multimedia/audio/qaudiooutput_alsa_p.cpp	Tue Feb 02 00:43:10 2010 +0200
+++ b/src/multimedia/audio/qaudiooutput_alsa_p.cpp	Fri Apr 16 15:50:13 2010 +0300
@@ -1,6 +1,6 @@
 /****************************************************************************
 **
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 ** All rights reserved.
 ** Contact: Nokia Corporation (qt-info@nokia.com)
 **
@@ -259,6 +259,7 @@
 {
     if(deviceState == QAudio::StoppedState)
         return;
+    errorState = QAudio::NoError;
     deviceState = QAudio::StoppedState;
     close();
     emit stateChanged(deviceState);
@@ -494,10 +495,13 @@
         err = snd_pcm_writei( handle, data, frames );
     }
     if(err > 0) {
-        totalTimeValue += err*1000000/settings.frequency();
+        totalTimeValue += err;
         resuming = false;
         errorState = QAudio::NoError;
-        deviceState = QAudio::ActiveState;
+        if (deviceState != QAudio::ActiveState) {
+            deviceState = QAudio::ActiveState;
+            emit stateChanged(deviceState);
+        }
         return snd_pcm_frames_to_bytes( handle, err );
     } else
         err = xrun_recovery(err);
@@ -542,7 +546,7 @@
 
 qint64 QAudioOutputPrivate::processedUSecs() const
 {
-    return totalTimeValue;
+    return qint64(1000000) * totalTimeValue / settings.frequency();
 }
 
 void QAudioOutputPrivate::resume()
@@ -562,10 +566,8 @@
             bytesAvailable = (int)snd_pcm_frames_to_bytes(handle, buffer_frames);
         }
         resuming = true;
-        if(pullMode)
-            deviceState = QAudio::ActiveState;
-        else
-            deviceState = QAudio::IdleState;
+
+        deviceState = QAudio::ActiveState;
 
         errorState = QAudio::NoError;
         timer->start(period_time/1000);
@@ -637,7 +639,9 @@
             // Got some data to output
             if(deviceState != QAudio::ActiveState)
                 return true;
-            write(audioBuffer,l);
+            qint64 bytesWritten = write(audioBuffer,l);
+            if (bytesWritten != l)
+                audioSource->seek(audioSource->pos()-(l-bytesWritten));
             bytesAvailable = bytesFree();
 
         } else if(l == 0) {
@@ -645,9 +649,11 @@
             bytesAvailable = bytesFree();
             if(bytesAvailable > snd_pcm_frames_to_bytes(handle, buffer_frames-period_frames)) {
                 // Underrun
-                errorState = QAudio::UnderrunError;
-                deviceState = QAudio::IdleState;
-                emit stateChanged(deviceState);
+                if (deviceState != QAudio::IdleState) {
+                    errorState = QAudio::UnderrunError;
+                    deviceState = QAudio::IdleState;
+                    emit stateChanged(deviceState);
+                }
             }
 
         } else if(l < 0) {
@@ -655,8 +661,17 @@
             errorState = QAudio::IOError;
             emit stateChanged(deviceState);
         }
-    } else
+    } else {
         bytesAvailable = bytesFree();
+        if(bytesAvailable > snd_pcm_frames_to_bytes(handle, buffer_frames-period_frames)) {
+            // Underrun
+            if (deviceState != QAudio::IdleState) {
+                errorState = QAudio::UnderrunError;
+                deviceState = QAudio::IdleState;
+                emit stateChanged(deviceState);
+            }
+        }
+    }
 
     if(deviceState != QAudio::ActiveState)
         return true;
@@ -671,35 +686,10 @@
 
 qint64 QAudioOutputPrivate::elapsedUSecs() const
 {
-    if(!handle)
-        return 0;
-
     if (deviceState == QAudio::StoppedState)
         return 0;
 
-#if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14)
-    snd_pcm_status_t* status;
-    snd_pcm_status_alloca(&status);
-
-    snd_timestamp_t t1,t2;
-    if( snd_pcm_status(handle, status) >= 0) {
-        snd_pcm_status_get_tstamp(status,&t1);
-        snd_pcm_status_get_trigger_tstamp(status,&t2);
-        t1.tv_sec-=t2.tv_sec;
-
-        signed long l = (signed long)t1.tv_usec - (signed long)t2.tv_usec;
-        if(l < 0) {
-            t1.tv_sec--;
-            l = -l;
-            l %= 1000000;
-        }
-        return ((t1.tv_sec * 1000000)+l);
-    } else
-        return 0;
-#else
     return clockStamp.elapsed()*1000;
-#endif
-    return 0;
 }
 
 void QAudioOutputPrivate::reset()