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

天行健 君子當自強而不息

創建游戲內核(17)

 

有關DirectAudio和DirectShow的基礎知識請參閱用DirectX Audio和DirectShow播放聲音和音樂

 

聲音內核為快速和容易地將聲音和音樂加入到游戲中提供了一種解決方案,聲音內核包含6個類組件,如下表所示:
 

說明
SOUND 包含DirectSound和DirectMusic對象,并控制音頻流(sound streaming)。
SOUND_DATA 這個類包含了使用SOUND_CHANNEL播放的波形數據。
SOUND_CHANNEL 這個類用于播放單個聲音,這種類一次最多可以同時使用32個(也就是說可以播放32個同步的聲音)。
MUSIC_CHANNEL 可以使用這個類播放單個歌曲文件,無論此文件是MIDI文件還是DirectMusic本地歌曲,一次只能使用一個這樣的類。
DLS 可下載聲音(downloadable sound)類對象,這個類允許用戶將不同的樂器加載到MUSIC_CHANNEL對象。
MP3 一個.mp3音樂播放類對象,這個類允許用戶播放.mp3歌曲并檢測這些歌曲的當前播放狀態。

 

波形數據和SOUND_DATA

SOUND_DATA類對象用于描述和包含單個的聲音(波形)。聲音頻率(sound frequency)、采樣精度(bits-per-sample)、音頻聲道數(number of channels)、文件大小以及聲源(source)都包含在SOUND_DATA類的聲明中,來看看它的定義:

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

protected:
    long _frequency;
    short _channels;
    short _bits_per_sample;

    FILE*   _fp;                // pointer to sound file
    char*   _ptr;               // pointer to current sound buffer will to be played
    char*   _buf;               // buffer to store sound data

    long    _buffer_size;       // sound buffer size
    long    _left_size;         // left size of sound buffer which need to loaded

    long    _file_start_pos;    // start position of wave file will to be loaded
    long    _file_curr_pos;     // current position of wave file will to be loaded

public:
    SOUND_DATA();
    ~SOUND_DATA();

    char* get_ptr();
    long  get_size();

    BOOL create();
    BOOL create(long size);
    void free();

    void set_format(long frequency, short channels, short bits_per_sample);
    void set_source(FILE* fp, long pos = -1, long size = -1);
    void set_source(void* ptr, long pos = -1, long size = -1);

    BOOL load_wav(char* filename, FILE* fp = NULL);
    BOOL load_wav_header(char* filename, FILE* fp = NULL);

    BOOL copy(SOUND_DATA* source);
};
 

#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()
 

接著來看看SOUND_DATA的實現:

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

    _frequency       = 22050;
    _channels        = 1;
    _bits_per_sample = 16;    
}

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

//------------------------------------------------------------------------------
// Create sound data buffer.
//------------------------------------------------------------------------------
BOOL SOUND_DATA::create()
{
    
return create(_buffer_size);
}

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

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

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

    
// clear out new buffer
    ZeroMemory(_buf, _buffer_size);

    
// point to new buffer
    _ptr = _buf;
    _fp  = NULL;    

    
return TRUE;
}

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

    _ptr = NULL;
    _buffer_size = 0;
}

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

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

//------------------------------------------------------------------------------
// Set play property for sound data buffer.
//------------------------------------------------------------------------------
void SOUND_DATA::set_format(long frequency, short channels, short bits_per_sample)
{
    _frequency  = frequency;
    _channels   = channels;
    _bits_per_sample = bits_per_sample;
}

//------------------------------------------------------------------------------
// Set position and size for sound data buffer.
//------------------------------------------------------------------------------
void SOUND_DATA::set_source(FILE* fp, long pos, long size)
{
    _fp  = fp;
    _ptr = NULL;

    
if(pos != -1)
        _file_start_pos = _file_curr_pos = pos;

    
if(size != -1)
        _buffer_size = _left_size = size;
}

//------------------------------------------------------------------------------
// Set position and size for sound buffer.
//------------------------------------------------------------------------------
void SOUND_DATA::set_source(void* ptr, long pos, long size)
{
    _fp = NULL;
    _ptr = (
char*) ptr;

    
if(pos != -1)
        _file_start_pos = _file_curr_pos = pos;

    
if(size != -1)
        _buffer_size = _left_size = size;
}

//------------------------------------------------------------------------------
// Load in wave file. 
//------------------------------------------------------------------------------
BOOL SOUND_DATA::load_wav(char* filename, FILE* fp)
{
    
// load wave header information first
    if(! load_wav_header(filename, fp))
        
return FALSE;

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

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

    
if(filename != NULL)
    {
        
if((fp = fopen(filename, "rb")) == NULL)
            
return FALSE;
    }

    fseek(fp, _file_start_pos, SEEK_SET);
    fread(_buf, 1, _buffer_size, fp);

    
// reset start position and current position
    _file_start_pos = _file_curr_pos = 0;

    
// close file
    if(filename != NULL)
        fclose(fp);

    
return TRUE;
}

