DirectX Audio和DirectShow入门

 Direct Audio

 摘自

Direct Audio是一个复合组件,它由DirectSound和DirectMusic两个组件组成。DirectMusic在DirectX8中得到了巨大的增强,但是DirectSound基本保持原有的状态。DirectSound是主要的数字声音回放组件。DirectMusic处理所有的乐曲格式,包括MIDI、DirectMusic本地格式文件和波表文件。DirectMusic处理完之后将它们送入DirectSound中做其他处理,这意味着回放MIDI的时候可以使用数字化的乐器。

 

DirectX Audio和DirectShow入门_第1张图片 

以下是DirectSound COM接口:

IDirectSound8:DirectSound接口。
IDirectSoundBuffer8:主缓冲区和辅助缓冲区接口,保存数据并控制回放。
IDirectSoundNotify8:通知对象,通知应用程序指定播放位置已经达到。

各个对象间的关系如下图所示:

DirectX Audio和DirectShow入门_第2张图片 

DirectSound8是主接口,用它来创建缓冲区(IDirectSoundBuffer8),然后用缓冲区接口创建通告接口(IDirectSoundNotify8),通告接口告诉应用程序指定的位置已经到达,通告接口在流化音频文件时非常有用。

 

DirectSound例子

 

使用DirectMusic

使用 DirectMusic的第一步是创建一个主对象,我们把这个对象叫做演奏器对象(performance object),它表现整个音乐系统,第二步创建一个叫加载器(loader object)的对象,加载器加载所有原始的音乐文件。

它们之间的交互过程如下所示:

 DirectX Audio和DirectShow入门_第3张图片  

最后必须加载音乐小节到音乐片段对象(segment object)中,多个小节可以被同时加载,并一个接一个地播放,这可以让我们创建更具动态效果的音乐。

 

DirectMusic例子

 

 

介绍

DirectShow是Windows平台的一种流多媒体架构(architecture)。使用它,你能够做到:

  • 播放多媒体流
  • 捕捉多媒体流
  • 多媒体编辑

DirectX是一组COM接口组件,DirectShow也不例外,DirectShow中经常使用的组件如下:

IGraphBuilder:  帮助建立滤波图,滤波过滤图是一组对象或接口的集合,用于处理某种媒体文件。
IMediaControl:控制数据在滤波图中的流程,使用该接口控制音乐的回放。
IMediaEvents:   从滤波图中获取事件及通告,当希望知道在滤波图中发生了什么的时候这个对象很有用,比如希望知道一个音乐是否仍然在播放或者已经停止播放。

其中第一个接口IGraphBuilder是比较重要的对象,其他对象都依赖于它,或者靠它创建。它创建滤波器,用于处理媒体问题,另外很多有用的功能也是依靠这个对象。

编译环境

include <Dshow.h>

linking “strmiids.lib”

第一步-初始化COM

DirectShow基于COM模型,你需要首先初始化COM:CoInitialize()。当然使用完COM需要:CoUninitialize().

Fiter

DirectShow由大量的COM对象(被叫做fiters)组成,有许多标准filters可以使用,当然你可以开发自己的filters来扩展DirectShow。举个简单的例子,怎样使用filters来播放一AVI文件:

  • 源文件filter(从AVI文件读数据)
  • AVI分路fiter(分离Audio和Video)
  • 解码fiter(根据使用的压缩类型解压缩Video帧)
  • Video渲染器filter(绘制Video帧)
  • DirectSound设备filter(发送audio到声卡)

可以看出:复杂的操作由一些小组件(filter)组成。

Pins

fiters直接连接也使用一种COM对象:Pins

 

上面播放AVI文件需要五个fiters协调完成(当然也需要Pins连接他们),必须全部成功,他们被称为"Filter Graph"。好像很复杂啊,但是DirectShow给我们提供了建立(Building)filter graph的组件:

  • Filter Graph 组件(用于文件回放和控制filter graph)
  • 捕捉Graph Builder(用于捕捉)
  • DVD Graph Builder(用于DVD回放)

Filter Graph管理器是DirectShow的基本组件,多数DirectShow应用会使用。它做下面的事情:

  • 提供我们方法:建立filter graph (增加,移除,连接fiters)
  • 协调filters之间状态变化(播放,暂停,停止,定位)
  • 处理filters之间同步(with a reference clock)
  • 事件通知(能够知道状态变化和其他事件)

下面是Filter Graph管理器暴露的重要接口:

IBasicAudio (controls the volume and balance of audio stream)
IBasicVideo (sets video properties)
IGraphBuilder (help building filter graph)
IMediaControl (controls flow of data in filter graph)
IMediaEventEx (for event notifications and for overriding default event handling)
IMediaSeeking (for seeking a position in stream)
IVideoWindow (sets video window properties)

下面是Filter Graph管理器创建步骤:

  • 对象创建

    IGraphBuilder *pGB   = NULL;
      CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,IID_IGraphBuilder, (void **)&pGB);

    这样就创建了一个Filter Graph管理器,并取得IGraphBuilder 接口指针。下面需要考虑谁建立graph, 支持下面方式:

    Filter Graph Manager builds the entire graph
    Filter Graph Manager builds the partial graph
    The application builds the entire graph

  • IGraphBuilder::RenderFile方法可以用来对具体文件类自动建立filter graph. 这种方式下,Fiter Graph管理器会根据具体媒体文件链接合适的filters,这叫做智能链接。

   实际上, DirectShow并不加载媒体文件,而是创建一个DirectShow滤波器到文件的连接。数据在解码的时候被流化,这样可以减少在播放过程中的内存使用,创建连接的过程叫做渲染(rendering)。渲染一个文件,需要调用IGraphBuilder::RenderFile函数。

      // Have the graph builder construct the appropriate graph automatically
      pGB->RenderFile(L"J:\\VIdeo\\ruby.avi", NULL);

  • IMediaControl::Run方法用来在filter grah中开始数据流动。IMediaControl提供了filter grah中数据流动的run,pause和stop操作。

   在媒体文件被渲染之后,就可以使用另外两个接口 IMediaControl和IMediaEvent进行播放或者对播放进行控制了。

第一个接口 IMediaControl用于播放和各种播放相关的操作,这个接口有三个函数:IMediaControl::Run,IMediaControl:: Pause,IMediaControl::Stop。 

    IMediaControl *pMC   = NULL;
    pGB->QueryInterface(IID_IMediaControl, (void **)&pMC);   
    pMC->Run();

  •  我们主要感兴趣的IMediaEvent函数大概有三个:GetEvent,FreeEventParams,WaitForCompletion。在需要逐帧连续监视事件的时候,用GetEvent和FreeEventParams组合是很有用的,它能帮助我们获取事件并作恰当的处理。但当我们需要连续播放而不希望连续监视播放过程的时候,另外一个函数就会很有用,即WaitForCompletion函数。它可以一直播放,在播放完成的时候,会把控制权交给我们。

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

Code

  

  • 在完成操作后,调用Release()释放资源。

   pMC->Release();
   pGB->Release();   

 

Code

 

 

Code

 

去学习

你可能感兴趣的:(show)