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

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

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


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



加入到MP3的革命中

MP3 是一種音頻壓縮格式,它通過刪除或修改音樂中不易被人耳察覺的部分來使音樂更小,占用的存儲(chǔ)空間更少。在項(xiàng)目中使用MP3(.MP3文件)需要使用 DirectX中的 DirectShow組件,在這個(gè)組件的幫助下,只需幾行短短的代碼,就能使用任意的MP3文件了(DirectShow也支持其他的媒體文件,比如 WMA,AVI,MPG等)。當(dāng)然要想使用更多的媒體文件,必須已經(jīng)在操作系統(tǒng)中安裝了解碼器。

解碼器(codec)是一個(gè)程序,用于解碼或編碼一些指定的格式(比如MP3解碼器專門解碼.MP3文件)。通??梢詮陌l(fā)明或者創(chuàng)建這種格式的公司中獲取這種格式的解碼器。比如,MP3解碼器來自于Fraunhofer Insitute。幸運(yùn)的是,MP3解碼器等幾種比較流行的解碼器已經(jīng)被集成到操作系統(tǒng)中(比如.mp3,.avi,.mpg等),而無需另外從 internet下載這些格式的解碼器了。

要在項(xiàng)目中使用DirectShow,需要包含dshow.h頭文件,并且在鏈接庫(kù)中加入strmiids.lib。



使用DirectShow

DirectX是一組COM接口組件,DirectShow也不例外,DirectShow中經(jīng)常使用的組件如下:

IGraphBuilder:  幫助建立濾波圖,濾波過濾圖是一組對(duì)象或接口的集合,用于處理某種媒體文件。
IMediaControl:控制數(shù)據(jù)在濾波圖中的流程,使用該接口控制音樂的回放。
IMediaEvents:   從濾波圖中獲取事件及通告,當(dāng)希望知道在濾波圖中發(fā)生了什么的時(shí)候這個(gè)對(duì)象很有用,比如希望知道一個(gè)音樂是否仍然在播放或者已經(jīng)停止播放。

其中第一個(gè)接口IGraphBuilder是比較重要的對(duì)象,其他對(duì)象都依賴于它,或者靠它創(chuàng)建。它創(chuàng)建濾波器,用于處理媒體問題,另外很多有用的功能也是依靠這個(gè)對(duì)象。

This interface provides methods that enable an application to build a filter graph. The Filter Graph Manager implements this interface.

IGraphBuilder inherits from the IFilterGraph interface. IFilterGraph provides basic operations, such as adding a filter to the graph or connecting two pins. IGraphBuilder adds further methods that construct graphs from partial information. For example, the IGraphBuilder::RenderFile method builds a graph for file playback, given the name of the file. The IGraphBuilder::Render method renders data from an output pin by connecting new filters to the pin.

Using these methods, an application does not need to specify every filter and pin connection in the graph. Instead, the Filter Graph Manager selects filters that are registered on the user's system, adds them to the graph, and connects them. For more information, see Intelligent Connect.

In addition to the methods inherited from IUnknown and IFilterGraph, the IGraphBuilder interface exposes the following methods.

Method Description
Connect Connects two pins. If they will not connect directly, this method connects them with intervening transforms.
Render Adds a chain of filters to a specified output pin to render it.
RenderFile Builds a filter graph that renders the specified file.
AddSourceFilter Adds a source filter to the filter graph for a specific file.
SetLogFile Sets the file for logging actions taken when attempting to perform an operation.
Abort Requests that the graph builder return as soon as possible from its current task.
ShouldOperationContinue Queries whether the current operation should continue.


使用DirectShow播放MP3的第一步是調(diào)用 CoCreateInstance函數(shù)創(chuàng)建濾波圖對(duì)象IGraphBuilder。

    // initialize COM
    //
    // initialize the COM library on the current thread and identifies the concurrency model as single-thread
    // apartment (STA).
    CoInitialize(0);

    
// create the DirectMusic performance object
    //
    // creates a single uninitialized object of the class associated with a specified CLSID.
    if(FAILED(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, 
                               (
void**)&g_graph_builder)))
    {
        MessageBox(NULL, "Unable to create DirectShow Graph Builder object.", "Error", MB_OK);
        
return FALSE;
    }

