/**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the QtMultimedia module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the either Technology Preview License Agreement or the ** Beta Release License Agreement. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain ** additional rights. These rights are described in the Nokia Qt LGPL ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this ** package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please ** contact the sales department at http://qt.nokia.com/contact. ** $QT_END_LICENSE$ ** ****************************************************************************/ // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists for the convenience // of other Qt classes. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include "qaudioinput_win32_p.h" //#define DEBUG_AUDIO 1 static CRITICAL_SECTION waveInCriticalSection; QAudioInputPrivate::QAudioInputPrivate(const QByteArray &device, const QAudioFormat& audioFormat): settings(audioFormat) { bytesAvailable = 0; buffer_size = 0; period_size = 0; m_device = device; totalTimeValue = 0; intervalTime = 1000; errorState = QAudio::NoError; deviceState = QAudio::StopState; audioSource = 0; pullMode = true; resuming = false; connect(this,SIGNAL(processMore()),SLOT(deviceReady())); InitializeCriticalSection(&waveInCriticalSection); } QAudioInputPrivate::~QAudioInputPrivate() { close(); DeleteCriticalSection(&waveInCriticalSection); } void CALLBACK QAudioInputPrivate::waveInProc( HWAVEIN hWaveIn, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 ) { Q_UNUSED(dwParam1) Q_UNUSED(dwParam2) Q_UNUSED(hWaveIn) QAudioInputPrivate* qAudio; qAudio = (QAudioInputPrivate*)(dwInstance); if(!qAudio) return; switch(uMsg) { case WIM_OPEN: break; case WIM_DATA: EnterCriticalSection(&waveInCriticalSection); if(qAudio->waveFreeBlockCount > 0) qAudio->waveFreeBlockCount--; LeaveCriticalSection(&waveInCriticalSection); qAudio->feedback(); break; case WIM_CLOSE: break; default: return; } } WAVEHDR* QAudioInputPrivate::allocateBlocks(int size, int count) { int i; unsigned char* buffer; WAVEHDR* blocks; DWORD totalBufferSize = (size + sizeof(WAVEHDR))*count; if((buffer=(unsigned char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, totalBufferSize)) == 0) { qWarning("QAudioInput: Memory allocation error"); return 0; } blocks = (WAVEHDR*)buffer; buffer += sizeof(WAVEHDR)*count; for(i = 0; i < count; i++) { blocks[i].dwBufferLength = size; blocks[i].lpData = (LPSTR)buffer; blocks[i].dwBytesRecorded=0; blocks[i].dwUser = 0L; blocks[i].dwFlags = 0L; blocks[i].dwLoops = 0L; result = waveInPrepareHeader(hWaveIn,&blocks[i], sizeof(WAVEHDR)); if(result != MMSYSERR_NOERROR) { qWarning("QAudioInput: Can't prepare block %d",i); return 0; } buffer += size; } return blocks; } void QAudioInputPrivate::freeBlocks(WAVEHDR* blockArray) { HeapFree(GetProcessHeap(), 0, blockArray); } QAudio::Error QAudioInputPrivate::error() const { return errorState; } QAudio::State QAudioInputPrivate::state() const { return deviceState; } QAudioFormat QAudioInputPrivate::format() const { return settings; } QIODevice* QAudioInputPrivate::start(QIODevice* device) { if(deviceState != QAudio::StopState) close(); if(!pullMode && audioSource) { delete audioSource; } if(device) { //set to pull mode pullMode = true; audioSource = device; } else { //set to push mode pullMode = false; audioSource = new InputPrivate(this); audioSource->open(QIODevice::ReadOnly | QIODevice::Unbuffered); } if( !open() ) return 0; emit stateChanged(deviceState); return audioSource; } void QAudioInputPrivate::stop() { if(deviceState == QAudio::StopState) return; deviceState = QAudio::StopState; close(); emit stateChanged(deviceState); } bool QAudioInputPrivate::open() { #ifdef DEBUG_AUDIO QTime now(QTime::currentTime()); qDebug()<> 3) * wfx.nChannels; wfx.nAvgBytesPerSec = wfx.nBlockAlign * wfx.nSamplesPerSec; UINT_PTR devId = WAVE_MAPPER; WAVEINCAPS wic; unsigned long iNumDevs,ii; iNumDevs = waveInGetNumDevs(); for(ii=0;ii 0) { if(pullMode) { l = audioSource->write(waveBlocks[header].lpData, waveBlocks[header].dwBytesRecorded); #ifdef DEBUG_AUDIO qDebug()<<"IN: "<= buffer_size/period_size) header = 0; p+=l; if(!pullMode) { if(l+period_size > len && waveFreeBlockCount == buffer_size/period_size) done = true; } else { if(waveFreeBlockCount == buffer_size/period_size) done = true; } written+=l; } #ifdef DEBUG_AUDIO qDebug()<<"read in len="<(audioSource); a->trigger(); } if(deviceState != QAudio::ActiveState) return true; if(timeStamp.elapsed() > intervalTime && intervalTime > 50) { emit notify(); timeStamp.restart(); } return true; } qint64 QAudioInputPrivate::clock() const { if(deviceState != QAudio::ActiveState) return 0; return timeStampOpened.elapsed(); } void QAudioInputPrivate::reset() { close(); } InputPrivate::InputPrivate(QAudioInputPrivate* audio) { audioDevice = qobject_cast(audio); } InputPrivate::~InputPrivate() {} qint64 InputPrivate::readData( char* data, qint64 len) { // push mode, user read() called if(audioDevice->deviceState != QAudio::ActiveState) return 0; // Read in some audio data return audioDevice->read(data,len); } qint64 InputPrivate::writeData(const char* data, qint64 len) { Q_UNUSED(data) Q_UNUSED(len) emit readyRead(); return 0; } void InputPrivate::trigger() { emit readyRead(); }