void CWaveEditControl::Draw(CWaveGenerator::LoopParameters LP) { m_LP=LP; if (Enabled) { if (height()) { DrawWave(); DrawLines(m_LP,m_LoopOn); } } }
BOOL CAudioCtrl::AddOutputBufferToQueue(int nIndex, int nSize) { ASSERT ( nIndex >= 0 && nIndex < m_wInQueu ); ASSERT ( m_szAryInData[nIndex] ); MMRESULT mmReturn = 0; // create the header LPWAVEHDR pHdr = m_pAryHdr[nIndex]; memset ( pHdr, 0, sizeof(WAVEHDR) ); // new a buffer pHdr->lpData = (char*)m_szAryInData[nIndex]; pHdr->dwBufferLength = m_dwQueuBufferSize; pHdr->dwBytesRecorded = nSize; pHdr->dwFlags = 0; pHdr->dwUser = nIndex; // prepare it mmReturn = ::waveOutPrepareHeader ( m_hPlay, pHdr, sizeof(WAVEHDR) ); if ( mmReturn ) { TRACE("waveOutPrepareHeader() failed!\r\n"); return FALSE; } // write the buffer to output queue mmReturn = ::waveOutWrite ( m_hPlay, pHdr, sizeof(WAVEHDR) ); if (mmReturn) { TRACE("waveOutWrite() failed!\r\n"); } // increment the number of waiting buffers m_nDataQueueNum++; // 将左右声道的音频数据拷贝到缓冲区用于波形绘制 int nBytesPickup = PickupMonoData ( m_Format.wBitsPerSample, pHdr->lpData, pHdr->dwBufferLength); //绘制波形 DrawWave((DWORD)nBytesPickup); return TRUE; }
LRESULT CWaveRecord::OnMM_WIM_DATA(WPARAM wParam, LPARAM lParam) { int nPickup = 0; MMRESULT mmResult = 0; LPWAVEHDR pHdr = (LPWAVEHDR)lParam; if(!m_bRecording) { return 0L; } mmResult = waveInUnprepareHeader(m_hWaveIn, pHdr, sizeof(WAVEHDR)); if(mmResult) { MyMessageBox(_T("waveInUnprepareHeader failed"), eERR_ERROR); return -1L; } if(m_bRecording) { nPickup = WriteToFile((PBYTE)pHdr->lpData, pHdr->dwBytesRecorded); if(nPickup == -1) { MyMessageBox(_T("Write file failed"), eERR_ERROR); return FALSE; } if(m_mp3_hIn) // Save to mp3 file { int nRecBytes[2] = {pHdr->dwBytesRecorded, pHdr->dwBytesRecorded}; char *pRecData[2] = {pHdr->lpData, pHdr->lpData}; DWORD dwSamplesBytes = m_dwSamplesEnMp3Block * (m_format.wBitsPerSample / 8); for(int nCh = 0; nCh < 2; nCh++ ) { if(m_mp3_File[nCh].m_hFile) { int nRemainSize = m_mp3_dwWavBufferSize - m_dwWaveDataBytes[nCh]; int nCopyBytes = (nRemainSize < nRecBytes[nCh]) ? nRemainSize : nRecBytes[nCh]; memcpy(m_mp3_pByWavBuffer[nCh] + m_dwWaveDataBytes[nCh], pRecData[nCh], nCopyBytes); m_dwWaveDataBytes[nCh] += nCopyBytes; // Compress mp3 for(; m_dwWaveDataBytes[nCh] > dwSamplesBytes; m_dwWaveDataBytes[nCh] -= dwSamplesBytes) { EncodeMp3(m_mp3_pByWavBuffer[nCh], dwSamplesBytes, nCh); memmove(m_mp3_pByWavBuffer[nCh], m_mp3_pByWavBuffer[nCh] + dwSamplesBytes, m_dwWaveDataBytes[nCh] - dwSamplesBytes); } char *pUnCopyData = pRecData[nCh] + nCopyBytes; int nUnCopyDataBytes = nRecBytes[nCh] - nCopyBytes; nRemainSize = m_mp3_dwWavBufferSize - m_dwWaveDataBytes[nCh]; nCopyBytes = (nRemainSize < nUnCopyDataBytes) ? nRemainSize : nUnCopyDataBytes; memcpy(m_mp3_pByWavBuffer[nCh] + m_dwWaveDataBytes[nCh], pUnCopyData, nCopyBytes ); } } } // Prepares a buffer for waveform-audio input mmResult = waveInPrepareHeader(m_hWaveIn, pHdr, sizeof(WAVEHDR)); if(mmResult) { MyMessageBox(_T("waveInPrepareHeader failed"), eERR_ERROR); return -1L; } else { mmResult = waveInAddBuffer(m_hWaveIn, pHdr, sizeof(WAVEHDR)); if(mmResult) { MyMessageBox(_T("waveInAddBuffer failed"), eERR_ERROR); return -1L; } else { if(m_hParentWnd) { DrawWave((DWORD)nPickup); } } } } else { if(m_dwBufNumInQueue <= 1) { StopRecord(); } else { m_dwBufNumInQueue--; } } return 0L; }
// // 录音对应当数据缓冲写满后触发的消息 // LRESULT CAudioCtrl::OnMM_WIM_DATA (WPARAM wParam, LPARAM lParam) { MMRESULT mmReturn = 0; LPWAVEHDR pHdr = (LPWAVEHDR) lParam; ASSERT ( pHdr ); // 清除波形输入缓冲区 mmReturn = ::waveInUnprepareHeader (m_hRecord, pHdr, sizeof(WAVEHDR)); if (mmReturn) { return -1L; } if(m_eStatus == ENUM_STATUS_RECORDING) { // 提取单声道PCM数据 int nBytesPickup = PickupMonoData(m_Format.wBitsPerSample, pHdr->lpData, pHdr->dwBytesRecorded); // 根据需要保存的通道文件类型选择PCM数据和数据长度 char *pRecData[ENUM_FILE_CHANNEL_NUM] = { pHdr->lpData, pHdr->lpData }; int nRecBytes[ENUM_FILE_CHANNEL_NUM] = { pHdr->dwBytesRecorded, pHdr->dwBytesRecorded }; if ( m_eRecChannel == ENUM_REC_CHANNEL_ALONE ) { pRecData[ENUM_FILE_CHANNEL_LEFT] = m_szLeftInData; nRecBytes[ENUM_FILE_CHANNEL_LEFT] = nBytesPickup; pRecData[ENUM_FILE_CHANNEL_RIGHT] = m_szRightInData; nRecBytes[ENUM_FILE_CHANNEL_RIGHT] = nBytesPickup; } // 保存到wave文件中 for ( int eFileChannel=ENUM_FILE_CHANNEL_COMMON; eFileChannel<ENUM_FILE_CHANNEL_NUM; eFileChannel++ ) { if ( m_hWaveFile[eFileChannel] ) { int length = ::mmioWrite(m_hWaveFile[eFileChannel], pRecData[eFileChannel], nRecBytes[eFileChannel] ); if ( length != nRecBytes[eFileChannel] ) { Stop (); m_nDataQueueNum --; TRACE("write file failed\r\n"); return -1L; } } } // 为波形输入准备一个输入缓冲区 mmReturn = ::waveInPrepareHeader (m_hRecord, pHdr, sizeof(WAVEHDR)); if (mmReturn) { TRACE("waveInPrepareHeader failed\r\n"); } else { // 给输入设备增加一个缓存 mmReturn = ::waveInAddBuffer(m_hRecord, pHdr, sizeof(WAVEHDR)); if (mmReturn) { TRACE("waveInAddBuffer() failed\r\n"); } else { DrawWave( (DWORD)nBytesPickup ); return S_OK; } } } else { if (m_nDataQueueNum == 1) { StopRec(); } else { m_nDataQueueNum --; } } return S_OK; }