一旦創(chuàng)建對(duì)象IGraphBuilder成功,就可以請(qǐng)求另兩個(gè)接口了:
 
// Query for the media control and event objects
g_graph_builder->QueryInterface(IID_IMediaControl, (void**)&g_media_control);
g_graph_builder->QueryInterface(IID_IMediaEvent, (
void**)&g_media_event);
 

加載媒體文件
 
實(shí)際上, DirectShow并不加載媒體文件,而是創(chuàng)建一個(gè)DirectShow濾波器到文件的連接。數(shù)據(jù)在解碼的時(shí)候被流化,這樣可以減少在播放過程中的內(nèi)存使用,創(chuàng)建連接的過程叫做渲染(rendering)。渲染一個(gè)文件,需要調(diào)用IGraphBuilder::RenderFile函數(shù)。

Builds a filter graph that renders the specified file.

Syntax

HRESULT RenderFile(
LPCWSTR lpwstrFile,
LPCWSTR lpwstrPlayList
);

Parameters

lpwstrFile
[in] Pointer to the name of the file containing the data to be rendered.
lpwstrPlayList
[in] Pointer to the playlist name. Reserved; must be NULL. (This parameter is currently unimplemented.)

Return Value

Returns an HRESULT value, which can include one of the following:

  • VFW_S_AUDIO_NOT_RENDERED
  • VFW_S_DUPLICATE_NAME
  • VFW_S_PARTIAL_RENDER
  • VFW_S_RPZA
  • VFW_S_VIDEO_NOT_RENDERED

Remarks

If the lpwstrPlayList parameter is NULL, this method would use the default playlist, which typically renders the entire file.

 

控制音樂的播放

在媒體文件被渲染之后,就可以使用另外兩個(gè)接口 IMediaControl和IMediaEvent進(jìn)行播放或者對(duì)播放進(jìn)行控制了。

第一個(gè)接口 IMediaControl用于播放和各種播放相關(guān)的操作,這個(gè)接口有三個(gè)函數(shù):IMediaControl::Run,IMediaControl:: Pause,IMediaControl::Stop。

The IMediaControl interface provides methods for controlling the flow of data through the filter graph. It includes methods for running, pausing, and stopping the graph. The Filter Graph Manager implements this interface. For more information on filter graph states, see Data Flow in the Filter Graph.

IMediaControl also provides Automation-compatible methods for building graphs. Applications written in Microsoft® Visual Basic® can use these methods to construct filter graphs or retrieve information about the graph. Applications written in C or C++ should use the methods in IGraphBuilder and IFilterGraph2 instead, because they are more efficient.

In addition to the methods inherited from IDispatch, the IMediaControl interface exposes the following methods.

Method Description
Run Runs all the filters in the filter graph.
Pause Pauses all filters in the filter graph.
Stop Stops all the filters in the filter graph.
StopWhenReady Pauses the filter graph, allowing filters to queue data, and then stops the filter graph.
GetState Retrieves the state of the filter graph.
RenderFile Builds a filter graph that renders the specified file. (For Visual Basic.)
AddSourceFilter Adds a source filter to the filter graph, for a specified file. (For Visual Basic.)
get_FilterCollection Retrieves a collection of the filters in the filter graph. (For Visual Basic.)
get_RegFilterCollection Retrieves a collection of all the filters listed in the registry. (For Visual Basic.)

 

如果要開始播放一段音樂,調(diào)用 IMediaControl::Run就可以了。

Switches the entire filter graph into a running state.

Syntax

HRESULT Run(void); 

Return Value

Returns S_OK if the graph is actually running.

