MFC音频API
- 格式:doc
- 大小:76.50 KB
- 文档页数:15
mfccpython代码如何使用Python计算MFCC特征?MFCC(Mel频率倒谱系数)是一种在语音处理和音频信号分析中广泛使用的特征提取方法。
它通过模拟人耳听觉的特点,将音频信号转换为一组特征向量,用于声音识别、语音识别和其他音频处理任务。
在本文中,我们将学习如何使用Python计算MFCC特征。
第一步:导入所需的库首先,我们需要导入一些Python库来处理音频信号和计算MFCC特征。
主要使用的库有:1. numpy:用于数值运算和矩阵操作。
2. scipy:用于信号处理和傅里叶变换。
3. librosa:一个音频处理库,提供了方便的接口来计算MFCC特征。
4. matplotlib:用于绘制图表以可视化MFCC特征。
下面是导入这些库的代码:import numpy as npfrom scipy.io import wavfileimport librosaimport matplotlib.pyplot as plt第二步:加载音频文件接下来,我们需要加载一个音频文件,以便将其转换为MFCC特征。
我们可以使用`scipy`库的`wavfile.read()`函数从.wav文件中读取音频信号。
这个函数返回音频信号的采样率和数据。
音频数据是一个numpy数组,其中每个元素代表一个采样点的振幅。
下面是加载音频文件的代码示例:# 读取音频文件filename = 'audio.wav'sample_rate, data = wavfile.read(filename)第三步:将音频信号转换为MFCC特征一旦我们加载了音频信号,我们就可以使用`librosa`库将其转换为MFCC 特征。
`librosa.feature.mfcc()`函数接受音频数据和采样率作为输入,并返回计算得到的MFCC特征。
我们还可以通过调整一些参数来控制MFCC 特征的计算方式。
下面是计算MFCC特征的代码示例:# 计算MFCC特征mfcc = librosa.feature.mfcc(data, sample_rate)第四步:可视化MFCC特征最后,我们可以使用`matplotlib`库来绘制MFCC特征的图表,以便更好地理解它们。
mfc中messagebeep函数使用mfc中的MessageBeep函数是用来在Windows操作系统中播放系统提供的各种提示音的一个函数。
通过使用MessageBeep函数,开发人员可以为用户提供一些即时的、直观的反馈信息,以增强用户交互体验。
本文将一步一步地解释如何使用MessageBeep函数,并提供一些实际应用示例和常见问题的解答。
第一步:包含头文件在使用MessageBeep函数之前,我们需要先包含Windows.h头文件。
Windows.h是一个重要的Windows API头文件,它提供了许多与操作系统相关的函数和常量的定义。
#include <windows.h>第二步:调用MessageBeep函数MessageBeep函数的原型如下:BOOL MessageBeep(UINT uType);该函数接受一个表示提示音类型的参数uType,并返回一个BOOL类型的值,表示函数是否执行成功。
不同的uType参数对应不同类型的提示音。
下面是一些常见的uType参数值和对应的声音效果:- MB_OK:播放一次短暂的“确认”音。
- MB_ICONASTERISK:播放一次具有高音频和频率的音,表示“信息”。
- MB_ICONEXCLAMATION:播放一次短而高的音,表示“警告”。
- MB_ICONHAND:播放一次低音频的音,表示“错误”。
我们可以根据具体需要选择适当的uType参数。
例如,如果我们想要播放一次错误提示音,可以使用以下代码:MessageBeep(MB_ICONHAND);当然,我们也可以将MessageBeep函数与其他MFC或Windows API函数结合使用,以根据一定的逻辑条件来调用MessageBeep函数。
第三步:错误处理在使用MessageBeep函数时,我们需要注意错误处理。
例如,如果uType 参数的值不属于有效范围,MessageBeep函数将返回0,表示执行失败。
Visual C++课程设计题目名称:简单的音乐播放器班级:信息安全1101姓名:曹廷祥学号:1111290103指导教师:阎光伟完成时间:2013.1.18一.题目描述音乐播放器是一种用于播放各种音乐文件的多媒体播放软件。
利用MFC应用程序、媒体控制接口MIC的基本知识,设计一个功能非常简单易于操作的MP3播放器。
要求能够播放常用Windows音频格式的文件;实现播放控制:播放、暂停、音量增减、添加歌曲等功能;实现从本地磁盘加入文件,然后对其进行播放。
本程序是基于MFC对话框的简单程序实现音乐的简单控制。
二.功能分析MFC简单音乐播放器主要对常用Windows音频格式的文件实现播放控制:播放歌曲、暂停播放、停止播放等;实现音量控制:静音、声音放大以及声音减小的功能。
利用MCI基本知识实现相关功能。
MCI(Media Control Interface)媒体控制接口是MircroSoft提供的一组多媒体设备和文件的标准接口,它的好处是可以方便地控制绝大多数多媒体设备包括音频、视频、影碟、像等多媒体设备,而不需要知道它们的内部工作状况。
它所支持的媒体格式包括avi、wav、mp3等等。
音频文件包括多种格式的文件,MP3就是其中的一种。
MP3是一种音频压缩的国际技术标准,它一般需要MP3播放器来读取。
通过该程序可以实现简单的音乐播放。
核心是让音乐文件和音乐播放设备关联。
3.系统结构分析(1)整体结构设计图3-1-a整体结构设计图(2)音乐播放流程图设计图3-2-a音乐播放流程图四.系统模块设计(1)背景图片和背景音乐首先将外部的音频文件资源添加到MFC声音资源中,手工制作背景图片加入到资源位图中。
在OnPaint()函数中添加设置显示代码。
最终使音乐播放器显示背景图片同时播放背景音乐。
(2)添加功能该功能能够在本地磁盘中寻找音乐文件,并将文件加载到程序中,获取音频文件的参数。
同时获取文件存取的路径并获取音频文件名,将音频文件名赋值给编辑框同时刷新显示。
mfc ffmpeg例子MFC(Microsoft Foundation Class)是微软提供的用于开发Windows应用程序的类库,而FFmpeg是一个开源的跨平台音视频处理工具。
结合MFC和FFmpeg可以实现在Windows平台上对音视频进行处理和播放的功能。
下面我将从MFC和FFmpeg的结合、示例代码和注意事项等方面来回答你的问题。
首先,我们需要在MFC应用程序中集成FFmpeg库。
你需要下载FFmpeg的开发包,并在MFC项目中进行配置。
接着,你可以使用FFmpeg提供的API来实现音视频的编解码、播放和处理等功能。
下面是一个简单的MFC和FFmpeg结合的示例代码:c++。
extern "C" {。
#include <libavformat/avformat.h>。
#include <libswscale/swscale.h>。
}。
// 初始化FFmpeg.av_register_all();// 打开输入文件。
AVFormatContext pFormatCtx = NULL;if (avformat_open_input(&pFormatCtx, "input.mp4", NULL, NULL) != 0) {。
return -1; // 打开文件失败。
}。
// 查找流信息。
if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {。
return -1; // 无法获取流信息。
}。
// 寻找视频流。
int videoStream = -1;for (int i = 0; i < pFormatCtx->nb_streams; i++) {。
if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {。
MFC播放MP3工程中添加 Winmm.lib stdafx.h 里面添加包含 Mmsystem.h 使用mciSendCommand函数播放MP3#include <windows.h>#include "resource.h"#pragma comment(lib, "winmm")LRESULT CALLBACK WndProc(HWND,UINT,WPARAM ,LPARA M );int MP3Player(HWND,int fnNum);HINSTANCE Hinstance;int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPr evInstance,LPSTR lpCmdLine,int nShowCmd){WNDCLASS wndclass;HWND hwnd;MSG msg;WCHAR *title=L"快乐の小②B制作";WCHAR *MP3=L"MP3 Player";Hinstance=hInstance;wndclass.cbClsExtra=NULL;wndclass.cbWndExtra=NULL;wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE _BRUSH);wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);wndclass.hIcon =LoadIcon(NULL,IDI_APPLICATION);wndclass.hInstance=hInstance;wndclass.lpfnWndProc=WndProc;wndclass.lpszClassName=MP3;wndclass.lpszMenuName=0;wndclass.style=CS_HREDRAW |CS_VREDRAW;if(!RegisterClass(&wndclass)){MessageBox(NULL,L"注册窗口失败!",L"Error Info",MB_OK);return 0;}hwnd=CreateWindowEx(WS_EX_LAYERED,MP3,title,WS_OVE RLAPPED | WS_CAPTION | WS_SYSMENU| WS_MINIMIZEBOX ,CW_USEDEFAULT,CW_USEDEFAULT,310,410,NULL,NULL,hIns tance,NULL);AnimateWindow(hwnd,1000,AW_BLEND|AW_SLIDE);//窗口效果函数//UpdateWindow(hwnd);while(GetMessage(&msg,NULL,0,0)){TranslateMessage(&msg);DispatchMessage(&msg);}return msg.wParam;}LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){PAINTSTRUCT ps;HDC hdc,hdcmem;HBITMAP hBitmap;BITMAP Bitmap;static HWND ChildHwnd_1=0;static HWND ChildHwnd_2=0;if(message == WM_PRINT || message == WM_PRINTCLIENT) {hdc=(HDC)wParam;hBitmap=LoadBitmap(Hinstance,MAKEINTRESOURCE(IDB_B ITMAP1));GetObject(hBitmap,sizeof(BITMAP),&Bitmap);hdcmem=CreateCompatibleDC(hdc);SelectObject(hdcmem,hBitmap);BitBlt(hdc,0,0,Bitmap.bmWidth,Bitmap.bmHeight,hdcmem,0 ,0,SRCCOPY);DeleteDC(hdcmem);}switch(message){case WM_CREATE:ChildHwnd_1=CreateWindowEx(WS_EX_LAYERED,L"Button", L"Play",WS_VISIBLE|WS_CHILD,50,330,70,30,hwnd,(HMENU)1,0, NULL);ChildHwnd_2=CreateWindowEx(WS_EX_LAYERED,L"Button", L"Stop",WS_VISIBLE|WS_CHILD,190,330,70,30,hwnd,(HMENU)2,0 ,NULL);return 0;case WM_CLOSE:DestroyWindow(hwnd);PostQuitMessage(0);return 0;case WM_COMMAND:switch(wParam){case 1:MP3Player(hwnd,1);break;case 2:MP3Player(hwnd,2);break;}return 0;case WM_PAINT:hBitmap=LoadBitmap(Hinstance,MAKEINTRESOURCE(IDB_B ITMAP1));GetObject(hBitmap,sizeof(BITMAP),&Bitmap);hdc=GetDC(hwnd);hdcmem=CreateCompatibleDC(hdc);SelectObject(hdcmem,hBitmap);BitBlt(hdc,0,0,Bitmap.bmWidth,Bitmap.bmHeight,hdcmem,0 ,0,SRCCOPY);DeleteDC(hdcmem);BeginPaint(hwnd,&ps);EndPaint(hwnd,&ps);return 0 ;}return DefWindowProc(hwnd,message,wParam,lParam);}int MP3Player(HWND hwnd,int fnNum){switch(fnNum){case 1://播放static MCI_OPEN_PARMS open;static MCI_PLAY_PARMS play;static MCIDEVICEID MP3ID;open.dwCallback=0;open.lpstrAlias=NULL;open.lpstrDeviceType=L"MPEG"; //MP3设备open.lpstrElementName=L"该死的温柔.mp3"; //要播放的文件open.wDeviceID=0;mciSendCommand(0,MCI_OPEN,MCI_WAIT| MCI_OPEN_ELE MENT,(DWORD)(LPMCI_OPEN_PARMS)&open);//初始化MP3ID=open.wDeviceID;play.dwCallback=(DWORD)hwnd; //播放程序的窗口句柄play.dwFrom=0;play.dwTo=0;mciSendCommand(MP3ID,MCI_PLAY,MCI_NOTIFY,(DWORD) (LPMCI_OPEN_PARMS)&play);return 0;case 2://停止MCI_GENERIC_PARMS close;close.dwCallback=(DWORD)hwnd;mciSendCommand(MP3ID,MCI_CLOSE,MCI_NOTIFY,(DWOR D) (LPMCI_GENERIC_PARMS)&close);return 0;}return 0;}。
打开vc6.0,建立如图所示mfc工程文件选择基于对话框的确定删除所有空间,建立如图所示对话框属性如下:播放IDC_open;添加IDC_fileopen;暂停IDC_pause;删除IDC_del;停止IDC_stop;退出IDC_exit;音乐名编辑框IDC_filename;音量控制滑块IDC_SLIDER1;音量控制编辑框IDC_vol;建立类向导对应如下:在onpaint函数下添加代码void CMp3Dlg::OnPaint(){if (IsIconic()){CPaintDC dc(this); // device context for paintingSendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);// Center icon in client rectangleint cxIcon = GetSystemMetrics(SM_CXICON);int cyIcon = GetSystemMetrics(SM_CYICON);CRect rect;GetClientRect(&rect);int x = (rect.Width() - cxIcon + 1) / 2;int y = (rect.Height() - cyIcon + 1) / 2;// Draw the icondc.DrawIcon(x, y, m_hIcon);}else{//CDialog::OnPaint();CPaintDC dc(this);CRect rect;GetClientRect(&rect);CDC dcMem;dcMem.CreateCompatibleDC(&dc);CBitmap bmpBackground;bmpBackground.LoadBitmap(IDB_BITMAP6); /IDB_BITMAP6是你的位图地址BITMAP bitmap;bmpBackground.GetBitmap(&bitmap);CBitmap *pbmpOld=dcMem.SelectObject(&bmpBackground);dc.StretchBlt(0,0,rect.Width(),rect.Height(),&dcMem,0,0,bitmap.bmWidth,bitmap.bmHeight ,SRCCOPY);}}编译运行,你就会看到背景有图片了。
xxxxxxxxxx《Windows编程》大作业题目:基于MFC的音乐播放工具姓名:学号:班级:指导老师: 2013.12.26一、功能描述具有一般播放*.mp3,*.wma,*.mdi,*.wav,*.avi,*.dat等文件,实现了基本控制功能和播放模式控制。
二、系统概述本系统使用windows media play控件实现音乐播放,并实现播放列表以及歌曲的循环顺序播放,并用按钮实现了添加文件、播放、暂停、停止、上一曲、下一曲及歌曲删除功能。
音量的增减由windows media play上自带的按钮实现,没有单独的音量增减按钮。
Windows media play控件自身有播放列表,但是网上资料不全,不知道如何去实现,只有自己用list control控件实现了播放列表。
本来是用vc++6.0创建工程,但过程中出现一些无法理解的错误,之后只能用vs2012打开工程,错误消失,所以工程文件比较大。
三、系统设计步骤1、创建MFC(exe)对话框工程2、在对话框中添加windows media play控件并添加成员变量m_Ctrplay系统会自动生成必需的媒体实现文件。
并在头文件中添加共有变量CWMPControl s m_control;CWMPSettings m_setting;CWMPMedia m_media;CWMPPlaylist m_list;3、界面设计:设计的界面如下图所示,其中播放控制按钮有打开文件,播放,暂停,停止,播放列表,退出,关于。
然后还有,播放模式的相关控制器件为list control控件添加成员变量m_listCtrl4、功能实现首先初始化播放控件及列表控件。
在OnInitDialog()方法中添加代码:m_setting = static_cast <CWMPSettings> (m_Ctrplay.GetSettings());m_control = static_cast <CWMPControls> (m_Ctrplay.GetControls());m_media = static_cast <CWMPMedia> (m_Ctrplay.newMedia(NULL));CRect rect;m_listCtrl.GetClientRect(&rect);m_listCtrl.SetExtendedStyle(m_listCtrl.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);m_listCtrl.InsertColumn(0,_T("名称"),LVCFMT_CENTER,2*rect.Width()/4,0);m_listCtrl.InsertColumn(1,_T("格式"),LVCFMT_CENTER,rect.Width()/4,1);m_listCtrl.InsertColumn(2,_T("时长"),LVCFMT_CENTER,rect.Width()/4,2);m_listCtrl.InsertColumn(3,_T(""),LVCFMT_CENTER,0,3);m_listCtrl.InsertColumn(4,_T(""),LVCFMT_CENTER,0,4);实现对控件的初始化。
研究生堂下考试答卷2011-2012学年第一学期考试科目面向对象方法(VC++)姓名于芳年级2011级专业电子与通信工程2010 年12 月18 日基于MFC的MP3播放器姓名:于芳学号:30125847569 专业:通信工程摘要:多媒体技术的概念和应用出现于20世纪80年代初期,经过十余年的发展,随着计算机科学网络的普及和多媒体技术的发展,已成为计算机领域发展的热点技术,针对目前各种媒体格式,如何简单方便的播放各类媒体已成为人们普遍关注的问题。
本设计就是基于面向对象技术,利用VC++6.0开发出适合多种格式的的多媒体MP3播放器。
该播放器是基于MFC集成开发环境,利用系统的媒体控制接口MCI命令来编程,建立了一个MP3播放器的类CPLAYERDlg,通过调用这个类的函数来实现各种Windows音频格式文件的播放。
它外观简洁,操作简便,支持的播放格式多、系统资源占用少、支持播放列表编辑等功能。
关键词:MP3 MFC 面向对象设计 VC++ MCI一系统设计的基本原理与思路本设计的基本原理就是利用MFC应用程序以及媒体控制接口MCI的基本知识而设计的。
Windows已经提供了一个关于多媒体处理的动态链接库WINMM.DLL,通过调用它所提供的API函数,就可以使用MCI指令进行多媒体方面的操作了。
1.1 MFC简介MFC是Visual C++是核心。
MFC类库将所有图形用户界面的元素如窗口、菜单和按钮等都以类的形式进行了封装,MFC AppWizard向导根据继承性利用MFC 派生出自己的类,并对Windows应用程序进行了分解,利用MFC派生类对应用程序重新进行组装,同时还规定了应用程序中各个MFC派生类对象之间的相互联系,实现了标准Windows应用程序的功能,这就是向导生成的所谓MFC应用程序框架。
每个MFC类都包括了一些函数,函数放到类中,符合C++编程方法。
这些函数,必须通过类定义对象才能使用。
如何来控制系统中任何的音频输出和输入,比如波形音频,MIDI ,CD音频,合成语音等音频输出以及Line in ,麦克等输入,windows给我们提供了一组API接口函数,称为Mixer 系列的函数,mixer也称为混音器,通过混音器可以实现混音和音量控制。
最基本的混音器结构单元是音频线路,比如microphone ,line in ,cd,midi等都是一个音频线路。
音频线路包含一个或者多个发源于单一音源或系统资源的声道,例如,一个立体声音频线路有两个声道,但仍然被看成是一个音频线路,因为它发源于一个音源。
下面我要先简单的介绍一下Mixer函数,其实反正总共也没有几个,使用起来很简单的。
mixerOpenmixerClosemixerGetDevCapsmixerGetLineControlsmixerGetLineInfomixerGetControlDetailsmixerSetControlDetailsmixerGetIDmixerGetNumDevs看到了吧,就这么简单的几个函数,通过这9个API,我们就可以来控制音频的输入和输出设备了,其实有关这几个函数的定义你可以在C:\Program Files\Microsoft Visual Studio\VC98\Include\mmsystem.h文件中找到。
下面我简单介绍一下这几个函数,详细地介绍你可以参见msdn。
mixerOpen和mixerClose函数用来打开和关闭混音器设备mixerGetNumDevs可以确定系统中有多少混音器设备mixerGetDevCaps函数可以确定混音器设备的能力mixerGetLineInfo可以检索指定音频线路的信息mixerGetLineControls用于检索一个或者多个与音频线路相关的控制的通用信息mixerGetControlDetails用于检索与某个音频线路相关的一个控制的属性mixerSetControlDetails用于设置制定控制的属性。
其实我们主要用到的就是后面的四个函数,希望大家重点研究一下。
混音器还提供了窗口回调服务,用户在调用mixeropen的时候,可以将一个窗口句柄作为参数传递给mixer,这样,当mixer设备发生变化时就会给回调窗口发送消息通知,比如用户通过控制面板调整了音量的大小,或者选择了某个录音设备。
消息的类型就两个MM_MIXM_LINE_CHANGE 和MM_MIXM_CONTROL_CHANGE。
下面就不多说了,我用一个例子告诉你如何在程序中对音频设备进行设置,先看看我提供的例子的界面图3这里播放和录音我都只是选择了几个常用的设备,当然系统提供的设备比我这里的举例用到的设备要多,你可以根据我提供的方法来对其他的设备进行控制。
还有说明一下,具有两个滑动条的表示左右声道。
但是像麦克风只有一个声道。
通过我们的程序界面我们就可以像在控制面板里一样可以调节左右声道的音量,以及选择某个设备进行录音,或者对某个音频线路进行静音,相应的系统的设置也会被改变,如果你通过系统的控制面板进行设置,在我们的程序界面也上同步的可以反映出来变化。
进入讨论组讨论。
关于工程的建立我就不多少了,很简单的,就是一个基于对话框的工程,上面放了一些控件。
下面我主要讲一下每个功能是如何实现的。
主要有三个功能 1 如何调整左右声道音量的大小,2 如何将某个设备静音,3 如何选择录音设备。
这里关于mixer函数的用法还要先唠叨几句。
一般来说,对音频线路的操作流程如下:1、通过GetLineInfo获取指定音频线路的信息,返回一个MIXERLINE结构2、然后通过GetLineControl获取音频线路相关的控制的通用信息,通过MIXERCONTROL结构返回。
3、通过GetConrolDetails获取指定控制的属性值4、通过SetControlDetails设置指定控制的属性值,对于每个线路设备,mixer都用一个类型值来标示,比如:V olume对应的值MIXERLINE_COMPONENTTYPE_DST_SPEAKERSCD 对于的值MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISCMidi对应的值为MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZERWave对应的值为MIXERLINE_COMPONENTTYPE_SRC_W A VEOUTLine in对应的值为MIXERLINE_COMPONENTTYPE_SRC_LINEMicrophone对应的值为MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE我们可以通过音频线路的类型值获得相应的线路的信息,也可以通过音频线路的设备ID来获取相应的线路的信息。
下面开始我们编程吧。
首先定义三个变量UINT m_uMxId; //mixer的IDHWND m_hWnd; //回调窗口句柄HMIXER m_hmx; //然后就是要打开mixer,可以在对话的初始化中作这些工作。
#define MAX_VOL_VALUE 65535if (MMSYSERR_NOERROR != mixerOpen(&m_hmx, m_uMxId,(DWORD)m_hWnd, 0, CALLBACK_WINDOW)){return FALSE;}if (MMSYSERR_NOERROR == mixerGetID((HMIXEROBJ)m_hmx, &m_uMxId, MIXER_OBJECTF_HMIXER)){return m_uMxId;}//设置Volume的滑动条的范围这里只以Volume为例。
m_SliderWaveL.SetRange(0, MAX_VOL_VALUE, TRUE);m_SliderWaveR.SetRange(0, MAX_VOL_VALUE, TRUE);接着我先演示一下如何获取和设置录音设备的左右声道的音量值,以及如何静音放音设备,这里以Volume为例,其他的设备类似,你可以照着我的代码,套用即可。
1、如何获取V olume设备的音量大小DWORD dwLValue;DWORD dwRValue;GetVolume(MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, &dwLValue,&dwRValue);//GetVolume函数的定义见下面,然后根据返回的值调整滑动条的位置m_SliderVolR.SetPos(MAX_VOL_VALUE - dwLValue);m_SliderVolL.SetPos(MAX_VOL_VALUE - dwRValue);2、如何根据滑动条的位置来调整系统音量的大小void CMixerControlDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) {// m_dwSpkR和m_dwSpkL是用来记录Volume左右声道的音量值,0~~65535CSliderCtrl *pSlider = (CSliderCtrl *)pScrollBar;int nValue = MAX_VOL_VALUE - pSlider->GetPos(); //获取滑动条的位置poselse if (m_SliderVolR.m_hWnd == pSlider->m_hWnd){//如果拖动的是Volume的左声道m_dwSpkR = nValue;// 设置Volume的音量值SetVolume(MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, m_dwSpkL, m_dwSpkR);}else if (m_SliderVolL.m_hWnd == pSlider->m_hWnd){//Volume右声道m_dwSpkL = nValue;// 设置Volume的音量值SetVolume(MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, m_dwSpkL, m_dwSpkR);}//其他音频线路可以依次类推在下面添加}GetVolume和SetVolume函数的定义下面给出BOOL CMixer::SetVolume(DWORD dwSrcType, DWORD dwLValue, DWORD dwRValue, BOOL bMono) {MIXERLINE mxl;if (! GetLineInfo(&mxl, MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, dwSrcType))return FALSE;MIXERCONTROL mxc;if (! GetLineControl(&mxc, &mxl, MIXERCONTROL_CONTROLTYPE_VOLUME))return FALSE;MIXERCONTROLDETAILS mxcd;MIXERCONTROLDETAILS_UNSIGNED mxcd_u1;MIXERCONTROLDETAILS_UNSIGNED mxcd_u[2];mxcd.cbStruct = sizeof(mxcd);mxcd.dwControlID = mxc.dwControlID;mxcd.cMultipleItems = 0;if (bMono){hannels = 1;mxcd.cbDetails = sizeof(mxcd_u1);mxcd.paDetails = &mxcd_u1;mxcd_u1.dwValue = dwLValue;}else{hannels = hannels;mxcd.cbDetails = sizeof(*mxcd_u);mxcd.paDetails = mxcd_u;mxcd_u[0].dwValue = dwLValue;mxcd_u[1].dwValue = dwRValue;}if (! SetControlDetails(&mxcd, MIXER_OBJECTF_MIXER))return FALSE;return TRUE;}BOOL CMixer::GetVolume(DWORD dwSrcType, DWORD* pdwLValue, DWORD* pdwRValue, BOOL bMono) {MIXERLINE mxl;if (! GetLineInfo(&mxl, MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, dwSrcType))return FALSE;MIXERCONTROL mxc;if (! GetLineControl(&mxc, &mxl, MIXERCONTROL_CONTROLTYPE_VOLUME))return FALSE;MIXERCONTROLDETAILS mxcd;MIXERCONTROLDETAILS_UNSIGNED mxcd_u1;MIXERCONTROLDETAILS_UNSIGNED mxcd_u[2];mxcd.cbStruct = sizeof(mxcd);mxcd.dwControlID = mxc.dwControlID;mxcd.cMultipleItems = 0;if (bMono){hannels = 1;mxcd.cbDetails = sizeof(mxcd_u1);mxcd.paDetails = &mxcd_u1;if (! GetControlDetails(&mxcd, MIXER_GETCONTROLDETAILSF_VALUE)) return FALSE;*pdwLValue = mxcd_u1.dwValue;}else{hannels = hannels;mxcd.cbDetails = sizeof(*mxcd_u);mxcd.paDetails = mxcd_u;if (! GetControlDetails(&mxcd, MIXER_GETCONTROLDETAILSF_VALUE))return FALSE;*pdwLValue = mxcd_u[0].dwValue;*pdwRValue = mxcd_u[1].dwValue;}return TRUE;}BOOL GetLineInfo(LPMIXERLINE pmxl, DWORD dwDstType, DWORD dwSrcType){MIXERCAPS mxcaps;if (! GetDevCaps(&mxcaps))return FALSE;UINT u=0;do{pmxl->cbStruct = sizeof(*pmxl);pmxl->dwDestination = u;u++;if (MMSYSERR_NOERROR != mixerGetLineControls((HMIXEROBJ)m_uMxId, pmxl, MIXER_GETLINEINFOF_DESTINATION)){}} while ((u < mxcaps.cDestinations) && (pmxl->dwComponentType != dwDstType));if (u > mxcaps.cDestinations)return FALSE;if (dwDstType == dwSrcType)return TRUE;pmxl->dwDestination = u;UINT cConnections = (UINT)pmxl->cConnections;UINT v=0;u--;do{pmxl->cbStruct = sizeof(*pmxl);pmxl->dwDestination = u;pmxl->dwSource = v;v++;if (MMSYSERR_NOERROR != mixerGetLineControls((HMIXEROBJ)m_uMxId, pmxl, MIXER_GETLINEINFOF_SOURCE)){}} while ((v < cConnections) && (pmxl->dwComponentType != dwSrcType));if((v > cConnections) || (pmxl->dwComponentType !=dwSrcType))return FALSE;return TRUE;}BOOL GetLineControl(LPMIXERCONTROL pmxc, LPMIXERLINE pmxl, DWORD dwType){LPMIXERCONTROL pamxctrl;DWORD cbmxctrls = sizeof(*pamxctrl) * (UINT)pmxl->cControls;pamxctrl = (LPMIXERCONTROL)LocalAlloc(LPTR, cbmxctrls);MIXERLINECONTROLS mxlc;mxlc.cbStruct = sizeof(mxlc);mxlc.dwLineID = pmxl->dwLineID;mxlc.dwControlType = dwType;ontrols = pmxl->cControls;mxlc.cbmxctrl = sizeof(*pamxctrl);mxlc.pamxctrl = pamxctrl;if (MMSYSERR_NOERROR != mixerGetControlDetails((HMIXEROBJ)m_uMxId, &mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE)){return FALSE;}memcpy(pmxc, pamxctrl, sizeof(*pamxctrl));LocalFree(pamxctrl);return TRUE;}进入讨论组讨论。