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

天行健 君子當自強而不息

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

 

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

 

使用SOUND_CHANNEL播放聲音

前面介紹了如何初始化聲音系統(tǒng)以及如何加載聲音數(shù)據(jù),很自然地,接下來就要講述如何播放聲音了,這也正是SOUND_CHANNEL類的用途所在。

首先定義兩個全局變量來保存音頻緩沖的大小和每個音頻數(shù)據(jù)塊的大小。

// these are the fixed sizes for sound channel buffers
const long g_sound_buffer_size = 65536;
const long g_sound_buffer_chunk = g_sound_buffer_size / 4;

第一個變量g_sound_buffer_size表示分配給用于播放聲音的每個DirectSound緩沖區(qū)的字節(jié)數(shù),這里使用65536字節(jié),因為此大小的緩沖區(qū)足夠保存相當于數(shù)秒高品質(zhì)的聲音數(shù)據(jù)。第二個g_sound_buffer_chunk是單個聲音數(shù)據(jù)塊的大小,使用4個數(shù)據(jù)塊,每個數(shù)據(jù)塊存儲了流式聲音的一個小的采樣。每播放完一個數(shù)據(jù)塊,緊接著就 開始播放下一個數(shù)據(jù)塊,同時使用新的聲音數(shù)據(jù)加載前一個數(shù)據(jù)塊。

一般不必改變這兩個變量的值,除非想要節(jié)約內(nèi)存。如果想節(jié)約內(nèi)存,只需將g_sound_buffer_size變量的值改變成較小的數(shù)字即可。g_sound_buffer_size變量使用不同的大小,各有其優(yōu)勢,比如g_sound_buffer_size變量的值越大,聲音內(nèi)核將新數(shù)據(jù)放到流中的頻率就越小,當然這也意味著要占用更多的內(nèi)存。

來看看SOUND_CHANNEL的定義:

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

protected:
    SOUND*                  _sound;         
// pointer to parent sound object
    IDirectSoundBuffer8*    _ds_buffer;     // pointer to DirectSound buffer object
    IDirectSoundNotify8*    _ds_notify;     // pointer to DirectSound notify object
    short                   _event_index;   

    
long                    _volume;        // sound buffer volume
    signed long             _pan;           // sound buffer pan
    BOOL                    _is_playing;    // sound buffer playing flag
    long                    _loop_times;    // loop times

    
long                    _frequency;
    
short                   _bits_per_sample;
    
short                   _channels;

    SOUND_DATA              _sound_data;

    
short                   _load_section;  // sound section will to be loaded
    short                   _stop_section;  // sound section will to be stoped
    short                   _next_notify;   // sound notification index will to be played

    BOOL _buffer_data();
    
void _update();

public:
    SOUND_CHANNEL();
    ~SOUND_CHANNEL();

    IDirectSoundBuffer8*    get_sound_buffer_com();
    IDirectSoundNotify8*    get_notify_com();

    BOOL create(SOUND* sound, 
long frequency = 22050, short channels = 1, short bits_per_sample = 16);
    BOOL create(SOUND* sound, SOUND_DATA* sound_data);
    
void free();

    BOOL play(SOUND_DATA* sound_data, 
long volume_percent = 100, long loop = 1);
    
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();
};
 

接著來看看它的實現(xiàn):

//------------------------------------------------------------------------------
// Constructor, initialize member data.
//------------------------------------------------------------------------------
SOUND_CHANNEL::SOUND_CHANNEL()
{
    _sound     = NULL;
    _ds_buffer = NULL;
    _ds_notify = NULL;

    _event_index = -1;

    _volume     = 0;
    _pan        = 0;
    _frequency  = 0;
    _is_playing = FALSE;
}

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

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

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

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

    
if((_sound = sound) == NULL)
        
return FALSE;

    
if(_sound->get_directsound_com() == NULL)
        
return FALSE;

    
// save playback format
    _frequency       = frequency;
    _bits_per_sample = bits_per_sample;
    _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) _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;

    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(_sound->get_directsound_com()->CreateSoundBuffer(&buffer_desc, &ds_buffer, NULL)))
        