Returns S_FALSE if the graph is preparing to run (the graph will run automatically when it's ready). Call GetState to wait for the transition to the running state to complete or to check if the transition has completed. If the method returns S_FALSE, subsequent calls to GetState will return a value of State_Running when the graph is actually running. If the transition to the running state is not complete GetState can return a return code of VFW_S_STATE_INTERMEDIATE.

Returns an HRESULT error code if the graph could not run and is now stopped.

Remarks

In a running state, data is pushed down the filter graph and rendered. The graph remains in a running state until it is stopped by the IMediaControl::Pause or IMediaControl::Stop method. The graph remains in a running state even after notifying the application of completion (that is, the EC_COMPLETE notification is sent to the application). This allows the application to determine whether to pause or stop after completion.

If the filter graph is in the stopped state, this method first pauses the graph before running.

If an error value is returned, some filters within the graph might have successfully entered the running state. In a multistream graph, entire streams might be playing successfully. The application must determine whether to stop running or not.

一旦播放開始,就可以隨時(shí)暫停播放或者停止播放,如果希望暫停播放,調(diào)用IMediaControl::Pause函數(shù)。

Pauses all the filters in the filter graph.

Syntax

HRESULT Pause(void);

Return Value

Returns S_OK if the graph is actually paused.

Returns S_FALSE if the graph is in paused state but some filters have not completed the transition to pause. Call GetState to wait for the transition to the paused state to complete or to check if the transition has completed. If the method returns S_FALSE, subsequent calls to GetState will return a value of State_Paused when the graph is paused. If the transition to paused is not complete GetState can return a return code of VFW_S_STATE_INTERMEDIATE.

Returns an HRESULT error code if the graph could not transition to paused state and is now stopped.

Remarks

In the paused state, filters process data but do not render it. Data is pushed down the filter graph and is processed by transform filters as far as buffering permits. No data is rendered (except that media types capable of being rendered statically, such as video, have a static, poster frame rendered in paused mode). Therefore, putting a filter graph into a paused state cues the graph for immediate rendering when put into a running state.

開始播放之后,可以隨時(shí)調(diào)用IMediaContrl::Stop函數(shù)來停止播放。

Switches all filters in the filter graph to a stopped state.

Syntax

HRESULT Stop(void); 

Return Value

Returns an HRESULT value.

Remarks

In this mode, filters release resources and no data is processed. If the filters are in a running state, this method pauses them before stopping them. This allows video renderers to make a copy of the current frame for poster frame display while stopped.

以下代碼演示了如何播放MP3文件。
 
//--------------------------------------------------------------------------------
// Play mp3 which specified by filename.
//--------------------------------------------------------------------------------
BOOL Play_MP3(char* filename)
{
    
// convert filename to wide-character string
    WCHAR w_filename[MAX_PATH] = {0};

    mbstowcs(w_filename, filename, MAX_PATH);

    
// render the file
    g_graph_builder->RenderFile(w_filename, NULL);

    
// play the file, switches the entire filter graph into a running state.
    g_media_control->Run();

    
return TRUE;
}
 


檢測(cè)播放事件

我們主要感興趣的IMediaEvent函數(shù)大概有三個(gè):GetEvent,F(xiàn)reeEventParams,WaitForCompletion。

The IMediaEvent interface contains methods for retrieving event notifications and for overriding the Filter Graph Manager's default handling of events. The IMediaEventEx interface inherits this interface and extends it.

The Filter Graph Manager implements this interface. Applications can use it to respond to events that occur in the filter graph, such as the end of a stream or a rendering error. Filters post events to the filter graph using the IMediaEventSink interface.

For more information about event notification, see Event Notification in DirectShow. For a list of system-defined event notifications, see Event Notification Codes.

In addition to the methods inherited from IDispatch, the IMediaEvent interface exposes the following methods.

Method Description
CancelDefaultHandling Cancels the Filter Graph Manager's default handling for a specified event.
FreeEventParams Frees resources associated with the parameters of an event.
GetEvent Retrieves the next event notification from the event queue.
GetEventHandle Retrieves a handle to a manual-reset event that remains signaled while the queue contains event notifications.
RestoreDefaultHandling Restores the Filter Graph Manager's default handling for a specified event.
WaitForCompletion Waits for the filter graph to render all available data.


第一個(gè)函數(shù)GetEvent可能是使用最多的函數(shù),它用于找回通知播放狀態(tài)的事件。

Retrieves the next notification event.

Syntax

HRESULT GetEvent(
long *lEventCode,
long *lParam1,
long *lParam2,
long msTimeout
);

Parameters

IEventCode
[out] Pointer to the next event notification.
lParam1
[out] Pointer to the first parameter of the event.
lParam2
[out] Pointer to the second parameter of the event.
msTimeout
[in] Time, in milliseconds, to wait before assuming that there are no events.

Return Value

Returns an HRESULT value that depends on the implementation of the interface. If the time-out is zero and no event is waiting, or if the time-out elapses before an event appears, this method returns E_ABORT.

Remarks

The application can pass a time-out value of INFINITE to indicate that the method should block until there is an event; however, applications should avoid using INFINITE. Threads cannot process any messages while waiting in GetEvent. If you call GetEvent from the thread that processes Windows messages, specify only small wait times on the call in order to remain responsive to user input. This is most important when streaming data from a source such as the Internet, because state transitions can take significantly more time to complete.

After calling GetEvent, applications should always call FreeEventParams to release any resource associated with the event.

For a list of notification codes and event parameter values, see Event Notification Codes.

一般我們最希望獲取到的事件是播放完成,這個(gè)事件的值是EC_COMPLETE。如果調(diào)用GetEvent函數(shù)之后,lEventCode的值是 EC_COMPLETE,說明播放完成了。

當(dāng)獲取并處理了GetEvent產(chǎn)生的事件后,必須把事件所占用的資源釋放,釋放資源使用IMediaEvent::FreeEventParams函數(shù)。

Frees resources associated with the parameters of an event.

Syntax

HRESULT FreeEventParams(
long lEventCode,
long lParam1,
long lParam2
);

Parameters

lEventCode
[in] Next event notification.
lParam1
[in] First parameter of the event.
lParam2
[in] Second parameter of the event.

Return Value

Returns an HRESULT value.

Remarks

Event parameters can be of type LONG or BSTR. If a BSTR is passed as an event, it will have been allocated by the task allocator and should be freed using this method. No reference-counted interfaces are passed to an application using IMediaEvent::GetEvent, because these cannot be overridden by IMediaEvent::CancelDefaultHandling. Therefore, do not use this method to release interfaces.

以下代碼演示了如何捕捉事件并釋放事件所占用的資源:
 
        // get th status of the song, it if is done, exit program.

        
long event_code, param1, param2;

        
// retrieves the next notification event
        if(SUCCEEDED(g_media_event->GetEvent(&event_code, &param1, &param2, 1)))
        {
            
if(event_code == EC_COMPLETE)
            {
                
// frees resources associated with the parameters of an events.
                g_media_event->FreeEventParams(event_code, param1, param2);

                
break;
            }                
        }

在需要逐幀連續(xù)監(jiān)視事件的時(shí)候,用GetEvent和FreeEventParams組合是很有用的,它能幫助我們獲取事件并作恰當(dāng)?shù)奶幚怼5?dāng)我們需要連續(xù)播放而不希望連續(xù)監(jiān)視播放過程的時(shí)候,另外一個(gè)函數(shù)就會(huì)很有用,即WaitForCompletion函數(shù)。它可以一直播放,在播放完成的時(shí)候,會(huì)把控制權(quán)交給我們。

