📄 mci_obuf.cpp
字号:
///////////////////////////////////////////////////////////////////////////////
// File: mci_obuf.cpp
// Author :
// Comments :
// Changings :18-01-1999 by MCO
//
///////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "mci_obuf.h"
BOOL gTEST = FALSE;
HANDLE MCIbuffer::m_hEvent;
//#pragma argsused
void CALLBACK MCICallBack(HWAVEOUT hwo, UINT uMsg,
DWORD dwInstance,
DWORD dwParam1,
DWORD dwParam2)
{
switch(uMsg)
{
case WOM_DONE:
{
LPWAVEHDR lpWaveHdr = (LPWAVEHDR) dwParam1;
waveOutUnprepareHeader(hwo, lpWaveHdr, sizeof(WAVEHDR));
SetEvent(MCIbuffer::m_hEvent);
}
break;
}
}
BOOL MCIbuffer::InitBuffer(CMpAudioFile* pHdr)
{
channels = 2;
data_size = channels * BUFFERSIZE;
if (pHdr->GetVersion() == MPEG2_LSF)
data_size >>= 1;
if (pHdr->GetLayer() == 1)
data_size /= 3;
hdr_size = sizeof(WAVEHDR);
lpwavehdr_arr = new LPWAVEHDR[3];
//phwo = &pHdr->phwo;
fillup = 0;
lpwf = (tWAVEFORMATEX *) new WAVEFORMATEX;
lpwf->wBitsPerSample = 16; // No 8-bit support yet
lpwf->wFormatTag = WAVE_FORMAT_PCM;
lpwf->nChannels = (WORD) channels;
lpwf->nSamplesPerSec = (DWORD) pHdr->GetFreq();
lpwf->nAvgBytesPerSec = (DWORD) channels *
pHdr->GetFreq() << 1;
lpwf->nBlockAlign = (WORD) (channels << 1);
lpwf->cbSize = 0;
if (waveOutOpen(&m_hWaveOut, WAVE_MAPPER, (const tWAVEFORMATEX *) lpwf,
(DWORD) MCICallBack, NULL,
WAVE_ALLOWSYNC | CALLBACK_FUNCTION)
!= MMSYSERR_NOERROR)
{
MessageBox(0, "Could not open wave device.",
"Audio playback error", MB_ICONSTOP | MB_OK);
gTEST = TRUE;
}
buffer_count = 0;
DWORD i;
for(i=0; i<3; i++) {
lpwavehdr_arr[i] = (LPWAVEHDR) new WAVEHDR;
LPWAVEHDR temp = lpwavehdr_arr[i];
if(!temp) return 0;
temp->lpData = (LPSTR) new char[data_size];
if(!temp->lpData) return 0;
temp->dwBufferLength = data_size;
temp->dwBytesRecorded = 0;
temp->dwUser = 0; // If played, dwUser = 1
temp->dwLoops = 0;
temp->dwFlags = NULL;
}
for(i=0; i<channels; i++)
bufferp[i] = i * channels;
user_stop = 0;
m_hEvent = CreateEvent(0,0,0,0);
return TRUE;
}
MCIbuffer::MCIbuffer(DWORD number_of_channels,
MPEG_Args *maplay_args)
{
channels = number_of_channels;
data_size = channels * BUFFERSIZE;
if (maplay_args->stream->GetVersion() == MPEG2_LSF)
data_size >>= 1;
if (maplay_args->stream->GetLayer() == 1)
data_size /= 3;
hdr_size = sizeof(WAVEHDR);
lpwavehdr_arr = new LPWAVEHDR[3];
//phwo = maplay_args->phwo;
fillup = 0;
lpwf = (tWAVEFORMATEX *) new WAVEFORMATEX;
lpwf->wBitsPerSample = 16; // No 8-bit support yet
lpwf->wFormatTag = WAVE_FORMAT_PCM;
lpwf->nChannels = (WORD) channels;
lpwf->nSamplesPerSec = (DWORD) maplay_args->stream->GetFreq();
lpwf->nAvgBytesPerSec = (DWORD) channels *
maplay_args->stream->GetFreq() << 1;
lpwf->nBlockAlign = (WORD) (channels << 1);
lpwf->cbSize = 0;
if (waveOutOpen(&m_hWaveOut, WAVE_MAPPER, (const tWAVEFORMATEX *) lpwf,
(DWORD) MCICallBack, NULL,
WAVE_ALLOWSYNC | CALLBACK_FUNCTION)
!= MMSYSERR_NOERROR)
{
MessageBox(maplay_args->hWnd, "Could not open wave device.",
"Audio playback error", MB_ICONSTOP | MB_OK);
return;
}
buffer_count = 0;
DWORD i;
for(i=0; i<3; i++) {
lpwavehdr_arr[i] = (LPWAVEHDR) new WAVEHDR;
LPWAVEHDR temp = lpwavehdr_arr[i];
if(!temp) return;
temp->lpData = (LPSTR) new char[data_size];
if(!temp->lpData) return;
temp->dwBufferLength = data_size;
temp->dwBytesRecorded = 0;
temp->dwUser = 0; // If played, dwUser = 1
temp->dwLoops = 0;
temp->dwFlags = NULL;
}
for(i=0; i<channels; i++)
bufferp[i] = i * channels;
user_stop = 0;
}
int pG=0;
void MCIbuffer::append(DWORD channel, WORD value)
{
// Need to break up the 32-bit integer into 2 8-bit bytes.
// (ignore the first two bytes - either 0x0000 or 0xffff)
// Note that Intel byte order is backwards!!!
LPSTR temp = lpwavehdr_arr[2]->lpData;
temp[bufferp[channel]] = (char) (value & 0xff);
temp[bufferp[channel]+1] = (char) (value >> 8);
bufferp[channel] += channels << 1;
return;
}
//#pragma argsused
void MCIbuffer::write_buffer(int& fd)
{
// Actually write only when buffer is actually full.
//if ((++buffer_count & 0x1f) == 0)
if ((++buffer_count % 6) == 0)
{
lpwavehdr_arr[2]->dwBufferLength = fd*2;
lpwavehdr_arr[0]->dwBufferLength = fd*2;
fd = 0;
buffer_count = 0;
// Wait for 2 completed headers
if (fillup > 1)
{
waveOutPrepareHeader(m_hWaveOut, lpwavehdr_arr[2], hdr_size);
waveOutWrite(m_hWaveOut, lpwavehdr_arr[2], hdr_size);
lpwavehdr_arr[2]->dwUser = 1;
wave_swap();
if (lpwavehdr_arr[2]->dwUser)
{
WaitForSingleObject(m_hEvent, 10000);
}
}
else
{
if (++fillup == 2)
{
waveOutPrepareHeader(m_hWaveOut, lpwavehdr_arr[0], hdr_size);
waveOutWrite(m_hWaveOut, lpwavehdr_arr[0], hdr_size);
lpwavehdr_arr[0]->dwUser = 1;
wave_swap();
waveOutPrepareHeader(m_hWaveOut, lpwavehdr_arr[0], hdr_size);
waveOutWrite(m_hWaveOut, lpwavehdr_arr[0], hdr_size);
lpwavehdr_arr[0]->dwUser = 1;
} else
{
wave_swap();
}
}
for(DWORD i=0; i<channels; i++)
bufferp[i] = i * channels;
}
return;
}
void MCIbuffer::wave_swap()
{
LPWAVEHDR temp = lpwavehdr_arr[2];
lpwavehdr_arr[2] = lpwavehdr_arr[1];
lpwavehdr_arr[1] = lpwavehdr_arr[0];
lpwavehdr_arr[0] = temp;
return;
}
#ifdef SEEK_STOP
void MCIbuffer::clear_buffer()
// Clear all the data in the buffers
{
waveOutReset(m_hWaveOut);
unsigned int i;
for(i=0; i<3; i++) {
LPWAVEHDR temp = lpwavehdr_arr[i];
if ((temp->dwUser) && (i < 2))
WaitForSingleObject(m_hEvent, 10000);
temp->dwUser = 0;
for(unsigned int j=0; j<data_size; j++)
temp->lpData[j] = (char) 0;
}
// waveOutReset(m_hWaveOut);
// Reset buffer pointers
for(i=0; i<channels; i++)
bufferp[i] = i * channels;
// Force the buffers to fillup before playing.
fillup = buffer_count = 0;
}
void MCIbuffer::set_stop_flag()
// Set the flag to avoid unpreparing non-existent headers
{
user_stop = 1;
return;
}
#endif
MCIbuffer::~MCIbuffer()
{
if (user_stop) {
if(!gTEST)
waveOutReset(m_hWaveOut);
} else {
if (fillup == 1) {
// Write the last header calculated (at the top of the array).
if(!gTEST)
{
waveOutPrepareHeader(m_hWaveOut, lpwavehdr_arr[0], hdr_size);
waveOutWrite(m_hWaveOut, lpwavehdr_arr[0], hdr_size);
}
WORD* p = (WORD*)lpwavehdr_arr[0]->lpData;
//m_pDlg->m_tracer.SetPick(*p -32768);
// Header has been written.
lpwavehdr_arr[0]->dwUser = 1;
}
if (buffer_count)
{
// Write the last wave header (probably not be written due to buffer
// size increase.)
for(unsigned int i = bufferp[channels-1]; i < data_size; i++)
lpwavehdr_arr[2]->lpData[i] = (char) 0;
if(!gTEST)
{
waveOutPrepareHeader(m_hWaveOut, lpwavehdr_arr[2], hdr_size);
waveOutWrite(m_hWaveOut, lpwavehdr_arr[2], hdr_size);
}
// Header has been written.
lpwavehdr_arr[2]->dwUser = 1;
wave_swap();
}
}
// Unprepare and free the header memory.
for (int j=2; j>=0; j--) {
if (lpwavehdr_arr[j]->dwUser && !user_stop)
WaitForSingleObject(m_hEvent, 10000);
delete [] lpwavehdr_arr[j]->lpData;
delete lpwavehdr_arr[j];
}
delete [] lpwavehdr_arr;
delete lpwf;
if(!gTEST)
{
while(waveOutClose(m_hWaveOut) == WAVERR_STILLPLAYING)
Sleep(SLEEPTIME);
}
CloseHandle(m_hEvent);
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -