青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

天行健 君子當自強而不息

創(chuàng)建游戲內核(19)【OO改良版】

 

本篇是創(chuàng)建游戲內核(18)【OO改良版】的續(xù)篇,關于該內核的細節(jié)說明請參閱創(chuàng)建游戲內核(19)


接口:

//======================================================================================
// This class encapsulate sound buffer playing.
//======================================================================================
typedef class SOUND_CHANNEL
{
    friend 
class SOUND;

public:
    SOUND_CHANNEL();
    ~SOUND_CHANNEL();

    IDirectSoundBuffer8*    get_ds_buffer();
    IDirectSoundNotify8*    get_ds_notify();

    BOOL create(SOUND_PTR sound, 
long frequency, short channels, short bits_per_sample);
    
void free();

    BOOL play(
const SOUND_DATA_PTR sound_data, long volume_percent, long loop_times);
    
void stop();

    
long get_volume();
    BOOL set_volume(
long percent);

    signed 
long get_pan();
    BOOL set_pan(signed 
long level);

    
long get_frequency();
    BOOL set_frequency(
long frequency);

    BOOL is_playing();

protected:
    BOOL _buffer_data();
    
void _update();

protected:
    SOUND_PTR               m_sound;         
// pointer to parent sound object
    IDirectSoundBuffer8*    m_ds_buffer;     // pointer to DirectSound buffer object
    IDirectSoundNotify8*    m_ds_notify;     // pointer to DirectSound notify object

    
short                   m_event_index;   

    
long                    m_volume;        // sound buffer volume
    signed long             m_pan;           // sound buffer pan
    BOOL                    m_is_playing;    // sound buffer playing flag
    long                    m_loop_times;    // loop times

    
long                    m_frequency;
    
short                   m_bits_per_sample;
    
short                   m_channels;

    SOUND_DATA              m_sound_data;

    
short                   m_load_section;  // sound section will to be loaded
    short                   m_stop_section;  // sound section will to be stoped
    short                   m_next_notify;   // sound notification index will to be played
} *SOUND_CHANNEL_PTR;

實現:
//------------------------------------------------------------------------------
// Constructor, initialize member data.
//------------------------------------------------------------------------------
SOUND_CHANNEL::SOUND_CHANNEL()
{
    m_sound     = NULL;
    m_ds_buffer = NULL;
    m_ds_notify = NULL;

    m_event_index = -1;

    m_volume     = 0;
    m_pan        = 0;
    m_frequency  = 0;
    m_is_playing = FALSE;
}

//------------------------------------------------------------------------------
// Destructor, release sound buffer and sound notification, set the event state 
// to nonsignaled.
//------------------------------------------------------------------------------
SOUND_CHANNEL::~SOUND_CHANNEL()
{
    free();
}

//------------------------------------------------------------------------------
// Release sound buffer and sound notification, set the event state to nonsignaled.
//------------------------------------------------------------------------------
void SOUND_CHANNEL::free()
{
    
// stop any playback
    stop();

    
// release the sound notification and sound buffer
    release_com(m_ds_notify);    
    release_com(m_ds_buffer);

    
// release event from parent SOUND class
    m_sound->release_event(this, &m_event_index);

    
// set to no parent sound
    m_sound = NULL;
}

//------------------------------------------------------------------------------
// Stop playing DirectSound buffer.
//------------------------------------------------------------------------------
void SOUND_CHANNEL::stop()
{
    
if(m_ds_buffer)
        m_ds_buffer->Stop();

    m_is_playing = FALSE;
}

//------------------------------------------------------------------------------
// Return pointer to DirectSound buffer.
//------------------------------------------------------------------------------
IDirectSoundBuffer8* SOUND_CHANNEL::get_ds_buffer()
{
    
return m_ds_buffer;
}

//------------------------------------------------------------------------------
// Return pointer to DirectSound notify.
//------------------------------------------------------------------------------
IDirectSoundNotify8* SOUND_CHANNEL::get_ds_notify()
{
    
return m_ds_notify;
}

