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

天行健 君子當(dāng)自強(qiáng)而不息

創(chuàng)建游戲內(nèi)核(18)

 

本篇是創(chuàng)建游戲內(nèi)核(17)的續(xù)篇,有關(guān)DirectAudio和DirectShow的基礎(chǔ)知識(shí)請(qǐng)參閱用DirectX Audio和DirectShow播放聲音和音樂(lè)

 

使用SOUND控制DirectX Audio對(duì)象

SOUND對(duì)象控制DirectSound和DirectMusic對(duì)象,控制回放聲音時(shí)的音量(全局音量控制),也觸發(fā)音頻流相關(guān)消息。

來(lái)看看它的定義:

#define EVENT_NUM 32

//======================================================================================
// This class encapsulate for DirectPerformance and DirectLoader and sound play event handle.
//======================================================================================
class SOUND
{
protected:
    
/////////////////////////////// Sound system related ///////////////////////////////

    HWND    _hwnd;      
// pointer to parent window handle
    long    _volume;    // global sound buffer volume

    // Events for all sound channel, the last event takes charge to close all other events.
    HANDLE  _events[EVENT_NUM+1]; 

    
// all sound channel pointers
    SOUND_CHANNEL*  _sound_channel[EVENT_NUM];

    HANDLE  _thread_handle;        
    DWORD   _thread_id;
    BOOL    _thread_active;

    
static DWORD    handle_notifications(LPVOID data);

    
/////////////////////////////// Sound related ///////////////////////////////

    IDirectSound8*          _ds;
    IDirectSoundBuffer*     _ds_buffer;

    
long    _coop_level;
    
long    _frequency;
    
short   _channels;
    
short   _bits_per_sample;

    
/////////////////////////////// Music related - MIDI ///////////////////////////////

    IDirectMusicPerformance8*   _dm_perf;
    IDirectMusicLoader8*        _dm_loader;

public:
    SOUND();
    ~SOUND();
    
    
// assign and release events
    BOOL assign_event(SOUND_CHANNEL* sound_channel, short* event_index, HANDLE* event_handle);
    BOOL release_event(SOUND_CHANNEL* sound_channel, 
short* event_index);

    
// function to retrieve com interfaces
    IDirectSound8*              get_directsound_com();
    IDirectSoundBuffer*         get_primary_buffer_com();
    IDirectMusicPerformance8*   get_performance_com();
    IDirectMusicLoader8*        get_loader_com();

    
// init and shutdown functions
    BOOL init(HWND hwnd, long frequency = 22050, short channels = 1, short bits_per_sample = 16,
              
long coop_level = DSSCL_PRIORITY);
    
void shutdown();

    
// volume get/get
    long get_volume();
    BOOL set_volume(
long percent);

    
// restore system to known state
    void restore();
};
 


接著是它的實(shí)現(xiàn):

//------------------------------------------------------------------------------
// Constructor, initialize member data.
//------------------------------------------------------------------------------
SOUND::SOUND()
{
    
// initialize com
    CoInitialize(NULL);

    memset(
this, 0, sizeof(*this));
}

//------------------------------------------------------------------------------
// Destructor, release main sound buffer, close all event and thread.
//------------------------------------------------------------------------------
SOUND::~SOUND()
{
    shutdown();

    
// uninitialize com
    CoUninitialize();
}

