213 return snd_pcm_hw_params_set_format( handle, hwparams, pcmformat); |
214 return snd_pcm_hw_params_set_format( handle, hwparams, pcmformat); |
214 } |
215 } |
215 |
216 |
216 QIODevice* QAudioOutputPrivate::start(QIODevice* device) |
217 QIODevice* QAudioOutputPrivate::start(QIODevice* device) |
217 { |
218 { |
218 if(deviceState != QAudio::StopState) |
219 if(deviceState != QAudio::StoppedState) |
219 deviceState = QAudio::StopState; |
220 deviceState = QAudio::StoppedState; |
220 |
221 |
221 errorState = QAudio::NoError; |
222 errorState = QAudio::NoError; |
222 |
223 |
223 // Handle change of mode |
224 // Handle change of mode |
224 if(audioSource && pullMode && !device) { |
225 if(audioSource && pullMode && !device) { |
254 return audioSource; |
255 return audioSource; |
255 } |
256 } |
256 |
257 |
257 void QAudioOutputPrivate::stop() |
258 void QAudioOutputPrivate::stop() |
258 { |
259 { |
259 if(deviceState == QAudio::StopState) |
260 if(deviceState == QAudio::StoppedState) |
260 return; |
261 return; |
261 deviceState = QAudio::StopState; |
262 deviceState = QAudio::StoppedState; |
262 close(); |
263 close(); |
263 emit stateChanged(deviceState); |
264 emit stateChanged(deviceState); |
264 } |
265 } |
265 |
266 |
266 bool QAudioOutputPrivate::open() |
267 bool QAudioOutputPrivate::open() |
279 int err=-1; |
280 int err=-1; |
280 int count=0; |
281 int count=0; |
281 unsigned int freakuency=settings.frequency(); |
282 unsigned int freakuency=settings.frequency(); |
282 |
283 |
283 QString dev = QLatin1String(m_device.constData()); |
284 QString dev = QLatin1String(m_device.constData()); |
284 if(!dev.contains(QLatin1String("default"))) { |
285 QList<QByteArray> devices = QAudioDeviceInfoInternal::availableDevices(QAudio::AudioOutput); |
285 #if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14) |
286 if(dev.compare(QLatin1String("default")) == 0) { |
286 dev = QString(QLatin1String("default:CARD=%1")).arg(QLatin1String(m_device.constData())); |
287 #if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14) |
|
288 dev = QLatin1String(devices.first().constData()); |
|
289 #else |
|
290 dev = QLatin1String("hw:0,0"); |
|
291 #endif |
|
292 } else { |
|
293 #if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14) |
|
294 dev = QLatin1String(m_device); |
287 #else |
295 #else |
288 int idx = 0; |
296 int idx = 0; |
289 char *name; |
297 char *name; |
290 |
298 |
|
299 QString shortName = QLatin1String(m_device.mid(m_device.indexOf('=',0)+1).constData()); |
|
300 |
291 while(snd_card_get_name(idx,&name) == 0) { |
301 while(snd_card_get_name(idx,&name) == 0) { |
292 if(m_device.contains(name)) |
302 if(qstrncmp(shortName.toLocal8Bit().constData(),name,shortName.length()) == 0) |
293 break; |
303 break; |
294 idx++; |
304 idx++; |
295 } |
305 } |
296 dev = QString(QLatin1String("hw:%1,0")).arg(idx); |
306 dev = QString(QLatin1String("hw:%1,0")).arg(idx); |
297 #endif |
307 #endif |
298 } |
308 } |
|
309 |
299 // Step 1: try and open the device |
310 // Step 1: try and open the device |
300 while((count < 5) && (err < 0)) { |
311 while((count < 5) && (err < 0)) { |
301 err=snd_pcm_open(&handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_PLAYBACK,0); |
312 err=snd_pcm_open(&handle,dev.toLocal8Bit().constData(),SND_PCM_STREAM_PLAYBACK,0); |
302 if(err < 0) |
313 if(err < 0) |
303 count++; |
314 count++; |
304 } |
315 } |
305 if (( err < 0)||(handle == 0)) { |
316 if (( err < 0)||(handle == 0)) { |
306 errorState = QAudio::OpenError; |
317 errorState = QAudio::OpenError; |
307 deviceState = QAudio::StopState; |
318 deviceState = QAudio::StoppedState; |
308 return false; |
319 return false; |
309 } |
320 } |
310 snd_pcm_nonblock( handle, 0 ); |
321 snd_pcm_nonblock( handle, 0 ); |
311 |
322 |
312 // Step 2: Set the desired HW parameters. |
323 // Step 2: Set the desired HW parameters. |
385 } |
396 } |
386 } |
397 } |
387 if( err < 0) { |
398 if( err < 0) { |
388 qWarning()<<errMessage; |
399 qWarning()<<errMessage; |
389 errorState = QAudio::OpenError; |
400 errorState = QAudio::OpenError; |
390 deviceState = QAudio::StopState; |
401 deviceState = QAudio::StoppedState; |
391 return false; |
402 return false; |
392 } |
403 } |
393 snd_pcm_hw_params_get_buffer_size(hwparams,&buffer_frames); |
404 snd_pcm_hw_params_get_buffer_size(hwparams,&buffer_frames); |
394 buffer_size = snd_pcm_frames_to_bytes(handle,buffer_frames); |
405 buffer_size = snd_pcm_frames_to_bytes(handle,buffer_frames); |
395 snd_pcm_hw_params_get_period_size(hwparams,&period_frames, &dir); |
406 snd_pcm_hw_params_get_period_size(hwparams,&period_frames, &dir); |
527 int QAudioOutputPrivate::notifyInterval() const |
538 int QAudioOutputPrivate::notifyInterval() const |
528 { |
539 { |
529 return intervalTime; |
540 return intervalTime; |
530 } |
541 } |
531 |
542 |
532 qint64 QAudioOutputPrivate::totalTime() const |
543 qint64 QAudioOutputPrivate::processedUSecs() const |
533 { |
544 { |
534 return totalTimeValue; |
545 return totalTimeValue; |
535 } |
546 } |
536 |
547 |
537 void QAudioOutputPrivate::resume() |
548 void QAudioOutputPrivate::resume() |
538 { |
549 { |
539 if(deviceState == QAudio::SuspendState) { |
550 if(deviceState == QAudio::SuspendedState) { |
540 int err = 0; |
551 int err = 0; |
541 |
552 |
542 if(handle) { |
553 if(handle) { |
543 err = snd_pcm_prepare( handle ); |
554 err = snd_pcm_prepare( handle ); |
544 if(err < 0) |
555 if(err < 0) |
569 |
580 |
570 void QAudioOutputPrivate::suspend() |
581 void QAudioOutputPrivate::suspend() |
571 { |
582 { |
572 if(deviceState == QAudio::ActiveState || deviceState == QAudio::IdleState || resuming) { |
583 if(deviceState == QAudio::ActiveState || deviceState == QAudio::IdleState || resuming) { |
573 timer->stop(); |
584 timer->stop(); |
574 deviceState = QAudio::SuspendState; |
585 deviceState = QAudio::SuspendedState; |
575 errorState = QAudio::NoError; |
586 errorState = QAudio::NoError; |
576 emit stateChanged(deviceState); |
587 emit stateChanged(deviceState); |
577 } |
588 } |
578 } |
589 } |
579 |
590 |
580 void QAudioOutputPrivate::userFeed() |
591 void QAudioOutputPrivate::userFeed() |
581 { |
592 { |
582 if(deviceState == QAudio::StopState || deviceState == QAudio::SuspendState) |
593 if(deviceState == QAudio::StoppedState || deviceState == QAudio::SuspendedState) |
583 return; |
594 return; |
584 #ifdef DEBUG_AUDIO |
595 #ifdef DEBUG_AUDIO |
585 QTime now(QTime::currentTime()); |
596 QTime now(QTime::currentTime()); |
586 qDebug()<<now.second()<<"s "<<now.msec()<<"ms :userFeed() OUT"; |
597 qDebug()<<now.second()<<"s "<<now.msec()<<"ms :userFeed() OUT"; |
587 #endif |
598 #endif |
656 timeStamp.restart(); |
667 timeStamp.restart(); |
657 } |
668 } |
658 return true; |
669 return true; |
659 } |
670 } |
660 |
671 |
661 qint64 QAudioOutputPrivate::clock() const |
672 qint64 QAudioOutputPrivate::elapsedUSecs() const |
662 { |
673 { |
663 if(!handle) |
674 if(!handle) |
664 return 0; |
675 return 0; |
665 |
676 |
666 if (deviceState == QAudio::StopState) |
677 if (deviceState == QAudio::StoppedState) |
667 return 0; |
678 return 0; |
668 |
679 |
669 #if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14) |
680 #if(SND_LIB_MAJOR == 1 && SND_LIB_MINOR == 0 && SND_LIB_SUBMINOR >= 14) |
670 snd_pcm_status_t* status; |
681 snd_pcm_status_t* status; |
671 snd_pcm_status_alloca(&status); |
682 snd_pcm_status_alloca(&status); |
672 |
683 |
673 snd_timestamp_t t1,t2; |
684 snd_timestamp_t t1,t2; |
674 if( snd_pcm_status(handle, status) >= 0) { |
685 if( snd_pcm_status(handle, status) >= 0) { |