Blocks execution of the application thread until the graph's operation finishes.

Syntax

HRESULT WaitForCompletion(
long msTimeout,
long *pEvCode
);

Parameters

msTimeout
[in] Duration of the time-out, in milliseconds. Pass zero to return immediately. To block indefinitely, pass INFINITE.
pEvCode
[out] Pointer to the event that terminated the wait. This value can be one of the following:
EC_COMPLETE Operation completed.
EC_ERRORABORT Error. Playback can't continue.
EC_USERABORT User terminated the operation.
Zero Operation has not completed.

Return Value

Returns one of the following HRESULT values.

E_ABORT Function timed out before the operation completed. This is equivalent to a zero pEvCode value.
S_OK Operation completed.
 

Remarks

This method is the equivalent of blocking until the event notification EC_COMPLETE, EC_ERRORABORT, or EC_USERABORT is received, or the time-out occurs.

When this method returns, the filter graph is still running. This method assumes that separate calls to the IMediaEvent interface are not being made. The method fails if the graph is not in, or transitioning into, a running state.

The time-out parameter (msTimeout) specifies the length of time to wait for completion. To test whether the operation completed, specify a zero msTimeout value and check the event code value (pEvCode) for zero, indicating that the operation has not completed.

 

釋放DirectShow資源

一旦播放完成,就要關(guān)閉和釋放所有占用的DirectShow資源。
 
    // stop music and relaese DirectShow objects

    // switches all filters in the filter graph to a stopped state.
    g_media_control->Stop();

    g_media_event->Release();
    g_media_event = NULL;

    g_media_control->Release();
    g_media_control = NULL;

    g_graph_builder->Release();
    g_graph_builder = NULL;

