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

天行健 君子當自強而不息

用DirectX Audio和DirectShow播放聲音和音樂(2)


本篇是用DirectX Audio和DirectShow播放聲音和音樂(1)的續篇。


開始使用主音頻緩存

讓緩存在程序啟動的時候開始播放可以節省不少處理器時間。因為內存資源是有限的,特別是在硬件設備中,而你使用的數據緩存可能需要任意大小,因此主音頻緩沖區和輔助緩沖區使用環形緩存。

環形緩沖的示意圖如下:

因為數據緩沖是一個一維數組,所以可以讓這個緩沖區頭尾相接。這是一個十分強大的技術,利用這個技術我們可以節省大量的內存。

聲音在進行混音處理后,被送入環形主音頻緩存。一旦播放位置到達主音頻緩存的終點,聲音又從頭開始播放,這樣聲音就被無間隙地連續播放。如果想要使用緩存的這種循環特性,需要指定啟用循環播放的特性,若不然當播放到緩沖區終點時,播放就停止了。

為了播放緩存中的音頻數據(在開啟循環選項的情況下播放),需要調用Play函數。

The Play method causes the sound buffer to play, starting at the play cursor.
HRESULT Play(
DWORD dwReserved1,
DWORD dwPriority,
DWORD dwFlags
);

Parameters

dwReserved1
Reserved. Must be 0.
dwPriority
Priority for the sound, used by the voice manager when assigning hardware mixing resources. The lowest priority is 0, and the highest priority is 0xFFFFFFFF. If the buffer was not created with the DSBCAPS_LOCDEFER flag, this value must be 0.
dwFlags
Flags specifying how to play the buffer. The following flags are defined:

Looping flag

Value Description
DSBPLAY_LOOPING After the end of the audio buffer is reached, play restarts at the beginning of the buffer. Play continues until explicitly stopped. This flag must be set when playing a primary buffer.

Voice allocation flags

The voice allocation flags are valid only for buffers created with the DSBCAPS_LOCDEFER flag. One of the following flags can be used to force the processing of the sound into hardware or software. If neither DBSPLAY_LOCHARDWARE nor DBSPLAY_LOCSOFTWARE is set, the sound is played in either software or hardware, depending on the availability of resources at the time the method is called. See Remarks.

 
Value Description
DSBPLAY_LOCHARDWARE Play this voice in a hardware buffer only. If the hardware has no available voices and no voice management flags are set, the call to IDirectSoundBuffer8::Play fails. This flag cannot be combined with DSBPLAY_LOCSOFTWARE.
DSBPLAY_LOCSOFTWARE Play this voice in a software buffer only. This flag cannot be combined with DSBPLAY_LOCHARDWARE or any voice management flag.

Voice management flags

The voice management flags are valid only for buffers created with the DSBCAPS_LOCDEFER flag, and are used for sounds that are to play in hardware. These flags enable hardware resources that are already in use to be yielded to the current sound. Only buffers created with the DSBCAPS_LOCDEFER flag are candidates for premature termination. See Remarks.

 

Value Description
DSBPLAY_TERMINATEBY_TIME If the hardware has no available voices, a currently playing nonlooping buffer will be stopped to make room for the new buffer. The buffer prematurely terminated is the one with the least time left to play.
DSBPLAY_TERMINATEBY_DISTANCE If the hardware has no available voices, a currently playing buffer will be stopped to make room for the new buffer. The buffer prematurely terminated will be selected from buffers that have the buffer's DSBCAPS_ MUTE3DATMAXDISTANCE flag set and are beyond their maximum distance. If there are no such buffers, the method fails.
DSBPLAY_TERMINATEBY_PRIORITY If the hardware has no available voices, a currently playing buffer will be stopped to make room for the new buffer. The buffer prematurely terminated will be the one with the lowest priority as set by the dwPriority parameter passed to IDirectSoundBuffer8::Play for the buffer.
 

Return Values

If the method succeeds, the return value is DS_OK. If the method fails, the return value may be one of the following error values:

Return code
DSERR_BUFFERLOST
DSERR_INVALIDCALL
DSERR_INVALIDPARAM
DSERR_PRIOLEVELNEEDED

當完成主音頻緩存設置后(以及整個音響系統),如果想停止它,需要調用IDirectSoundBuffer::Stop。

