获取语音设备并创建Interface
 
    DirectSound开发中常常需要获取系统当前可用的语音设备列表,在SDK Samples中最先介绍了它。DirectX将它封装成函数DirectSoundEnumerate/DirectSoundCaptureEnumerate,我们所要做的只是以DSEnumCallback作为接口模板,添加一个自定义的回调函数,然后简单的调用一下即可。
    获取设备列表后,创建DirectSound环境使用函数DirectSoundCreate8/DirectSoundCaptureCreate8。

下面是示例源代码:

/*----------------------------------------------------------------------------------
*  File: EnumDevices.cpp
*
*  Desc: This sample shows how to enumerate DirectSound sound and capture devices.
*
*  Copyright (c) Microsoft Corp. All rights reserved.
*
*
*  DirectSoundEnumerate
*  DirectSoundCaptureEnumerate
*  DirectSoundCreate8
*  DirectSoundCaptureCreate8
*  DXTRACE_ERR_MSGBOX : 在DEBUG模式下用来显示错误信息
*  DSEnumCallback     : 用来枚举设备的回调函数
*-----------------------------------------------------------------------------------*/

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

#pragma comment( lib,"Dsound.lib" )
#ifdef _DEBUG
    #pragma comment( lib,"dxerr9.lib" )
#endif

INT_PTR CALLBACK MainDlgProc( HWND,UINT,WPARAM,LPARAM );
INT_PTR CALLBACK DSoundEnumCallback( GUID*,LPSTR, LPSTR,VOID* );
HRESULT OnInitDialog( HWND );
HRESULT InitDirectSound( HWND );
HRESULT FreeDirectSound();

#define SAFE_DELETE(p)  { if(p) { delete (p);     (p)=NULL; } }
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }

LPDIRECTSOUND8        g_pDS        = NULL; //用来存放IDirectSound8 interface地址
LPDIRECTSOUNDCAPTURE8 g_pDSCapture = NULL; //用来存放IDirectSoundCapture8 interface地址

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pszCmdLine, int iCmdShow)
{
    //初始化COM, 可参考DirectX开发文档中创建COM对象部分(Creating a COM Object)
    CoInitialize( NULL );

// Display the main dialog box.
    DialogBox( hInstance, MAKEINTRESOURCE(IDD_MAIN), NULL, MainDlgProc );

//释放COM
    CoUninitialize();

return TRUE;
}

//主窗口回调函数
INT_PTR CALLBACK MainDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam )
{
    HRESULT hr;

switch( msg )
    {
        case WM_INITDIALOG:
            if( FAILED( hr = OnInitDialog( hDlg ) ) )
            {
                DXTRACE_ERR_MSGBOX( TEXT("OnInitDialog"), hr );
                MessageBox( hDlg, "枚举DirectSound设备错误,程序退出.", "EnumDevices", MB_OK | MB_ICONERROR );
                EndDialog( hDlg, IDABORT );
            }
            break;

case WM_COMMAND:
            switch( LOWORD(wParam) )
            {
                case IDC_BUTTON_CREATE:
                    //尝试创建
                    if( SUCCEEDED( hr = InitDirectSound( hDlg ) ) )
                        MessageBox( hDlg, TEXT("创建DirectSound interface成功."), TEXT("EnumDevices"), MB_OK );
                    else
                    {
                        DXTRACE_ERR_MSGBOX( TEXT("InitDirectSound"), hr );
                        MessageBox( hDlg, TEXT("创建DirectSound interface失败."), TEXT("EnumDevices"), MB_OK | MB_ICONERROR );
                    }
                    break;

case IDOK:
                    EndDialog( hDlg, IDCANCEL );
                    break;

default:
                    return FALSE;
            }
            break;

case WM_DESTROY:
            FreeDirectSound(); //不要忘记释放设备
            break;

default:
            return FALSE;
    }
    return TRUE;
}

