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 ;
}
#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 ;
}