int main() { HWAVEIN inStream; HWAVEOUT outStream; WAVEFORMATEX waveFormat; WAVEHDR buffer[4]; // pingpong buffers waveFormat.wFormatTag = WAVE_FORMAT_PCM; // PCM audio waveFormat.nSamplesPerSec = 22050; // really 22050 frames/sec waveFormat.nChannels = 2; // stereo waveFormat.wBitsPerSample = 16; // 16bits per sample waveFormat.cbSize = 0; // no extra data waveFormat.nBlockAlign = waveFormat.nChannels * waveFormat.wBitsPerSample / 2; waveFormat.nAvgBytesPerSec = waveFormat.nBlockAlign * waveFormat.nSamplesPerSec; // Event: default security descriptor, Manual Reset, initial non-signaled HANDLE event = CreateEvent(NULL, TRUE, FALSE, "waveout event"); waveInOpen( &inStream, WAVE_MAPPER, &waveFormat, (unsigned long)event, 0, CALLBACK_EVENT); waveOutOpen(&outStream, WAVE_MAPPER, &waveFormat, (unsigned long)event, 0, CALLBACK_EVENT); // initialize the input and output PingPong buffers int index; for(index = 0; index < 4; index++) { buffer[index].dwBufferLength = NUM_FRAMES * waveFormat.nBlockAlign; buffer[index].lpData = (void *)malloc(NUM_FRAMES * waveFormat.nBlockAlign); buffer[index].dwFlags = 0; waveInPrepareHeader( inStream, &buffer[index], sizeof(WAVEHDR)); } ResetEvent(event); for(index= 0; index < 4; index++) // queue all buffers for input waveInAddBuffer(inStream, &buffer[index], sizeof(WAVEHDR)); waveInStart(inStream); while(!( buffer[1].dwFlags & WHDR_DONE)); // poll(!) for 2 full input buffers // move the two full buffers to output waveOutWrite(outStream, &buffer[0], sizeof(WAVEHDR)); waveOutWrite(outStream, &buffer[1], sizeof(WAVEHDR)); int inIndex = 2, outIndex = 0; // the next input and output to watch while(1) { // poll for completed input and output buffers if(buffer[inIndex].dwFlags & WHDR_DONE) { // input buffer complete? waveInAddBuffer( inStream, &buffer[inIndex], sizeof(WAVEHDR)); inIndex = (inIndex+1)%4; // next buffer to watch for full } if(buffer[outIndex].dwFlags & WHDR_DONE) { // output buffer complete? waveOutWrite( outStream, &buffer[outIndex], sizeof(WAVEHDR)); outIndex = (outIndex+1)%4; // next buffer to watch for empty } } }
int audioStreamer_waveOut::Read(char *buf, int len) // returns 0 if blocked, < 0 if error, > 0 if data { if (!m_hwi) return -1; #if 0 // lame, this doesnt really do what we want it to // check to see if all are full, and if so, kill a lot of em { int x; int cnt=0; for (x = 0; x < m_bufs.GetSize(); x ++) { WAVEHDR *th = (WAVEHDR *) m_bufs.Get(x)->Get(); if (th->dwFlags & WHDR_DONE) cnt++; } if (cnt >= m_bufs.GetSize()-1) { // audiostream_onover(); for (x = 0; x < m_bufs.GetSize(); x ++) { if (x != m_whichbuf) { WAVEHDR *th = (WAVEHDR *) m_bufs.Get(x)->Get(); if (th->dwFlags & WHDR_DONE) { th->dwBytesRecorded=0; th->dwFlags = WHDR_PREPARED; waveInAddBuffer(m_hwi,th,sizeof(WAVEHDR)); } } } } } #endif WAVEHDR *th = (WAVEHDR *) m_bufs.Get(m_whichbuf)->Get(); while (!(th->dwFlags & WHDR_DONE)) { Sleep(WO_SLEEP); } len=min(len,(int)th->dwBytesRecorded); memcpy(buf,th->lpData,len); th->dwBytesRecorded=0; th->dwFlags = WHDR_PREPARED; waveInAddBuffer(m_hwi,th,sizeof(WAVEHDR)); if (++m_whichbuf >= m_bufs.GetSize()) m_whichbuf=0; return len; }
//-------------------------------------------------------------------------------------- // Class: SoundResources // Method: (protected) _prepareBuffer // Description: Prepares the internal buffers for the doble buffering. //-------------------------------------------------------------------------------------- void SoundResources::_prepareBuffers(void) { //---------------------------------------------------------------------- // Preparing all memory buffer allocation //---------------------------------------------------------------------- m_WaveHeader[2].dwBufferLength = m_WaveHeader[1].dwBufferLength = m_WaveHeader[0].dwBufferLength = dwBufferLength; m_WaveHeader[0].lpData = (char *)VirtualAlloc(0, m_WaveHeader[0].dwBufferLength, MEM_COMMIT, PAGE_READWRITE); m_WaveHeader[1].lpData = (char *)VirtualAlloc(0, m_WaveHeader[1].dwBufferLength, MEM_COMMIT, PAGE_READWRITE); m_WaveHeader[2].lpData = (char *)VirtualAlloc(0, m_WaveHeader[2].dwBufferLength, MEM_COMMIT, PAGE_READWRITE); //---------------------------------------------------------------------- // Initialize dwFlags and dwLoops to 0. This seems to be necesary according to the // Microsoft Windows documentation //---------------------------------------------------------------------- m_WaveHeader[0].dwFlags = m_WaveHeader[1].dwFlags = m_WaveHeader[2].dwFlags = 0L; m_WaveHeader[0].dwLoops = m_WaveHeader[1].dwLoops = m_WaveHeader[2].dwFlags = 0L; //---------------------------------------------------------------------- // Initialize the headers //---------------------------------------------------------------------- if ((m_err = waveInPrepareHeader(m_WaveInHandle, &m_WaveHeader[0], sizeof(WAVEHDR)))) printf("yarpsounddriver: Error preparing WAVEHDR -- %08X\n", m_err); if ((m_err = waveInPrepareHeader(m_WaveInHandle, &m_WaveHeader[1], sizeof(WAVEHDR)))) printf("yarpsounddriver: Error preparing WAVEHDR -- %08X\n", m_err); if ((m_err = waveInPrepareHeader(m_WaveInHandle, &m_WaveHeader[2], sizeof(WAVEHDR)))) printf("yarpsounddriver: Error preparing WAVEHDR -- %08X\n", m_err); //---------------------------------------------------------------------- // It is necessary to queue the two buffers. //---------------------------------------------------------------------- if ((m_err = waveInAddBuffer(m_WaveInHandle, &m_WaveHeader[0], sizeof(WAVEHDR)))) printf("yarpsounddriver: Error queueing WAVEHDR 1! -- %08X\n", m_err); if ((m_err = waveInAddBuffer(m_WaveInHandle, &m_WaveHeader[1], sizeof(WAVEHDR)))) printf("yarpsounddriver: Error queueing WAVEHDR 2! -- %08X\n", m_err); if ((m_err = waveInAddBuffer(m_WaveInHandle, &m_WaveHeader[2], sizeof(WAVEHDR)))) printf("yarpsounddriver: Error queueing WAVEHDR 2! -- %08X\n", m_err); }
int RecData(int i) { WORD wResult; SendInBuffers--; if (!StopRecord) { InFillBuffer(i); wResult = waveInAddBuffer(hWaveIn,WaveInBuf[i].lpWaveHdr,sizeof(WAVEHDR)); if (wResult != 0) { WaveInFreeAll(); return 0; } SendInBuffers++; } else { if (!SendInBuffers) { WaveInFreeAll(); StopRecord=FALSE; waveInClose(hWaveIn); } } return 1; }
/** * WAV録音準備 * @param filename 保存ファイル名 * @param channel チャンネル * @param rate レート * @param bits ビット数 * @param interval 取得タイミング */ void openWAV(const tjs_char *filename, int channel, int rate, int bits, int interval) { closeWAV(); // ファイルを開く wvout = TVPCreateIStream(filename, TJS_BS_WRITE); // フォーマットを指定 WAVEFORMATEX waveForm; waveForm.wFormatTag = WAVE_FORMAT_PCM; waveForm.nChannels = channel; waveForm.nSamplesPerSec = rate; waveForm.wBitsPerSample = bits; waveForm.nBlockAlign = waveForm.nChannels * waveForm.wBitsPerSample / 8; waveForm.nAvgBytesPerSec = waveForm.nSamplesPerSec * waveForm.nBlockAlign; // waveIn を開く if (waveInOpen(&hwi, WAVE_MAPPER, &waveForm, (DWORD)waveInProc, (DWORD)this, CALLBACK_FUNCTION) != MMSYSERR_NOERROR) { TVPThrowExceptionMessage(L"waveInOpen"); } /* キャプチャバッファ確保 */ int length = waveForm.nAvgBytesPerSec * interval / 1000; wvhdr.lpData = new char[length]; wvhdr.dwBufferLength = length; wvhdr.dwFlags = 0; wvhdr.reserved = 0; // バッファを設定 waveInPrepareHeader(hwi, &wvhdr, sizeof(wvhdr)); waveInAddBuffer(hwi, &wvhdr, sizeof(wvhdr)); }
//为录音分配一组内存 BOOL CAudioRec::AllocBuffer() { BOOL bRet=FALSE; UINT i; m_pHdr=new WAVEHDR[NUM_BUF]; //为了使录音连续,采用多个缓冲区 for(i=0;i<NUM_BUF;i++) { ZeroMemory(&m_pHdr[i],sizeof(WAVEHDR)); m_pHdr[i].lpData=new char[m_nBufSize]; m_pHdr[i].dwBufferLength=m_nBufSize; m_mmr=waveInPrepareHeader(m_hIn,&m_pHdr[i],sizeof(WAVEHDR)); if(m_mmr) goto RET; m_mmr=waveInAddBuffer(m_hIn,&m_pHdr[i],sizeof(WAVEHDR)); if(m_mmr) goto RET; } bRet=TRUE; RET: return bRet; }
static bool_t getbuffer(WAVEHDR *pwh) { GDataBuffer *paud; // Get the next data block to send gfxSystemLock(); paud = gaudioRecordGetFreeBlockI(); if (!paud && !nQueuedBuffers) gaudioRecordDoneI(); gfxSystemUnlock(); if (!paud) return FALSE; // Prepare the wave header for Windows pwh->dwUser = (DWORD_PTR)paud; pwh->lpData = (LPSTR)(paud+1); // The data is on the end of the structure pwh->dwBufferLength = paud->size; pwh->dwFlags = 0; if (waveInPrepareHeader(ah, pwh, sizeof(WAVEHDR))) { fprintf(stderr, "GAUDIO: Failed to prepare a record buffer"); exit(-1); } // Send it to windows if (waveInAddBuffer(ah, pwh, sizeof(WAVEHDR))) { fprintf(stderr, "GAUDIO: Failed to add the record buffer"); exit(-1); } nQueuedBuffers++; return TRUE; }
DWORD WINAPI CAudio::waveInCallBack( LPVOID lparam ) { CAudio *pThis = (CAudio *)lparam; MSG Msg; while (GetMessage(&Msg, NULL, 0, 0)) { if (Msg.message == MM_WIM_DATA) { // 通知的数据到来 SetEvent(pThis->m_hEventWaveIn); // 等待开始下次录音 WaitForSingleObject(pThis->m_hStartRecord, INFINITE); pThis->m_nWaveInIndex = 1 - pThis->m_nWaveInIndex; MMRESULT mmResult = waveInAddBuffer(pThis->m_hWaveIn, pThis->m_lpInAudioHdr[pThis->m_nWaveInIndex], sizeof(WAVEHDR)); if (mmResult != MMSYSERR_NOERROR) return -1; } // Why never happend this if (Msg.message == MM_WIM_CLOSE) break; TranslateMessage(&Msg); DispatchMessage(&Msg); } return 0; }
BOOL RUIAudio::RecAddBuffer(RUIBuffer* pRUIBuffer) { if (pRUIBuffer == NULL) { ASSERT(FALSE); return FALSE; } BYTE* pBufferRec = pRUIBuffer->GetBuffer(); WAVEHDR* pWaveHdr = (WAVEHDR*) pBufferRec; pWaveHdr->lpData = (LPSTR) (pBufferRec + sizeof(WAVEHDR)); pWaveHdr->dwBufferLength = pRUIBuffer->GetBufferSize() - sizeof(WAVEHDR); pWaveHdr->dwFlags = 0; pWaveHdr->dwUser = 0; if (waveInPrepareHeader(m_hWaveIn, pWaveHdr, sizeof(WAVEHDR)) != MMSYSERR_NOERROR) { ASSERT(FALSE); return FALSE; } if (waveInAddBuffer(m_hWaveIn, pWaveHdr, sizeof(WAVEHDR)) != MMSYSERR_NOERROR) { ASSERT(FALSE); return FALSE; } return TRUE; }
int openMicAndStartRecording(DWORD threadId) { int i; WAVEFORMATEX m_WaveFormatEx = getDefaultFormat(); if( MMSYSERR_NOERROR != waveInOpen(&g_recordHandler,WAVE_MAPPER,&m_WaveFormatEx,threadId,0,CALLBACK_THREAD)){ printf("ER1!\n"); return -1; } for(i=0; i<MAXRECBUFFER; i++){ rechead[i]=CreateWaveHeader(); if(MMSYSERR_NOERROR != waveInPrepareHeader(g_recordHandler,rechead[i], sizeof(WAVEHDR)) ){ printf("ER2! i=%d\n", i); return -1; } if(MMSYSERR_NOERROR != waveInAddBuffer(g_recordHandler, rechead[i], sizeof(WAVEHDR))){ printf("ER3!\n"); return -1; } if(MMSYSERR_NOERROR != waveInStart(g_recordHandler)){ printf("ER4!\n"); return -1; } } printf("Start recording OK!\n"); return 0; }
static int ALCwinmmCapture_captureProc(void *arg) { ALCwinmmCapture *self = arg; WAVEHDR *WaveHdr; MSG msg; althrd_setname(althrd_current(), RECORD_THREAD_NAME); while(GetMessage(&msg, NULL, 0, 0)) { if(msg.message != WIM_DATA) continue; /* Don't wait for other buffers to finish before quitting. We're * closing so we don't need them. */ if(ATOMIC_LOAD(&self->killNow, almemory_order_acquire)) break; WaveHdr = ((WAVEHDR*)msg.lParam); ll_ringbuffer_write(self->Ring, WaveHdr->lpData, WaveHdr->dwBytesRecorded / self->Format.nBlockAlign ); // Send buffer back to capture more data waveInAddBuffer(self->InHdl, WaveHdr, sizeof(WAVEHDR)); IncrementRef(&self->WaveBuffersCommitted); } return 0; }
static int CaptureThreadProc(void *arg) { ALCdevice *Device = (ALCdevice*)arg; WinMMData *data = Device->ExtraData; WAVEHDR *WaveHdr; MSG msg; althrd_setname(althrd_current(), "alsoft-record"); while(GetMessage(&msg, NULL, 0, 0)) { if(msg.message != WIM_DATA) continue; /* Don't wait for other buffers to finish before quitting. We're * closing so we don't need them. */ if(data->killNow) break; WaveHdr = ((WAVEHDR*)msg.lParam); WriteRingBuffer(data->Ring, (ALubyte*)WaveHdr->lpData, WaveHdr->dwBytesRecorded/data->Format.nBlockAlign); // Send buffer back to capture more data waveInAddBuffer(data->WaveHandle.In, WaveHdr, sizeof(WAVEHDR)); IncrementRef(&data->WaveBuffersCommitted); } return 0; }
// Define: readBuffer(char*) DWORD waveCapture::readBuffer(char* pWAVBuffer) { DWORD _dwBytesRecorded = 0; while(1) { WaitForSingleObject(hevent, INFINITE); if(buff[_dwBufferCount]->dwFlags & WHDR_DONE) { _dwBytesRecorded = buff[_dwBufferCount]->dwBytesRecorded; memcpy(pWAVBuffer, buff[_dwBufferCount]->lpData, buff[_dwBufferCount]->dwBytesRecorded); waveInAddBuffer(hwi, buff[_dwBufferCount], sizeof(WAVEHDR)); } if(_dwBufferCount == __dwNumBuffers -1) { _dwBufferCount = 0; } else { _dwBufferCount++; } if (_dwBytesRecorded > 0) break; } dwTotalBufferLength += _dwBytesRecorded; return _dwBytesRecorded; }
void RUIAudio::On_WIM_DATA(WAVEHDR* pWaveHdr) { if (m_hWaveIn != NULL && pWaveHdr != NULL && m_pRUIBufferListPCM != NULL && pWaveHdr->dwBytesRecorded > 0) { DWORD dwCurrTick = GetTickCount(); #ifdef _USE_AAC_CODEC // [neuromos] !아래 코드는 TCP만 지원함 RUIBuffer* pRUIBufferPCM = m_pRUIBufferListPCM->AddBuffer((BYTE*) (pWaveHdr->lpData), pWaveHdr->dwBytesRecorded, dwCurrTick); #else if (m_nCodec != PCM_16) { DWORD dwFrameSizeEnc = EncodeVoicePCM(m_nCodec, (void*) (pWaveHdr->lpData), pWaveHdr->dwBytesRecorded, (void*) m_pFrameRecEnc, WAVE_FRAME_SIZE); m_pRUIBufferListSend->AddUDPFrame(m_nFrameType, 0, m_dwFrameKey, dwFrameSizeEnc , dwCurrTick, (BYTE*) m_pFrameRecEnc , dwFrameSizeEnc , 0); } else m_pRUIBufferListSend->AddUDPFrame(m_nFrameType, 0, m_dwFrameKey, pWaveHdr->dwBytesRecorded, dwCurrTick, (BYTE*) (pWaveHdr->lpData), pWaveHdr->dwBytesRecorded, 0); #endif m_dwFrameKey++; if (waveInPrepareHeader(m_hWaveIn, pWaveHdr, sizeof(WAVEHDR)) != MMSYSERR_NOERROR) { ASSERT(FALSE); return; } if( waveInAddBuffer (m_hWaveIn, pWaveHdr, sizeof(WAVEHDR)) != MMSYSERR_NOERROR) { ASSERT(FALSE); return; } } }
bool CAudio::InitializeWaveIn() { if (!waveInGetNumDevs()) return false; MMRESULT mmResult; DWORD dwThreadID = 0; m_hThreadCallBack = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)waveInCallBack, (LPVOID)this, CREATE_SUSPENDED, &dwThreadID); mmResult = waveInOpen(&m_hWaveIn, (WORD)WAVE_MAPPER, &(m_GSMWavefmt.wfx), (LONG)dwThreadID, (LONG)0, CALLBACK_THREAD); if (mmResult != MMSYSERR_NOERROR) return false; for (int i = 0; i < 2; i++) { m_lpInAudioHdr[i]->lpData = (LPSTR)m_lpInAudioData[i]; m_lpInAudioHdr[i]->dwBufferLength = m_nBufferLength; m_lpInAudioHdr[i]->dwFlags = 0; m_lpInAudioHdr[i]->dwLoops = 0; waveInPrepareHeader(m_hWaveIn, m_lpInAudioHdr[i], sizeof(WAVEHDR)); } waveInAddBuffer(m_hWaveIn, m_lpInAudioHdr[m_nWaveInIndex], sizeof(WAVEHDR)); ResumeThread(m_hThreadCallBack); waveInStart(m_hWaveIn); m_bIsWaveInUsed = true; return true; }
void QAudioInputPrivate::resume() { if(deviceState == QAudio::SuspendedState) { deviceState = QAudio::ActiveState; for(int i=0; i<buffer_size/period_size; i++) { result = waveInAddBuffer(hWaveIn, &waveBlocks[i], sizeof(WAVEHDR)); if(result != MMSYSERR_NOERROR) { qWarning("QAudioInput: failed to setup block %d,err=%d",i,result); errorState = QAudio::OpenError; deviceState = QAudio::StoppedState; emit stateChanged(deviceState); return; } } mutex.lock(); waveFreeBlockCount = buffer_size/period_size; mutex.unlock(); waveCurrentBlock = 0; header = 0; resuming = true; waveInStart(hWaveIn); QTimer::singleShot(20,this,SLOT(feedback())); emit stateChanged(deviceState); } }
static int add_wave_in(struct ausrc_st *st) { struct dspbuf *db = &st->bufs[st->pos]; WAVEHDR *wh = &db->wh; MMRESULT res; wh->lpData = (LPSTR)db->mb->buf; wh->dwBufferLength = db->mb->size; wh->dwBytesRecorded = 0; wh->dwFlags = 0; wh->dwUser = (DWORD_PTR)db->mb; waveInPrepareHeader(st->wavein, wh, sizeof(*wh)); res = waveInAddBuffer(st->wavein, wh, sizeof(*wh)); if (res != MMSYSERR_NOERROR) { warning("winwave: add_wave_in: waveInAddBuffer fail: %08x\n", res); return ENOMEM; } INC_RPOS(st->pos); st->inuse++; return 0; }
bool CSoundChannel::m_bStartRecording() { CWaitAndSignal mutex(m_Mutex); if(m_iBufByteOffset != 0x7fffffff) //已经开始RECORD了 return true; //将所有的BUFFER加入到RECORD设备上去采集数据 for(int i=0; i<m_Buffers.size(); i++) { CWaveBuffer* buffer = m_Buffers[i]; if(buffer->m_dwPrepare(m_hWaveIn) != MMSYSERR_NOERROR) return false; if(waveInAddBuffer(m_hWaveIn, &buffer->m_header, sizeof(WAVEHDR)) != MMSYSERR_NOERROR) return false; }//end of for m_iBufByteOffset = 0; //开始录音 if(waveInStart(m_hWaveIn) == MMSYSERR_NOERROR) return true; m_iBufByteOffset = 0x7fffffff; return false; }
/* CaptureThreadProc Used by "MMSYSTEM" Device. Called when a WaveIn buffer had been filled with new audio data. */ static DWORD WINAPI CaptureThreadProc(LPVOID lpParameter) { ALCdevice *pDevice = (ALCdevice*)lpParameter; WinMMData *pData = pDevice->ExtraData; LPWAVEHDR pWaveHdr; ALuint FrameSize; MSG msg; FrameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType); while(GetMessage(&msg, NULL, 0, 0)) { if(msg.message != WIM_DATA || pData->bWaveShutdown) continue; pWaveHdr = ((LPWAVEHDR)msg.lParam); WriteRingBuffer(pData->pRing, (ALubyte*)pWaveHdr->lpData, pWaveHdr->dwBytesRecorded/FrameSize); // Send buffer back to capture more data waveInAddBuffer(pData->hWaveHandle.In,pWaveHdr,sizeof(WAVEHDR)); InterlockedIncrement(&pData->lWaveBuffersCommitted); } // Signal Wave Thread completed event if(pData->hWaveThreadEvent) SetEvent(pData->hWaveThreadEvent); ExitThread(0); return 0; }
void fill_sound_buffer(LPWAVEHDR p) { error_code = waveInAddBuffer( hwavein, p, sizeof(WAVEHDR) ); if ( error_code != MMSYSERR_NOERROR ) errormsg("Error adding buffer.",error_code); else current_sound_fill++; }
static void nt_resyncaudio(void) { UINT mmresult; int nad, nda, count; if (nt_resync_cancelled) return; /* for each open input device, eat all buffers which are marked ready. The next one will thus be "busy". */ post("resyncing audio"); for (nad = 0; nad < nt_nwavein; nad++) { int phase = ntsnd_inphase[nad]; for (count = 0; count < MAXRESYNC; count++) { WAVEHDR *inwavehdr = ntsnd_invec[nad][phase].lpWaveHdr; if (!(inwavehdr->dwFlags & WHDR_DONE)) break; if (inwavehdr->dwFlags & WHDR_PREPARED) waveInUnprepareHeader(ntsnd_indev[nad], inwavehdr, sizeof(WAVEHDR)); inwavehdr->dwFlags = 0L; waveInPrepareHeader(ntsnd_indev[nad], inwavehdr, sizeof(WAVEHDR)); mmresult = waveInAddBuffer(ntsnd_indev[nad], inwavehdr, sizeof(WAVEHDR)); if (mmresult != MMSYSERR_NOERROR) nt_waveinerror("waveInAddBuffer: %s\n", mmresult); ntsnd_inphase[nad] = phase = WRAPFWD(phase + 1); } if (count == MAXRESYNC) post("resync error 1"); } /* Each output buffer which is "ready" is filled with zeros and queued. */ for (nda = 0; nda < nt_nwaveout; nda++) { int phase = ntsnd_outphase[nda]; for (count = 0; count < MAXRESYNC; count++) { WAVEHDR *outwavehdr = ntsnd_outvec[nda][phase].lpWaveHdr; if (!(outwavehdr->dwFlags & WHDR_DONE)) break; if (outwavehdr->dwFlags & WHDR_PREPARED) waveOutUnprepareHeader(ntsnd_outdev[nda], outwavehdr, sizeof(WAVEHDR)); outwavehdr->dwFlags = 0L; memset((char *)(ntsnd_outvec[nda][phase].lpData), 0, (CHANNELS_PER_DEVICE * SAMPSIZE * nt_realdacblksize)); waveOutPrepareHeader(ntsnd_outdev[nda], outwavehdr, sizeof(WAVEHDR)); mmresult = waveOutWrite(ntsnd_outdev[nda], outwavehdr, sizeof(WAVEHDR)); if (mmresult != MMSYSERR_NOERROR) nt_waveouterror("waveOutAddBuffer: %s\n", mmresult); ntsnd_outphase[nda] = phase = WRAPFWD(phase + 1); } if (count == MAXRESYNC) post("resync error 2"); } #ifdef MIDI_TIMESTAMP nt_resetmidisync(); #endif }
void WaveInStart(WaveIn *waveIn, BOOL prep) { MMRESULT res; res = waveInReset(waveIn->handler); if(res) { return; } // prepare header an add the buffer waveIn->header.lpData = (char *) waveIn->data; waveIn->header.dwBufferLength = waveIn->n * 2; waveIn->header.dwBytesRecorded = 0; waveIn->header.dwFlags = 0L; waveIn->header.dwLoops = 0L; waveIn->header.dwUser = 0L; waveInPrepareHeader(waveIn->handler, &waveIn->header, sizeof(WAVEHDR)); res = waveInAddBuffer(waveIn->handler, &waveIn->header, sizeof(WAVEHDR)); if(res) { return; } res = waveInStart(waveIn->handler); if(res) { return; } }
LRESULT CFirstPageDlg::OnMM_WIM_DATA(UINT wParam, LONG lParam) { // TODO: Add your message handler code here and/or call default // Reallocate save buffer memory ////////////////////////////////////////////////////////////////////////// pNewBuffer = (PBYTE)realloc (pSaveBuffer, dwDataLength +((PWAVEHDR) lParam)->dwBytesRecorded) ; if (pNewBuffer == NULL) { waveInClose (hWaveIn) ; MessageBeep (MB_ICONEXCLAMATION) ; AfxMessageBox(_T("OnMM_WIM_DATA:memory error")); return 0; } pSaveBuffer = pNewBuffer ; CopyMemory (pSaveBuffer + dwDataLength, ((PWAVEHDR) lParam)->lpData,((PWAVEHDR) lParam)->dwBytesRecorded) ; dwDataLength += ((PWAVEHDR) lParam)->dwBytesRecorded ; if (!bRecording) { waveInClose (hWaveIn) ; return 0 ; } waveInAddBuffer (hWaveIn, (PWAVEHDR) lParam, sizeof (WAVEHDR)) ; TRACE("done input data\n"); return 0; }
/*------------------------------------------------------------------------------*/ static void WaveOutSync( void ) { MMRESULT mmRes; switch ( WaveOutStep ){ case -1: dprintf( 0, 7, "WaveOut Error%d (0x%08X)", WaveOutErrorStep, (int)WaveOutErrorRes ); break; case 0: if ( SettingData.WAVOut != 0 ){ WaveOutStep = 1; } break; case 1: mmRes = waveOutOpen( &HdWaveOut, WaveOutUse, &WaveFormat, (DWORD)WaveOutProc, 0, CALLBACK_FUNCTION ); if ( WaveOutErrorCheck( mmRes ) != FALSE ){ return; } WaveOutStep = 2; break; case 2: if ( WaveInStep != 4 ){ break; } if ( WaveOutStatus == WAVEOUTSTATUS_OPEN ){ WaveOutStep = 3; } break; case 3: if ( SettingData.WAVOut == 0 ){ WaveOutStep = 4; break; } while ( WaveBuff[WaveOutNextNo].dwUser & 0x0001 ){ mmRes = waveInUnprepareHeader( HdWaveIn, &WaveBuff[WaveOutNextNo], sizeof(WAVEHDR) ); if ( WaveOutFlag != 0 ){ mmioWrite( hWaveRec, (char *)WaveBuff[WaveOutNextNo].lpData, WaveBuff[WaveOutNextNo].dwBufferLength ); } int diff = (WaveOutNextNo+WAVEBUFFNUM - WaveOutLastNo)%WAVEBUFFNUM; if ( diff <= WAVEBUFFNUM/2 ){ mmRes = waveOutPrepareHeader( HdWaveOut, &WaveBuff[WaveOutNextNo], sizeof(WAVEHDR) ); mmRes = waveOutWrite( HdWaveOut, &WaveBuff[WaveOutNextNo], sizeof(WAVEHDR) ); WaveBuff[WaveOutNextNo].dwUser |= 0x0020; } else { WaveBuff[WaveOutNextNo].dwUser |= 0x0010; } WaveBuff[WaveOutNextNo].dwUser &= ~0x0001; WaveOutNextNo = (WaveOutNextNo + 1 ) % WAVEBUFFNUM; } while ( WaveBuff[WaveOutLastNo].dwUser & 0x0010 ){ if ( WaveBuff[WaveOutNextNo].dwUser & 0x0020 ){ mmRes = waveOutUnprepareHeader( HdWaveOut, &WaveBuff[WaveOutLastNo], sizeof(WAVEHDR) ); } mmRes = waveInPrepareHeader( HdWaveIn, &WaveBuff[WaveOutLastNo], sizeof(WAVEHDR) ); mmRes = waveInAddBuffer( HdWaveIn, &WaveBuff[WaveOutLastNo], sizeof(WAVEHDR) ); WaveBuff[WaveOutLastNo].dwUser &= ~0x0030; WaveOutLastNo = (WaveOutLastNo + 1 ) % WAVEBUFFNUM; } break; case 4: waveOutReset( HdWaveOut ); for ( int i=0; i<WAVEBUFFNUM; i++ ){ waveOutUnprepareHeader( HdWaveOut, &WaveBuff[i], sizeof(WAVEHDR) ); } waveOutClose( HdWaveOut ); WaveOutStep = 0; break; } }
//分配内存 BOOL CWaveIn::PerPareBuffer() { //已经分配内存 if (m_bAllocBuffer) { //返回 return FALSE; } //重置录音设备 m_mmr = waveInReset(m_hIn); //出错 if (m_mmr) { //返回 return FALSE; } //循环变量 UINT i; //新建WAVEHDR结构 m_pHdr = new WAVEHDR[NUM_BUF]; for (i = 0; i < NUM_BUF; i++) { //初始化 ZeroMemory(&m_pHdr[i], sizeof(WAVEHDR)); //波形缓存 m_pHdr[i].lpData = new char[SIZE_AUDIO_FRAME]; //缓存大小 m_pHdr[i].dwBufferLength = SIZE_AUDIO_FRAME; m_pHdr[i].dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP; m_pHdr[i].dwLoops = 1; //准备缓存 m_mmr = waveInPrepareHeader(m_hIn, &m_pHdr[i], sizeof(WAVEHDR)); //出错 if (m_mmr) { //返回 return FALSE; } //添加缓存到录音设备 m_mmr = waveInAddBuffer(m_hIn, &m_pHdr[i], sizeof(WAVEHDR)); //出错 if (m_mmr) { //返回 return FALSE; } } //设置内存分配标记 m_bAllocBuffer = TRUE; //返回 return TRUE; }
static DWORD widAddBuffer(WAVEMAPDATA* wim, LPWAVEHDR lpWaveHdrDst, DWORD dwParam2) { PACMSTREAMHEADER ash; LPWAVEHDR lpWaveHdrSrc; TRACE("(%p %p %08x)\n", wim, lpWaveHdrDst, dwParam2); if (!wim->hAcmStream) { return waveInAddBuffer(wim->u.in.hInnerWave, lpWaveHdrDst, dwParam2); } lpWaveHdrDst->dwFlags |= WHDR_INQUEUE; ash = (PACMSTREAMHEADER)lpWaveHdrDst->reserved; lpWaveHdrSrc = (LPWAVEHDR)((LPSTR)ash + sizeof(ACMSTREAMHEADER)); return waveInAddBuffer(wim->u.in.hInnerWave, lpWaveHdrSrc, sizeof(*lpWaveHdrSrc)); }
/** * win32ai_open(int sample_rate) * Setup audio for input at specified rate. * returns -1 on error, 0 on happy. */ int win32ai_open(int sample_rate) { WAVEFORMATEX waveFormat; MMRESULT res; int i; // create an event by which audio driver will notify us whinEvent = CreateEvent(NULL, FALSE, FALSE, NULL); // populate whinFormat struct waveFormat.wFormatTag = WAVE_FORMAT_PCM; waveFormat.nChannels = 1; waveFormat.nSamplesPerSec = sample_rate; waveFormat.nAvgBytesPerSec = sample_rate * SAMPLE_BITS / 8; waveFormat.nBlockAlign = SAMPLE_BITS / 8; waveFormat.wBitsPerSample = SAMPLE_BITS; waveFormat.cbSize = 0; whinBufNo = 0; whinBufIndex = 0; // open audio device res = waveInOpen(&wavein, WAVE_MAPPER, &waveFormat, (DWORD) whinEvent, (DWORD) 0, CALLBACK_EVENT); if (checkWaveInResult(wavein, res, "waveInOpen")) return -1; // create buffers for (i = 0; i < WaveBuf_N; ++i) { // allocate buffer header whin[i] = (WAVEHDR*) calloc(1, sizeof(WAVEHDR)); if (whin[i] == NULL) { perror("malloc WAVEHDR"); return -1; /* need to cleanup XXX */ } // allocate buffer whin[i]->lpData = malloc(WaveBuf_SIZE); if (whin[i]->lpData == NULL) { perror("new char[WaveBuf_SIZE]"); return -1; /* need to cleanup XXX */ } whin[i]->dwBufferLength = WaveBuf_SIZE; // prepare buffer res = waveInPrepareHeader(wavein, whin[i], sizeof(WAVEHDR)); if (checkWaveInResult(wavein, res, "waveInPrepareHeader")) return -1; // give buffer to driver res = waveInAddBuffer(wavein, whin[i], sizeof(WAVEHDR)); if (checkWaveInResult(wavein, res, "waveInAddBuffer")) return -1; /* need to cleanup XXX */ } // start device, yeeeeeee haw! res = waveInStart(wavein); if (checkWaveInResult(wavein, res, "waveInStart")) return -1; /* need to cleanup XXX */ return 0; }
void CALLBACK CAudioCapture::waveInProc(HWAVEIN hwi, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2) { CAudioCapture* pObj = (CAudioCapture*)dwInstance; DWORD dwBytesWritten = 0; if(hwi != NULL) { if(uMsg == WIM_DATA) { // RETAILMSG(1, (L"WAV: WaveIn Data.. time %u \n", GetTickCount())); if(pObj->m_bUseBufferA == TRUE) { if (pObj->m_waveHdrA.dwBytesRecorded > 0) { WriteFile(pObj->m_hFile, pObj->m_waveHdrA.lpData, pObj->m_waveHdrA.dwBytesRecorded, &dwBytesWritten, NULL); pObj->m_waveHdrA.dwBytesRecorded = 0; waveInAddBuffer(pObj->m_hWaveIn, &pObj->m_waveHdrA, sizeof(WAVEHDR)); } pObj->m_bUseBufferA = FALSE; } else { if (pObj->m_waveHdrB.dwBytesRecorded > 0) { WriteFile(pObj->m_hFile, pObj->m_waveHdrB.lpData, pObj->m_waveHdrB.dwBytesRecorded, &dwBytesWritten, NULL); pObj->m_waveHdrB.dwBytesRecorded = 0; waveInAddBuffer(pObj->m_hWaveIn, &pObj->m_waveHdrB, sizeof(WAVEHDR)); } pObj->m_bUseBufferA = TRUE; } pObj->m_ulCapturedBytes += dwBytesWritten; if (pObj->m_ulCapturedBytes >= pObj->m_iMaxFileSizeBytes) pObj->Stop(); } else if(uMsg == WIM_OPEN) { OutputDebugStringW(L"WAV: WaveIn device open..\n"); } else if(uMsg == WIM_CLOSE) { OutputDebugStringW(L"WAV: WaveIn device closed..\n"); } } }
void CAudioInput::OpenMic() { SetWaveHDRInit(); SetWaveInitFormat(); waveInOpen(&h_input, 0, &my_wave_format, (DWORD)waveInProc, 0, CALLBACK_FUNCTION); waveInPrepareHeader(h_input, mp_wave_header, sizeof(WAVEHDR)); waveInAddBuffer(h_input, mp_wave_header, sizeof(WAVEHDR)); waveInStart(h_input); }
/* * Class: com_ibm_media_protocol_device_DevicePushSourceStream * Method: read * Signature: ([BII)I */ JNIEXPORT jint JNICALL Java_com_ibm_media_protocol_device_DevicePushSourceStream_read (JNIEnv* env, jobject obj, jbyteArray arr, jint offset, jint length) { MMRESULT result; jclass cls; jmethodID mid; jsize len = (*env)->GetArrayLength(env, arr); jbyte* body = (*env)->GetByteArrayElements(env, arr, JNI_FALSE); /* fill the buffer struct */ waveHeader.lpData = &body[offset]; waveHeader.dwBufferLength = length; waveHeader.dwBytesRecorded = 0; waveHeader.dwUser = NULL; waveHeader.dwFlags = NULL; waveHeader.dwLoops = NULL; waveHeader.lpNext = NULL; waveHeader.reserved = NULL; isBufferFilled = FALSE; /* preper the buffer */ result = waveInPrepareHeader(hwi, &waveHeader, sizeof(WAVEHDR)); /* DEBUG */ if (result != MMSYSERR_NOERROR) printf("ERROR while adding buffer to device !\n %d\n", result); /* end DEBUG */ result = waveInAddBuffer(hwi, &waveHeader, sizeof(WAVEHDR)); /* DEBUG */ if (result != MMSYSERR_NOERROR) printf("ERROR while adding buffer to device !\n %d\n", result); /* end DEBUG */ if (!isStarted) startDevice(); /* wait until buffer was filled */ while (!isBufferFilled) Sleep(10); (*env)->ReleaseByteArrayElements(env, arr, body, 0); /* notify DevicePushSourceStream it can generate another transferData call */ if (isStarted) { cls = (*env)->GetObjectClass(env, obj); mid = (*env)->GetMethodID(env, cls, "notify", "()V"); if (mid == 0) { printf("Error indentifying native method\n"); return; } (*env)->CallVoidMethod(env, obj, mid); } return waveHeader.dwBytesRecorded; }