利用fmod建立简易播放器

本文介绍了一个基于FMOD和WASAPI的音频播放器实现案例,通过使用多线程监听全局键盘事件来控制播放功能。对比了不同音频接口的表现,并提供了具体的代码示例。

fmod是个可利用于多平台的音频api接口,可贵的是基于非商业的应用是免费的

而且貌似合适的音频库也不是很多,就选用它了。win7下面有个新的音频接口(wasapi)

那个接口是低延时的,而且fmod也可以直接调用,所以还是很不错的。

在调用时使用2d模式,和wasapi独占模式。由于是要尽量简单,只是实现了多线程的监听全局键盘事件

和简单的停止和下一曲功能,还有很大的改进空间。。

听感来说,明显wasapi的能量更为集中,定位感也更好,而其他像dsound的模糊的一塌糊涂,wave的好一点,但是还是比不上独占模式。

不多说了,直接上代码!


  
#include " fmod.hpp "
#include
" fmod_errors.h "
// #include "lisDll2.h"
#include < iostream >
#include
< assert.h >
#include
< Windows.h >
using namespace std;
FMOD_RESULT result;
FMOD::System
* fsystem;
FMOD::Sound
* fsound;
HHOOK hHook;
bool needChang = false ;
bool needStop = false ;
#define CHKERR(X) {if (X != FMOD_OK)\
{\
printf(
" FMOD error! (%d) %s\n " , X,FMOD_ErrorString(X));\
exit(
- 1 );\
}\
}
void init_mus(){
result
= FMOD::System_Create( & fsystem);
assert(result
== FMOD_OK);
result
= fsystem -> setOutput(FMOD_OUTPUTTYPE::FMOD_OUTPUTTYPE_WASAPI);
assert(result
== FMOD_OK);
result
= fsystem -> setSpeakerMode(FMOD_SPEAKERMODE_STEREO);
assert(result
== FMOD_OK);
// fsystem->set3DSpeakerPosition(FMOD_SPEAKER_FRONT_LEFT, -1.5f, 0.0f, true);
// fsystem->set3DSpeakerPosition(FMOD_SPEAKER_FRONT_RIGHT, 1.5f, 0.0f, true);

result
= fsystem -> init( 100 ,FMOD_INIT_WASAPI_EXCLUSIVE, 0 );
assert(result
== FMOD_OK);
}
void play_mus( char * path){
bool isp;
FMOD::Channel
* channel = NULL;
FMOD::Channel
* ch;
result
= fsystem -> createStream(path,FMOD_HARDWARE, 0 , & fsound);
CHKERR(result);
result
= fsystem -> playSound(FMOD_CHANNEL_FREE,fsound, false , & ch);
CHKERR(result);
ch
-> isPlaying( & isp);
while (isp){
Sleep(
100 );
ch
-> isPlaying( & isp);
if (needChang){
fsystem
-> playSound(FMOD_CHANNEL_FREE,fsound, true , & ch);
ch
-> stop();
needChang
= 0 ;
break ;
}
}
}
void my_release(){
fsystem
-> release();
}
void get_Path( char * dd){
WIN32_FIND_DATA FD ;
HANDLE hFind
= NULL;
char my_path_name[ 1024 ];

SetCurrentDirectory(dd);
sprintf(my_path_name,
" %s%s " ,dd, " \\*.mp3 " );
hFind
= FindFirstFile(my_path_name, & FD);
if (hFind != INVALID_HANDLE_VALUE){
printf(
" %s\n " ,FD.cFileName);
puts(
" about to play... " );
play_mus(FD.cFileName);
// hFind = FindFirstFile(my_path_name,&FD);
}
while (FindNextFile(hFind, & FD) == true ){
if (needStop == true ){
needStop
= false ;
hFind
= NULL;
break ;
}
printf(
" %s\n " ,FD.cFileName);
puts(
" about to play... " );
play_mus(FD.cFileName);
}

hFind
= NULL;

}
LRESULT CALLBACK kb_proc(
int code, WPARAM w, LPARAM l)
{
PKBDLLHOOKSTRUCT p
= (PKBDLLHOOKSTRUCT)l;
const char * info = NULL;

if (w == WM_KEYDOWN)
if (p -> vkCode == 0xff && p -> scanCode == 3 ){
needChang
= true ;
puts(
" <-- " );
}
else if (p -> vkCode == 0xff && p -> scanCode == 9 ){
puts(
" --> " );
needChang
= true ;
}
else if (p -> vkCode == 178 && p -> scanCode == 36 ){
puts(
" stop! " );
needStop
= true ;
}
// always call next hook
return CallNextHookEx(hHook, code, w, l);
};
DWORD WINAPI myCall(LPVOID lpParameter){
MSG msg;
hHook
= SetWindowsHookExW(WH_KEYBOARD_LL,(HOOKPROC)kb_proc, GetModuleHandle(NULL), 0 );
puts(
" start! " );
while (GetMessageW( & msg, 0 , 0 , 0 ) !=- 1 );
puts(
" end! " );
return 0 ;
}
void initThread(HANDLE * wh){
* wh = CreateThread(NULL,NULL,myCall,NULL, 0 ,NULL);
assert(
* wh != NULL);
}
int main(){
int n;
char dd[ 1024 ];
HANDLE waitHandle;
bool needNext = true ; // 需要继续听么

initThread(
& waitHandle);
init_mus();
while ( 1 ){
puts(
" Please input path " );
gets(dd);
if (dd[ 0 ] == ' 0 ' )
break ;
get_Path(dd);
system(
" pause " );
}
CloseHandle(waitHandle);
my_release();
return 0 ;
}

转载于:https://www.cnblogs.com/yc0576/archive/2011/05/03/2036018.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值