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