天行健 君子当自强而不息

创建游戏内核(17)【OO改良版】

 

本篇是创建游戏内核(16)【OO改良版】的续篇,关于该内核的细节说明请参阅创建游戏内核(17)


接口:

//======================================================================================
// This class encapsulate how to load sound data.
//======================================================================================
typedef class SOUND_DATA
{
private:
    friend 
class SOUND_CHANNEL; // let SOUND_CHANNEL can use this class's member data and function

public:
    SOUND_DATA();
    ~SOUND_DATA();

    
char* get_buffer();
    
long  get_buffer_size();
    
    BOOL copy_sound_data(
const SOUND_DATA* source);
    
void free();

    
void set_sound_data_format(long frequency, short channels, short bits_per_sample);
    BOOL load_wav(
const char* filename);
        
private:
    BOOL _create(
long buffer_size);
    BOOL _load_wav_header(
const char* filename);

protected:
    
long    m_frequency;
    
short   m_channels;
    
short   m_bits_per_sample;
    
    
char*   m_ptr;               // pointer to current sound buffer will to be played
    char*   m_buf;               // buffer to store sound data

    
long    m_buffer_size;       // sound buffer size
    long    m_left_size;         // left size of sound buffer which need to loaded

    
long    m_file_start_pos;    // start position of wave file will to be loaded
    long    m_file_curr_pos;     // current position of wave file will to be loaded
} *SOUND_DATA_PTR;

实现:
#pragma pack(1)

// .WAV file header
struct WAVE_HEADER
{
    
char    riff_sig[4];            // 'RIFF'
    long    waveform_chunk_size;    // 8
    char    wave_sig[4];            // 'WAVE'
    char    format_sig[4];          // 'fmt ' (notice space after)
    long    format_chunk_size;      // 16;
    short   format_tag;             // WAVE_FORMAT_PCM
    short   channels;               // # of channels
    long    sample_rate;            // sampling rate
    long    bytes_per_sec;          // bytes per second
    short   block_align;            // sample block alignment
    short   bits_per_sample;        // bits per second
    char    data_sig[4];            // 'data'
    long    data_size;              // size of waveform data
};

#pragma pack()

//------------------------------------------------------------------------------
// Constructor, initialize member data.
//------------------------------------------------------------------------------
SOUND_DATA::SOUND_DATA()
{
    memset(
this, 0, sizeof(*this));

    m_frequency       = 22050;
    m_channels        = 1;
    m_bits_per_sample = 16;    
}

//------------------------------------------------------------------------------
// Destructor, release sound data buffer.
//------------------------------------------------------------------------------
SOUND_DATA::~SOUND_DATA()
{
    free();
}

//------------------------------------------------------------------------------
// Release sound data buffer.
//------------------------------------------------------------------------------
void SOUND_DATA::free()
{
    
if(m_buf)
    {
        delete[] m_buf;
        m_buf = NULL;
    }

    m_ptr = NULL;
    m_buffer_size = 0;
}

//------------------------------------------------------------------------------
// Create sound data buffer with specified size.
//------------------------------------------------------------------------------
BOOL SOUND_DATA::_create(long size)
{
    
// free prior allocated data
    free();

    
// check for valid size
    if((m_buffer_size = size) == 0)
        
return FALSE;

    
// create a new buffer
    m_buf = new char[m_buffer_size];
    
if(m_buf == NULL)
        
return FALSE;

    
// clear out new buffer
    ZeroMemory(m_buf, m_buffer_size);

    
// point to new buffer
    m_ptr = m_buf;

    
return TRUE;
}

//------------------------------------------------------------------------------
// Load wave header from file.
//------------------------------------------------------------------------------
BOOL SOUND_DATA::_load_wav_header(const char* filename)
{
    
// error checking
    if(filename == NULL)
        
return FALSE;

    FILE* _fp;

    
// open file
    if((_fp = fopen(filename, "rb")) == NULL)
        
return FALSE;

    
// read in header and parse
    WAVE_HEADER _wave_header;

    fread(&_wave_header, 1, 
sizeof(WAVE_HEADER), _fp);

    
// check signature
    if(!memcmp(_wave_header.riff_sig, "RIFF", 4) && !memcmp(_wave_header.wave_sig, "WAVE", 4) &&
       !memcmp(_wave_header.format_sig, "fmt ", 4) && !memcmp(_wave_header.data_sig, "data", 4))
    {
        
// all signatures satisfied

        m_frequency       = _wave_header.sample_rate;
        m_channels        = _wave_header.channels;
        m_bits_per_sample = _wave_header.bits_per_sample;

        m_buffer_size     = m_left_size = _wave_header.data_size;
        m_file_start_pos  = m_file_curr_pos = ftell(_fp);

        
// close if we opened file, otherwise return to original position.
        fclose(_fp);

        
return TRUE;
    }
    
    
return FALSE;
}

//------------------------------------------------------------------------------
// Get pointer to sound data buffer.
//------------------------------------------------------------------------------
char* SOUND_DATA::get_buffer()
{
    
return m_buf;
}

//------------------------------------------------------------------------------
// Get size of sound data buffer.
//------------------------------------------------------------------------------
long SOUND_DATA::get_buffer_size()
{
    
return m_buffer_size;
}

//------------------------------------------------------------------------------
// Set play property for sound data buffer.
//------------------------------------------------------------------------------
void SOUND_DATA::set_sound_data_format(long frequency, short channels, short bits_per_sample)
{
    m_frequency  = frequency;
    m_channels   = channels;
    m_bits_per_sample = bits_per_sample;
}

//------------------------------------------------------------------------------
// Load in wave file. 
//------------------------------------------------------------------------------
BOOL SOUND_DATA::load_wav(const char* filename)
{
    
if(filename == NULL)
        
return FALSE;

    
// load wave header information first
    if(! _load_wav_header(filename))
        
return FALSE;

    
// create sound data buffer.
    if(! _create(m_buffer_size))
        
return FALSE;

    
// open file, seek to position and read in data.

    FILE* _fp;

    
if((_fp = fopen(filename, "rb")) == NULL)
        
return FALSE;

    fseek(_fp, m_file_start_pos, SEEK_SET);
    fread(m_buf, 1, m_buffer_size, _fp);

    
// reset start position and current position
    m_file_start_pos = m_file_curr_pos = 0;

    
// close file
    fclose(_fp);

    
return TRUE;
}

//------------------------------------------------------------------------------
// Copy sound data from another sound data.
//------------------------------------------------------------------------------
BOOL SOUND_DATA::copy_sound_data(const SOUND_DATA* source)
{
    
if(source == NULL)
        
return FALSE;

    
// note that m_buf is not assigned!!

    m_frequency       = source->m_frequency;
    m_channels        = source->m_channels;
    m_bits_per_sample = source->m_bits_per_sample;

    m_ptr             = source->m_ptr;
    m_buffer_size     = source->m_buffer_size;
    m_left_size       = source->m_left_size;
    m_file_curr_pos   = source->m_file_curr_pos;
    m_file_start_pos  = source->m_file_start_pos;

    
return TRUE;
}

posted on 2007-10-10 18:09 lovedday 阅读(159) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


公告

导航

统计

常用链接

随笔分类(178)

3D游戏编程相关链接

搜索

最新评论