//------------------------------------------------------------------------------
// Load wave header from file.
//------------------------------------------------------------------------------
BOOL SOUND_DATA::load_wav_header(char* filename, FILE* fp)
{
    
if(filename == NULL && fp == NULL)
        
return FALSE;

    
if(filename != NULL)
    {
        
if((fp = fopen(filename, "rb")) == NULL)
            
return FALSE;
    }

    
// save position in file
    long org_file_pos = ftell(fp);

    BOOL rv = 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

        _frequency = wave_header.sample_rate;
        _channels  = wave_header.channels;
        _bits_per_sample = wave_header.bits_per_sample;

        _buffer_size = _left_size = wave_header.data_size;
        _file_start_pos = _file_curr_pos = ftell(fp);

        rv = TRUE;
    }

    
// close if we opened file, otherwise return to original position.
    if(filename != NULL)
        fclose(fp);
    
else
        fseek(fp, org_file_pos, SEEK_SET);

    
return rv;
}

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

    
// note that _buf is not assigned!!

    _frequency       = source->_frequency;
    _channels        = source->_channels;
    _bits_per_sample = source->_bits_per_sample;

    _fp              = source->_fp;
    _ptr             = source->_ptr;
    _buffer_size     = source->_buffer_size;
    _left_size       = source->_left_size;
    _file_curr_pos   = source->_file_curr_pos;
    _file_start_pos  = source->_file_start_pos;

    
return TRUE;
}
 

使用SOUND_DATA類對象存儲回放格式和聲音的數據源,聲音有兩個來源:一個文件或內存緩沖區。另外,如果聲音太大而不能放進內存中,可以設置成從音頻流讀取。

加載單個.wav文件,最快的方法就是使用SOUND_DATA::load_wav函數。load_wav函數帶有兩個參數:要加載的.wav文件的文件名以及源文件指針。對于這兩個參數,只能用其中一個,同時將另外一個設置為NULL。源文件指針使程序員能夠將多個.wav文件打包進單個文件,并且仍然能夠單獨加載這些被打包的.wav文件。

除了加載單個的.wav文件外,還可以采用設置聲音的數據源這種方式。當聲音文件太大(超過64k)而無法存放到聲音緩沖區中的時候,這種方式就特別有用,方法就是將文件或內存緩沖區中的聲音數據放到流中。SOUND_DATA::set_source函數正好用于解決這個問題,此函數有兩個版本可供使用:

void set_source(FILE* fp, long pos = -1, long size = -1);
void set_source(void* ptr, long pos = -1, long size = -1);

可以選擇一個源文件指針或一個內存指針,pos參數將聲音數據的起始位置(偏移量)傳送給SOUND_DATA類,size參數用于設置流的總字節數(聲音的大小)。

注意pos和size的缺省值都是-1,就使得類能夠對文件位置進行設置。為了達到設置聲音數據源的目的,首先必須使用set_format函數設置回放格式,然后必須使用load_wav_header函數解析波形文件頭,此函數所帶參數的含義同load_wav函數相同。

另外,如果聲音被存儲到內存中以及從內存中流出,就必須使用SOUND_DATA::create函數創建此內存緩沖區。可以自己指定緩沖區的大小,也可以讓create函數使用通過load_wav_header函數解析出來的緩沖區大小。調用SOUND_DATA::get_ptr函數可以得到指向內存緩沖區的指針,可以安全地使用此指針存儲聲音。