下面給出完整的代碼示例,由于DirectX9已經(jīng)將DirectShow移除,所以需要安裝DirectX8 SDK,并在Vistual Studio中設(shè)置頭文件目錄。

點(diǎn)擊下載源碼和工程

 
/***************************************************************************************
PURPOSE:
    MP3 Playing Demo
 ***************************************************************************************/


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

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

#pragma warning(disable : 4996)

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

// window handles, class.
HWND g_hwnd;
char g_class_name[] = "MP3PlayClass";

// DirectShows components
IGraphBuilder*  g_graph_builder = NULL;
IMediaControl*  g_media_control = NULL;
IMediaEvent*    g_media_event   = NULL;

//--------------------------------------------------------------------------------
// Play mp3 which specified by filename.
//--------------------------------------------------------------------------------
BOOL Play_MP3(char* filename)
{
    
// convert filename to wide-character string
    WCHAR w_filename[MAX_PATH] = {0};

    mbstowcs(w_filename, filename, MAX_PATH);

    
// render the file
    g_graph_builder->RenderFile(w_filename, NULL);

    
// play the file, switches the entire filter graph into a running state.
    g_media_control->Run();

    
return TRUE;
}

//--------------------------------------------------------------------------------
// 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;    

    
// 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_MP3PLAY), 0, NULL);

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

    
// initialize COM
    //
    // initialize the COM library on the current thread and identifies the concurrency model as single-thread
    // apartment (STA).
    CoInitialize(0);

    
// create the DirectMusic performance object
    //
    // creates a single uninitialized object of the class associated with a specified CLSID.
    if(FAILED(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, 
                               (
void**)&g_graph_builder)))
    {
        MessageBox(NULL, "Unable to create DirectShow Graph Builder object.", "Error", MB_OK);
        
return FALSE;
    }

    
// Query for the media control and event objects
    g_graph_builder->QueryInterface(IID_IMediaControl, (void**)&g_media_control);
    g_graph_builder->QueryInterface(IID_IMediaEvent, (
void**)&g_media_event);
    
    
// play mp3
    Play_MP3("escape.mp3");
    
    
// 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);            
        }             

        
// get th status of the song, it if is done, exit program.

        
long event_code, param1, param2;

        
// retrieves the next notification event
        if(SUCCEEDED(g_media_event->GetEvent(&event_code, &param1, &param2, 1)))
        {
            
if(event_code == EC_COMPLETE)
            {
                
// frees resources associated with the parameters of an events.
                g_media_event->FreeEventParams(event_code, param1, param2);

                
break;
            }                
        }

        
// frees resources associated with the parameters of an events.
        g_media_event->FreeEventParams(event_code, param1, param2);
    }

    
// stop music and relaese DirectShow objects

    // switches all filters in the filter graph to a stopped state.
    g_media_control->Stop();

    g_media_event->Release();
    g_media_event = NULL;

    g_media_control->Release();
    g_media_control = NULL;

    g_graph_builder->Release();
    g_graph_builder = NULL;

    UnregisterClass(g_class_name, inst);

    
// release COM system
    //
    // Closes the COM library on the current thread, unloads all DLLs loaded by the thread, frees any other
    // resources that the thread maintains, and forces all RPC connections on the thread to close.
    CoUninitialize();
    
    
return (int) msg.wParam;
}
 

運(yùn)行截圖:



posted on 2007-08-04 18:18 lovedday 閱讀(8168) 評(píng)論(20)  編輯 收藏 引用

評(píng)論

# re: 用DirectX Audio和DirectShow播放聲音和音樂(7) 2007-08-13 22:32 artcpp

非常感謝您的一系列文件,對(duì)我自學(xué)編程(尤其是Direct方面)起到了很大的引導(dǎo)作用??!謝謝您!  回復(fù)  更多評(píng)論   

# re: 用DirectX Audio和DirectShow播放聲音和音樂(7) 2007-08-13 22:33 artcpp

不知能否QQ聯(lián)系:請(qǐng)教一個(gè)DirectShow播放MP3,在個(gè)別機(jī)器上失敗的奇怪問題。我的QQ:1090833,盼,多謝??!  回復(fù)  更多評(píng)論   

