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

天行健 君子當自強而不息

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

 

本篇是創建游戲內核(18)【OO改良版】的續篇,關于該內核的細節說明請參閱創建游戲內核(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)  編輯 收藏 引用


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


公告

導航

統計

常用鏈接

隨筆分類(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>
            久久国产精品久久久久久久久久 | 欧美在线视频一区二区| 国产麻豆精品视频| 欧美日韩另类综合| 欧美性猛交一区二区三区精品| 国外视频精品毛片| 欧美大香线蕉线伊人久久国产精品| 亚洲精品国产品国语在线app| 久久久91精品国产一区二区三区| 欧美日韩在线一区二区| 尤物精品在线| 91久久精品国产91久久性色| 在线视频亚洲| 国产精品99久久不卡二区| 欧美国产极速在线| 亚洲一区二区三区在线看| 久热爱精品视频线路一| 欧美国产精品va在线观看| 欧美精品自拍| 国产亚洲人成网站在线观看| 夜夜爽www精品| 你懂的亚洲视频| 嫩草影视亚洲| 亚洲第一区在线| 久久久久.com| 久久综合狠狠综合久久综合88 | 亚洲国产日韩欧美一区二区三区| 亚洲国产1区| 黄色成人在线| 好吊色欧美一区二区三区四区| 美女啪啪无遮挡免费久久网站| 久久久噜噜噜久久人人看| 欧美一区二区高清| 你懂的国产精品永久在线| 欧美激情自拍| 亚洲视频中文| 国产精品入口尤物| 欧美一区二区三区啪啪| 久久婷婷久久| 久久国产精品第一页| 久久夜色撩人精品| 欧美色图天堂网| 99国产精品自拍| 久久综合久久久久88| 在线中文字幕日韩| 亚洲国产精品ⅴa在线观看| 久久综合久久综合久久| 欧美精品一区二区三区在线播放| 久久精品99无色码中文字幕| 欧美成人综合一区| 亚洲网在线观看| 久久久久久久久久久久久9999| 亚洲青色在线| 国产网站欧美日韩免费精品在线观看| 亚洲裸体俱乐部裸体舞表演av| 国产九九精品| 欧美一区二区视频在线观看2020| 欧美区视频在线观看| 国产区日韩欧美| 亚洲欧美日韩精品久久奇米色影视| 久久在线播放| 亚洲综合久久久久| 国产精品高潮粉嫩av| 亚洲激情午夜| 欧美成人久久| 亚洲午夜视频在线| 久久精品久久99精品久久| 国产精品毛片在线看| 国产精品一国产精品k频道56| 亚洲永久精品国产| 亚洲欧洲综合| 欧美日韩久久| 亚洲人成人一区二区在线观看| 欧美二区在线播放| 久久久精品一区| 曰韩精品一区二区| 久久久7777| 嫩草成人www欧美| 欧美精品手机在线| aⅴ色国产欧美| 一区二区三区欧美| 国产精品久久久久久久久| 香蕉成人伊视频在线观看| 日韩一级免费观看| 国产精品乱人伦一区二区| 亚洲一区二区精品在线| 欧美一级黄色网| 一区二区精品| 国产精品亚洲一区| 亚洲精品视频在线看| 国产精品中文在线| 亚洲网在线观看| 一区二区高清| 亚洲国产精品一区二区尤物区| 亚洲欧美激情一区| 欧美一区三区三区高中清蜜桃| 欧美日韩免费在线观看| 久久亚洲精品视频| 亚洲欧美日韩一区二区三区在线观看| 国产手机视频精品| 99re6热在线精品视频播放速度| 亚洲欧美视频在线| 久久九九精品99国产精品| 伊人久久大香线蕉综合热线| 国产精品国产三级国产普通话三级 | 久久精品亚洲一区二区三区浴池| 亚洲欧美大片| 国产一区二区精品丝袜| 99在线精品观看| 欧美在线观看一二区| 亚洲精品国产视频| 亚洲精品一级| 欧美激情日韩| 免费av成人在线| 欧美一级片一区| 亚洲人成在线观看一区二区| 久久久www| 亚洲图片激情小说| 久久av资源网| 91久久精品国产91性色tv| 亚洲视频精品| 午夜在线一区二区| 国产在线视频欧美一区二区三区| 亚洲图片欧美一区| 午夜精品在线观看| 韩日在线一区| 美女性感视频久久久| 欧美视频在线免费看| 亚洲欧美另类在线观看| 久久亚洲欧洲| 日韩性生活视频| 欧美精品在线一区| 性欧美xxxx视频在线观看| 亚洲视频精选| 久久精品亚洲一区二区三区浴池| 91久久中文| 亚洲精品乱码久久久久久蜜桃91| 欧美中文字幕在线| 亚洲三级网站| 亚洲精品久久久久久下一站| 中日韩男男gay无套| 日韩亚洲欧美一区| 国产精品久久中文| 久久精品国产第一区二区三区最新章节 | 久久蜜臀精品av| 亚洲激情一区| 亚洲男人第一av网站| 亚洲人成小说网站色在线| 精品福利av| 国产精品久久久久久久久免费樱桃 | 亚洲一区二区三区精品在线| 一色屋精品视频免费看| 一区二区三区在线高清| 欧美日本精品一区二区三区| 在线综合亚洲| 欧美大成色www永久网站婷| 欧美一区免费视频| 亚洲自拍偷拍色片视频| 91久久精品国产91久久| 国产精品一区二区在线观看网站| 久久嫩草精品久久久久| 欧美在线看片| 久久蜜桃香蕉精品一区二区三区| 久久精品日产第一区二区| 亚洲七七久久综合桃花剧情介绍| 欧美在线电影| 在线观看精品| 久久免费99精品久久久久久| 亚洲一级在线观看| 久久精品国产v日韩v亚洲| 国产精品制服诱惑| 欧美在线视频网站| 久久精品成人一区二区三区| 久久亚洲精品一区| 亚洲国产精品福利| 日韩视频一区二区| 国产欧美一区二区精品忘忧草| 香蕉成人啪国产精品视频综合网| 性刺激综合网| 1024亚洲| 欧美色视频日本高清在线观看| 欧美亚洲在线视频| 久久久久成人精品| 一区二区av在线| 国产乱码精品1区2区3区| 美女日韩欧美| 在线中文字幕日韩| 亚洲黄色免费电影| 亚洲视屏在线播放| 亚洲国产精品黑人久久久| 欧美日韩国产在线播放网站| 久久精品综合| 亚洲精品欧美| 久久久www成人免费毛片麻豆| 亚洲欧洲在线看| 精品动漫3d一区二区三区免费版| 欧美大片免费| 久久免费国产| 亚洲午夜影视影院在线观看| 91久久精品久久国产性色也91|