Пример #1
0
//---------------------------------------------------------------------------
// サウンドカードの出力でのオープン
//	WFX.wFormatTag = WAVE_FORMAT_PCM;
//	WFX.nChannels = 1;
//	WFX.wBitsPerSample = 16;
//	WFX.nSamplesPerSec = 11025;
//	WFX.nBlockAlign = WORD(WFX.nChannels *(WFX.wBitsPerSample/8));
//	WFX.nAvgBytesPerSec = WFX.nBlockAlign * WFX.nSamplesPerSec;
//	WFX.cbSize = 0;
BOOL __fastcall CWave::OutOpen(LPWAVEFORMATEX pWFX, UINT IDDevice, DWORD Size)
{
	if( m_pDLL ){
		m_OutOpen = m_pDLL->OutOpen(pWFX->nSamplesPerSec, Size);
		if( !m_OutOpen ) PumpMessages();
        return m_OutOpen;
	}
	if( m_OutOpen ) OutAbort();
	m_Error = 0;
	m_OutBCC = 0x7fffffff;
	m_OutWait = FALSE;
	m_OutUnder = FALSE;
	m_OutWP = m_OutRP = m_OutBC = 0;
	m_OWFX = *pWFX;
    m_OutLen = Size;
	m_OutBuffSize = Size * (m_OWFX.wBitsPerSample/8) * m_OWFX.nChannels;
	m_OutMemSize = sizeof(WAVEHDR) + m_OutBuffSize;
	if( m_OutMemSize & 3 ) m_OutMemSize += 4 - (m_OutMemSize & 3);
	m_OutAllocSize = m_OutMemSize * m_OutFifoSize;
	m_OutEvent = ::CreateEvent(NULL, FALSE,FALSE,NULL);
	if( (m_Error = ::waveOutOpen( &m_hout, IDDevice , pWFX, (DWORD)WaveOutProc, (DWORD)this, CALLBACK_FUNCTION ) ) != MMSYSERR_NOERROR ){
		OutAbort();
		return FALSE;
	}
	if( (m_Error = ::waveOutPause(m_hout))!= MMSYSERR_NOERROR ){
		OutAbort();
		return FALSE;
	}
	// バッファーの準備
	m_pOutBase = new char[m_OutAllocSize];
	::VirtualLock(m_pOutBase, m_OutAllocSize);
	memset(m_pOutBase, 0, m_OutAllocSize);
	LPSTR p = m_pOutBase;
	for(int i = 0; i < m_OutFifoSize; i++, p += m_OutMemSize ){
		m_pOutBuff[i] = (WAVEHDR *)p;
		((WAVEHDR *)p)->dwBufferLength = m_OutBuffSize;
		((WAVEHDR *)p)->dwFlags = 0;
		((WAVEHDR *)p)->dwUser = NULL;
		((WAVEHDR *)p)->dwLoops = NULL;
		((WAVEHDR *)p)->lpData = p + sizeof(WAVEHDR);
		if(	(m_Error = ::waveOutPrepareHeader(m_hout, (WAVEHDR *)p, sizeof(WAVEHDR)) ) != MMSYSERR_NOERROR ){
			OutAbort();
			return FALSE;
		}
	}
	m_OutOpen = TRUE;
	m_OutFirst = TRUE;
	return TRUE;
}
Пример #2
0
//---------------------------------------------------------------------------
BOOL __fastcall CWave::OutWrite(const SHORT *pData)
{
	if( m_pDLL ){
		return m_pDLL->OutWrite(pData);
	}
	int Len = m_OutLen;
	int i;
	if( !m_OutOpen ){
		m_Error = 1;
		return FALSE;
	}
	if( m_OutUnder ){
		m_Error = 1;
		OutClose();
		return FALSE;
	}

	// 送信バッファ空き待ち
	EnterCriticalSection(&m_OutCS);
	if( m_OutBC >= m_OutFifoSize ){
		m_OutWait++;
		::LeaveCriticalSection(&m_OutCS);
		if( ::WaitForSingleObject( m_OutEvent, WAVE_TIMEOUT_EVENT ) != WAIT_OBJECT_0 ){
			m_Error = 2;
			OutAbort();
			return FALSE;
		}
	}
	else {
		::LeaveCriticalSection(&m_OutCS);
	}

	// データの変換
	LPWAVEHDR hp = m_pOutBuff[m_OutWP];
	SHORT *wp = (SHORT *)hp->lpData;
	if( m_OWFX.nChannels == 2 ){
		for( i = 0; i < Len; i++ ){
			*wp++ = *pData;
			*wp++ = *pData++;
		}
	}
	else {
		memcpy(wp, pData, sizeof(SHORT)*Len);
	}
	::waveOutWrite(m_hout, hp, sizeof(WAVEHDR) );
	::EnterCriticalSection(&m_OutCS);	// m_OutCS++が1命令では展開されない
	m_OutBC++;
	::LeaveCriticalSection(&m_OutCS);
	if(	m_OutFirst ){
		if( (m_OutBC >= 8) || (m_OutBC >= (m_OutFifoSize-1)) ){
			m_OutFirst = FALSE;
			::waveOutRestart( m_hout );
		}
	}
	m_OutWP++;
	if( m_OutWP >= m_OutFifoSize){
		m_OutWP = 0;
	}
	return TRUE;
}