src/multimedia/audio/qaudiooutput_win32_p.cpp
branchRCL_3
changeset 7 3f74d0d4af4c
parent 4 3b1da2848fc7
child 13 c0432d11811c
equal deleted inserted replaced
6:dee5afe5301f 7:3f74d0d4af4c
   209 {
   209 {
   210 #ifdef DEBUG_AUDIO
   210 #ifdef DEBUG_AUDIO
   211     QTime now(QTime::currentTime());
   211     QTime now(QTime::currentTime());
   212     qDebug()<<now.second()<<"s "<<now.msec()<<"ms :open()";
   212     qDebug()<<now.second()<<"s "<<now.msec()<<"ms :open()";
   213 #endif
   213 #endif
       
   214     if (!(settings.frequency() >= 8000 && settings.frequency() <= 48000)) {
       
   215         errorState = QAudio::OpenError;
       
   216         deviceState = QAudio::StoppedState;
       
   217         emit stateChanged(deviceState);
       
   218         qWarning("QAudioOutput: open error, frequency out of range.");
       
   219         return false;
       
   220     }
   214     if(buffer_size == 0) {
   221     if(buffer_size == 0) {
   215         // Default buffer size, 200ms, default period size is 40ms
   222         // Default buffer size, 200ms, default period size is 40ms
   216         buffer_size = settings.frequency()*settings.channels()*(settings.sampleSize()/8)*0.2;
   223         buffer_size = settings.frequency()*settings.channels()*(settings.sampleSize()/8)*0.2;
   217 	period_size = buffer_size/5;
   224 	period_size = buffer_size/5;
   218     } else {
   225     } else {
   287 {
   294 {
   288     if(deviceState == QAudio::StoppedState)
   295     if(deviceState == QAudio::StoppedState)
   289         return;
   296         return;
   290 
   297 
   291     deviceState = QAudio::StoppedState;
   298     deviceState = QAudio::StoppedState;
       
   299     errorState = QAudio::NoError;
   292     int delay = (buffer_size-bytesFree())*1000/(settings.frequency()
   300     int delay = (buffer_size-bytesFree())*1000/(settings.frequency()
   293                   *settings.channels()*(settings.sampleSize()/8));
   301                   *settings.channels()*(settings.sampleSize()/8));
   294     waveOutReset(hWaveOut);
   302     waveOutReset(hWaveOut);
   295     Sleep(delay+10);
   303     Sleep(delay+10);
   296 
   304 
   338     return intervalTime;
   346     return intervalTime;
   339 }
   347 }
   340 
   348 
   341 qint64 QAudioOutputPrivate::processedUSecs() const
   349 qint64 QAudioOutputPrivate::processedUSecs() const
   342 {
   350 {
   343     return totalTimeValue;
   351     if (deviceState == QAudio::StoppedState)
       
   352         return 0;
       
   353     qint64 result = qint64(1000000) * totalTimeValue /
       
   354         (settings.channels()*(settings.sampleSize()/8)) /
       
   355         settings.frequency();
       
   356 
       
   357     return result;
   344 }
   358 }
   345 
   359 
   346 qint64 QAudioOutputPrivate::write( const char *data, qint64 len )
   360 qint64 QAudioOutputPrivate::write( const char *data, qint64 len )
   347 {
   361 {
   348     // Write out some audio data
   362     // Write out some audio data
       
   363     if (deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState)
       
   364         return 0;
   349 
   365 
   350     char* p = (char*)data;
   366     char* p = (char*)data;
   351     int l = (int)len;
   367     int l = (int)len;
   352 
   368 
   353     WAVEHDR* current;
   369     WAVEHDR* current;
   383         EnterCriticalSection(&waveOutCriticalSection);
   399         EnterCriticalSection(&waveOutCriticalSection);
   384         qDebug("write out l=%d, waveFreeBlockCount=%d",
   400         qDebug("write out l=%d, waveFreeBlockCount=%d",
   385                 current->dwBufferLength,waveFreeBlockCount);
   401                 current->dwBufferLength,waveFreeBlockCount);
   386         LeaveCriticalSection(&waveOutCriticalSection);
   402         LeaveCriticalSection(&waveOutCriticalSection);
   387 #endif
   403 #endif
   388         totalTimeValue += current->dwBufferLength
   404         totalTimeValue += current->dwBufferLength;
   389             /(settings.channels()*(settings.sampleSize()/8))
       
   390             *1000000/settings.frequency();;
       
   391         waveCurrentBlock++;
   405         waveCurrentBlock++;
   392         waveCurrentBlock %= buffer_size/period_size;
   406         waveCurrentBlock %= buffer_size/period_size;
   393         current = &waveBlocks[waveCurrentBlock];
   407         current = &waveBlocks[waveCurrentBlock];
   394         current->dwUser = 0;
   408         current->dwUser = 0;
       
   409         errorState = QAudio::NoError;
       
   410         if (deviceState != QAudio::ActiveState) {
       
   411             deviceState = QAudio::ActiveState;
       
   412             emit stateChanged(deviceState);
       
   413         }
   395     }
   414     }
   396     return (len-l);
   415     return (len-l);
   397 }
   416 }
   398 
   417 
   399 void QAudioOutputPrivate::resume()
   418 void QAudioOutputPrivate::resume()
   407     }
   426     }
   408 }
   427 }
   409 
   428 
   410 void QAudioOutputPrivate::suspend()
   429 void QAudioOutputPrivate::suspend()
   411 {
   430 {
   412     if(deviceState == QAudio::ActiveState) {
   431     if(deviceState == QAudio::ActiveState || deviceState == QAudio::IdleState) {
       
   432         int delay = (buffer_size-bytesFree())*1000/(settings.frequency()
       
   433                 *settings.channels()*(settings.sampleSize()/8));
   413         waveOutPause(hWaveOut);
   434         waveOutPause(hWaveOut);
       
   435         Sleep(delay+10);
   414         deviceState = QAudio::SuspendedState;
   436         deviceState = QAudio::SuspendedState;
   415         errorState = QAudio::NoError;
   437         errorState = QAudio::NoError;
   416         emit stateChanged(deviceState);
   438         emit stateChanged(deviceState);
   417     }
   439     }
   418 }
   440 }
   431     }
   453     }
   432 }
   454 }
   433 
   455 
   434 bool QAudioOutputPrivate::deviceReady()
   456 bool QAudioOutputPrivate::deviceReady()
   435 {
   457 {
       
   458     if(deviceState == QAudio::StoppedState)
       
   459         return false;
       
   460 
   436     if(pullMode) {
   461     if(pullMode) {
   437         int chunks = bytesAvailable/period_size;
   462         int chunks = bytesAvailable/period_size;
   438 #ifdef DEBUG_AUDIO
   463 #ifdef DEBUG_AUDIO
   439         qDebug()<<"deviceReady() avail="<<bytesAvailable<<" bytes, period size="<<period_size<<" bytes";
   464         qDebug()<<"deviceReady() avail="<<bytesAvailable<<" bytes, period size="<<period_size<<" bytes";
   440         qDebug()<<"deviceReady() no. of chunks that can fit ="<<chunks<<", chunks in bytes ="<<chunks*period_size;
   465         qDebug()<<"deviceReady() no. of chunks that can fit ="<<chunks<<", chunks in bytes ="<<chunks*period_size;
   463 	    waveOutPause(hWaveOut);
   488 	    waveOutPause(hWaveOut);
   464         int input = period_size*chunks;
   489         int input = period_size*chunks;
   465         int l = audioSource->read(audioBuffer,input);
   490         int l = audioSource->read(audioBuffer,input);
   466         if(l > 0) {
   491         if(l > 0) {
   467             int out= write(audioBuffer,l);
   492             int out= write(audioBuffer,l);
   468             if(out > 0)
   493             if(out > 0) {
   469                 deviceState = QAudio::ActiveState;
   494                 if (deviceState != QAudio::ActiveState) {
       
   495                     deviceState = QAudio::ActiveState;
       
   496                     emit stateChanged(deviceState);
       
   497                 }
       
   498             }
       
   499             if ( out < l) {
       
   500                 // Didnt write all data
       
   501                 audioSource->seek(audioSource->pos()-(l-out));
       
   502             }
   470 	    if(startup)
   503 	    if(startup)
   471 	        waveOutRestart(hWaveOut);
   504 	        waveOutRestart(hWaveOut);
   472         } else if(l == 0) {
   505         } else if(l == 0) {
   473             bytesAvailable = bytesFree();
   506             bytesAvailable = bytesFree();
   474 
   507 
   476             EnterCriticalSection(&waveOutCriticalSection);
   509             EnterCriticalSection(&waveOutCriticalSection);
   477             check = waveFreeBlockCount;
   510             check = waveFreeBlockCount;
   478             LeaveCriticalSection(&waveOutCriticalSection);
   511             LeaveCriticalSection(&waveOutCriticalSection);
   479             if(check == buffer_size/period_size) {
   512             if(check == buffer_size/period_size) {
   480                 errorState = QAudio::UnderrunError;
   513                 errorState = QAudio::UnderrunError;
   481                 deviceState = QAudio::IdleState;
   514                 if (deviceState != QAudio::IdleState) {
   482                 emit stateChanged(deviceState);
   515                     deviceState = QAudio::IdleState;
       
   516                     emit stateChanged(deviceState);
       
   517                 }
   483             }
   518             }
   484 
   519 
   485         } else if(l < 0) {
   520         } else if(l < 0) {
   486             bytesAvailable = bytesFree();
   521             bytesAvailable = bytesFree();
   487             errorState = QAudio::IOError;
   522             errorState = QAudio::IOError;
   488         }
   523         }
   489     }
   524     } else {
   490     if(deviceState != QAudio::ActiveState)
   525         int buffered;
       
   526 	EnterCriticalSection(&waveOutCriticalSection);
       
   527 	buffered = waveFreeBlockCount;
       
   528 	LeaveCriticalSection(&waveOutCriticalSection);
       
   529         errorState = QAudio::UnderrunError;
       
   530         if (buffered >= buffer_size/period_size && deviceState == QAudio::ActiveState) {
       
   531             deviceState = QAudio::IdleState;
       
   532             emit stateChanged(deviceState);
       
   533         }
       
   534     }
       
   535     if(deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState)
   491         return true;
   536         return true;
   492 
   537 
   493     if((timeStamp.elapsed() + elapsedTimeOffset) > intervalTime) {
   538     if((timeStamp.elapsed() + elapsedTimeOffset) > intervalTime) {
   494         emit notify();
   539         emit notify();
   495 	elapsedTimeOffset = timeStamp.elapsed() + elapsedTimeOffset - intervalTime;
   540 	elapsedTimeOffset = timeStamp.elapsed() + elapsedTimeOffset - intervalTime;