//------------------------------------------------------------------------------
// Initialize DierctSound and DirectMusic.
//------------------------------------------------------------------------------
BOOL SOUND::init(HWND hwnd, long frequency, short channels, short bits_per_sample, long coop_level)
{
    
// shutdown system in case of prior install
    shutdown();

    
// save parent window handle
    if((_hwnd = hwnd) == NULL)
        
return FALSE;

    
///////////////////////////////////////////////////////////////////
    // Initialize DirectSound
    ///////////////////////////////////////////////////////////////////

    
// save settings for sound setup
    if(coop_level == DSSCL_NORMAL)
        coop_level = DSSCL_PRIORITY;

    _coop_level      = coop_level;
    _frequency       = frequency;
    _channels        = channels;
    _bits_per_sample = bits_per_sample;

    
// create an IDirectSound8 object
    if(FAILED(DirectSoundCreate8(NULL, &_ds, NULL)))
        
return FALSE;

    
// set cooperative mode
    if(FAILED(_ds->SetCooperativeLevel(_hwnd, _coop_level)))
        
return FALSE;

    
// create sound buffer

    DSBUFFERDESC ds_buffer_desc;

    
// get primary buffer control
    ZeroMemory(&ds_buffer_desc, sizeof(DSBUFFERDESC));

    ds_buffer_desc.dwSize        = 
sizeof(DSBUFFERDESC);
    ds_buffer_desc.dwFlags       = DSBCAPS_PRIMARYBUFFER | DSBCAPS_CTRLVOLUME;
    ds_buffer_desc.dwBufferBytes = 0;
    ds_buffer_desc.lpwfxFormat   = NULL;

    
if(FAILED(_ds->CreateSoundBuffer(&ds_buffer_desc, &_ds_buffer, NULL)))
        
return FALSE;

    
// set wave format for sound buffer

    WAVEFORMATEX wave_format;

    
// set the primary buffer format

    ZeroMemory(&wave_format, 
sizeof(WAVEFORMATEX));

    wave_format.wFormatTag      = WAVE_FORMAT_PCM;
    wave_format.nChannels       = (WORD) _channels;
    wave_format.nSamplesPerSec  = _frequency;
    wave_format.wBitsPerSample  = (WORD) _bits_per_sample;
    wave_format.nBlockAlign     = wave_format.wBitsPerSample / 8 * wave_format.nChannels;
    wave_format.nAvgBytesPerSec = wave_format.nSamplesPerSec * wave_format.nBlockAlign;

    
if(FAILED(_ds_buffer->SetFormat(&wave_format)))
        
return FALSE;

    
// create the events, plus an extra one for thread termination.
    for(short i = 0; i < EVENT_NUM+1; i++)
    {
        
if((_events[i] = CreateEvent(NULL, FALSE, FALSE, NULL)) == NULL)
            
return FALSE;
    }

    
// create a thread for handling notifications
    _thread_handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) handle_notifications, this, 0, &_thread_id);

    
if(_thread_handle == NULL)
        
return FALSE;

    
///////////////////////////////////////////////////////////////////
    // Initialize DirectMusic
    ///////////////////////////////////////////////////////////////////

    
// create the DirectMusic loader object
    CoCreateInstance(CLSID_DirectMusicLoader, NULL, CLSCTX_INPROC, IID_IDirectMusicLoader8, (void**) &_dm_loader);

    
// create the DirectMusic performance object
    CoCreateInstance(CLSID_DirectMusicPerformance, NULL, CLSCTX_INPROC, IID_IDirectMusicPerformance8,
                     (
void**) &_dm_perf);

    
// Initialize the performance with the standard audio path.
    // This initializes both DirectMusic and DirectSound and sets up the synthesizer. 
    _dm_perf->InitAudio(NULL, NULL, _hwnd, DMUS_APATH_SHARED_STEREOPLUSREVERB, 128, DMUS_AUDIOF_ALL, NULL);

    
// set the performance global volume to +10 decibels
    long volume_level = 1000;

    
if(FAILED(_dm_perf->SetGlobalParam(GUID_PerfMasterVolume, &volume_level, sizeof(long))))
        
return FALSE;

    CHAR    path[MAX_PATH];
    WCHAR   w_path[MAX_PATH];

    
// tell DirectMusic where the default search path is

    GetCurrentDirectory(MAX_PATH, path);
    MultiByteToWideChar(CP_ACP, 0, path, -1, w_path, MAX_PATH);

    _dm_loader->SetSearchDirectory(GUID_DirectMusicAllTypes, w_path, FALSE);

    
// set default volume to full
    set_volume(100);

    
return TRUE;
}