# re: 用DirectX Audio和DirectShow播放聲音和音樂(7) 2007-08-13 22:52 lovedday

@artcpp
不用客氣,用“你”就好了,用“您”我擔(dān)當(dāng)不起,很高興我的文章能幫到你,這也是我繼續(xù)寫技術(shù)文章的動(dòng)力,提高自己的同時(shí)還能幫到別人。其實(shí)我的水平也很菜的,如果可以幫到你,一定盡力。^_^  回復(fù)  更多評(píng)論   

# re: 用DirectX Audio和DirectShow播放聲音和音樂(7) 2007-10-04 18:09 bluesea

不知道為什么到 directX 9.0 里,要把 DirectShow 去掉了呢?  回復(fù)  更多評(píng)論   

# re: 用DirectX Audio和DirectShow播放聲音和音樂(7) 2007-10-07 13:29 lovedday

據(jù)說是轉(zhuǎn)移到win32 sdk去了,可能是DirectShow功能越來越通用,越來越重要的原因。  回復(fù)  更多評(píng)論   

# re: 用DirectX Audio和DirectShow播放聲音和音樂(7)[未登錄] 2008-01-02 15:42 max

您好~~ 很感謝你的文章, 對(duì)我?guī)椭艽? 不過, 我有個(gè)問題, 關(guān)於只播音訊時(shí), 為什麼不論我用你的方式, 或msdn上的教學(xué), 我的directshow (on mobile 6) 都只能播放出wav檔, 可以給我解感一下嗎?? 需要另外加filter或什麼類的嗎, 不是graphfilter就自動(dòng)建立基本的filter嗎, 我弄好久了, 我需要能播放midi, mp3, wma.....  回復(fù)  更多評(píng)論   

# re: 用DirectX Audio和DirectShow播放聲音和音樂(7) 2008-04-06 13:46 wind

很感謝你這一系列啊,我正在做基于DIRECTX的MP3播放系統(tǒng)設(shè)計(jì)的畢業(yè)設(shè)計(jì),還有沒有這方面比較好用的資料啊,最好注釋比較淺顯詳盡的,感激不盡啊~~~我的郵箱是coolwind2006@126.com  回復(fù)  更多評(píng)論   

# re: 用DirectX Audio和DirectShow播放聲音和音樂(7) 2008-04-06 14:03 lovedday

沒了,去買書看看吧,這些東西我也是書上看到的。  回復(fù)  更多評(píng)論   

# re: 用DirectX Audio和DirectShow播放聲音和音樂(7) 2008-04-21 18:21 淼焱

我有一些問題想請(qǐng)教一下 我的QQ 282338785 謝謝!!  回復(fù)  更多評(píng)論   

# re: 用DirectX Audio和DirectShow播放聲音和音樂(7) 2008-04-21 18:26 lovedday

隔了這么久了,DirectShow的一些知識(shí)我可能都忘了,這樣吧,你給我寫信,我的email是lovedday@gmail.com,看我能不能幫上忙,別說什么請(qǐng)教,我也沒什么經(jīng)驗(yàn)的。  回復(fù)  更多評(píng)論   

# re: 用DirectX Audio和DirectShow播放聲音和音樂(7) 2008-08-18 04:54 lyra

你的東西太好了 謝謝  回復(fù)  更多評(píng)論   

# re: 用DirectX Audio和DirectShow播放聲音和音樂(7) 2008-10-17 22:12 來來往往

你的資料太好了,謝謝共享  回復(fù)  更多評(píng)論   

# re: 用DirectX Audio和DirectShow播放聲音和音樂(7) 2008-11-10 01:04 wlxfm

怎樣做一個(gè)模擬鍵盤的軟件,用VC++?基于DirectX,就象iDreamPiano一樣。  回復(fù)  更多評(píng)論   

# re: 用DirectX Audio和DirectShow播放聲音和音樂(7) 2009-05-06 20:05 李平

真的很感謝兄弟啊,這么珍貴的資料,看來自學(xué)DirectSound有希望了!!!萬分感激?。。?!  回復(fù)  更多評(píng)論   

# re: 用DirectX Audio和DirectShow播放聲音和音樂(7) 2009-05-19 00:46 果蠅

