src/multimedia/audio/qaudiooutput_alsa_p.cpp
changeset 18 2f34d5167611
parent 3 41300fa6a67c
child 19 fcece45ef507
equal deleted inserted replaced
3:41300fa6a67c 18:2f34d5167611
     1 /****************************************************************************
     1 /****************************************************************************
     2 **
     2 **
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     4 ** All rights reserved.
     4 ** All rights reserved.
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     6 **
     6 **
     7 ** This file is part of the QtMultimedia module of the Qt Toolkit.
     7 ** This file is part of the QtMultimedia module of the Qt Toolkit.
     8 **
     8 **
   257 
   257 
   258 void QAudioOutputPrivate::stop()
   258 void QAudioOutputPrivate::stop()
   259 {
   259 {
   260     if(deviceState == QAudio::StoppedState)
   260     if(deviceState == QAudio::StoppedState)
   261         return;
   261         return;
       
   262     errorState = QAudio::NoError;
   262     deviceState = QAudio::StoppedState;
   263     deviceState = QAudio::StoppedState;
   263     close();
   264     close();
   264     emit stateChanged(deviceState);
   265     emit stateChanged(deviceState);
   265 }
   266 }
   266 
   267 
   492         // Only write space worth
   493         // Only write space worth
   493         frames = snd_pcm_bytes_to_frames( handle, (int)space );
   494         frames = snd_pcm_bytes_to_frames( handle, (int)space );
   494         err = snd_pcm_writei( handle, data, frames );
   495         err = snd_pcm_writei( handle, data, frames );
   495     }
   496     }
   496     if(err > 0) {
   497     if(err > 0) {
   497         totalTimeValue += err*1000000/settings.frequency();
   498         totalTimeValue += err;
   498         resuming = false;
   499         resuming = false;
   499         errorState = QAudio::NoError;
   500         errorState = QAudio::NoError;
   500         deviceState = QAudio::ActiveState;
   501         if (deviceState != QAudio::ActiveState) {
       
   502             deviceState = QAudio::ActiveState;
       
   503             emit stateChanged(deviceState);
       
   504         }
   501         return snd_pcm_frames_to_bytes( handle, err );
   505         return snd_pcm_frames_to_bytes( handle, err );
   502     } else
   506     } else
   503         err = xrun_recovery(err);
   507         err = xrun_recovery(err);
   504 
   508 
   505     if(err < 0) {
   509     if(err < 0) {
   540     return intervalTime;
   544     return intervalTime;
   541 }
   545 }
   542 
   546 
   543 qint64 QAudioOutputPrivate::processedUSecs() const
   547 qint64 QAudioOutputPrivate::processedUSecs() const
   544 {
   548 {
   545     return totalTimeValue;
   549     return qint64(1000000) * totalTimeValue / settings.frequency();
   546 }
   550 }
   547 
   551 
   548 void QAudioOutputPrivate::resume()
   552 void QAudioOutputPrivate::resume()
   549 {
   553 {
   550     if(deviceState == QAudio::SuspendedState) {
   554     if(deviceState == QAudio::SuspendedState) {
   560                 xrun_recovery(err);
   564                 xrun_recovery(err);
   561 
   565 
   562             bytesAvailable = (int)snd_pcm_frames_to_bytes(handle, buffer_frames);
   566             bytesAvailable = (int)snd_pcm_frames_to_bytes(handle, buffer_frames);
   563         }
   567         }
   564         resuming = true;
   568         resuming = true;
   565         if(pullMode)
   569 
   566             deviceState = QAudio::ActiveState;
   570         deviceState = QAudio::ActiveState;
   567         else
       
   568             deviceState = QAudio::IdleState;
       
   569 
   571 
   570         errorState = QAudio::NoError;
   572         errorState = QAudio::NoError;
   571         timer->start(period_time/1000);
   573         timer->start(period_time/1000);
   572         emit stateChanged(deviceState);
   574         emit stateChanged(deviceState);
   573     }
   575     }
   635         l = audioSource->read(audioBuffer,snd_pcm_frames_to_bytes(handle, input));
   637         l = audioSource->read(audioBuffer,snd_pcm_frames_to_bytes(handle, input));
   636         if(l > 0) {
   638         if(l > 0) {
   637             // Got some data to output
   639             // Got some data to output
   638             if(deviceState != QAudio::ActiveState)
   640             if(deviceState != QAudio::ActiveState)
   639                 return true;
   641                 return true;
   640             write(audioBuffer,l);
   642             qint64 bytesWritten = write(audioBuffer,l);
       
   643             if (bytesWritten != l)
       
   644                 audioSource->seek(audioSource->pos()-(l-bytesWritten));
   641             bytesAvailable = bytesFree();
   645             bytesAvailable = bytesFree();
   642 
   646 
   643         } else if(l == 0) {
   647         } else if(l == 0) {
   644             // Did not get any data to output
   648             // Did not get any data to output
   645             bytesAvailable = bytesFree();
   649             bytesAvailable = bytesFree();
   646             if(bytesAvailable > snd_pcm_frames_to_bytes(handle, buffer_frames-period_frames)) {
   650             if(bytesAvailable > snd_pcm_frames_to_bytes(handle, buffer_frames-period_frames)) {
   647                 // Underrun
   651                 // Underrun
       
   652                 if (deviceState != QAudio::IdleState) {
       
   653                     errorState = QAudio::UnderrunError;
       
   654                     deviceState = QAudio::IdleState;
       
   655                     emit stateChanged(deviceState);
       
   656                 }
       
   657             }
       
   658 
       
   659         } else if(l < 0) {
       
   660             close();
       
   661             errorState = QAudio::IOError;
       
   662             emit stateChanged(deviceState);
       
   663         }
       
   664     } else {
       
   665         bytesAvailable = bytesFree();
       
   666         if(bytesAvailable > snd_pcm_frames_to_bytes(handle, buffer_frames-period_frames)) {
       
   667             // Underrun
       
   668             if (deviceState != QAudio::IdleState) {
   648                 errorState = QAudio::UnderrunError;
   669                 errorState = QAudio::UnderrunError;
   649                 deviceState = QAudio::IdleState;
   670                 deviceState = QAudio::IdleState;
   650                 emit stateChanged(deviceState);
   671                 emit stateChanged(deviceState);
   651             }
   672             }
   652 
   673         }
   653         } else if(l < 0) {
   674     }
   654             close();
       
   655             errorState = QAudio::IOError;
       
   656             emit stateChanged(deviceState);
       
   657         }
       
   658     } else
       
   659         bytesAvailable = bytesFree();
       
   660 
   675 
   661     if(deviceState != QAudio::ActiveState)
   676     if(deviceState != QAudio::ActiveState)
   662         return true;
   677         return true;
   663 
   678 
   664     if((timeStamp.elapsed() + elapsedTimeOffset) > intervalTime) {
   679     if((timeStamp.elapsed() + elapsedTimeOffset) > intervalTime) {
   669     return true;
   684     return true;
   670 }
   685 }
   671 
   686 
   672 qint64 QAudioOutputPrivate::elapsedUSecs() const
   687 qint64 QAudioOutputPrivate::elapsedUSecs() const
   673 {
   688 {
   674     if(!handle)
       
   675         return 0;
       
   676 
       
   677     if (deviceState == QAudio::StoppedState)
   689     if (deviceState == QAudio::StoppedState)
   678         return 0;
   690         return 0;
   679 
   691 
   680 #if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14)
       
   681     snd_pcm_status_t* status;
       
   682     snd_pcm_status_alloca(&status);
       
   683 
       
   684     snd_timestamp_t t1,t2;
       
   685     if( snd_pcm_status(handle, status) >= 0) {
       
   686         snd_pcm_status_get_tstamp(status,&t1);
       
   687         snd_pcm_status_get_trigger_tstamp(status,&t2);
       
   688         t1.tv_sec-=t2.tv_sec;
       
   689 
       
   690         signed long l = (signed long)t1.tv_usec - (signed long)t2.tv_usec;
       
   691         if(l < 0) {
       
   692             t1.tv_sec--;
       
   693             l = -l;
       
   694             l %= 1000000;
       
   695         }
       
   696         return ((t1.tv_sec * 1000000)+l);
       
   697     } else
       
   698         return 0;
       
   699 #else
       
   700     return clockStamp.elapsed()*1000;
   692     return clockStamp.elapsed()*1000;
   701 #endif
       
   702     return 0;
       
   703 }
   693 }
   704 
   694 
   705 void QAudioOutputPrivate::reset()
   695 void QAudioOutputPrivate::reset()
   706 {
   696 {
   707     if(handle)
   697     if(handle)