The Stop method causes the sound buffer to stop playing.

HRESULT Stop();

Parameters

None.

Return Values

If the method succeeds, the return value is DS_OK. If the method fails, the return value may be one of the following error values:

Remarks

For secondary sound buffers, IDirectSoundBuffer8::Stop sets the play cursor to the sample that follows the last sample played. This means that when the Play method is next called on the buffer, it will continue playing where it left off.

For the primary buffer, if an application has the DSSCL_WRITEPRIMARY level, this method will stop the buffer and reset the play cursor to 0 (the beginning of the buffer). This is necessary because the primary buffers on most sound cards can play only from the beginning of the buffer.

However, if IDirectSoundBuffer8::Stop is called on a primary buffer and the application has a cooperative level other than DSSCL_WRITEPRIMARY, this method simply reverses the effects of IDirectSoundBuffer8::Play. It configures the primary buffer to stop if no secondary buffers are playing. If other buffers are playing in this or other applications, the primary buffer will not actually stop until they are stopped. This method is useful because playing the primary buffer consumes processing overhead even if the buffer is playing sound data with the amplitude of 0 decibels.


使用輔助音頻緩存

想要使用輔助音頻緩存的數據,需要將輔助音頻緩存中包含的數據填充到主音頻緩存,如下圖所示:

如果在主音頻緩存的同一區域寫入兩段音頻數據,這兩段聲音就會被同時播放。輔助音頻緩存使用 IDirectSoundBuffer8接口,這個接口和IDirectSoundBuffer十分類似,實際上如果想要創建 IDirectSoundBuffer8接口,必須先創建IDirectSoundBuffer接口,然后通過請求新接口來獲取 IDirectSoundBuffer8接口。

創建輔助音頻緩存和創建主音頻緩存時主要的不同是必須在初始化時設置回放格式,這意味著緩沖區只能使用一種格式。如果希望使用另外的格式,必須釋放當前的緩存,重新創建另外一個。

代碼示例:

     // initialize and configure directsound

    // creates and initializes an object that supports the IDirectSound8 interface
    if(FAILED(DirectSoundCreate8(NULL, &g_ds, NULL)))
    {
        MessageBox(NULL, "Unable to create DirectSound object", "Error", MB_OK);
        
return 0;
    }

    
// set the cooperative level of the application for this sound device
    g_ds->SetCooperativeLevel(g_hwnd, DSSCL_NORMAL);

    
// create a sound buffer

    // setup the WAVEFORMATEX structure
    WAVEFORMATEX wave_format;

    ZeroMemory(&wave_format, 
sizeof(WAVEFORMATEX));

    wave_format.wFormatTag      = WAVE_FORMAT_PCM;
    wave_format.nChannels       = 1;        
// mono
    wave_format.nSamplesPerSec  = 11025;    
    wave_format.wBitsPerSample  = 16;
    wave_format.nBlockAlign     = (wave_format.wBitsPerSample / 8) * wave_format.nChannels;
    wave_format.nAvgBytesPerSec = wave_format.nSamplesPerSec * wave_format.nBlockAlign;

    
// setup the DSBUFFERDESC structure
    DSBUFFERDESC ds_buffer_desc;

    
// zero out strcutre
    ZeroMemory(&ds_buffer_desc, sizeof(DSBUFFERDESC));

    ds_buffer_desc.dwSize        = 
sizeof(DSBUFFERDESC); 
    ds_buffer_desc.dwFlags       = DSBCAPS_CTRLVOLUME;
    ds_buffer_desc.dwBufferBytes = wave_format.nAvgBytesPerSec * 2;  
// 2 seconds
    ds_buffer_desc.lpwfxFormat   = &wave_format;

    
// create the fist version object
    if(FAILED(g_ds->CreateSoundBuffer(&ds_buffer_desc, &ds, NULL)))
    {
        
// error ocuurred
        MessageBox(NULL, "Unable to create sound buffer", "Error", MB_OK);
    }
    
else
    {
        
// get the version 8 interface
        ds->QueryInterface(IID_IDirectSoundBuffer8, (void**)&g_ds_buffer);

        
// release the original interface
        ds->Release();
}

 

鎖定和加載 --- 在緩沖區中加載數據