//------------------------------------------------------------------------------
// Release main sound buffer, close all events and threads.
//------------------------------------------------------------------------------
void SOUND::shutdown()
{
    
// stop the music, and close down.
    if(_dm_perf != NULL)
    {
        _dm_perf->Stop(NULL, NULL, 0, 0);
        _dm_perf->CloseDown();
    }

    
// release the DirectMusic objects
    release_com(_dm_perf);
    release_com(_dm_loader);

    
// go through all used sound channels and free them
    for(short i = 0; i < EVENT_NUM; i++)
    {
        
if(_sound_channel[i] != NULL)
        {
            _sound_channel[i]->free();
            _sound_channel[i] = NULL;
        }

        
// clear the event status
        if(_events[i] != NULL)
            ResetEvent(_events[i]);
    }

    
// stop the primary channel from playing
    if(_ds_buffer != NULL)
        _ds_buffer->Stop();

    
// release the DirectSound objects
    release_com(_ds_buffer);
    release_com(_ds);

    
// force a closure of the thread by triggering the last event and waiting for it to terminate
    if(_thread_handle != NULL)
    {
        
if(_events[EVENT_NUM] != NULL)
        {
            
while(_thread_active)
                
// set the specified event object to the signaled state
                SetEvent(_events[EVENT_NUM]);
        }
        
else
        {
            
// getting here means no event assigned
            TerminateThread(_thread_handle, 0);
        }
    }

    
// close all event handles
    for(short i = 0; i < EVENT_NUM+1; i++)
    {
        
if(_events[i] != NULL)
        {
            CloseHandle(_events[i]);
            _events[i] = NULL;
        }
    }

    
// free the thread handle
    if(_thread_handle != NULL)
    {
        CloseHandle(_thread_handle);
        _thread_handle = NULL;
    }

    _thread_id = 0;
}

//------------------------------------------------------------------------------
// Return pointer to DirectSound.
//------------------------------------------------------------------------------
IDirectSound8* SOUND::get_directsound_com()
{
    
return _ds;
}

//------------------------------------------------------------------------------
// Return pointer to primary DirectSound buffer.
//------------------------------------------------------------------------------
IDirectSoundBuffer* SOUND::get_primary_buffer_com()
{
    
return _ds_buffer;
}

//------------------------------------------------------------------------------
// Return pointer to DirectMusic performance object.
//------------------------------------------------------------------------------
IDirectMusicPerformance8* SOUND::get_performance_com()
{
    
return _dm_perf;
}

//------------------------------------------------------------------------------
// Return pointer to DirectMusic loader object.
//------------------------------------------------------------------------------
IDirectMusicLoader8* SOUND::get_loader_com()
{
    
return _dm_loader;
}

//------------------------------------------------------------------------------
// Assign sound channel with specified event.
//------------------------------------------------------------------------------
BOOL SOUND::assign_event(SOUND_CHANNEL* sound_channel, short* event_index, HANDLE* event_handle)
{
    
for(short i = 0; i < EVENT_NUM; i++)
    {
        
if(_events[i] != NULL && _sound_channel[i] == NULL)
        {
            
// set the specified event object to the nonsignaled state
            ResetEvent(_events[i]);

            _sound_channel[i] = sound_channel;
            
            *event_index  = i;
            *event_handle = _events[i];

            
return TRUE;
        }
    }

    
return FALSE;
}

//------------------------------------------------------------------------------
// Set the event state to nonsignaled.
//------------------------------------------------------------------------------
BOOL SOUND::release_event(SOUND_CHANNEL* sound_channel, short* event_index)
{
    
if((unsigned short)(*event_index) < EVENT_NUM && _sound_channel[*event_index] == sound_channel)
    {
        ResetEvent(_events[*event_index]);

        
// set event channel pointer with NULL
        _sound_channel[*event_index] = NULL;
        *event_index = -1;

        
return TRUE;
    }

    
return FALSE;
}

//------------------------------------------------------------------------------
// Get global sound volume.
//------------------------------------------------------------------------------
long SOUND::get_volume()
{
    
return _volume;
}

//------------------------------------------------------------------------------
// Set the global sound volume.
//------------------------------------------------------------------------------
BOOL SOUND::set_volume(long percent)
{
    
long volume;

    
if(_ds_buffer == NULL)
        
return FALSE;

    
// calculate a usable volume level
    if(percent == 0)
        volume = DSBVOLUME_MIN;
    
else
        volume = -20 * (100 - (percent % 101));

    
if(FAILED(_ds_buffer->SetVolume(volume)))
        
return FALSE;

    _volume = percent % 101;

    
return TRUE;
}