//------------------------------------------------------------------------------
// Create sound buffer, set sound notification and event.
//------------------------------------------------------------------------------
BOOL SOUND_CHANNEL::create(SOUND_PTR sound, long frequency, short channels, short bits_per_sample)
{
    
// free a prior channel
    free();

    m_sound = sound;

    
if(m_sound == NULL || m_sound->get_directsound() == NULL)
        
return FALSE;

    
// save playback format
    m_frequency       = frequency;
    m_bits_per_sample = bits_per_sample;
    m_channels        = channels;

    WAVEFORMATEX _wave_format;

    
// create a new sound buffer for this channel, using specified format.

    ZeroMemory(&_wave_format, 
sizeof(WAVEFORMATEX));

    _wave_format.wFormatTag      = WAVE_FORMAT_PCM;
    _wave_format.nChannels       = (WORD) m_channels;
    _wave_format.nSamplesPerSec  = m_frequency;
    _wave_format.wBitsPerSample  = (WORD) m_bits_per_sample;
    _wave_format.nBlockAlign     = _wave_format.wBitsPerSample / 8 * _wave_format.nChannels;
    _wave_format.nAvgBytesPerSec = _wave_format.nSamplesPerSec * _wave_format.nBlockAlign;

    DSBUFFERDESC _buffer_desc;

    ZeroMemory(&_buffer_desc, 
sizeof(DSBUFFERDESC));

    _buffer_desc.dwSize          = 
sizeof(DSBUFFERDESC);
    _buffer_desc.dwFlags         = DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPAN | DSBCAPS_CTRLFREQUENCY | 
                                   DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_LOCSOFTWARE;
    _buffer_desc.dwBufferBytes   = g_sound_buffer_size;
    _buffer_desc.lpwfxFormat     = &_wave_format;

    IDirectSoundBuffer* _ds_buffer;

    
if(FAILED(m_sound->get_directsound()->CreateSoundBuffer(&_buffer_desc, &_ds_buffer, NULL)))
        
return FALSE;

    
// query for newer interface
    if(FAILED(_ds_buffer->QueryInterface(IID_IDirectSoundBuffer8, (void**) &m_ds_buffer)))
    {
        _ds_buffer->Release();
        
return FALSE;
    }

    
// release old object - we have the newer one now
    _ds_buffer->Release();

    
// create the notification interface
    if(FAILED(m_ds_buffer->QueryInterface(IID_IDirectSoundNotify8, (void**) &m_ds_notify)))
        
return FALSE;

    HANDLE _event_handle;

    
// get an event for this sound channel
    if(! m_sound->assign_event_for_sound_channel(this, &m_event_index, &_event_handle))
        
return FALSE;

    DSBPOSITIONNOTIFY _pos_notify[4];

    
// setup the 4 notification positions
    _pos_notify[0].dwOffset     = g_sound_buffer_chunk - 1;
    _pos_notify[0].hEventNotify = _event_handle;
    _pos_notify[1].dwOffset     = g_sound_buffer_chunk * 2 - 1;
    _pos_notify[1].hEventNotify = _event_handle;
    _pos_notify[2].dwOffset     = g_sound_buffer_chunk * 3 - 1;
    _pos_notify[2].hEventNotify = _event_handle;
    _pos_notify[3].dwOffset     = g_sound_buffer_size - 1;
    _pos_notify[3].hEventNotify = _event_handle;

    
if(FAILED(m_ds_notify->SetNotificationPositions(4, _pos_notify)))
        
return FALSE;

    
// set pan and default volume
    set_volume(100);
    set_pan(0);

    
return TRUE;
}