緩存接口有一對處理數據加載的函數。 IDirectSoundBuffer8::Lock函數鎖定音頻緩沖數據,并且找回指向緩沖區數據的數據指針; IDirectSoundBuffer8::Unlock釋放在鎖定操作中使用的資源。

當鎖定緩存以后,就能對緩沖區進行寫入操作。先告訴緩沖寫入偏移量的字節數、寫入位置、要寫入數據的字節數,寫入完成后返回兩個指向數據的指針以及寫入數據的字節數。為什么會有兩個指針和兩個數據大小呢?因為音頻數據緩沖區是環形的,寫入的數據也需要跨過起始位置。返回的第一個指針是請求的位置,第一個值是從請求的位置到結束所寫入的字節數,第二個指針通常是緩存區的起始位置,第二個值是從起點開始寫入的字節數。

這里有一個長度是 65536字節大小的緩沖區,這個緩沖區被鎖定,以便于寫入62000字節的數據。第一個指針處寫入了60000字節,第二個指針處還剩下2000字節,如下圖所示:



Lock函數使用信息如下:

The Lock method readies all or part of the buffer for a data write and returns pointers to which data can be written.

HRESULT Lock(
DWORD dwOffset,
DWORD dwBytes,
LPVOID * ppvAudioPtr1,
LPDWORD pdwAudioBytes1,
LPVOID * ppvAudioPtr2,
LPDWORD pdwAudioBytes2,
DWORD dwFlags
);

Parameters

dwOffset
Offset, in bytes, from the start of the buffer to the point where the lock begins. This parameter is ignored if DSBLOCK_FROMWRITECURSOR is specified in the dwFlags parameter.
dwBytes
Size, in bytes, of the portion of the buffer to lock. The buffer is conceptually circular, so this number can exceed the number of bytes between dwOffset and the end of the buffer.
ppvAudioPtr1
Address of a variable that receives a pointer to the first locked part of the buffer.
pdwAudioBytes1
Address of a variable that receives the number of bytes in the block at ppvAudioPtr1. If this value is less than dwBytes, the lock has wrapped and ppvAudioPtr2 points to a second block of data at the beginning of the buffer .
ppvAudioPtr2
Address of a variable that receives a pointer to the second locked part of the capture buffer. If NULL is returned, the ppvAudioPtr1 parameter points to the entire locked portion of the capture buffer.
pdwAudioBytes2
Address of a variable that receives the number of bytes in the block at ppvAudioPtr2. If ppvAudioPtr2 is NULL, this value is zero.
dwFlags
Flags modifying the lock event. The following flags are defined:

 

Value Description
DSBLOCK_FROMWRITECURSOR Start the lock at the write cursor. The dwOffset parameter is ignored.
DSBLOCK_ENTIREBUFFER Lock the entire buffer. The dwBytes parameter is ignored.
 

Return Values

If the method succeeds, the return value is DS_OK. If the method fails, the return value may be one of the following error values:

Return code
DSERR_BUFFERLOST
DSERR_INVALIDCALL
DSERR_INVALIDPARAM
DSERR_PRIOLEVELNEEDED

Remarks

This method accepts an offset and a byte count, and returns two write pointers and their associated sizes. If the locked portion does not extend to the end of the buffer and wrap to the beginning, the second pointer, ppvAudioBytes2, receives NULL. If the lock does wrap, ppvAudioBytes2 points to the beginning of the buffer.

If the application passes NULL for the ppvAudioPtr2 and pdwAudioBytes2 parameters, the lock extends no further than the end of the buffer and does not wrap.

After writing data to the pointers returned by this method, the application must immediately call Unlock to notify DirectSound that the data is ready for playback. Failure to do so can cause audio breakup or silence on some sound device configurations.

This method returns write pointers only. The application should not try to read sound data from this pointer, because the data might not be valid. For example, if the buffer is located in on-card memory, the pointer might be an address to a temporary buffer in system memory. When IDirectSoundBuffer8::Unlock is called, the contents of this temporary buffer are transferred to the on-card memory.


以下這段代碼鎖定輔助音頻緩沖區,并且填充隨機數據。
 
       // lock buffer, fill with random values, and unlock.

        
char* ptr;
        DWORD size;

        
