andyhebear1
08-02-2010 08:52:04
/*********************************************************
* Time:2010-02-08
* Author:Rains (QQ:233685340) http://hi.baidu.com/andyhebear/
* Memo:FMode声音库 管理器
**********************************************************/
using System;
using System.Collections.Generic;
//using System.Linq;
using System.Text;
using FMOD;
using FMODNet;
namespace FMODNet.Mehdi_Media_Player {
static class SoundManager {
#region 字段
private static FMOD.System system = null;
private static Sound music = null;
private static string currentPath;
private static Channel Channel = null;
public delegate void EndMusicEventHandler(object sender, EventArgs e);
public delegate void ErrorEventHandler(RESULT result);
private static CHANNEL_CALLBACK channelCallback;
public static event EndMusicEventHandler EndMusic;
public static event ErrorEventHandler EngineError;
#endregion
#region 属性
public static string CurrentPath {
get { return currentPath; }
set { currentPath = value; }
}
public static Sound Music {
get { return music; }
}
#endregion
#region Init-UpDate-Release
public static void Initialize(int NbChannel) {
RESULT result;
result = Factory.System_Create(ref system);
if (EngineError != null) EngineError(result);
uint version = 0;
result = system.getVersion(ref version);
if (EngineError != null) EngineError(result);
if (version < VERSION.number) {
throw new ApplicationException("错误!您使用的FMOD版本已经过期 " + version.ToString("X") + ". 当前最新版本是 " + VERSION.number.ToString("X") + ".");
}
result = system.init(NbChannel, INITFLAG.NORMAL, (IntPtr)null);
if (EngineError != null) EngineError(result);
channelCallback = new CHANNEL_CALLBACK(OnEndMusic);
}
public static void Update() {
RESULT result = system.update();
if (EngineError != null) EngineError(result);
}
public static void Release() {
RESULT result = RESULT.OK;
if (music != null) {
result = music.release();
if (EngineError != null) EngineError(result);
}
if (system != null)
result = system.release();
if (EngineError != null) EngineError(result);
}
#endregion
#region 主要方法
#region 播放 方法
public static void Play() {
Play(currentPath);
}
public static void Play(string path) {
Play(path, false);
}
public static void Play(string path, bool paused) {
bool isPlaying = false;
RESULT result = RESULT.OK;
if (Channel != null) {
//si la musique existe
//result = Channel.isPlaying(ref isPlaying);
isPlaying = Channel.IsPlaying;
}
else {
isPlaying = false;
}
//if (EngineError != null) EngineError(result);
if ((currentPath == path) && isPlaying)//si la musique du chemin courant est entrain detre joué
{
return;
}
else if (currentPath == path)//sinon la musique du chemin courant nest pas entrain detre joué
{
FMOD.Channel c = Channel.SoundChanel;
result = system.playSound(CHANNELINDEX.FREE, music.sound, false, ref c);
if (EngineError != null) EngineError(result);
if (Channel != null)
result = Channel.SoundChanel.setCallback(channelCallback);
if (EngineError != null) EngineError(result);
}
else {
//si cest une nouvelle musique
if (music != null) {
if (Channel != null) {
Channel.stop();
Channel = null;
}
result = music.release();
music = null;
if (EngineError != null) EngineError(result);
}
result = system.createStream(path, MODE.SOFTWARE | MODE.CREATECOMPRESSEDSAMPLE | MODE.LOOP_OFF, ref music.sound);
if (EngineError != null) EngineError(result);
FMOD.Channel c = Channel.SoundChanel;
result = system.playSound(CHANNELINDEX.FREE, music.sound, paused, ref c);
if (EngineError != null) EngineError(result);
if (Channel != null)
result = Channel.setCallback(channelCallback);
if (EngineError != null) EngineError(result);
currentPath = path;
}
}
#endregion
#region 停止方法
public static void Stop() {
if (Channel != null) {
Channel.stop();
Channel = null;
//RESULT result = Channel.stop();
//Channel = null;
//if (EngineError != null) EngineError(result);
}
}
#endregion
#region 暂停方法
public static bool GetPaused() {
bool pause = false;
if (Channel != null) {
return Channel.GetPaused();
//RESULT result = Channel.getPaused(ref pause);
//if (EngineError != null) EngineError(result);
}
return pause;
}
public static void SetPaused(bool stat) {
if (Channel != null) {
Channel.SetPaused(stat);
//RESULT result = Channel.setPaused(stat);
//if (EngineError != null) EngineError(result);
}
}
public static void SetPaused() {
bool paused = false;
if (Channel != null) {
Channel.SetPaused(!Channel.GetPaused());
//RESULT result = Channel.getPaused(ref paused);
//if (EngineError != null) EngineError(result);
//result = Channel.setPaused(!paused);
//if (EngineError != null) EngineError(result);
}
}
#endregion
#region 音量控制
public static void SetMute() {
bool mute = false;
if (Channel != null) {
Channel.setMute(!Channel.getMute());
//
//RESULT result = Channel.getMute(ref mute);
//if (EngineError != null) EngineError(result);
//result = Channel.setMute(!mute);
//if (EngineError != null) EngineError(result);
}
}
public static void SetMute(bool value) {
if (Channel != null) {
Channel.setMute(value);
//RESULT result = Channel.setMute(value);
//if (EngineError != null) EngineError(result);
}
}
public static bool GetMute() {
bool mute = false;
if (Channel != null) {
return Channel.getMute();
//RESULT result = Channel.getMute(ref mute);
//if (EngineError != null) EngineError(result);
}
return mute;
}
public static float GetVolume() {
float vol = 1.0f;
if (Channel != null) {
vol = Channel.Volume;
//RESULT result = Channel.getVolume(ref vol);
//if (EngineError != null) EngineError(result);
}
return vol;
}
public static void SetVolume(float Value) {
Value = Math.Abs(Value);
if (Channel != null) {
Channel.Volume = Value;
//RESULT result = Channel.setVolume(Value);
//if (EngineError != null) EngineError(result);
}
}
#endregion
#region 频率
public static float GetFrequency() {
float frq = 0;
if (Channel != null) {
frq = Channel.Pitch;
//RESULT result = Channel.getFrequency(ref frq);
//if (EngineError != null) EngineError(result);
}
return ((frq * 100.0f) / 48000);
}
public static void SetFrequency(float freq) {
if (Channel != null) {
Channel.Pitch=(freq * 48000 / 100.0f);
//RESULT result = Channel.setFrequency(freq * 48000 / 100.0f);
//if (EngineError != null) EngineError(result);
}
}
#endregion
#region 位置
public static void SetPosition(uint pos) {
uint ln = 0;
if (music != null) ln=(uint)music.Length;//getLength(ref ln, TIMEUNIT.MS);
pos = (ln * pos / 100);
if (Channel != null) {
Channel.Position = (int)pos;
//RESULT result = Channel.setPosition(pos, TIMEUNIT.MS);
//if (EngineError != null) EngineError(result);
}
}
public static uint GetPosition() {
uint ln = 0;
uint ms = 0;
if (music != null) {
//RESULT result = music.getLength(ref ln, TIMEUNIT.MS);
//if (EngineError != null) EngineError(result);
ms = GetMsPosition();
ms = (100 * ms / ln);
}
else
ms = 0;
return ms;
}
public static void SetMsPosition(uint ms) {
if (Channel != null) {
Channel.Position = (int)ms;
//RESULT result = Channel.setPosition(ms, TIMEUNIT.MS);
//if (EngineError != null) EngineError(result);
}
}
public static uint GetMsPosition() {
uint ms = 0;
if (Channel != null) {
//RESULT result = Channel.getPosition(ref ms, TIMEUNIT.MS);
//if (EngineError != null) EngineError(result);
return (uint)Channel.Position;
}
return ms;
}
public static uint GetLength() {
uint ln = 0;
if (music != null) ln=(uint)music.Length;//getLength(ref ln, TIMEUNIT.MS);
return ln;
}
#endregion
#endregion
#region 事件
//RESULT CHANNEL_CALLBACK(IntPtr channelraw, CHANNEL_CALLBACKTYPE type, IntPtr commanddata1, IntPtr commanddata2);
private static RESULT OnEndMusic(IntPtr channelraw, FMOD.CHANNEL_CALLBACKTYPE type, IntPtr commanddata1, IntPtr commanddata2) {
Channel = null;//
if (EndMusic != null)
EndMusic(currentPath, new EventArgs());
return RESULT.OK;
}
#endregion
#region 错误提示
public static void ShowErrorException(RESULT result) {
if (result != RESULT.OK) {
throw new ApplicationException("Sound Manager Error! " + result + " - " + Error.String(result));
}
}
public static void ShowErrorDialogBox(RESULT result, string AppName) {
if (result != RESULT.OK) {
System.Windows.Forms.MessageBox.Show("Sound Manager Error! " + result + " - " + Error.String(result), AppName, System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
}
}
#endregion
#region 其他
public static bool IsPlaying() {
bool ply = false;
if (Channel != null) {
return Channel.IsPlaying;
//RESULT result = Channel.isPlaying(ref ply);
//if (EngineError != null) EngineError(result);
}
return ply;
}
#endregion
}
}