//初始化窗体
HRESULT OnInitDialog( HWND hDlg )
{
    HRESULT hr;

//枚举sound devices并添加到组合框中
    HWND hSoundDeviceCombo = GetDlgItem( hDlg, IDC_COMBO_SOUND_DEVICE );
    if( FAILED( hr = DirectSoundEnumerate( (LPDSENUMCALLBACK)DSoundEnumCallback, (VOID*)hSoundDeviceCombo ) ) )
        return DXTRACE_ERR_MSGBOX( TEXT("DirectSoundEnumerate"), hr );

//枚举capture devices并添加到组合框中
    HWND hCaptureDeviceCombo = GetDlgItem( hDlg, IDC_COMBO_CAPTURE_DEVICE );
    if( FAILED( hr = DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK)DSoundEnumCallback, (VOID*)hCaptureDeviceCombo ) ) )
        return DXTRACE_ERR_MSGBOX( TEXT("DirectSoundCaptureEnumerate"), hr );

//选中组合框中的第一个设备
    SendMessage( hSoundDeviceCombo,   CB_SETCURSEL, 0, 0 );
    SendMessage( hCaptureDeviceCombo, CB_SETCURSEL, 0, 0 );

return S_OK;
}

//供枚举函数使用的回调函数
INT_PTR CALLBACK DSoundEnumCallback( GUID* pGUID, LPSTR strDesc, LPSTR strDrvName, VOID* pContext )
{
    //注意定义为静态变量
    static GUID  AudioDriverGUIDs[20]; //预留20个设备的存储空间
    static DWORD dwAudioDriverIndex = 0;

GUID* pTemp  = NULL;

if( pGUID )
    {
        if( dwAudioDriverIndex >= 20 )
            return TRUE;

pTemp = &AudioDriverGUIDs[dwAudioDriverIndex++];
        memcpy( pTemp, pGUID, sizeof(GUID) );
    }

HWND hSoundDeviceCombo = (HWND)pContext;

//把设备名称添加到组合框中
    SendMessage( hSoundDeviceCombo, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)strDesc );

//获取当前设备名称在组合框中的索引值
    int nIndex = (int)SendMessage( hSoundDeviceCombo, CB_FINDSTRING, 0, (LPARAM) (LPCTSTR) strDesc );

//将存储在AudioDriverGUIDs设备数组中的GUID保存到对应项中
    SendMessage( hSoundDeviceCombo, CB_SETITEMDATA, nIndex, (LPARAM) pTemp );

return TRUE;
}

//创建IDirectSound
HRESULT InitDirectSound( HWND hDlg )
{
    HRESULT hr;

//首先释放当前可能使用的DirectSound对象
    FreeDirectSound();

HWND hSoundDeviceCombo   = GetDlgItem( hDlg, IDC_COMBO_SOUND_DEVICE );
    HWND hCaptureDeviceCombo = GetDlgItem( hDlg, IDC_COMBO_CAPTURE_DEVICE );

int nSoundIndex   = (int)SendMessage( hSoundDeviceCombo,   CB_GETCURSEL, 0, 0 );
    int nCaptureIndex = (int)SendMessage( hCaptureDeviceCombo, CB_GETCURSEL, 0, 0 );

//获取当前选择项所对应的GUID数据
    GUID* pSoundGUID   = (GUID*) SendMessage( hSoundDeviceCombo, CB_GETITEMDATA, nSoundIndex, 0 );
    GUID* pCaptureGUID = (GUID*) SendMessage( hCaptureDeviceCombo, CB_GETITEMDATA, nCaptureIndex, 0 );

//使用所选设备创建IDirectSound
    if( FAILED( hr = DirectSoundCreate8( pSoundGUID, &g_pDS, NULL ) ) )
        return DXTRACE_ERR_MSGBOX( TEXT("DirectSoundCreate"), hr );

//作为一个示例,我们尝试创建后马上释放掉.
    SAFE_RELEASE( g_pDS );

//使用所选设备创建IDirectSoundCapture
    if( FAILED( hr = DirectSoundCaptureCreate8( pCaptureGUID, &g_pDSCapture, NULL ) ) )
        return DXTRACE_ERR_MSGBOX( TEXT("DirectSoundCaptureCreate"), hr );

//释放
    SAFE_RELEASE( g_pDSCapture );

return S_OK;
}

//释放对象
HRESULT FreeDirectSound()
{
    SAFE_RELEASE( g_pDSCapture );
    SAFE_RELEASE( g_pDS );

return S_OK;

}

