src/multimedia/audio/qaudioinput_win32_p.cpp
changeset 3 41300fa6a67c
parent 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
2:56cd8111b7f7 3:41300fa6a67c
    69     period_size = 0;
    69     period_size = 0;
    70     m_device = device;
    70     m_device = device;
    71     totalTimeValue = 0;
    71     totalTimeValue = 0;
    72     intervalTime = 1000;
    72     intervalTime = 1000;
    73     errorState = QAudio::NoError;
    73     errorState = QAudio::NoError;
    74     deviceState = QAudio::StopState;
    74     deviceState = QAudio::StoppedState;
    75     audioSource = 0;
    75     audioSource = 0;
    76     pullMode = true;
    76     pullMode = true;
    77     resuming = false;
    77     resuming = false;
    78     finished = false;
    78     finished = false;
    79 
    79 
   151     return blocks;
   151     return blocks;
   152 }
   152 }
   153 
   153 
   154 void QAudioInputPrivate::freeBlocks(WAVEHDR* blockArray)
   154 void QAudioInputPrivate::freeBlocks(WAVEHDR* blockArray)
   155 {
   155 {
       
   156     WAVEHDR* blocks = blockArray;
       
   157 
       
   158     int count = buffer_size/period_size;
       
   159 
       
   160     for(int i = 0; i < count; i++) {
       
   161         waveInUnprepareHeader(hWaveIn,&blocks[i], sizeof(WAVEHDR));
       
   162         blocks+=sizeof(WAVEHDR);
       
   163     }
   156     HeapFree(GetProcessHeap(), 0, blockArray);
   164     HeapFree(GetProcessHeap(), 0, blockArray);
   157 }
   165 }
   158 
   166 
   159 QAudio::Error QAudioInputPrivate::error() const
   167 QAudio::Error QAudioInputPrivate::error() const
   160 {
   168 {
   171     return settings;
   179     return settings;
   172 }
   180 }
   173 
   181 
   174 QIODevice* QAudioInputPrivate::start(QIODevice* device)
   182 QIODevice* QAudioInputPrivate::start(QIODevice* device)
   175 {
   183 {
   176     if(deviceState != QAudio::StopState)
   184     if(deviceState != QAudio::StoppedState)
   177         close();
   185         close();
   178 
   186 
   179     if(!pullMode && audioSource) {
   187     if(!pullMode && audioSource) {
   180         delete audioSource;
   188         delete audioSource;
   181     }
   189     }
   199     return audioSource;
   207     return audioSource;
   200 }
   208 }
   201 
   209 
   202 void QAudioInputPrivate::stop()
   210 void QAudioInputPrivate::stop()
   203 {
   211 {
   204     if(deviceState == QAudio::StopState)
   212     if(deviceState == QAudio::StoppedState)
   205         return;
   213         return;
   206 
   214 
   207     close();
   215     close();
   208     emit stateChanged(deviceState);
   216     emit stateChanged(deviceState);
   209 }
   217 }
   220         buffer_size = settings.frequency()*settings.channels()*(settings.sampleSize()/8)*0.1;
   228         buffer_size = settings.frequency()*settings.channels()*(settings.sampleSize()/8)*0.1;
   221 	period_size = buffer_size/5;
   229 	period_size = buffer_size/5;
   222     } else {
   230     } else {
   223         period_size = buffer_size/5;
   231         period_size = buffer_size/5;
   224     }
   232     }
   225 #ifdef Q_OS_WINCE
       
   226     // For wince reduce size to 40ms for buffer size and 20ms period
       
   227     buffer_size = settings.frequency()*settings.channels()*(settings.sampleSize()/8)*0.04;
       
   228     period_size = buffer_size/2;
       
   229 #endif
       
   230     timeStamp.restart();
   233     timeStamp.restart();
   231     elapsedTimeOffset = 0;
   234     elapsedTimeOffset = 0;
   232     wfx.nSamplesPerSec = settings.frequency();
   235     wfx.nSamplesPerSec = settings.frequency();
   233     wfx.wBitsPerSample = settings.sampleSize();
   236     wfx.wBitsPerSample = settings.sampleSize();
   234     wfx.nChannels = settings.channels();
   237     wfx.nChannels = settings.channels();
   258     if(waveInOpen(&hWaveIn, devId, &wfx,
   261     if(waveInOpen(&hWaveIn, devId, &wfx,
   259                 (DWORD_PTR)&waveInProc,
   262                 (DWORD_PTR)&waveInProc,
   260                 (DWORD_PTR) this,
   263                 (DWORD_PTR) this,
   261                 CALLBACK_FUNCTION) != MMSYSERR_NOERROR) {
   264                 CALLBACK_FUNCTION) != MMSYSERR_NOERROR) {
   262         errorState = QAudio::OpenError;
   265         errorState = QAudio::OpenError;
   263         deviceState = QAudio::StopState;
   266         deviceState = QAudio::StoppedState;
   264         emit stateChanged(deviceState);
   267         emit stateChanged(deviceState);
   265         qWarning("QAudioInput: failed to open audio device");
   268         qWarning("QAudioInput: failed to open audio device");
   266         return false;
   269         return false;
   267     }
   270     }
   268     waveBlocks = allocateBlocks(period_size, buffer_size/period_size);
   271     waveBlocks = allocateBlocks(period_size, buffer_size/period_size);
   269 
   272 
   270     if(waveBlocks == 0) {
   273     if(waveBlocks == 0) {
   271         errorState = QAudio::OpenError;
   274         errorState = QAudio::OpenError;
   272         deviceState = QAudio::StopState;
   275         deviceState = QAudio::StoppedState;
   273         emit stateChanged(deviceState);
   276         emit stateChanged(deviceState);
   274         qWarning("QAudioInput: failed to allocate blocks. open failed");
   277         qWarning("QAudioInput: failed to allocate blocks. open failed");
   275         return false;
   278         return false;
   276     }
   279     }
   277 
   280 
   284     for(int i=0; i<buffer_size/period_size; i++) {
   287     for(int i=0; i<buffer_size/period_size; i++) {
   285         result = waveInAddBuffer(hWaveIn, &waveBlocks[i], sizeof(WAVEHDR));
   288         result = waveInAddBuffer(hWaveIn, &waveBlocks[i], sizeof(WAVEHDR));
   286         if(result != MMSYSERR_NOERROR) {
   289         if(result != MMSYSERR_NOERROR) {
   287             qWarning("QAudioInput: failed to setup block %d,err=%d",i,result);
   290             qWarning("QAudioInput: failed to setup block %d,err=%d",i,result);
   288             errorState = QAudio::OpenError;
   291             errorState = QAudio::OpenError;
   289             deviceState = QAudio::StopState;
   292             deviceState = QAudio::StoppedState;
   290             emit stateChanged(deviceState);
   293             emit stateChanged(deviceState);
   291             return false;
   294             return false;
   292         }
   295         }
   293     }
   296     }
   294     result = waveInStart(hWaveIn);
   297     result = waveInStart(hWaveIn);
   295     if(result) {
   298     if(result) {
   296         qWarning("QAudioInput: failed to start audio input");
   299         qWarning("QAudioInput: failed to start audio input");
   297         errorState = QAudio::OpenError;
   300         errorState = QAudio::OpenError;
   298         deviceState = QAudio::StopState;
   301         deviceState = QAudio::StoppedState;
   299         emit stateChanged(deviceState);
   302         emit stateChanged(deviceState);
   300         return false;
   303         return false;
   301     }
   304     }
   302     timeStampOpened.restart();
   305     timeStampOpened.restart();
   303     elapsedTimeOffset = 0;
   306     elapsedTimeOffset = 0;
   307     return true;
   310     return true;
   308 }
   311 }
   309 
   312 
   310 void QAudioInputPrivate::close()
   313 void QAudioInputPrivate::close()
   311 {
   314 {
   312     if(deviceState == QAudio::StopState)
   315     if(deviceState == QAudio::StoppedState)
   313         return;
   316         return;
   314 
   317 
   315     waveInReset(hWaveIn);
   318     waveInReset(hWaveIn);
   316     waveInClose(hWaveIn);
   319     waveInClose(hWaveIn);
   317     deviceState = QAudio::StopState;
   320     deviceState = QAudio::StoppedState;
   318 
   321 
   319     int count = 0;
   322     int count = 0;
   320     while(!finished && count < 100) {
   323     while(!finished && count < 500) {
   321         count++;
   324         count++;
   322         Sleep(10);
   325         Sleep(10);
   323     }
   326     }
   324 
   327 
   325     EnterCriticalSection(&waveInCriticalSection);
   328     EnterCriticalSection(&waveInCriticalSection);
   331     freeBlocks(waveBlocks);
   334     freeBlocks(waveBlocks);
   332 }
   335 }
   333 
   336 
   334 int QAudioInputPrivate::bytesReady() const
   337 int QAudioInputPrivate::bytesReady() const
   335 {
   338 {
       
   339     if(period_size == 0 || buffer_size == 0)
       
   340         return 0;
       
   341 
   336     int buf = ((buffer_size/period_size)-waveFreeBlockCount)*period_size;
   342     int buf = ((buffer_size/period_size)-waveFreeBlockCount)*period_size;
   337     if(buf < 0)
   343     if(buf < 0)
   338         buf = 0;
   344         buf = 0;
   339     return buf;
   345     return buf;
   340 }
   346 }
   344     bool done = false;
   350     bool done = false;
   345 
   351 
   346     char*  p = data;
   352     char*  p = data;
   347     qint64 l = 0;
   353     qint64 l = 0;
   348     qint64 written = 0;
   354     qint64 written = 0;
       
   355 
   349     while(!done) {
   356     while(!done) {
   350         // Read in some audio data
   357         // Read in some audio data
   351         if(waveBlocks[header].dwBytesRecorded > 0) {
   358         if(waveBlocks[header].dwBytesRecorded > 0 && waveBlocks[header].dwFlags & WHDR_DONE) {
   352             if(pullMode) {
   359             if(pullMode) {
   353                 l = audioSource->write(waveBlocks[header].lpData,
   360                 l = audioSource->write(waveBlocks[header].lpData,
   354                         waveBlocks[header].dwBytesRecorded);
   361                         waveBlocks[header].dwBytesRecorded);
   355 #ifdef DEBUG_AUDIO
   362 #ifdef DEBUG_AUDIO
   356                 qDebug()<<"IN: "<<waveBlocks[header].dwBytesRecorded<<", OUT: "<<l;
   363                 qDebug()<<"IN: "<<waveBlocks[header].dwBytesRecorded<<", OUT: "<<l;
   389             }
   396             }
   390         } else {
   397         } else {
   391             //no data, not ready yet, next time
   398             //no data, not ready yet, next time
   392             return 0;
   399             return 0;
   393         }
   400         }
       
   401 
       
   402         waveInUnprepareHeader(hWaveIn,&waveBlocks[header], sizeof(WAVEHDR));
       
   403 
   394         EnterCriticalSection(&waveInCriticalSection);
   404         EnterCriticalSection(&waveInCriticalSection);
   395         waveFreeBlockCount++;
   405         waveFreeBlockCount++;
   396         LeaveCriticalSection(&waveInCriticalSection);
   406         LeaveCriticalSection(&waveInCriticalSection);
   397         waveBlocks[header].dwBytesRecorded=0;
   407         waveBlocks[header].dwBytesRecorded=0;
   398         waveBlocks[header].dwFlags = 0L;
   408         waveBlocks[header].dwFlags = 0L;
   399         result = waveInPrepareHeader(hWaveIn,&waveBlocks[header], sizeof(WAVEHDR));
   409         result = waveInPrepareHeader(hWaveIn,&waveBlocks[header], sizeof(WAVEHDR));
   400         if(result != MMSYSERR_NOERROR) {
   410         if(result != MMSYSERR_NOERROR) {
       
   411             result = waveInPrepareHeader(hWaveIn,&waveBlocks[header], sizeof(WAVEHDR));
   401             qWarning("QAudioInput: failed to prepare block %d,err=%d",header,result);
   412             qWarning("QAudioInput: failed to prepare block %d,err=%d",header,result);
   402             errorState = QAudio::OpenError;
   413             errorState = QAudio::IOError;
   403             deviceState = QAudio::StopState;
   414             EnterCriticalSection(&waveInCriticalSection);
   404             emit stateChanged(deviceState);
   415             waveFreeBlockCount--;
       
   416             LeaveCriticalSection(&waveInCriticalSection);
       
   417             return 0;
   405         }
   418         }
   406         result = waveInAddBuffer(hWaveIn, &waveBlocks[header], sizeof(WAVEHDR));
   419         result = waveInAddBuffer(hWaveIn, &waveBlocks[header], sizeof(WAVEHDR));
   407         if(result != MMSYSERR_NOERROR) {
   420         if(result != MMSYSERR_NOERROR) {
   408             qWarning("QAudioInput: failed to setup block %d,err=%d",header,result);
   421             qWarning("QAudioInput: failed to setup block %d,err=%d",header,result);
   409             errorState = QAudio::OpenError;
   422             errorState = QAudio::IOError;
   410             deviceState = QAudio::StopState;
   423             EnterCriticalSection(&waveInCriticalSection);
   411             emit stateChanged(deviceState);
   424             waveFreeBlockCount--;
       
   425             LeaveCriticalSection(&waveInCriticalSection);
       
   426             return 0;
   412         }
   427         }
   413         header++;
   428         header++;
   414         if(header >= buffer_size/period_size)
   429         if(header >= buffer_size/period_size)
   415             header = 0;
   430             header = 0;
   416         p+=l;
   431         p+=l;
   433     return written;
   448     return written;
   434 }
   449 }
   435 
   450 
   436 void QAudioInputPrivate::resume()
   451 void QAudioInputPrivate::resume()
   437 {
   452 {
   438     if(deviceState == QAudio::SuspendState) {
   453     if(deviceState == QAudio::SuspendedState) {
   439         deviceState = QAudio::ActiveState;
   454         deviceState = QAudio::ActiveState;
   440         for(int i=0; i<buffer_size/period_size; i++) {
   455         for(int i=0; i<buffer_size/period_size; i++) {
   441             result = waveInAddBuffer(hWaveIn, &waveBlocks[i], sizeof(WAVEHDR));
   456             result = waveInAddBuffer(hWaveIn, &waveBlocks[i], sizeof(WAVEHDR));
   442             if(result != MMSYSERR_NOERROR) {
   457             if(result != MMSYSERR_NOERROR) {
   443                 qWarning("QAudioInput: failed to setup block %d,err=%d",i,result);
   458                 qWarning("QAudioInput: failed to setup block %d,err=%d",i,result);
   444                 errorState = QAudio::OpenError;
   459                 errorState = QAudio::OpenError;
   445                 deviceState = QAudio::StopState;
   460                 deviceState = QAudio::StoppedState;
   446                 emit stateChanged(deviceState);
   461                 emit stateChanged(deviceState);
   447                 return;
   462                 return;
   448             }
   463             }
   449         }
   464         }
   450         EnterCriticalSection(&waveInCriticalSection);
   465         EnterCriticalSection(&waveInCriticalSection);
   486 int QAudioInputPrivate::notifyInterval() const
   501 int QAudioInputPrivate::notifyInterval() const
   487 {
   502 {
   488     return intervalTime;
   503     return intervalTime;
   489 }
   504 }
   490 
   505 
   491 qint64 QAudioInputPrivate::totalTime() const
   506 qint64 QAudioInputPrivate::processedUSecs() const
   492 {
   507 {
   493     return totalTimeValue;
   508     return totalTimeValue;
   494 }
   509 }
   495 
   510 
   496 void QAudioInputPrivate::suspend()
   511 void QAudioInputPrivate::suspend()
   497 {
   512 {
   498     if(deviceState == QAudio::ActiveState) {
   513     if(deviceState == QAudio::ActiveState) {
   499         waveInReset(hWaveIn);
   514         waveInReset(hWaveIn);
   500         deviceState = QAudio::SuspendState;
   515         deviceState = QAudio::SuspendedState;
   501         emit stateChanged(deviceState);
   516         emit stateChanged(deviceState);
   502     }
   517     }
   503 }
   518 }
   504 
   519 
   505 void QAudioInputPrivate::feedback()
   520 void QAudioInputPrivate::feedback()
   508     QTime now(QTime::currentTime());
   523     QTime now(QTime::currentTime());
   509     qDebug()<<now.second()<<"s "<<now.msec()<<"ms :feedback() INPUT "<<this;
   524     qDebug()<<now.second()<<"s "<<now.msec()<<"ms :feedback() INPUT "<<this;
   510 #endif
   525 #endif
   511     bytesAvailable = bytesReady();
   526     bytesAvailable = bytesReady();
   512 
   527 
   513     if(!(deviceState==QAudio::StopState||deviceState==QAudio::SuspendState))
   528     if(!(deviceState==QAudio::StoppedState||deviceState==QAudio::SuspendedState))
   514         emit processMore();
   529         emit processMore();
   515 }
   530 }
   516 
   531 
   517 bool QAudioInputPrivate::deviceReady()
   532 bool QAudioInputPrivate::deviceReady()
   518 {
   533 {
   537         timeStamp.restart();
   552         timeStamp.restart();
   538     }
   553     }
   539     return true;
   554     return true;
   540 }
   555 }
   541 
   556 
   542 qint64 QAudioInputPrivate::clock() const
   557 qint64 QAudioInputPrivate::elapsedUSecs() const
   543 {
   558 {
   544     if (deviceState == QAudio::StopState)
   559     if (deviceState == QAudio::StoppedState)
   545         return 0;
   560         return 0;
   546 
   561 
   547     return timeStampOpened.elapsed()*1000;
   562     return timeStampOpened.elapsed()*1000;
   548 }
   563 }
   549 
   564