return FALSE;

    
// query for newer interface
    if(FAILED(ds_buffer->QueryInterface(IID_IDirectSoundBuffer8, (void**) &_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(_ds_buffer->QueryInterface(IID_IDirectSoundNotify8, (void**) &_ds_notify)))
        
return FALSE;

    HANDLE event_handle;

    
// get an event for this
    if(! _sound->assign_event(this, &_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(_ds_notify->SetNotificationPositions(4, pos_notify)))
        
return FALSE;

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

    
return TRUE;
}

//------------------------------------------------------------------------------
// Create sound buffer.
//------------------------------------------------------------------------------
BOOL SOUND_CHANNEL::create(SOUND* sound, SOUND_DATA* sound_data)
{
    
return create(sound, sound_data->_frequency, sound_data->_channels, sound_data->_bits_per_sample);
}

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

    
// release the notification
    release_com(_ds_notify);

    
// release the sound buffer
    release_com(_ds_buffer);

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

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

//------------------------------------------------------------------------------
// Play sound buffer.
//------------------------------------------------------------------------------
BOOL SOUND_CHANNEL::play(SOUND_DATA* sound_data, long volume_percent, long loop_times)
{
    
if(sound_data == NULL || _ds_buffer == NULL || _ds_notify == NULL)
        
return FALSE;

    
// stop any playback
    stop();

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

    
// setup playing information
    _sound_data.copy(sound_data);

    
// set looping times
    _loop_times = loop_times;

    
// calculate stop section position
    if(_loop_times == 0)
        _stop_section = -1;
    
else
        _stop_section = (
short
            (((_sound_data._buffer_size * _loop_times) % g_sound_buffer_size) / g_sound_buffer_chunk) ;

    _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

    _next_notify = 0;

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

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

    
// flag as playing
    _is_playing = TRUE;

    
return TRUE;
}

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

    _is_playing = FALSE;
}

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

//------------------------------------------------------------------------------
// Set volume for sound buffer.
//------------------------------------------------------------------------------
BOOL SOUND_CHANNEL::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;
}

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

//------------------------------------------------------------------------------
// Set pan for sound buffer.
//------------------------------------------------------------------------------
BOOL SOUND_CHANNEL::set_pan(long level)
{
    signed 
long pan;
    
    
if(_ds_buffer == NULL)
        
return FALSE;

    
// calculate a suable setting
    if(level < 0)
        pan = DSBPAN_LEFT / 100 * (-level % 101);
    
else
        pan = DSBPAN_LEFT / 100 * (level % 101);

    
if(FAILED(_ds_buffer->SetPan(pan)))
        
return FALSE;

    _pan = level % 101;

    
return TRUE;
}

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

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

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

    _frequency = frequency;

    
return TRUE;
}

//------------------------------------------------------------------------------
// Checks whether sound buffer is playing.
//------------------------------------------------------------------------------
BOOL SOUND_CHANNEL::is_playing()
{
    
if(_sound == NULL || _ds_buffer == NULL || _ds_notify == NULL)
        
return FALSE;

    
return _is_playing;
}

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

    
// setup position to load in
    long lock_pos = (_load_section % 4) * g_sound_buffer_chunk;

    
long size;
    