posted on 2007-09-25 00:23 lovedday 閱讀(334) 評論(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>
            亚洲黄色一区| 亚洲国产欧美一区二区三区同亚洲| 亚洲第一伊人| 91久久久在线| 久久综合网络一区二区| 一色屋精品视频免费看| 免费在线日韩av| 亚洲欧美激情四射在线日| 鲁鲁狠狠狠7777一区二区| 久久精品人人| 亚洲欧美激情四射在线日| 国产精品一区一区三区| 欧美午夜精品久久久久免费视| 麻豆国产va免费精品高清在线| 亚洲一二三区精品| 黑人巨大精品欧美黑白配亚洲 | 国产一区二区三区最好精华液| 男女激情视频一区| 欧美激情亚洲精品| 久久久久青草大香线综合精品| 亚洲国产日韩一区| 亚洲国产精品国自产拍av秋霞| 亚洲日本一区二区三区| 免费中文日韩| 小辣椒精品导航| 亚洲视频日本| 亚洲精品自在久久| 欧美国产亚洲视频| 久久综合色播五月| 日韩视频在线观看国产| 亚洲精选中文字幕| 欧美一区二区三区日韩视频| 亚洲色图自拍| 老牛嫩草一区二区三区日本| 欧美一区亚洲一区| 午夜久久tv| 宅男精品导航| 久久免费少妇高潮久久精品99| 欧美制服丝袜第一页| 欧美精品久久久久久久免费观看| 国产精品久久久一区麻豆最新章节 | 欧美日韩久久不卡| 亚洲一区二区三区中文字幕| 一片黄亚洲嫩模| 99热免费精品在线观看| 亚洲精品在线免费观看视频| 午夜久久黄色| 欧美精品aa| 黄色成人av网站| 亚洲自啪免费| 亚洲欧美久久久| 性色av一区二区怡红| 亚洲激情国产精品| 久久大逼视频| 欧美激情一区二区| 亚洲第一综合天堂另类专| 一区二区三区自拍| 91久久精品国产91性色| 欧美日本一道本| 欧美激情亚洲| 亚洲国产精品精华液网站| 91久久黄色| 国产精品国产亚洲精品看不卡15| 欧美日韩视频在线一区二区观看视频 | 国产精品成人一区二区三区吃奶| 亚洲精品永久免费| 亚洲深爱激情| 欧美主播一区二区三区美女 久久精品人| 亚洲影院在线观看| 99国内精品久久久久久久软件| 欧美成人精品一区| 国产精品丝袜久久久久久app| 国产亚洲精品激情久久| 午夜视频在线观看一区二区| 久久综合国产精品| 亚洲国产精品va在线观看黑人| 久久国产视频网站| 伊人久久大香线| 欧美国产精品久久| 亚洲综合视频网| 国产女人18毛片水18精品| 亚洲乱码国产乱码精品精天堂| 欧美国产日本| 欧美激情中文字幕一区二区| 一区二区冒白浆视频| 久久婷婷影院| 久久精品在线| 国产欧美日韩中文字幕在线| 久久精品国产一区二区电影| 久久久久久久久久久久久久一区| 亚洲国产精品第一区二区| 亚洲人成在线观看网站高清| 国产精品毛片在线| 免费一级欧美片在线播放| 99riav1国产精品视频| 欧美有码视频| 亚洲精品在线免费| 国产麻豆综合| 欧美激情在线狂野欧美精品| 欧美视频日韩视频| 99re8这里有精品热视频免费| 夜夜嗨av一区二区三区中文字幕| 国产欧美日韩一区| 亚洲人成免费| 国产一区二区三区日韩欧美| 最近看过的日韩成人| 国产精品夜色7777狼人| 欧美激情一级片一区二区| 国产精品一区二区你懂的| 亚洲福利电影| 国语自产在线不卡| 一本大道av伊人久久综合| 亚洲国产精品va| 久久国产一区二区| 欧美高清一区| 亚洲精品乱码| 欧美国产丝袜视频| 国产精品免费看| 亚洲激情小视频| 国产亚洲精品久久久久婷婷瑜伽 | 一区二区三区高清| 最新日韩在线视频| 欧美一区激情| 午夜日韩在线观看| 欧美激情精品久久久久久变态| 久久免费精品日本久久中文字幕| 午夜精品国产| 国产亚洲午夜高清国产拍精品| 亚洲激情在线| 亚洲国产欧美一区二区三区久久| 欧美激情在线狂野欧美精品| 国产亚洲va综合人人澡精品| 免费观看国产成人| 国产日韩在线视频| 亚洲一级黄色| 激情另类综合| 欧美一站二站| 久久综合免费视频影院| 国产精品嫩草影院一区二区| 亚洲人人精品| 亚洲理伦电影| 蜜臀久久99精品久久久画质超高清| 国产精品成人在线| 亚洲视频中文| 亚洲字幕一区二区| 欧美性片在线观看| 一区二区三区欧美视频| 亚洲社区在线观看| 国产精品极品美女粉嫩高清在线| 一本色道久久综合亚洲二区三区| 亚洲视频www| 国产精品免费一区二区三区在线观看 | 亚洲人成在线影院| 一区二区三欧美| 欧美网站大全在线观看| 中国av一区| 久久久久九九视频| 欧美成人黑人xx视频免费观看| 老巨人导航500精品| 亚洲国产专区校园欧美| 欧美女主播在线| 亚洲专区国产精品| 久久这里只有| 99国产精品一区| 国产老女人精品毛片久久| 午夜久久一区| 欧美电影在线观看| 亚洲精品欧洲精品| 国产精品久久网| 久久视频一区二区| 一区二区三区精品视频| 久久激情视频| 91久久久一线二线三线品牌| 欧美婷婷久久| 久久久久青草大香线综合精品| 亚洲破处大片| 久久精品日韩欧美| 亚洲国产婷婷| 国产精品99免费看 | 亚洲欧美精品在线观看| 国产精品v欧美精品v日本精品动漫| 亚洲国产精品成人综合色在线婷婷| 中文精品99久久国产香蕉| 欧美亚男人的天堂| 久久精品国产欧美亚洲人人爽| 亚洲国产成人在线| 欧美一区观看| 亚洲国产成人91精品| 亚洲伊人伊色伊影伊综合网| 国产精品毛片va一区二区三区| 亚洲性视频h| 亚洲一区二区三区777| 国产亚洲毛片在线| 蜜臀av性久久久久蜜臀aⅴ| 亚洲图片在线观看| 亚洲激情综合| 先锋影院在线亚洲| 男人的天堂亚洲| 另类天堂视频在线观看| 免费av成人在线|