src/multimedia/audio/qaudioinput_alsa_p.cpp
changeset 3 41300fa6a67c
parent 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
2:56cd8111b7f7 3:41300fa6a67c
    50 // We mean it.
    50 // We mean it.
    51 //
    51 //
    52 
    52 
    53 #include <QtCore/qcoreapplication.h>
    53 #include <QtCore/qcoreapplication.h>
    54 #include "qaudioinput_alsa_p.h"
    54 #include "qaudioinput_alsa_p.h"
       
    55 #include "qaudiodeviceinfo_alsa_p.h"
    55 
    56 
    56 QT_BEGIN_NAMESPACE
    57 QT_BEGIN_NAMESPACE
    57 
    58 
    58 //#define DEBUG_AUDIO 1
    59 //#define DEBUG_AUDIO 1
    59 
    60 
    73     period_time = 20000;
    74     period_time = 20000;
    74     totalTimeValue = 0;
    75     totalTimeValue = 0;
    75     intervalTime = 1000;
    76     intervalTime = 1000;
    76     audioBuffer = 0;
    77     audioBuffer = 0;
    77     errorState = QAudio::NoError;
    78     errorState = QAudio::NoError;
    78     deviceState = QAudio::StopState;
    79     deviceState = QAudio::StoppedState;
    79     audioSource = 0;
    80     audioSource = 0;
    80     pullMode = true;
    81     pullMode = true;
    81     resuming = false;
    82     resuming = false;
    82 
    83 
    83     QStringList list1 = QString(QLatin1String(device)).split(QLatin1String(":"));
    84     m_device = device;
    84     m_device = QByteArray(list1.at(0).toLocal8Bit().constData());
       
    85 
    85 
    86     timer = new QTimer(this);
    86     timer = new QTimer(this);
    87     connect(timer,SIGNAL(timeout()),SLOT(userFeed()));
    87     connect(timer,SIGNAL(timeout()),SLOT(userFeed()));
    88 }
    88 }
    89 
    89 
   204     return snd_pcm_hw_params_set_format( handle, hwparams, format);
   204     return snd_pcm_hw_params_set_format( handle, hwparams, format);
   205 }
   205 }
   206 
   206 
   207 QIODevice* QAudioInputPrivate::start(QIODevice* device)
   207 QIODevice* QAudioInputPrivate::start(QIODevice* device)
   208 {
   208 {
   209     if(deviceState != QAudio::StopState)
   209     if(deviceState != QAudio::StoppedState)
   210         close();
   210         close();
   211 
   211 
   212     if(!pullMode && audioSource) {
   212     if(!pullMode && audioSource) {
   213         delete audioSource;
   213         delete audioSource;
   214     }
   214     }
   232     return audioSource;
   232     return audioSource;
   233 }
   233 }
   234 
   234 
   235 void QAudioInputPrivate::stop()
   235 void QAudioInputPrivate::stop()
   236 {
   236 {
   237     if(deviceState == QAudio::StopState)
   237     if(deviceState == QAudio::StoppedState)
   238         return;
   238         return;
   239 
   239 
   240     deviceState = QAudio::StopState;
   240     deviceState = QAudio::StoppedState;
   241 
   241 
   242     close();
   242     close();
   243     emit stateChanged(deviceState);
   243     emit stateChanged(deviceState);
   244 }
   244 }
   245 
   245 
   257     int err=-1;
   257     int err=-1;
   258     int count=0;
   258     int count=0;
   259     unsigned int freakuency=settings.frequency();
   259     unsigned int freakuency=settings.frequency();
   260 
   260 
   261     QString dev = QString(QLatin1String(m_device.constData()));
   261     QString dev = QString(QLatin1String(m_device.constData()));
   262     if(!dev.contains(QLatin1String("default"))) {
   262     QList<QByteArray> devices = QAudioDeviceInfoInternal::availableDevices(QAudio::AudioInput);
   263 #if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14) 
   263     if(dev.compare(QLatin1String("default")) == 0) {
   264         dev = QString(QLatin1String("default:CARD=%1")).arg(QLatin1String(m_device.constData()));
   264 #if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14)
       
   265         dev = QLatin1String(devices.first());
       
   266 #else
       
   267         dev = QLatin1String("hw:0,0");
       
   268 #endif
       
   269     } else {
       
   270 #if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14)
       
   271         dev = QLatin1String(m_device);
   265 #else
   272 #else
   266         int idx = 0;
   273         int idx = 0;
   267         char *name;
   274         char *name;
   268 
   275 
       
   276         QString shortName = QLatin1String(m_device.mid(m_device.indexOf('=',0)+1).constData());
       
   277 
   269         while(snd_card_get_name(idx,&name) == 0) {
   278         while(snd_card_get_name(idx,&name) == 0) {
   270             if(m_device.contains(name))
   279             if(qstrncmp(shortName.toLocal8Bit().constData(),name,shortName.length()) == 0)
   271                 break;
   280                 break;
   272             idx++;
   281             idx++;
   273         }
   282         }
   274         dev = QString(QLatin1String("hw:%1,0")).arg(idx);
   283         dev = QString(QLatin1String("hw:%1,0")).arg(idx);
   275 #endif
   284 #endif
   276     }
   285     }
   277     
   286 
   278     // Step 1: try and open the device
   287     // Step 1: try and open the device
   279     while((count < 5) && (err < 0)) {
   288     while((count < 5) && (err < 0)) {
   280         err=snd_pcm_open(&handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_CAPTURE,0);
   289         err=snd_pcm_open(&handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_CAPTURE,0);
   281         if(err < 0)
   290         if(err < 0)
   282             count++;
   291             count++;
   283     }
   292     }
   284     if (( err < 0)||(handle == 0)) {
   293     if (( err < 0)||(handle == 0)) {
   285         errorState = QAudio::OpenError;
   294         errorState = QAudio::OpenError;
   286         deviceState = QAudio::StopState;
   295         deviceState = QAudio::StoppedState;
   287         emit stateChanged(deviceState);
   296         emit stateChanged(deviceState);
   288         return false;
   297         return false;
   289     }
   298     }
   290     snd_pcm_nonblock( handle, 0 );
   299     snd_pcm_nonblock( handle, 0 );
   291 
   300 
   365         }
   374         }
   366     }
   375     }
   367     if( err < 0) {
   376     if( err < 0) {
   368         qWarning()<<errMessage;
   377         qWarning()<<errMessage;
   369         errorState = QAudio::OpenError;
   378         errorState = QAudio::OpenError;
   370         deviceState = QAudio::StopState;
   379         deviceState = QAudio::StoppedState;
   371         emit stateChanged(deviceState);
   380         emit stateChanged(deviceState);
   372         return false;
   381         return false;
   373     }
   382     }
   374     snd_pcm_hw_params_get_buffer_size(hwparams,&buffer_frames);
   383     snd_pcm_hw_params_get_buffer_size(hwparams,&buffer_frames);
   375     buffer_size = snd_pcm_frames_to_bytes(handle,buffer_frames);
   384     buffer_size = snd_pcm_frames_to_bytes(handle,buffer_frames);
   411     return true;
   420     return true;
   412 }
   421 }
   413 
   422 
   414 void QAudioInputPrivate::close()
   423 void QAudioInputPrivate::close()
   415 {
   424 {
   416     deviceState = QAudio::StopState;
   425     deviceState = QAudio::StoppedState;
   417     timer->stop();
   426     timer->stop();
   418 
   427 
   419     if ( handle ) {
   428     if ( handle ) {
   420         snd_pcm_drop( handle );
   429         snd_pcm_drop( handle );
   421         snd_pcm_close( handle );
   430         snd_pcm_close( handle );
   488 
   497 
   489         qint64 l = audioSource->write(audioBuffer,err);
   498         qint64 l = audioSource->write(audioBuffer,err);
   490         if(l < 0) {
   499         if(l < 0) {
   491             close();
   500             close();
   492             errorState = QAudio::IOError;
   501             errorState = QAudio::IOError;
   493             deviceState = QAudio::StopState;
   502             deviceState = QAudio::StoppedState;
   494             emit stateChanged(deviceState);
   503             emit stateChanged(deviceState);
   495         } else if(l == 0) {
   504         } else if(l == 0) {
   496             errorState = QAudio::NoError;
   505             errorState = QAudio::NoError;
   497             deviceState = QAudio::IdleState;
   506             deviceState = QAudio::IdleState;
   498         } else {
   507         } else {
   506     return 0;
   515     return 0;
   507 }
   516 }
   508 
   517 
   509 void QAudioInputPrivate::resume()
   518 void QAudioInputPrivate::resume()
   510 {
   519 {
   511     if(deviceState == QAudio::SuspendState) {
   520     if(deviceState == QAudio::SuspendedState) {
   512         int err = 0;
   521         int err = 0;
   513 
   522 
   514         if(handle) {
   523         if(handle) {
   515             err = snd_pcm_prepare( handle );
   524             err = snd_pcm_prepare( handle );
   516             if(err < 0)
   525             if(err < 0)
   556 int QAudioInputPrivate::notifyInterval() const
   565 int QAudioInputPrivate::notifyInterval() const
   557 {
   566 {
   558     return intervalTime;
   567     return intervalTime;
   559 }
   568 }
   560 
   569 
   561 qint64 QAudioInputPrivate::totalTime() const
   570 qint64 QAudioInputPrivate::processedUSecs() const
   562 {
   571 {
   563     return totalTimeValue;
   572     return totalTimeValue;
   564 }
   573 }
   565 
   574 
   566 void QAudioInputPrivate::suspend()
   575 void QAudioInputPrivate::suspend()
   567 {
   576 {
   568     if(deviceState == QAudio::ActiveState||resuming) {
   577     if(deviceState == QAudio::ActiveState||resuming) {
   569         timer->stop();
   578         timer->stop();
   570         deviceState = QAudio::SuspendState;
   579         deviceState = QAudio::SuspendedState;
   571         emit stateChanged(deviceState);
   580         emit stateChanged(deviceState);
   572     }
   581     }
   573 }
   582 }
   574 
   583 
   575 void QAudioInputPrivate::userFeed()
   584 void QAudioInputPrivate::userFeed()
   576 {
   585 {
   577     if(deviceState == QAudio::StopState || deviceState == QAudio::SuspendState)
   586     if(deviceState == QAudio::StoppedState || deviceState == QAudio::SuspendedState)
   578         return;
   587         return;
   579 #ifdef DEBUG_AUDIO
   588 #ifdef DEBUG_AUDIO
   580     QTime now(QTime::currentTime());
   589     QTime now(QTime::currentTime());
   581     qDebug()<<now.second()<<"s "<<now.msec()<<"ms :userFeed() IN";
   590     qDebug()<<now.second()<<"s "<<now.msec()<<"ms :userFeed() IN";
   582 #endif
   591 #endif
   604         timeStamp.restart();
   613         timeStamp.restart();
   605     }
   614     }
   606     return true;
   615     return true;
   607 }
   616 }
   608 
   617 
   609 qint64 QAudioInputPrivate::clock() const
   618 qint64 QAudioInputPrivate::elapsedUSecs() const
   610 {
   619 {
   611     if(!handle)
   620     if(!handle)
   612         return 0;
   621         return 0;
   613 
   622 
   614     if (deviceState == QAudio::StopState)
   623     if (deviceState == QAudio::StoppedState)
   615         return 0;
   624         return 0;
   616 
   625 
   617 #if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14) 
   626 #if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14)
   618     snd_pcm_status_t* status;
   627     snd_pcm_status_t* status;
   619     snd_pcm_status_alloca(&status);
   628     snd_pcm_status_alloca(&status);
   620 
   629 
   621     snd_timestamp_t t1,t2;
   630     snd_timestamp_t t1,t2;
   622     if( snd_pcm_status(handle, status) >= 0) {
   631     if( snd_pcm_status(handle, status) >= 0) {