72 deviceState = QAudio::StoppedState; |
70 deviceState = QAudio::StoppedState; |
73 audioSource = 0; |
71 audioSource = 0; |
74 pullMode = true; |
72 pullMode = true; |
75 resuming = false; |
73 resuming = false; |
76 finished = false; |
74 finished = false; |
77 |
|
78 connect(this,SIGNAL(processMore()),SLOT(deviceReady())); |
|
79 |
|
80 InitializeCriticalSection(&waveInCriticalSection); |
|
81 } |
75 } |
82 |
76 |
83 QAudioInputPrivate::~QAudioInputPrivate() |
77 QAudioInputPrivate::~QAudioInputPrivate() |
84 { |
78 { |
85 stop(); |
79 stop(); |
86 DeleteCriticalSection(&waveInCriticalSection); |
|
87 } |
80 } |
88 |
81 |
89 void CALLBACK QAudioInputPrivate::waveInProc( HWAVEIN hWaveIn, UINT uMsg, |
82 void CALLBACK QAudioInputPrivate::waveInProc( HWAVEIN hWaveIn, UINT uMsg, |
90 DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 ) |
83 DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 ) |
91 { |
84 { |
96 QAudioInputPrivate* qAudio; |
89 QAudioInputPrivate* qAudio; |
97 qAudio = (QAudioInputPrivate*)(dwInstance); |
90 qAudio = (QAudioInputPrivate*)(dwInstance); |
98 if(!qAudio) |
91 if(!qAudio) |
99 return; |
92 return; |
100 |
93 |
|
94 QMutexLocker(&qAudio->mutex); |
|
95 |
101 switch(uMsg) { |
96 switch(uMsg) { |
102 case WIM_OPEN: |
97 case WIM_OPEN: |
103 break; |
98 break; |
104 case WIM_DATA: |
99 case WIM_DATA: |
105 EnterCriticalSection(&qAudio->waveInCriticalSection); |
|
106 if(qAudio->waveFreeBlockCount > 0) |
100 if(qAudio->waveFreeBlockCount > 0) |
107 qAudio->waveFreeBlockCount--; |
101 qAudio->waveFreeBlockCount--; |
108 qAudio->feedback(); |
102 qAudio->feedback(); |
109 LeaveCriticalSection(&qAudio->waveInCriticalSection); |
|
110 break; |
103 break; |
111 case WIM_CLOSE: |
104 case WIM_CLOSE: |
112 EnterCriticalSection(&qAudio->waveInCriticalSection); |
|
113 qAudio->finished = true; |
105 qAudio->finished = true; |
114 LeaveCriticalSection(&qAudio->waveInCriticalSection); |
|
115 break; |
106 break; |
116 default: |
107 default: |
117 return; |
108 return; |
118 } |
109 } |
119 } |
110 } |
154 WAVEHDR* blocks = blockArray; |
145 WAVEHDR* blocks = blockArray; |
155 |
146 |
156 int count = buffer_size/period_size; |
147 int count = buffer_size/period_size; |
157 |
148 |
158 for(int i = 0; i < count; i++) { |
149 for(int i = 0; i < count; i++) { |
159 waveInUnprepareHeader(hWaveIn,&blocks[i], sizeof(WAVEHDR)); |
150 waveInUnprepareHeader(hWaveIn,blocks, sizeof(WAVEHDR)); |
160 blocks+=sizeof(WAVEHDR); |
151 blocks+=sizeof(WAVEHDR); |
161 } |
152 } |
162 HeapFree(GetProcessHeap(), 0, blockArray); |
153 HeapFree(GetProcessHeap(), 0, blockArray); |
163 } |
154 } |
164 |
155 |
276 emit stateChanged(deviceState); |
267 emit stateChanged(deviceState); |
277 qWarning("QAudioInput: failed to allocate blocks. open failed"); |
268 qWarning("QAudioInput: failed to allocate blocks. open failed"); |
278 return false; |
269 return false; |
279 } |
270 } |
280 |
271 |
281 EnterCriticalSection(&waveInCriticalSection); |
272 mutex.lock(); |
282 waveFreeBlockCount = buffer_size/period_size; |
273 waveFreeBlockCount = buffer_size/period_size; |
283 LeaveCriticalSection(&waveInCriticalSection); |
274 mutex.unlock(); |
284 |
275 |
285 waveCurrentBlock = 0; |
276 waveCurrentBlock = 0; |
286 |
277 |
287 for(int i=0; i<buffer_size/period_size; i++) { |
278 for(int i=0; i<buffer_size/period_size; i++) { |
288 result = waveInAddBuffer(hWaveIn, &waveBlocks[i], sizeof(WAVEHDR)); |
279 result = waveInAddBuffer(hWaveIn, &waveBlocks[i], sizeof(WAVEHDR)); |
322 while(!finished && count < 500) { |
313 while(!finished && count < 500) { |
323 count++; |
314 count++; |
324 Sleep(10); |
315 Sleep(10); |
325 } |
316 } |
326 |
317 |
327 EnterCriticalSection(&waveInCriticalSection); |
318 mutex.lock(); |
328 for(int i=0; i<waveFreeBlockCount; i++) { |
319 for(int i=0; i<waveFreeBlockCount; i++) |
329 if(waveBlocks[i].dwFlags & WHDR_PREPARED) |
320 waveInUnprepareHeader(hWaveIn,&waveBlocks[i],sizeof(WAVEHDR)); |
330 waveInUnprepareHeader(hWaveIn,&waveBlocks[i],sizeof(WAVEHDR)); |
|
331 } |
|
332 LeaveCriticalSection(&waveInCriticalSection); |
|
333 freeBlocks(waveBlocks); |
321 freeBlocks(waveBlocks); |
|
322 mutex.unlock(); |
334 } |
323 } |
335 |
324 |
336 int QAudioInputPrivate::bytesReady() const |
325 int QAudioInputPrivate::bytesReady() const |
337 { |
326 { |
338 if(period_size == 0 || buffer_size == 0) |
327 if(period_size == 0 || buffer_size == 0) |
399 break; |
388 break; |
400 } |
389 } |
401 |
390 |
402 waveInUnprepareHeader(hWaveIn,&waveBlocks[header], sizeof(WAVEHDR)); |
391 waveInUnprepareHeader(hWaveIn,&waveBlocks[header], sizeof(WAVEHDR)); |
403 |
392 |
404 EnterCriticalSection(&waveInCriticalSection); |
393 mutex.lock(); |
405 waveFreeBlockCount++; |
394 waveFreeBlockCount++; |
406 LeaveCriticalSection(&waveInCriticalSection); |
395 mutex.unlock(); |
|
396 |
407 waveBlocks[header].dwBytesRecorded=0; |
397 waveBlocks[header].dwBytesRecorded=0; |
408 waveBlocks[header].dwFlags = 0L; |
398 waveBlocks[header].dwFlags = 0L; |
409 result = waveInPrepareHeader(hWaveIn,&waveBlocks[header], sizeof(WAVEHDR)); |
399 result = waveInPrepareHeader(hWaveIn,&waveBlocks[header], sizeof(WAVEHDR)); |
410 if(result != MMSYSERR_NOERROR) { |
400 if(result != MMSYSERR_NOERROR) { |
411 result = waveInPrepareHeader(hWaveIn,&waveBlocks[header], sizeof(WAVEHDR)); |
401 result = waveInPrepareHeader(hWaveIn,&waveBlocks[header], sizeof(WAVEHDR)); |
412 qWarning("QAudioInput: failed to prepare block %d,err=%d",header,result); |
402 qWarning("QAudioInput: failed to prepare block %d,err=%d",header,result); |
413 errorState = QAudio::IOError; |
403 errorState = QAudio::IOError; |
414 EnterCriticalSection(&waveInCriticalSection); |
404 |
|
405 mutex.lock(); |
415 waveFreeBlockCount--; |
406 waveFreeBlockCount--; |
416 LeaveCriticalSection(&waveInCriticalSection); |
407 mutex.unlock(); |
|
408 |
417 return 0; |
409 return 0; |
418 } |
410 } |
419 result = waveInAddBuffer(hWaveIn, &waveBlocks[header], sizeof(WAVEHDR)); |
411 result = waveInAddBuffer(hWaveIn, &waveBlocks[header], sizeof(WAVEHDR)); |
420 if(result != MMSYSERR_NOERROR) { |
412 if(result != MMSYSERR_NOERROR) { |
421 qWarning("QAudioInput: failed to setup block %d,err=%d",header,result); |
413 qWarning("QAudioInput: failed to setup block %d,err=%d",header,result); |
422 errorState = QAudio::IOError; |
414 errorState = QAudio::IOError; |
423 EnterCriticalSection(&waveInCriticalSection); |
415 |
|
416 mutex.lock(); |
424 waveFreeBlockCount--; |
417 waveFreeBlockCount--; |
425 LeaveCriticalSection(&waveInCriticalSection); |
418 mutex.unlock(); |
|
419 |
426 return 0; |
420 return 0; |
427 } |
421 } |
428 header++; |
422 header++; |
429 if(header >= buffer_size/period_size) |
423 if(header >= buffer_size/period_size) |
430 header = 0; |
424 header = 0; |
431 p+=l; |
425 p+=l; |
432 |
426 |
433 EnterCriticalSection(&waveInCriticalSection); |
427 mutex.lock(); |
434 if(!pullMode) { |
428 if(!pullMode) { |
435 if(l+period_size > len && waveFreeBlockCount == buffer_size/period_size) |
429 if(l+period_size > len && waveFreeBlockCount == buffer_size/period_size) |
436 done = true; |
430 done = true; |
437 } else { |
431 } else { |
438 if(waveFreeBlockCount == buffer_size/period_size) |
432 if(waveFreeBlockCount == buffer_size/period_size) |
439 done = true; |
433 done = true; |
440 } |
434 } |
441 LeaveCriticalSection(&waveInCriticalSection); |
435 mutex.unlock(); |
442 |
436 |
443 written+=l; |
437 written+=l; |
444 } |
438 } |
445 #ifdef DEBUG_AUDIO |
439 #ifdef DEBUG_AUDIO |
446 qDebug()<<"read in len="<<written; |
440 qDebug()<<"read in len="<<written; |
527 { |
519 { |
528 #ifdef DEBUG_AUDIO |
520 #ifdef DEBUG_AUDIO |
529 QTime now(QTime::currentTime()); |
521 QTime now(QTime::currentTime()); |
530 qDebug()<<now.second()<<"s "<<now.msec()<<"ms :feedback() INPUT "<<this; |
522 qDebug()<<now.second()<<"s "<<now.msec()<<"ms :feedback() INPUT "<<this; |
531 #endif |
523 #endif |
|
524 if(!(deviceState==QAudio::StoppedState||deviceState==QAudio::SuspendedState)) |
|
525 QMetaObject::invokeMethod(this, "deviceReady", Qt::QueuedConnection); |
|
526 } |
|
527 |
|
528 bool QAudioInputPrivate::deviceReady() |
|
529 { |
532 bytesAvailable = bytesReady(); |
530 bytesAvailable = bytesReady(); |
533 |
|
534 if(!(deviceState==QAudio::StoppedState||deviceState==QAudio::SuspendedState)) |
|
535 emit processMore(); |
|
536 } |
|
537 |
|
538 bool QAudioInputPrivate::deviceReady() |
|
539 { |
|
540 #ifdef DEBUG_AUDIO |
531 #ifdef DEBUG_AUDIO |
541 QTime now(QTime::currentTime()); |
532 QTime now(QTime::currentTime()); |
542 qDebug()<<now.second()<<"s "<<now.msec()<<"ms :deviceReady() INPUT"; |
533 qDebug()<<now.second()<<"s "<<now.msec()<<"ms :deviceReady() INPUT"; |
543 #endif |
534 #endif |
544 if(deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState) |
535 if(deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState) |