太感謝了  回復(fù)  更多評(píng)論   

# re: 用DirectX Audio和DirectShow播放聲音和音樂(7)[未登錄] 2009-05-19 13:49 李帥

怎么讓這個(gè)音樂循環(huán)播放?  回復(fù)  更多評(píng)論   

# re: 用DirectX Audio和DirectShow播放聲音和音樂(7) 2009-09-01 04:54 lyra

非常感謝,看你的資料有兩年了,謝謝您。祝您家庭幸福,身體健康,事業(yè)成功。  回復(fù)  更多評(píng)論   

# re: 用DirectX Audio和DirectShow播放聲音和音樂(7) 2010-01-17 10:09 yinian

非常感謝您這么詳細(xì)的介紹,實(shí)際上也是一個(gè)非常好的教程了。我現(xiàn)在有個(gè)疑惑的是,微軟為什么要在DirectX9里面把DirectShow刪除呢,是不是DShow本身存在技術(shù)方面的原因,另外,既然新的DirectX中已經(jīng)沒有DShow了,是不是意味著windows以后的版本對(duì)DShow的支持也不會(huì)更新了,那么現(xiàn)在使用DShow是不是會(huì)以后會(huì)碰到一些難以解決的問題呢?  回復(fù)  更多評(píng)論   

# re: 用DirectX Audio和DirectShow播放聲音和音樂(7) 2013-03-15 17:40

謝謝你的文章,我還有一些具體的問題想問一下,希望能加一下qq:1054359972  回復(fù)  更多評(píng)論   

# re: 用DirectX Audio和DirectShow播放聲音和音樂(7) 2014-09-27 17:52 CMZ

其實(shí)我想問下。通過這些demo可以播放音樂。但是怎么實(shí)現(xiàn)循環(huán)播放呢?  回復(fù)  更多評(píng)論   


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


公告

導(dǎo)航

統(tǒng)計(jì)

常用鏈接

