⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mci_obuf.cpp

📁 完整的MP3播放器源码
💻 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 + -