//------------------------------------------------------------------------------
// Handle all sound events.
//------------------------------------------------------------------------------
DWORD SOUND::handle_notifications(LPVOID data)
{
    MSG msg;

    SOUND* sound = (SOUND*) data;

    sound->_thread_active = TRUE;

    BOOL complete = FALSE;

    
while(! complete)
    {
        
// wait for a message
        DWORD result = MsgWaitForMultipleObjects(EVENT_NUM+1, sound->_events, FALSE, INFINITE, QS_ALLEVENTS);

        
// get channel index to update
        DWORD channel_index = result - WAIT_OBJECT_0;

        
// check for channel update
        if(channel_index >= 0 && channel_index < EVENT_NUM)
        {
            
if(sound->_sound_channel[channel_index] != NULL)
                sound->_sound_channel[channel_index]->_update();
        }
        
else if(channel_index == EVENT_NUM) // check for thread closure
            complete = TRUE;
        
else if(channel_index > EVENT_NUM)  // check for waiting messages
        {
            
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
            {
                
if(msg.message == WM_QUIT)
                {
                    complete = TRUE;
                    
break;
                }
            }
        }
    }

    sound->_thread_active = FALSE;

    
return 0L;
}

//------------------------------------------------------------------------------
// Restore primary DirectSound buffer and DirectSound channel buffer.
//------------------------------------------------------------------------------
void SOUND::restore()
{
    
// handle primary
    if(_ds_buffer != NULL)
        _ds_buffer->Restore();

    
// handle all used sound channels
    for(short i = 0; i < EVENT_NUM; i++)
    {
        
if(_sound_channel[i] != NULL)
            _sound_channel[i]->_ds_buffer->Restore();
    }
}

在SOUND類(lèi)中,使用的函數(shù)主要有init,shutdown,set_volume。要使用init,必須給它傳遞一個(gè)父窗口的句柄,以及可選的混音器(mixer)設(shè)置(系統(tǒng)默認(rèn)為22050赫茲,單聲道,使用DSSCL_PRIORITY協(xié)作級(jí)別的16位采樣)。

SOUND::set_volume將percent參數(shù)設(shè)置為0(靜音)-- 100(最大音量)之間的值,就可以改變音量的設(shè)置。


posted on 2007-09-29 21:27 lovedday 閱讀(386) 評(píng)論(0)  編輯 收藏 引用


只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


公告

導(dǎo)航

統(tǒng)計(jì)

常用鏈接

隨筆分類(lèi)(178)

3D游戲編程相關(guān)鏈接

搜索