隨筆分類(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>
            欧美视频日韩视频| 久久精品国产清高在天天线| 欧美午夜a级限制福利片| 久久综合久久美利坚合众国| 亚洲欧美国产日韩天堂区| 99国内精品| 亚洲美女淫视频| 99re66热这里只有精品3直播| 亚洲国产婷婷香蕉久久久久久99| 亚洲欧美在线一区| 欧美一区二区三区在线播放| 欧美在线视频免费观看| 久久久国产午夜精品| 欧美制服第一页| 久久综合中文| 欧美激情第六页| 亚洲精品激情| 亚洲在线视频免费观看| 久久九九热免费视频| 欧美成人官网二区| 国产精品草莓在线免费观看| 国产亚洲第一区| 亚洲国产精品久久久久婷婷老年 | 国产视频一区二区在线观看 | 国产主播一区二区三区| 在线看片成人| 在线视频免费在线观看一区二区| 午夜国产精品视频| 嫩草成人www欧美| 亚洲看片网站| 欧美一级片一区| 欧美黄色aaaa| 国产日韩欧美在线播放| 久久精品免费播放| 欧美激情综合五月色丁香| 国产精品国产三级国产专播品爱网 | 久久综合九色九九| 欧美片在线播放| 国产一区二区三区四区三区四| 亚洲成在线观看| 亚洲欧美美女| 亚洲国产精品久久久久久女王| 亚洲婷婷在线| 欧美激情精品久久久久久黑人| 国产网站欧美日韩免费精品在线观看| 亚洲国产裸拍裸体视频在线观看乱了| 亚洲欧美在线播放| 最近中文字幕日韩精品| 久久精品午夜| 国产伦精品一区二区三| 在线亚洲欧美视频| 亚洲国产精品成人精品| 久久精品观看| 国产欧美日韩综合一区在线播放| 亚洲看片网站| 欧美成人午夜激情在线| 久久成人精品无人区| 国产精品久久久久久久久免费| 亚洲欧洲综合另类| 六月婷婷一区| 欧美一区在线视频| 国产欧美日韩中文字幕在线| 亚洲综合999| 99av国产精品欲麻豆| 欧美日韩精品一本二本三本| 亚洲人成在线免费观看| 欧美电影电视剧在线观看| 久久精品理论片| 国模套图日韩精品一区二区| 久久久7777| 欧美在线你懂的| 狠狠v欧美v日韩v亚洲ⅴ| 久久国产精品第一页| 亚洲欧美日韩在线观看a三区| 国产精品捆绑调教| 久久9热精品视频| 午夜精品视频在线观看| 国产日韩在线亚洲字幕中文| 久久精品国产第一区二区三区| 亚洲欧美中文在线视频| 国产无一区二区| 免费在线播放第一区高清av| 久久久国产精品一区二区中文| 黄色日韩网站视频| 欧美成人高清视频| 免费亚洲电影| 一区二区三区四区国产精品| 在线综合+亚洲+欧美中文字幕| 国产精品二区二区三区| 午夜精品久久久久久| 午夜精品久久久久久久蜜桃app| 亚洲午夜精品久久久久久app| 亚洲黄色三级| 欧美国产日韩亚洲一区| 一本色道久久综合亚洲精品高清| 亚洲精品在线三区| 国产精品久久久99| 久久久人成影片一区二区三区观看| 久久久久免费| 在线一区二区三区四区| 亚洲欧美久久久久一区二区三区| 黑人一区二区三区四区五区| 亚洲国产精品99久久久久久久久| 欧美日韩三级| 久久久国产精品亚洲一区 | 欧美jizzhd精品欧美巨大免费| 亚洲一区二区精品在线| 久久大香伊蕉在人线观看热2| 亚洲国产欧美一区| 亚洲午夜激情在线| 在线观看中文字幕亚洲| 夜夜嗨av一区二区三区| 好吊视频一区二区三区四区| 亚洲欧洲日本在线| 国模一区二区三区| 99视频一区二区| 亚洲高清免费在线| 亚洲伊人伊色伊影伊综合网 | 午夜精品理论片| 蜜桃av一区二区在线观看| 午夜免费在线观看精品视频| 欧美.www| 久久久久.com| 国产精品va在线| 亚洲国产日韩美| 国产午夜精品久久久久久免费视 | 亚洲视频一二三| 免费观看日韩| 久久久国产精品一区二区三区| 欧美日韩一区在线观看视频| 欧美99在线视频观看| 国产精品入口尤物| 亚洲区欧美区| 亚洲国产欧美日韩精品| 久久人人九九| 久久最新视频| 合欧美一区二区三区| 久久超碰97人人做人人爱| 欧美一区网站| 国产精品乱看| 亚洲一区二区三区免费在线观看| 一本一本a久久| 欧美电影免费观看| 欧美福利精品| 亚洲福利视频二区| 久久人91精品久久久久久不卡| 久久亚洲国产精品一区二区| 国产热re99久久6国产精品| 韩国欧美一区| 国产欧美日韩精品丝袜高跟鞋| 亚洲毛片在线观看| 亚洲视频免费| 国产乱码精品一区二区三区五月婷 | 久久国产精品亚洲77777| 国产欧美一区二区精品婷婷 | 日韩一级精品| 欧美视频在线观看 亚洲欧| 亚洲一级片在线看| 久久中文字幕一区| 亚洲精品久久7777| 欧美日韩在线另类| 香蕉久久精品日日躁夜夜躁| 欧美专区在线观看| 影音先锋亚洲电影| 麻豆精品在线播放| 日韩亚洲欧美一区| 午夜在线视频观看日韩17c| 国产精品免费看| 久久av一区| 老司机久久99久久精品播放免费| 国产香蕉97碰碰久久人人| 亚洲一区免费| 亚洲深夜福利视频| 激情久久综合| 亚洲图片欧美一区| 亚洲第一页中文字幕| 激情综合久久| 久久精品亚洲热| 久久久综合激的五月天| 99精品欧美| 欧美大学生性色视频| 欧美福利电影网| 欧美三级网址| 久久中文久久字幕| 欧美成人免费一级人片100| 有码中文亚洲精品| 久久这里有精品视频| 亚洲少妇中出一区| 国产精品地址| 亚洲欧美国产精品桃花| 久久夜色精品一区| 亚洲网站在线| 久久国产精品久久w女人spa| 国产欧美精品久久| 久久久精品一区二区三区| 亚洲影视综合| 国产视频亚洲| 欧美成人影音| 免费欧美视频| 日韩一级不卡|