// readies all or part of the buffer for a data write and returns pointers to which data can be written
        if(SUCCEEDED(g_ds_buffer->Lock(0, 0, (void**)&ptr, &size, NULL, 0, DSBLOCK_ENTIREBUFFER)))
        {
            
for(DWORD i = 0; i < size; i++)
                ptr[i] = rand() % 256;
        }

填充完數據后,應該給緩沖區解鎖,調用IDirectSoundBuffer8::Unlock解鎖。

The Unlock method releases a locked sound buffer.

HRESULT Unlock(
LPVOID pvAudioPtr1,
DWORD dwAudioBytes1,
LPVOID pvAudioPtr2,
DWORD dwAudioBytes2
);

Parameters

pvAudioPtr1
Address of the value retrieved in the ppvAudioPtr1 parameter of the Lock method.
dwAudioBytes1
Number of bytes written to the portion of the buffer at pvAudioPtr1. See Remarks.
pvAudioPtr2
Address of the value retrieved in the ppvAudioPtr2 parameter of the IDirectSoundBuffer8::Lock method.
dwAudioBytes2
Number of bytes written to the portion of the buffer at pvAudioPtr2. See Remarks.

Return Values

If the method succeeds, the return value is DS_OK. If the method fails, the return value may be one of the following error values:

Return code
DSERR_INVALIDCALL
DSERR_INVALIDPARAM
DSERR_PRIOLEVELNEEDED

Remarks

An application must pass both pointers, pvAudioPtr1 and pvAudioPtr2, returned by the IDirectSoundBuffer8::Lock method to ensure the correct pairing of IDirectSoundBuffer8::Lock and IDirectSoundBuffer8::Unlock. The second pointer is needed even if nothing was written to the second pointer.

The values in dwAudioBytes1 and dwAudioBytes2 must specify the number of bytes actually written to each part of the buffer, which might be less than the size of the lock. DirectSound uses these values to determine how much data to commit to the device.

以下代碼解鎖剛才鎖定的輔助音頻緩沖區:

// releases a locked sound buffer
g_ds_buffer->Unlock(ptr, size, NULL, 0);

播放緩沖區中的聲音

在輔助音頻緩沖區中播放音頻和在主音頻緩沖區中播放是一樣的,惟一不同的是這次需要設置播放的起始位置,通過IDirectSoundBuffer8:: SetCurrentPosition來設置。一般情況下,會選擇從緩沖的開頭播放,需要注意的是,停止播放一段音頻并不會重置播放位置,所以可以通過停止播放來達到暫停的目的,只需要再次調用播放函數來恢復播放。

The SetCurrentPosition method sets the position of the play cursor, which is the point at which the next byte of data is read from the buffer.

HRESULT SetCurrentPosition(
DWORD dwNewPosition
);

Parameters

dwNewPosition
Offset of the play cursor, in bytes, from the beginning of the buffer.

Return Values

If the method succeeds, the return value is DS_OK. If the method fails, the return value may be one of the following error values:

Return code
DSERR_INVALIDCALL
DSERR_INVALIDPARAM
DSERR_PRIOLEVELNEEDED

Remarks

This method cannot be called on the primary buffer.

If the buffer is playing, the cursor immediately moves to the new position and play continues from that point. If it is not playing, playback will begin from the new position the next time the Play method is called.


改變音量

DirectSound 在播放聲音時按照采樣時的最大音量播放,加之受限于音頻硬件,所以沒有辦法讓音量變得更大,DirectSound只能讓音量變得更小些。這是通過減小聲音級別來完成的,這個級別的單位是百分之一分貝。范圍從0(最大音量)-- 10000(無聲),利用這個特性可以在程序中加入“淡入”或“淡出“的效果。

要調整音量,可以使用 IDirectSoundBuffer8::SetVolume函數。

The SetVolume method sets the attenuation of the sound.

HRESULT SetVolume(
LONG lVolume
);

Parameters

lVolume
Attenuation, in hundredths of a decibel (dB).

Return Values

If the method succeeds, the return value is DS_OK. If the method fails, the return value may be one of the following error values:

Return code
DSERR_CONTROLUNAVAIL
DSERR_GENERIC
DSERR_INVALIDPARAM
DSERR_PRIOLEVELNEEDED

Remarks