DirectSound开发相关推荐

  1. DirectSound开发指南(1)

    1DirectSound简介(Introduction to DirectSound) 曾经学习过Directshow的开发,对于Dsound一直没有仔细的莱学习,以前只是知道Dsound是做音频开发 ...

  2. DirectSound开发指南

    1DirectSound简介(Introduction to DirectSound) 曾经学习过Directshow的开发,对于Dsound一直没有仔细的莱学习,以前只是知道Dsound是做音频开发 ...

  3. Directsound开发指南(4)

    4DirectSound开发高级技巧 4.1Dsound驱动模型(DirectSound Driver Models) 在VXD驱动模型下,所有的DirectSound的混音工作都是由Dsound.v ...

  4. Directsound开发指南(2)

    3.2Dsound的buffer对象(DirectSound Buffers) 在存储和播放几个音频流的时候,你的应用程序要给每一个音频流都要创建一个辅助缓冲区(buffer)对象. 辅助缓冲区可以和 ...

  5. DirectSound播放音频应用程序开发快速入门

    [来源天极网] 摘要:DirectSound编程的入门介绍,通过实例讲解了如何利用DirectSound最基本的功能-----播放音频,并提供了DirectSound播放音频文件的两种方式(Stati ...

  6. Directsound 详解

    关键词: Directsound stream buffer ,static buffer wave 文件播放 一.配置DirectDounf的开发环境 在进行DirectSound开发之前,一定要设 ...

  7. 用DirectX Audio和DirectShow播放声音和音乐

    项目中的声音播放效果,原来使用MFC对话框的播放测试例子已经通过.但是和项目结合起来有莫名异常发生还需要再继续研究一下声音的播放. 现在暂时使用playSound方法实现,但是还是要实现混音播放效果才 ...

  8. java知识体系介绍

    国内最牛七星级团队马士兵.高淇等11位十年开发经验专家录制 目 录 百战程序员Java1573题 2百战程序员介绍 3JavaSE编程基础 9第一章 初识Java 9阶段项目课程1 11第二章 数据类 ...

  9. TXT音乐播放器与DirectSound与C++,开发笔记与EXE免费下载(一)

    一.前言 之前提到,使用C语言开发TXT音乐播放器.使用PlaySound方法播放wav文件时,无法同时播放多个wav文件:当开始播放下一个wav文件时,之前正在播放的wav文件就会停止,导致音乐播放 ...

最新文章

  1. 腾讯优图+厦门大学发布!2021十大人工智能趋势
  2. wincc报表步骤实例_Wincc 如何连接SQL Server 数据库
  3. cpu风扇声音大_笔记本电脑风扇声音大怎么办
  4. node环境下express路由,
  5. 高可用架构-- MySQL主从复制的配置
  6. C++11 修复了双重检查锁定问题(转)
  7. 五步使用法——搞定XMLHttpRequest
  8. HTML,模仿网易登陆界面
  9. Html转Word解决转存图片时候的跨域问题、默认打开视图问题
  10. 关闭cidaemon进程的方法
  11. 男女偷情为了什么   文 / 自然人生
  12. BAT批处理判断是否是文件夹,是则遍历
  13. Xiaojie雷达之路---DPM External Functions详解
  14. 我的功放和你们用的功放芯片的SD_MUTE脚电平不一样_该如何处理
  15. scikit-image图像处理入门
  16. linux启动/停止/重启MySQL的命令
  17. 最通俗的理解什么是冒泡
  18. 给你一个全新的软件,你就是负责人,你怎么去开展工作
  19. 国庆假期欣赏机械之美
  20. #第五章“拷问”既往的股市理论5.1有人情味的“拷问”

热门文章

  1. 机器学习笔记(十六)——EM算法概述
  2. 京东到家休闲食品即时消费趋势报告
  3. 软件开发包(SDK)安全与合规报告(2020)
  4. 2020年中国无人经济市场研究报告
  5. linux 移动硬盘 mnt,linux 移动硬盘 mnt
  6. 作者:刘峰(1974-),男,中国科学院计算机网络信息中心高级工程师
  7. 作者:周园春(1975-),男,博士,中国科学院计算机网络信息中心研究员、博士生导师。...
  8. 【Python】SyntaxError: Non-ASCII character ‘\xe8‘ in file main.py on line 7, but no encoding declared;
  9. 埃氏筛秒素数题(洛谷P5723题题解,Java语言描述)
  10. 【数据结构与算法】数组动态分配方式的思考