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 { |
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); |
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() |