Allowable values are between DSBVOLUME_MAX (no attenuation) and DSBVOLUME_MIN (silence). These values are defined in Dsound.h as 0 and ?10,000 respectively. The value DSBVOLUME_MAX represents the original, unadjusted volume of the stream. The value DSBVOLUME_MIN indicates an audio volume attenuated by 100 dB, which, for all practical purposes, is silence. DirectSound does not support amplification.


以下給出一個完整示例來運用剛才學到的知識。

點擊下載源碼和工程

源碼示例:
 
/***************************************************************************************
PURPOSE:
    Lock Load Playing Demo
 ***************************************************************************************/


#define DIRECTINPUT_VERSION 0x0800

#include <windows.h>
#include <stdio.h>
#include <dsound.h>
#include "resource.h"

#pragma comment(lib, "dxguid.lib")
#pragma comment(lib, "dsound.lib")

#pragma warning(disable : 4996)

#define Safe_Release(p) if((p)) (p)->Release();

// window handles, class and caption text.
HWND g_hwnd;
char g_class_name[] = "LockLoadClass";

IDirectSound8*          g_ds;           
// directsound component
IDirectSoundBuffer8*    g_ds_buffer;    // sound buffer object

//--------------------------------------------------------------------------------
// Window procedure.
//--------------------------------------------------------------------------------
long WINAPI Window_Proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    
switch(msg)
    {
    
case WM_DESTROY:
        PostQuitMessage(0);
        
return 0;
    }

    
return (long) DefWindowProc(hwnd, msg, wParam, lParam);
}

//--------------------------------------------------------------------------------
// Main function, routine entry.
//--------------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE inst, HINSTANCE, LPSTR cmd_line, int cmd_show)
{
    WNDCLASS            win_class;
    MSG                 msg;
    IDirectSoundBuffer* ds = NULL;

    
// create window class and register it
    win_class.style         = CS_HREDRAW | CS_VREDRAW;
    win_class.lpfnWndProc   = Window_Proc;
    win_class.cbClsExtra    = 0;
    win_class.cbWndExtra    = DLGWINDOWEXTRA;
    win_class.hInstance     = inst;
    win_class.hIcon         = LoadIcon(inst, IDI_APPLICATION);
    win_class.hCursor       = LoadCursor(NULL, IDC_ARROW);
    win_class.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
    win_class.lpszMenuName  = NULL;
    win_class.lpszClassName = g_class_name;    

    
if(! RegisterClass(&win_class))
        
return FALSE;

    
// create the main window
    g_hwnd = CreateDialog(inst, MAKEINTRESOURCE(IDD_LOCKLOAD), 0, NULL);

    ShowWindow(g_hwnd, cmd_show);
    UpdateWindow(g_hwnd);

    
// initialize and configure directsound

    // creates and initializes an object that supports the IDirectSound8 interface
    if(FAILED(DirectSoundCreate8(NULL, &g_ds, NULL)))
    {
        MessageBox(NULL, "Unable to create DirectSound object", "Error", MB_OK);
        
return 0;
    }

    
// set the cooperative level of the application for this sound device
    g_ds->SetCooperativeLevel(g_hwnd, DSSCL_NORMAL);

    
// create a sound buffer

    // setup the WAVEFORMATEX structure
    WAVEFORMATEX wave_format;

    ZeroMemory(&wave_format, 
sizeof(WAVEFORMATEX));

    wave_format.wFormatTag      = WAVE_FORMAT_PCM;
    wave_format.nChannels       = 1;        
// mono
    wave_format.nSamplesPerSec  = 11025;    
    wave_format.wBitsPerSample  = 16;
    wave_format.nBlockAlign     = (wave_format.wBitsPerSample / 8) * wave_format.nChannels;
    wave_format.nAvgBytesPerSec = wave_format.nSamplesPerSec * wave_format.nBlockAlign;

    
// setup the DSBUFFERDESC structure
    DSBUFFERDESC ds_buffer_desc;

    
// zero out strcutre
    ZeroMemory(&ds_buffer_desc, sizeof(DSBUFFERDESC));

    ds_buffer_desc.dwSize        = 
sizeof(DSBUFFERDESC); 
    ds_buffer_desc.dwFlags       = DSBCAPS_CTRLVOLUME;
    ds_buffer_desc.dwBufferBytes = wave_format.nAvgBytesPerSec * 2;  
// 2 seconds
    ds_buffer_desc.lpwfxFormat   = &wave_format;

    
// create the fist version object
    if(FAILED(g_ds->CreateSoundBuffer(&ds_buffer_desc, &ds, NULL)))
    {
        
// error ocuurred
        MessageBox(NULL, "Unable to create sound buffer", "Error", MB_OK);
    }
    
else
    {
        
// get the version 8 interface
        ds->QueryInterface(IID_IDirectSoundBuffer8, (void**)&g_ds_buffer);

        
// release the original interface
        ds->Release();

        
// lock buffer, fill with random values, and unlock.

        
char* ptr;
        DWORD size;

        
// readies all or part of the buffer for a data write and returns pointers to which data can be written
        if(SUCCEEDED(g_ds_buffer->Lock(0, 0, (void**)&ptr, &size, NULL, 0, DSBLOCK_ENTIREBUFFER)))
        {
            
for(DWORD i = 0; i < size; i++)
                ptr[i] = rand() % 256;
        }

        
// releases a locked sound buffer
        g_ds_buffer->Unlock(ptr, size, NULL, 0);

        
// play sound looping

        // sets the position of the play cursor, 
        // which is the point at which the next byte of data is read from the buffer.
        g_ds_buffer->SetCurrentPosition(0);

        
// set the attenuation of the sound
        g_ds_buffer->SetVolume(DSBVOLUME_MAX);

        
// causes the sound buffer to play, starting at the play cursor.
        g_ds_buffer->Play(0, 0, DSBPLAY_LOOPING);
    }

    
// start message pump, waiting for signal to quit.
    ZeroMemory(&msg, sizeof(MSG));

    
while(msg.message != WM_QUIT)
    {
        
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }        
    }

    