char* ptr;

    
// lock sound buffer to get pointer to sound data
    if(FAILED(_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(_sound_data._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(_sound_data._left_size > load_size)
            {
                
// load in sound data
                if(_sound_data._fp != NULL)
                {
                    
// load in sound data from file
                    fseek(_sound_data._fp, _sound_data._file_curr_pos, SEEK_SET);
                    fread(&ptr[load_pos], 1, load_size, _sound_data._fp);
                }
                
else
                    
// load into sound data from buffer
                    memcpy(&ptr[load_pos], &_sound_data._ptr[_sound_data._file_curr_pos], load_size);

                
// decrease sound data, advance current sound buffer position.
                _sound_data._left_size     -= load_size;
                _sound_data._file_curr_pos += load_size;
                
break;
            }
            
else        // _sound_data._left_size <= load_size
            {
                
// load in sound data
                if(_sound_data._fp != NULL)
                {
                    
// load in sound data from file
                    fseek(_sound_data._fp, _sound_data._file_curr_pos, SEEK_SET);
                    fread(&ptr[load_pos], 1, _sound_data._left_size, _sound_data._fp);
                }
                
else
                    
// load in sound data from buffer
                    memcpy(&ptr[load_pos], &_sound_data._ptr[_sound_data._file_curr_pos], _sound_data._left_size);

                
// decrease sound data, advance current sound buffer position.
                load_size -= _sound_data._left_size;
                load_pos  += _sound_data._left_size;

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

                    
if(_loop_times == 0)
                    {
                        
// clear out remaining buffer space
                        if(load_size)
                            ZeroMemory(&ptr[load_pos], load_size);

                        _sound_data._left_size = 0L;
                        
break;
                    }
                }

                
// reset sound data current position and left size
                _sound_data._file_curr_pos = _sound_data._file_start_pos;
                _sound_data._left_size     = _sound_data._buffer_size;

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

    
// unlock the buffer
    _ds_buffer->Unlock(ptr, size, NULL, 0);

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

    
return TRUE;
}

//------------------------------------------------------------------------------
// Update for sound buffer palying.
//------------------------------------------------------------------------------
void SOUND_CHANNEL::_update()
{
    
// check for end of sound
    if(_next_notify == _stop_section && _sound_data._left_size == 0)
        stop();
    
else
    {
        
// buffer in more data
        _buffer_data();

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

最多可以將SOUND_CHANNEL類實例化32次,也就是說同時可以用多達32個聲道進行播放(聲音內(nèi)核不允許同時32個以上的實例,任何超過32的值,都無法被成功初始化)。調(diào)用SOUND_CHANNEL::create函數(shù)可以初始化各個聲道,需要提供一個預初始化的SOUND類以及回放格式。為方便起見,甚至可以使用存儲在SOUND_DATA類中的回放格式創(chuàng)建聲道。

使用SOUND_CHANNEL類進行的操作中,最頻繁的就是播放聲音、停止播放聲音以及改變聲音的音量。要播放聲音,需要給SOUND_CHANNEL::play函數(shù)傳遞三個參數(shù):保存在SOUND_DATA類中要播放的聲音數(shù)據(jù)、音量的大小以及連續(xù)播放聲音的次數(shù)。

接著我們編寫測試代碼:

點擊下載源碼和工程

/*****************************************************************************
PURPOSE:
    Test for class SOUND, SOUND_DATA, SOUND_CHANNEL.
*****************************************************************************/


#include "Core_Global.h"

class APP : public APPLICATION
{
private:
    SOUND _sound;
    SOUND_DATA _sound_data[2];
    SOUND_CHANNEL _sound_channel[2];

    FILE* _fp;

public:
    APP()
    {
        _fp = NULL;
    }

    BOOL init();
    BOOL frame();
    BOOL shutdown();
};

BOOL APP::init()
{
    
// Initialize DierctSound and DirectMusic.
    _sound.init(get_hwnd());

    
// load into sound data from wave file
    _sound_data[0].load_wav("test1.wav", NULL);
    _sound_data[1].load_wav("test2.wav", NULL);
    
    
// create sound channel
    _sound_channel[0].create(&_sound, &_sound_data[0]);
    _sound_channel[1].create(&_sound, &_sound_data[1]);

    
// play sound
    _sound_channel[0].play(&_sound_data[0]);
    _sound_channel[1].play(&_sound_data[1], 100, 0); 
// lopping forever   
    
    
return TRUE;
}

BOOL APP::frame()
{    
    
return TRUE;
}

BOOL APP::shutdown()
{
    
if(_fp) 
        fclose(_fp);

    
return TRUE;
}

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

    
return app.run();
}

posted on 2007-09-29 22:03 lovedday 閱讀(377) 評論(0)  編輯 收藏 引用


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


公告

導航

統(tǒng)計

常用鏈接

隨筆分類(178)

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

搜索

最新評論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美电影免费观看高清| 亚洲视频高清| 欧美日本高清| 亚洲高清在线观看一区| 国产精品免费观看视频| 蜜臀av性久久久久蜜臀aⅴ| 在线视频国产日韩| 麻豆精品一区二区av白丝在线| 欧美成人小视频| 亚洲精品自在在线观看| 欧美日韩一区在线视频| 洋洋av久久久久久久一区| 欧美一区二区久久久| 国产农村妇女毛片精品久久莱园子 | 欧美一区二区三区电影在线观看| 夜夜嗨一区二区| 国产精品美女诱惑| 亚洲四色影视在线观看| 久久久综合视频| 亚洲狼人精品一区二区三区| 欧美日韩高清不卡| 欧美在线视频播放| 国产精品99久久久久久人| 亚洲国产老妈| 久久精品一区二区国产| 亚洲少妇在线| av成人福利| 91久久综合| 亚洲国产免费| 海角社区69精品视频| 欧美视频精品在线| 欧美大片免费观看| 欧美国产免费| 欧美日韩一区二区在线播放| 欧美大片在线观看| 欧美+亚洲+精品+三区| 米奇777超碰欧美日韩亚洲| 欧美一级专区| 久久精品中文字幕免费mv| 日韩一区二区高清| 国产精品无码专区在线观看| 国产精品美女xx| 国产精品美女黄网| 国产女主播视频一区二区| 国产精品国产一区二区| 国产欧美一区二区精品仙草咪| 国产精品久久久久久影视| 国产欧美高清| 亚洲大胆人体在线| 一区二区三区欧美日韩| 欧美在线观看网址综合| 亚洲精品永久免费| 欧美一级理论性理论a| 欧美1区2区| 国产九九精品| 91久久久久久久久| 亚洲免费在线观看视频| 噜噜噜在线观看免费视频日韩| 亚洲精品乱码久久久久久按摩观 | 亚洲一区二区黄| 欧美亚洲网站| 亚洲国产精品免费| 亚洲一区二区三区在线观看视频| 久久久亚洲成人| 欧美午夜a级限制福利片| 亚洲美女av在线播放| 久久综合久色欧美综合狠狠 | 亚洲美女在线国产| 一本一本a久久| 国产日韩欧美麻豆| 欧美精品一区二| 亚洲欧美视频一区二区三区| 玖玖精品视频| 一区二区三区日韩欧美精品| 国产自产v一区二区三区c| 玖玖在线精品| 亚洲三级网站| 欧美阿v一级看视频| 欧美国产一区视频在线观看| 亚洲午夜精品网| 国产欧美日韩另类一区| 久久精品系列| 一本色道久久综合亚洲精品不 | 久久一区国产| 亚洲一区二区精品| 91久久综合| 亚洲精品极品| 亚洲国产精品悠悠久久琪琪| 国产精品日韩精品| 国产精品久久久久影院亚瑟| 亚洲视频二区| 久久激情视频| 日韩视频中文| 久久成人18免费观看| 亚洲一区亚洲二区| 久久精品国产清高在天天线| 亚洲女与黑人做爰| 久久精品91久久香蕉加勒比| 久久久久久97三级| 亚洲欧洲一区| 久久成人资源| 国产精品久久久久免费a∨大胸| 久久夜色精品国产| 久久久91精品| 亚洲欧美日韩一区二区| 欧美日韩成人综合| 在线免费不卡视频| 久热国产精品视频| 麻豆9191精品国产| 久久精品一区蜜桃臀影院 | 亚洲激情影院| 亚洲免费播放| 亚洲日本成人女熟在线观看| 亚洲国产精品99久久久久久久久| 亚洲精品欧美极品| 亚洲国产成人精品久久久国产成人一区 | 久久久噜噜噜久久| 欧美三级在线视频| 久久精品国产第一区二区三区| 亚洲一区二区免费| 日韩一级在线观看| 国产精品性做久久久久久| 亚洲天堂av高清| 欧美精品福利| 亚洲特级毛片| 亚洲精品在线看| 欧美另类变人与禽xxxxx| 国内精品免费在线观看| 亚洲视频久久| 最新国产拍偷乱拍精品| 午夜久久影院| 国产一区二区0| 久久综合狠狠综合久久综合88| 日韩亚洲欧美中文三级| 国产在线视频不卡二| 亚洲专区在线| 激情懂色av一区av二区av| 欧美在线中文字幕| 亚洲激情在线观看| 亚洲黑丝在线| 9色porny自拍视频一区二区| 国产精品白丝av嫩草影院 | 欧美午夜精品久久久久久久 | 久久精品人人做人人爽电影蜜月| 欧美77777| 亚洲精选视频免费看| 欧美日韩一区二区在线观看| 91久久一区二区| 亚洲伊人网站| 国产三级欧美三级| 最新日韩中文字幕| 免费一区二区三区| 久久亚洲国产精品一区二区 | 久久久久久久一区二区三区| 性做久久久久久久免费看| 久久嫩草精品久久久精品| 欧美激情亚洲自拍| 在线成人av.com| 9久re热视频在线精品| 欧美伊久线香蕉线新在线| 亚洲国产日韩精品| 欧美日韩国产综合视频在线观看 | 亚洲影院免费| 欧美大胆成人| 夜色激情一区二区| 亚洲免费一区二区| 含羞草久久爱69一区| 久久免费高清| 91久久午夜| 久久国产精品网站| 一区二区不卡在线视频 午夜欧美不卡在 | 韩国精品在线观看| 久久av一区二区| 一区二区三区高清在线| 久久久久久9| 久久av红桃一区二区小说| 宅男噜噜噜66国产日韩在线观看| 欧美专区福利在线| 国产综合18久久久久久| 亚洲字幕一区二区| 在线成人欧美| 亚洲视频成人| 国产精品www| 亚洲性夜色噜噜噜7777| 亚洲人成精品久久久久| 欧美日韩小视频| 亚洲区在线播放| 久久福利毛片| 欧美在线亚洲在线| 91久久精品美女高潮| 久久精品综合网| 99在线精品观看| 亚洲欧美色一区| 欧美中文在线免费| 国产精品视频一| 亚洲伦理在线免费看| 国产精品毛片大码女人| 性色一区二区三区| 久久综合999| 99精品热视频|