//------------------------------------------------------------------------------
// Play sound buffer.
//------------------------------------------------------------------------------
BOOL SOUND_CHANNEL::play(const SOUND_DATA_PTR sound_data, long volume_percent, long loop_times)
{
    
if(sound_data == NULL || m_ds_buffer == NULL || m_ds_notify == NULL)
        
return FALSE;

    
// stop any playback
    stop();

    
// restore a lost buffer just in case
    m_ds_buffer->Restore();

    
// setup playing information
    m_sound_data.copy_sound_data(sound_data);

    
// set looping times
    m_loop_times = loop_times;

    
// calculate stop section position
    if(m_loop_times == 0)
        m_stop_section = -1;
    
else
        m_stop_section = (
short
            (((m_sound_data.m_buffer_size * m_loop_times) % g_sound_buffer_size) / g_sound_buffer_chunk) ;

    m_load_section = 0;

    
// load sound data into sound buffer from sound file or sound data object
    _buffer_data();
    _buffer_data();
    _buffer_data();
    _buffer_data();

    
// set the volume
    set_volume(volume_percent);

    
// set position and begin play

    m_next_notify = 0;

    
if(FAILED(m_ds_buffer->SetCurrentPosition(0)))
        
return FALSE;

    
if(FAILED(m_ds_buffer->Play(0, 0, DSBPLAY_LOOPING)))
        
return FALSE;

    
// flag as playing
    m_is_playing = TRUE;

    
return TRUE;
}

//------------------------------------------------------------------------------
// Get sound buffer volume.
//------------------------------------------------------------------------------
long SOUND_CHANNEL::get_volume()
{
    
return m_volume;
}

//------------------------------------------------------------------------------
// Set volume for sound buffer.
//------------------------------------------------------------------------------
BOOL SOUND_CHANNEL::set_volume(long percent)
{
    
if(! set_ds_buffer_volume(m_ds_buffer, percent))
        
return FALSE;

    m_volume = percent % 101;

    
return TRUE;
}

//------------------------------------------------------------------------------
// Get sound buffer pan.
//------------------------------------------------------------------------------
signed long SOUND_CHANNEL::get_pan()
{
    
return m_pan;
}

//------------------------------------------------------------------------------
// Set pan for sound buffer.
//------------------------------------------------------------------------------
BOOL SOUND_CHANNEL::set_pan(long level)
{
    
if(! set_ds_buffer_pan(m_ds_buffer, level))
        
return FALSE;    

    m_pan = level % 101;

    
return TRUE;
}

//------------------------------------------------------------------------------
// Get sound buffer frequency.
//------------------------------------------------------------------------------
long SOUND_CHANNEL::get_frequency()
{
    
return m_frequency;
}

//------------------------------------------------------------------------------
// Set frequency for sound buffer.
//------------------------------------------------------------------------------
BOOL SOUND_CHANNEL::set_frequency(long frequency)
{
    
if(m_ds_buffer == NULL)
        
return FALSE;

    
if(FAILED(m_ds_buffer->SetFrequency(frequency)))
        
return FALSE;

    m_frequency = frequency;

    
return TRUE;
}

//------------------------------------------------------------------------------
// Checks whether sound buffer is playing.
//------------------------------------------------------------------------------
BOOL SOUND_CHANNEL::is_playing()
{
    
if(m_sound == NULL || m_ds_buffer == NULL || m_ds_notify == NULL)
        
return FALSE;

    
return m_is_playing;
}

//------------------------------------------------------------------------------
// Load sound data into sound buffer from sound file or sound data object.
//------------------------------------------------------------------------------
BOOL SOUND_CHANNEL::_buffer_data()
{
    
if(m_ds_buffer == NULL)
        
return FALSE;

    
// setup position to load in
    long _lock_pos = (m_load_section % 4) * g_sound_buffer_chunk;

    
long  _size;
    
char* _ptr;

    
// lock sound buffer to get pointer to sound data
    if(FAILED(m_ds_buffer->Lock(_lock_pos, g_sound_buffer_chunk, (void**) &_ptr, (DWORD*) &_size, NULL, NULL, 0)))
        
return FALSE;

    
// clear out buffer if nothing left to load
    if(m_sound_data.m_left_size == 0)
        ZeroMemory(_ptr, _size);
    
else
    {
        
// load in the data - take looping into account
        long _load_size = _size;
        
long _load_pos  = 0;

        
// load sound data until specfied load _size is satisfied
        for(;;)
        {
            
if(m_sound_data.m_left_size > _load_size)
            {
                
// load into sound data from buffer
                memcpy(&_ptr[_load_pos], &m_sound_data.m_ptr[m_sound_data.m_file_curr_pos], _load_size);

                
// decrease _size of sound data needed to load, advance current sound buffer position.
                m_sound_data.m_left_size     -= _load_size;
                m_sound_data.m_file_curr_pos += _load_size;

                
break;
            }
            
else        // m_sound_data._left_size <= _load_size
            {
                
// load in sound data from buffer
                memcpy(&_ptr[_load_pos], &m_sound_data.m_ptr[m_sound_data.m_file_curr_pos], m_sound_data.m_left_size);

                
// decrease _size of sound data needed to load, advance current sound buffer position.
                _load_size -= m_sound_data.m_left_size;
                _load_pos  += m_sound_data.m_left_size;

                
// check if we need to stop loop
                if(m_loop_times >= 1)
                {
                    m_loop_times--;

                    
if(m_loop_times == 0)
                    {
                        
// clear out remaining buffer space
                        if(_load_size)
                            ZeroMemory(&_ptr[_load_pos], _load_size);

                        m_sound_data.m_left_size = 0L;
                        
break;
                    }
                }

                
// reset sound data current position and left _size
                m_sound_data.m_file_curr_pos = m_sound_data.m_file_start_pos;
                m_sound_data.m_left_size     = m_sound_data.m_buffer_size;

                
// set if we need to stop loading data
                if(_load_size == 0)
                    
break;
            }
        }
    }

    
// unlock the buffer
    m_ds_buffer->Unlock(_ptr, _size, NULL, 0);

    
// mark next section to load
    if(++m_load_section > 3)
        m_load_section = 0;

    
return TRUE;
}

//------------------------------------------------------------------------------
// Update for sound buffer playing.
//------------------------------------------------------------------------------
void SOUND_CHANNEL::_update()
{
    
// check for end of sound
    if(m_next_notify == m_stop_section && m_sound_data.m_left_size == 0)
        stop();
    
else
    {
        
// buffer in more data
        _buffer_data();

        
if(++m_next_notify > 3)
            m_next_notify = 0;
    }
}

測試代碼:
/*****************************************************************************
PURPOSE:
    Test for class SOUND, SOUND_DATA, SOUND_CHANNEL.
*****************************************************************************/


#include "core_common.h"
#include "core_framework.h"
#include "core_sound.h"

class APP : public FRAMEWORK
{
public:
    BOOL init()
    {
        
// Initialize DierctSound and DirectMusic.
        m_sound.init(g_hwnd, 22050, 1, 16, DSSCL_NORMAL);

        
// load into sound data from wave file
        m_sound_data[0].load_wav("test1.wav");
        m_sound_data[1].load_wav("test2.wav");
        
        
// create sound channel

        m_sound_channel[0].create(&m_sound, 
            m_sound_data[0].get_frequency(), m_sound_data[0].get_channels(), m_sound_data[0].get_bits_per_sample());

        m_sound_channel[1].create(&m_sound, 
            m_sound_data[1].get_frequency(), m_sound_data[1].get_channels(), m_sound_data[1].get_bits_per_sample());

        
// play sound
        m_sound_channel[0].play(&m_sound_data[0], 100, 1);
        m_sound_channel[1].play(&m_sound_data[1], 50, 0); 
// lopping forever   
        
        
return TRUE;
    }

    BOOL frame()
    {
        
return TRUE;
    }

    BOOL shutdown()
    {
        
return TRUE;
    }

private:
    SOUND m_sound;
    SOUND_DATA m_sound_data[2];
    SOUND_CHANNEL m_sound_channel[2];

    FILE* _fp;
};

int PASCAL WinMain(HINSTANCE inst, HINSTANCE, LPSTR cmd_line, int cmd_show)
{
    APP app;

    
if(! build_window(inst, "MainClass", "MainWindow", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480))
        
return -1;
    
    app.run();

    
return 0;
}

posted on 2007-10-10 20:28 lovedday 閱讀(238) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發(fā)表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


公告

導航

統(tǒng)計

常用鏈接

隨筆分類(178)

3D游戲編程相關鏈接

搜索

最新評論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲视频福利| 亚洲在线观看视频网站| 欧美激情第一页xxx| 久久久久久久综合| 久久激情久久| 老**午夜毛片一区二区三区| 老司机精品视频一区二区三区| 麻豆精品视频| 欧美精品一区二区三区四区| 欧美视频在线观看视频极品| 国产精品自拍视频| 国产一区二区三区四区三区四| 国产一区二区精品久久| 雨宫琴音一区二区在线| 亚洲人成艺术| 亚洲深夜av| 久久国产精品99久久久久久老狼| 久久色在线观看| 你懂的网址国产 欧美| 欧美成人免费全部| 99精品欧美一区| 久久激情中文| 欧美午夜视频一区二区| 激情欧美日韩一区| 中文精品视频| 欧美成人一区二区三区片免费| 亚洲日本激情| 蜜乳av另类精品一区二区| 久久综合久久久| 99热在这里有精品免费| 久久精品导航| 国产精品久久久久av| 在线观看视频一区二区欧美日韩 | 国产欧美日本| 亚洲激情女人| 久久国产99| 亚洲一区二区三区乱码aⅴ蜜桃女| 久久久久天天天天| 国产精品一区二区女厕厕| 日韩视频免费观看| 美女被久久久| 午夜精品福利一区二区三区av | 欧美成人嫩草网站| 国产专区欧美专区| 午夜一区在线| 一本色道久久综合| 欧美激情第二页| 亚洲国产日韩在线| 久久久久亚洲综合| 性欧美激情精品| 国产乱码精品| 午夜亚洲精品| 亚洲免费视频观看| 国产精品v欧美精品v日本精品动漫| 亚洲欧洲日夜超级视频| 欧美大片在线看| 欧美阿v一级看视频| 激情国产一区| 嫩草影视亚洲| 欧美高清在线一区| 日韩视频专区| 日韩视频不卡中文| 欧美色网一区二区| 亚洲一区欧美一区| 亚洲午夜伦理| 国产日本欧美一区二区三区| 欧美在线视频全部完| 亚洲欧美日韩视频二区| 国产日本欧美视频| 蜜桃av噜噜一区| 欧美成人免费在线视频| 一区二区电影免费在线观看| 99re热这里只有精品免费视频| 欧美日韩亚洲国产精品| 亚洲欧美日韩一区在线观看| 午夜精彩视频在线观看不卡| 韩日欧美一区| 亚洲高清在线精品| 欧美香蕉视频| 久久久噜噜噜久久中文字幕色伊伊 | 在线国产欧美| 欧美不卡视频一区发布| 欧美91精品| 亚洲一区二区毛片| 亚洲欧美综合国产精品一区| 国模精品娜娜一二三区| 亚洲成色最大综合在线| 欧美三级电影网| 久久精品国产综合精品| 欧美成人一区二区三区| 亚洲欧美日韩爽爽影院| 久久人人精品| 亚洲欧美成人精品| 久久在线免费观看| 亚洲在线成人| 欧美91大片| 久久久久99| 欧美激情在线| 久久夜色精品国产欧美乱极品| 欧美电影在线免费观看网站| 性久久久久久久久久久久| 久久综合九色九九| 午夜亚洲性色福利视频| 麻豆国产va免费精品高清在线| 亚洲在线成人| 欧美精品三区| 免费不卡亚洲欧美| 国产精品人人爽人人做我的可爱| 欧美国产日韩一二三区| 国产精品素人视频| 亚洲青色在线| 亚洲电影第1页| 亚洲在线免费观看| 99国产一区| 免费观看久久久4p| 久久久一区二区| 国产精品夜夜夜一区二区三区尤| 欧美激情一区二区久久久| 国产三级欧美三级| 亚洲午夜激情| 亚洲午夜视频| 欧美精品日韩一区| 亚洲国产成人一区| 尤物网精品视频| 久久久xxx| 久热精品在线视频| 国产一区二区三区直播精品电影| 亚洲精品综合久久中文字幕| 亚洲国产欧美日韩另类综合| 久久精品国产91精品亚洲| 欧美在线视频在线播放完整版免费观看 | 欧美国产高潮xxxx1819| 国产日韩在线一区二区三区| 亚洲在线免费观看| 欧美一区免费视频| 国产精品少妇自拍| 亚洲综合清纯丝袜自拍| 亚洲欧美日韩精品久久亚洲区| 欧美日韩午夜激情| 99这里只有精品| 亚洲欧美一区二区精品久久久| 欧美三级不卡| 亚洲视频免费观看| 欧美一区二区三区视频在线 | 久热精品视频在线| 激情懂色av一区av二区av| 久久高清福利视频| 老司机成人网| 亚洲人成网站999久久久综合| 欧美成人亚洲成人日韩成人| 亚洲激情视频在线观看| 一区二区不卡在线视频 午夜欧美不卡'| 男女精品视频| 亚洲国产精品一区二区第四页av| 亚洲精品视频一区二区三区| 欧美日韩成人一区二区| 亚洲视频1区| 久久米奇亚洲| 亚洲美女av在线播放| 国产精品电影观看| 久久大综合网| 亚洲大片免费看| 亚洲在线观看免费视频| 韩国av一区二区三区四区| 欧美成人中文| 亚洲一区观看| 欧美寡妇偷汉性猛交| 中日韩美女免费视频网址在线观看 | 在线成人免费视频| 欧美精品日韩综合在线| 亚洲一区二区欧美日韩| 久久琪琪电影院| 在线天堂一区av电影| 国产一区二区在线观看免费播放| 久久久久久高潮国产精品视| 91久久综合亚洲鲁鲁五月天| 欧美一区二区三区四区在线观看| 在线欧美影院| 国产精品免费看久久久香蕉| 另类av一区二区| 一区二区三区福利| 蜜桃av噜噜一区| 欧美一级久久久| 日韩一级黄色av| 精品51国产黑色丝袜高跟鞋| 欧美色图首页| 欧美精品v日韩精品v韩国精品v| 亚洲欧美在线高清| 亚洲精品极品| 欧美国产欧美亚洲国产日韩mv天天看完整| 亚洲在线播放| 一本大道av伊人久久综合| 黄色综合网站| 国产日韩欧美一二三区| 欧美日韩色综合| 欧美大胆人体视频| 久久青青草原一区二区| 欧美一区二区三区在线观看视频 | 亚洲一区在线视频| 亚洲裸体视频|