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

天行健 君子當自強而不息

創建游戲內核(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>
            久久久人成影片一区二区三区| 久久精品亚洲一区| 亚洲精品影视| 亚洲欧美日韩国产成人| 国产日韩精品一区二区三区 | 国产精品国产三级国产aⅴ浪潮| 一区二区三区视频观看| 亚洲欧美久久| 亚洲国产专区校园欧美| 亚洲国产成人精品视频| 一区二区三区视频在线| 免费日本视频一区| 国产精品久久久久9999吃药| 日韩视频中文字幕| 国产日韩欧美一二三区| 国产精品高清一区二区三区| 欧美不卡在线视频| 亚洲欧洲精品天堂一级| 欧美激情一区二区三区在线| 男女激情视频一区| 久久久综合免费视频| 久久精品123| 欧美一区二区三区视频| 亚洲欧美网站| 久久久久久9| 欧美激情影音先锋| 欧美精品久久久久久久久老牛影院| 久久精品视频在线免费观看| 久久精品国产69国产精品亚洲| 久久国产直播| 久久精品视频免费播放| 99国产麻豆精品| 亚洲一品av免费观看| 欧美日韩p片| 欧美精品一区二| 亚洲丁香婷深爱综合| 国产精品男人爽免费视频1| 在线午夜精品| 久久精视频免费在线久久完整在线看| 亚洲综合欧美| 免费亚洲婷婷| 中文一区二区| 亚洲一卡久久| 欧美精品一区二区在线播放| 国产欧美韩国高清| 亚洲片在线观看| 一本色道久久88综合亚洲精品ⅰ | 欧美日本簧片| 国产精品一级| 在线午夜精品| 最新日韩在线| 欧美伦理91i| 亚洲精品国产精品国自产在线| 亚洲一区不卡| 亚洲伊人色欲综合网| 欧美成人精品在线观看| 亚洲黄色片网站| 欧美mv日韩mv国产网站app| 欧美一区二区高清在线观看| 国产精品美女久久久免费| 一片黄亚洲嫩模| 亚洲国产导航| 欧美日韩一区二区精品| 亚洲天堂网站在线观看视频| 一本色道久久综合亚洲精品不| 亚洲国产欧美日韩精品| 一本一本久久| 欧美午夜不卡视频| 欧美综合国产| 久久久欧美精品| 99国产精品视频免费观看| 中文网丁香综合网| 亚洲欧美久久| 亚洲人午夜精品| 国产日韩精品入口| 欧美大尺度在线观看| 亚洲免费成人av| 午夜国产不卡在线观看视频| 欧美日韩国产一区| 久久精视频免费在线久久完整在线看 | 一区二区三区久久久| 久久久之久亚州精品露出| 你懂的国产精品永久在线| 亚洲欧洲免费视频| 亚洲大片精品永久免费| 国产精品视频午夜| 欧美一区三区二区在线观看| 免费看亚洲片| 久久精品一区二区三区中文字幕| 老司机一区二区| 久久精品国产精品亚洲精品| 欧美日韩国产免费观看| 亚洲高清一区二区三区| 在线观看国产精品网站| 欧美一区不卡| 久久久久久国产精品mv| 欧美一区二区三区免费大片| 雨宫琴音一区二区在线| 欧美制服丝袜| 国产夜色精品一区二区av| 亚洲精品国产精品久久清纯直播| 国产午夜精品麻豆| 亚洲专区一区| 久久久久久9| 国产乱码精品一区二区三| 亚洲欧美日韩国产综合精品二区| 国产精品高潮在线| 亚洲欧美成人一区二区在线电影| 在线免费观看成人网| 欧美黄色网络| 亚洲一区二区不卡免费| 久久偷看各类wc女厕嘘嘘偷窃| 欧美亚一区二区| 久久只有精品| 亚洲伊人久久综合| 久久精品一区二区三区中文字幕 | 亚洲深夜激情| 国产精品视频免费一区| 久久久久国产精品一区| 亚洲日本aⅴ片在线观看香蕉| 亚洲欧美国内爽妇网| 一区二区三区在线观看国产| 欧美色网一区二区| 欧美性片在线观看| 国产精品女主播| 国产精品高清一区二区三区| 99视频+国产日韩欧美| 香蕉久久一区二区不卡无毒影院| 欧美亚洲综合在线| 久久电影一区| 欧美成人免费在线观看| 欧美日韩国产123区| 欧美日韩免费观看一区二区三区| 国产精品豆花视频| 国产一区二区三区高清| 一区精品在线| 欧美无乱码久久久免费午夜一区| 免费人成精品欧美精品| 欧美精品激情blacked18| 欧美日韩综合在线| 国产精品久久久久久久久久ktv | 亚洲激情校园春色| 在线成人亚洲| 篠田优中文在线播放第一区| 亚洲自拍偷拍福利| 亚洲欧美日韩综合国产aⅴ| 亚洲第一在线| 久久一本综合频道| 久久久噜噜噜| 欧美高清在线一区| 久久精品综合| 裸体一区二区| 欧美性jizz18性欧美| 狠狠噜噜久久| 久久久精品tv| 亚洲一区免费观看| 国产精品免费福利| 欧美日韩一区二区三区四区在线观看 | 久久久www| 嫩模写真一区二区三区三州| 欧美特黄一级大片| 一本色道久久综合亚洲精品婷婷| 欧美在线免费播放| 在线亚洲观看| 欧美大学生性色视频| 国产精品盗摄久久久| 久久影视精品| 欧美日韩色一区| 亚洲国产一区二区a毛片| 男人天堂欧美日韩| 久久国产88| 韩曰欧美视频免费观看| 午夜影视日本亚洲欧洲精品| 另类天堂av| 久久伊人精品天天| 一区二区在线观看视频| 久久久久国产免费免费| 欧美大片va欧美在线播放| 国产亚洲精品福利| 久久国产精品久久久久久久久久 | 国产精品亚洲一区| 久久精品国产亚洲aⅴ| 先锋a资源在线看亚洲| 国产一级精品aaaaa看| 亚洲高清资源| 日韩一级免费| 国产欧美日韩综合精品二区| 久久精品主播| 国产精品欧美日韩| 久热精品视频在线| 欧美电影在线播放| 欧美大成色www永久网站婷| 美日韩丰满少妇在线观看| 一区二区国产日产| 蜜臀av性久久久久蜜臀aⅴ| 亚洲社区在线观看| 久久中文字幕导航| 久久综合久久综合久久综合| 欧美精品电影在线| 六月天综合网|