最新評(píng)論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美在线免费播放| 久久青草欧美一区二区三区| 91久久综合| 欧美裸体一区二区三区| 一区二区电影免费在线观看| 亚洲精品乱码久久久久久蜜桃91| 欧美激情第六页| 夜夜嗨av一区二区三区| 亚洲一级免费视频| 国内一区二区在线视频观看| 欧美高清视频在线| 欧美日韩免费一区| 欧美一区二区三区在线看| 久久久久久久999精品视频| 亚洲激情六月丁香| 一区二区三区高清| 精品成人国产| 日韩视频在线一区二区三区| 国产精品综合av一区二区国产馆| 久久久水蜜桃| 欧美精品久久久久久久免费观看 | 欧美freesex交免费视频| 99在线精品观看| 午夜精品免费在线| 亚洲三级影院| 午夜伦欧美伦电影理论片| 亚洲大黄网站| 亚洲欧美成aⅴ人在线观看| 激情视频一区二区| 99在线精品观看| 亚洲高清网站| 亚洲欧美精品在线观看| 亚洲精品免费一二三区| 欧美伊久线香蕉线新在线| 99精品视频网| 久久久久一区二区三区| 亚洲男人第一网站| 欧美激情视频一区二区三区在线播放 | 在线综合欧美| 久久久精品网| 校园激情久久| 欧美日韩中文字幕在线视频| 免费日韩av电影| 国产婷婷色综合av蜜臀av| 亚洲另类自拍| 亚洲精品乱码久久久久久按摩观| 亚洲欧美另类在线| 亚洲一区二区在线免费观看视频 | 一区二区欧美日韩| 亚洲人成在线观看一区二区| 欧美一区影院| 久久岛国电影| 国产精品丝袜91| 日韩视频免费大全中文字幕| 亚洲国产精品va在线看黑人| 久久福利毛片| 久久久国产成人精品| 国产精品欧美一区二区三区奶水| 亚洲精品国产品国语在线app| 亚洲福利视频在线| 久久久久综合| 久久这里有精品15一区二区三区| 国产欧美一区二区精品性色| 亚洲视频大全| 亚洲欧洲av一区二区三区久久| 欧美日韩美女| aa国产精品| 亚洲一区二区影院| 国产精品久久久久高潮| 亚洲一级黄色| 欧美综合二区| 国产在线拍揄自揄视频不卡99| 欧美亚洲在线观看| 久久躁狠狠躁夜夜爽| 在线观看日韩一区| 免费看黄裸体一级大秀欧美| 亚洲国产精品99久久久久久久久| 亚洲欧洲综合另类| 欧美久久一级| 亚洲调教视频在线观看| 欧美淫片网站| 激情伊人五月天久久综合| 美女亚洲精品| 夜夜精品视频| 久久精品视频在线观看| 在线欧美亚洲| 欧美片在线播放| 亚洲女人天堂成人av在线| 久久影院午夜论| 亚洲黄色成人| 国产精品福利在线观看网址| 性欧美18~19sex高清播放| 免费不卡欧美自拍视频| 日韩视频在线播放| 欧美激情第六页| 亚洲视频一二三| 国产三级精品在线不卡| 免费亚洲一区二区| 国产精品99久久99久久久二8| 欧美一区激情| 亚洲美女视频| 国产在线精品一区二区中文| 欧美极品色图| 亚洲欧美一级二级三级| 亚洲国产精品久久久久婷婷884| 亚洲一区二区三区精品在线| 久久久久久国产精品一区| 亚洲日本乱码在线观看| 国产视频亚洲| 欧美日韩亚洲不卡| 久久久久久69| 亚洲欧美日本另类| 91久久精品国产91性色tv| 久久久精品性| 亚洲综合精品一区二区| 亚洲欧洲视频| 精品1区2区3区4区| 国产精品三上| 欧美日韩中文另类| 欧美激情区在线播放| 久久激情综合网| 午夜精品久久久久久久99樱桃| 亚洲欧洲在线看| 欧美黑人在线观看| 久久资源在线| 久久久国产视频91| 欧美亚洲免费高清在线观看| 99精品视频网| 亚洲精品一线二线三线无人区| 韩国一区二区三区美女美女秀| 国产精品久久久久久久久| 欧美日韩国产a| 欧美大片免费久久精品三p| 亚洲图片欧美日产| 亚洲视频电影图片偷拍一区| 亚洲精品中文字幕在线| 亚洲国产成人精品久久久国产成人一区| 久久国产免费看| 欧美一区二区三区喷汁尤物| 亚洲欧美另类在线| 亚洲欧美成人综合| 亚洲一区二区在线免费观看| 正在播放亚洲| 亚洲无亚洲人成网站77777| 一本色道**综合亚洲精品蜜桃冫 | 亚洲综合色噜噜狠狠| 亚洲欧美日韩直播| 亚洲影院污污.| 亚洲欧美综合| 欧美综合国产| 久久蜜桃香蕉精品一区二区三区| 久久精品国产清高在天天线| 久久精品综合网| 久久夜精品va视频免费观看| 麻豆精品在线观看| 欧美国产综合视频| 欧美日韩一区二区三区四区在线观看 | 欧美精品www在线观看| 欧美绝品在线观看成人午夜影视| 欧美日产一区二区三区在线观看| 欧美日本国产一区| 国产精品久久777777毛茸茸| 国产老女人精品毛片久久| 国产综合在线看| 亚洲日本电影| 亚洲欧美日韩精品久久久久| 久久精品人人做人人综合| 噜噜噜久久亚洲精品国产品小说| 美日韩精品免费| 亚洲日韩中文字幕在线播放| 亚洲桃色在线一区| 久久久精品999| 欧美日韩国产综合视频在线观看| 国产精品任我爽爆在线播放| 精品动漫一区| 宅男噜噜噜66一区二区66| 欧美在线精品免播放器视频| 欧美a级一区| 一区二区三区你懂的| 欧美主播一区二区三区美女 久久精品人| 久久永久免费| 国产精品素人视频| 亚洲欧洲日本国产| 欧美在线视频一区二区| 欧美国产日韩一二三区| 在线一区二区三区四区| 久久久人成影片一区二区三区 | 欧美日韩免费在线| 国产综合色产在线精品| 99精品视频免费在线观看| 久久久久国产精品www| 亚洲精品自在在线观看| 久久精品99| 国产精品扒开腿做爽爽爽视频| 亚洲第一精品影视| 久久av资源网| 99精品国产热久久91蜜凸| 老司机精品久久| 国产有码在线一区二区视频| 亚洲自拍三区|