// release directsound objects
    g_ds->Release();

    UnregisterClass(g_class_name, inst);
    
    
return (int) msg.wParam;
}
 

運行截圖:



閱讀下篇:用DirectX Audio和DirectShow播放聲音和音樂(3)

posted on 2007-07-26 20:00 lovedday 閱讀(4187) 評論(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>
            久久精品在线| 久久婷婷久久| 亚洲美女黄色片| 欧美日韩精品高清| 中文日韩在线| 午夜精品视频一区| 国产一区在线免费观看| 久久躁狠狠躁夜夜爽| 玖玖综合伊人| 99国产精品私拍| 在线视频亚洲欧美| 国产综合av| 亚洲国产一区二区三区高清| 欧美精品一区二| 亚洲自拍16p| 久久精品国产在热久久| 亚洲日本成人| 一本色道久久综合亚洲精品高清| 国产精品美女主播在线观看纯欲| 久久精品一区二区三区不卡牛牛| 玖玖精品视频| 午夜精品久久久| 久久午夜精品一区二区| 一区二区三区视频在线看| 亚洲欧美日韩精品久久久久| 好吊一区二区三区| 亚洲精品小视频在线观看| 国产精品一香蕉国产线看观看| 久久亚洲风情| 欧美午夜宅男影院| 久热综合在线亚洲精品| 欧美视频在线观看一区二区| 久久天堂国产精品| 欧美性做爰猛烈叫床潮| 欧美成人国产va精品日本一级| 国产精品99一区二区| 欧美国产日韩在线| 国产欧美日韩亚州综合| 亚洲欧洲精品一区二区精品久久久| 国产欧美日韩三区| 亚洲精品国产无天堂网2021| 影音先锋中文字幕一区| 亚洲欧洲99久久| 一区二区三区av| 女人香蕉久久**毛片精品| 欧美中文字幕久久| 欧美三级午夜理伦三级中视频| 男女激情久久| 国产综合视频| 亚洲性视频网站| 亚洲少妇一区| 欧美日本在线| 欧美激情 亚洲a∨综合| 国内成+人亚洲| 亚洲免费在线观看视频| 亚洲一区不卡| 欧美日韩国产电影| 亚洲人成在线观看网站高清| 亚洲国产天堂久久综合网| 欧美在线|欧美| 久久精品一区二区三区中文字幕 | 最近中文字幕mv在线一区二区三区四区| 国产精品久久久久久久第一福利| 亚洲人成亚洲人成在线观看| 最新国产成人在线观看| 久久久久久久久岛国免费| 久久精品国产在热久久 | 国产欧美日韩视频在线观看 | 亚洲午夜一区二区三区| 一本一本久久a久久精品牛牛影视| 巨胸喷奶水www久久久免费动漫| 另类av一区二区| 在线精品亚洲| 欧美大片国产精品| 亚洲久久一区二区| 亚洲宅男天堂在线观看无病毒| 国产精品videossex久久发布| 一本色道久久综合亚洲精品按摩 | 伊人激情综合| 鲁大师影院一区二区三区| 欧美激情片在线观看| 亚洲精品一区在线观看香蕉| 欧美理论视频| 亚洲特级片在线| 久久久97精品| 亚洲高清资源| 欧美日韩国产综合久久| 中文欧美在线视频| 久久精品系列| 日韩午夜三级在线| 国产精品人人做人人爽| 欧美一区精品| 亚洲黄色大片| 欧美亚洲视频| 亚洲国产二区| 国产精品人成在线观看免费| 欧美中文在线视频| 亚洲黄网站在线观看| 亚洲在线视频网站| 亚洲第一精品夜夜躁人人爽 | 欧美在线视频二区| 亚洲成色最大综合在线| 亚洲一区久久| 亚洲电影有码| 国产精品视频999| 久久一区二区三区国产精品 | 欧美一区二区免费| 欧美激情一区二区三区在线视频 | 国产一区在线播放| 欧美日韩免费高清一区色橹橹| 亚洲欧美日本国产有色| 亚洲国产高清视频| 欧美影片第一页| 99精品热视频只有精品10| 国产亚洲欧美在线| 欧美日韩综合在线| 美女黄色成人网| 亚久久调教视频| 一区二区欧美视频| 欧美激情一区在线观看| 久久久久久精| 亚洲欧美日韩一区二区在线| 91久久夜色精品国产网站| 国产视频一区免费看| 欧美日韩国产限制| 男女精品网站| 久久精品国产免费看久久精品 | 久久欧美中文字幕| 亚洲男人第一网站| 一本色道久久88综合亚洲精品ⅰ| 韩日在线一区| 国产啪精品视频| 国产精品热久久久久夜色精品三区 | 亚洲一区免费视频| 99综合精品| 亚洲精品九九| 亚洲乱码国产乱码精品精天堂| 激情久久中文字幕| 国产一区二区三区无遮挡| 国产日韩精品在线播放| 国产伦理精品不卡| 国产精品永久| 国产欧美一区二区精品仙草咪| 欧美日韩一区二区三区视频| 欧美日韩1区2区3区| 欧美伦理在线观看| 欧美日韩精品在线| 欧美亚韩一区| 国产精品成人观看视频国产奇米| 欧美三级第一页| 国产精品激情av在线播放| 国产精品女人毛片| 国产视频亚洲精品| 激情av一区| 亚洲人成网站在线播| 99视频精品免费观看| 亚洲性av在线| 欧美一二三区精品| 欧美与黑人午夜性猛交久久久| 亚洲一区国产视频| 欧美在线观看天堂一区二区三区| 欧美一区二区三区电影在线观看| 亚洲欧美乱综合| 久久久久**毛片大全| 麻豆av福利av久久av| 欧美成人资源| 国产精品hd| 韩国欧美一区| 亚洲美女毛片| 亚洲在线视频网站| 久久视频在线看| 欧美高清视频在线播放| 99爱精品视频| 久久久久国产精品www | 亚洲一区二区三区免费观看 | 久久亚洲精品伦理| 欧美激情片在线观看| 国产精品日日摸夜夜摸av| 黄色综合网站| 亚洲午夜久久久久久久久电影院| 欧美在线视频一区二区| 亚洲国产精品va在线看黑人 | 欧美肥婆在线| 中文av字幕一区| 久久人人九九| 国产精品第一区| 亚洲福利av| 欧美一级网站| 亚洲精品女人| 午夜天堂精品久久久久| 欧美电影免费观看| 国产一区二区中文| 亚洲一级特黄| 亚洲国产精品成人久久综合一区| 亚洲女女女同性video| 欧美激情精品久久久久| 国产一区二区精品丝袜| 亚洲一区三区电影在线观看| 牛牛国产精品| 久久精品99国产精品日本|