Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Diagnostics;
- using System.IO;
- using System.Runtime.CompilerServices;
- using System.Runtime.InteropServices;
- using System.Text;
- namespace ForeverZer0.Audio
- {
- public class MciPlayer : IDisposable, IComparable<MciPlayer>
- {
- #region DLL Imports
- /// <summary>
- /// Hook for sending MCI commands
- /// </summary>
- /// <param name="strCommand">The command to make</param>
- /// <param name="strReturn">Any data returned by the command</param>
- /// <param name="iReturnLength">The maximum size of the return data</param>
- /// <param name="hwndCallback">A handle to a window that will recieve notifications</param>
- /// <returns>The error code from the command</returns>
- [DllImport("winmm.dll")]
- private static extern long mciSendString(string strCommand, StringBuilder strReturn,
- int iReturnLength, IntPtr hwndCallback);
- /// <summary>
- /// Gets error messages associated with MCI error codes
- /// </summary>
- /// <param name="errCode">The MCI error code</param>
- /// <param name="strReturn">Any data returned by the command</param>
- /// <param name="iReturnLength">The maximum size of the return data</param>
- /// <returns>Integer that represents true/false if call was successful</returns>
- [DllImport("winmm.dll")]
- public static extern int mciGetErrorString(int errCode, StringBuilder strReturn,
- int iReturnLength);
- #endregion
- #region Constants
- /// <summary>
- /// The size of the buffer to use for return values
- /// </summary>
- public const int BUFFER_SIZE = 128;
- #endregion
- #region Private Properties
- private string _name, _filename, _cmd, _errorMessage;
- private StringBuilder _buffer, _errorBuffer, _log;
- private IntPtr _windowHandle;
- private bool _disposed;
- #endregion
- #region Public Properties
- /// <summary>
- /// Gets or sets the master volume. Values outside of 0 to 1000 will be automatically corrected.
- /// </summary>
- public int Volume { get { return GetVolume(); } set { SetVolume(value); } }
- /// <summary>
- /// Gets or sets the left volume. Values outside of 0 to 1000 will be automatically corrected.
- /// </summary>
- public int VolumeLeft { get { return GetVolumeLeft(); } set { SetVolumeLeft(value); } }
- /// <summary>
- /// Gets or sets the right volume. Values outside of 0 to 1000 will be automatically corrected.
- /// </summary>
- public int VolumeRight { get { return GetVolumeRight(); } set { SetVolumeRight(value); } }
- /// <summary>
- /// Gets or sets the speed of playaback. Values outside of 0 to 2000 will be automatically corrected.
- /// </summary>
- public int Speed { get { return GetSpeed(); } set { SetSpeed(value); } }
- /// <summary>
- /// Gets or sets the treble. Values outside of 0 to 2000 will be automatically corrected.
- /// </summary>
- public int Treble { get { return GetTreble(); } set { SetTreble(value); } }
- /// <summary>
- /// Gets or sets the bass. Values outside of 0 to 2000 will be automatically corrected.
- /// </summary>
- public int Bass { get { return GetBass(); } set { SetBass(value); } }
- /// <summary>
- /// Gets or sets the current millisecond position of playback
- /// </summary>
- public long Position { get { return GetPosition(); } set { SetPosition(value); } }
- /// <summary>
- /// Gets the length of the file in milliseconds
- /// </summary>
- public long Length { get { return GetLength(); } }
- /// <summary>
- /// Gets or sets the path of the current file.
- /// </summary>
- public string Filename { get { return _filename; } set { Load(value); } }
- /// <summary>
- /// Gets or sets repeat mode
- /// </summary>
- public bool Repeat { get; set; }
- /// <summary>
- /// Gets the status of the mixer as a string
- /// </summary>
- public MciStatus Status { get { return GetStatus(); } }
- /// <summary>
- /// Gets or sets the window handle that will receive notifications
- /// </summary>
- public IntPtr WindowHandle { get { return _windowHandle; } set { _windowHandle = value; } }
- /// <summary>
- /// Enables logging functions for the mixer.
- /// </summary>
- /// <remarks>Having logging enabled can degrade performance</remarks>
- public bool LoggingEnabled { get; set; }
- /// <summary>
- /// Gets the log buffer as a string
- /// </summary>
- public string Log { get { return _log.ToString(); } }
- #endregion
- #region Construction
- /// <summary>
- /// Creates and returns a new instance of the mixer
- /// </summary>
- /// <param name="name">The alias name of the mixer</param>
- /// <param name="handle">The handle of the window to recieve notifications from the player</param>
- public MciPlayer(string name, IntPtr handle)
- {
- _name = name;
- _buffer = new StringBuilder(BUFFER_SIZE);
- _errorBuffer = new StringBuilder(BUFFER_SIZE);
- _windowHandle = handle;
- _disposed = false;
- _log = new StringBuilder();
- }
- /// <summary>
- /// Creates and returns a new instance of the mixer
- /// </summary>
- /// <param name="name">The alias name of the mixer</param>
- public MciPlayer(string name) : this(name, IntPtr.Zero) { }
- #endregion
- #region Playback Control
- /// <summary>
- /// Loads a file and readies it for playback
- /// </summary>
- /// <param name="filename">The path to the file</param>
- public void Load(string filename)
- {
- if (_disposed)
- throw new ObjectDisposedException(_name);
- this.Close();
- _filename = filename;
- _cmd = String.Format("open \"{0}\" type mpegvideo alias {1} notify", _filename, _name);
- LogError(mciSendString(_cmd, null, 0, WindowHandle));
- OnOpen(new OnOpenEventArgs(_filename));
- }
- /// <summary>
- /// Begins playback of a loaded file
- /// </summary>
- /// <param name="repeat">Flag to repeat playback when file is done playing</param>
- /// <param name="position">The millisecond to begin playback at</param>
- public void Play(bool repeat, int position)
- {
- if (_disposed)
- throw new ObjectDisposedException(_name);
- if (!File.Exists(_filename))
- return;
- Repeat = repeat;
- _cmd = String.Format("seek {0} to {1} notify", _name, position == 0 ? "start" : position.ToString());
- LogError(mciSendString(_cmd, null, 0, WindowHandle));
- _cmd = String.Format("play {0} notify{1}", _name, repeat ? " repeat" : "");
- LogError(mciSendString(_cmd, null, 0, WindowHandle));
- OnPlay(new OnPlayEventArgs(_filename, GetLength()));
- }
- /// <summary>
- /// Begins playback of a loaded file
- /// </summary>
- /// <param name="repeat">Flag to repeat playback when file is done playing</param>
- public void Play(bool repeat) { Play(repeat, 0); }
- /// <summary>
- /// Begins playback of a loaded file
- /// </summary>
- public void Play() { Play(false, 0); }
- /// <summary>
- /// Pause playback while maintaining current position
- /// </summary>
- public void Pause()
- {
- _cmd = String.Format("pause {0} notify", _name);
- LogError(mciSendString(_cmd, null, 0, WindowHandle));
- OnPause(new OnPauseEventArgs(GetPosition(), false));
- }
- /// <summary>
- /// Resume playback on a paused mixer
- /// </summary>
- public void Resume()
- {
- _cmd = String.Format("resume {0} notify", _name);
- LogError(mciSendString(_cmd, null, 0, WindowHandle));
- OnPause(new OnPauseEventArgs(GetPosition(), true));
- }
- /// <summary>
- /// Sets the millisecond of the current playback position
- /// </summary>
- /// <param name="millisecond">The millisecond position</param>
- public void Seek(long millisecond)
- {
- SetPosition(millisecond);
- }
- /// <summary>
- /// Stops playback and moves the current position back to the beginning of the file
- /// </summary>
- public void Stop()
- {
- _cmd = String.Format("seek {0} to start notify", _name);
- LogError(mciSendString(_cmd, null, 0, WindowHandle));
- _cmd = String.Format("stop {0} notify", _name);
- LogError(mciSendString(_cmd, null, 0, WindowHandle));
- OnStop(new EventArgs());
- }
- /// <summary>
- /// Stops playback and destroys the player
- /// </summary>
- public void Close()
- {
- _cmd = String.Format("close {0} notify", _name);
- LogError(mciSendString(_cmd, null, 0, WindowHandle));
- _filename = null;
- OnClose(new EventArgs());
- }
- /// <summary>
- /// Closes any files opened in the mixer
- /// </summary>
- public void Dispose()
- {
- if (!_disposed)
- {
- this.Close();
- _disposed = true;
- GC.SuppressFinalize(this);
- }
- }
- /// <summary>
- /// Begins recording from the input
- /// </summary>
- /// <param name="bits">The bits per sample for the recording</param>
- /// <param name="sampleRate">The sample rate of the recording</param>
- /// <param name="channels">The number of channels of the recording</param>
- public void Record(int bits, int sampleRate, int channels)
- {
- this.Close();
- _cmd = String.Format("open new type waveaudio alias {0}", _name);
- LogError(mciSendString(_cmd, null, 0, WindowHandle));
- _cmd = String.Format("set {0} bitspersample {1}", _name, bits);
- LogError(mciSendString(_cmd, null, 0, WindowHandle));
- _cmd = String.Format("set {0} samplespersec {1}", _name, sampleRate);
- LogError(mciSendString(_cmd, null, 0, WindowHandle));
- _cmd = String.Format("set {0} channels {1}", _name, channels);
- LogError(mciSendString(_cmd, null, 0, WindowHandle));
- _cmd = String.Format("record {0} notify", _name);
- LogError(mciSendString(_cmd, null, 0, WindowHandle));
- OnRecord(new OnRecordEventArgs(bits, sampleRate, channels));
- }
- /// <summary>
- /// Begins recording from the input
- /// </summary>
- /// <param name="bits">The bits per sample for the recording</param>
- /// <param name="sampleRate">The sample rate of the recording</param>
- public void Record(int bits, int sampleRate) { Record(bits, sampleRate, 2); }
- /// <summary>
- /// Begins recording from the input
- /// </summary>
- /// <param name="bits">The bits per sample for the recording</param>
- public void Record(int bits) { Record(bits, 44100, 2); }
- /// <summary>
- /// Begins recording from the input
- /// </summary>
- public void Record() { Record(16, 44100, 2); }
- /// <summary>
- /// Saves a recorded file to disk in WAV format
- /// </summary>
- /// <param name="filename">The path of the file to save</param>
- /// <remarks>The WAV extension will be added if path does not have it</remarks>
- public void SaveRecording(string filename)
- {
- if (IsRecording())
- this.Stop();
- string ext = Path.GetExtension(filename);
- if (ext != ".wav")
- {
- filename = Path.Combine(Path.GetDirectoryName(filename),
- Path.GetFileNameWithoutExtension(filename) + ".wav");
- }
- _cmd = String.Format("save {0} {1}", _name, filename);
- LogError(mciSendString(_cmd, null, 0, WindowHandle));
- _cmd = String.Format("close {0}", _name);
- LogError(mciSendString(_cmd, null, 0, WindowHandle));
- }
- /// <summary>
- /// Mutes/unmutes all sound while continuing to play
- /// </summary>
- /// <param name="on">Flag to enable/disable sound</param>
- public void Mute(bool on)
- {
- _cmd = String.Format("setaudio {0} {1}", _name, on ? "off" : "on");
- LogError(mciSendString(_cmd, null, 0, WindowHandle));
- }
- /// <summary>
- /// Mutes/unmutes all sound on the left channel while continuing to play
- /// </summary>
- /// <param name="on">Flag to enable/disable sound</param>
- public void MuteLeft(bool on)
- {
- _cmd = String.Format("setaudio {0} left {1}", _name, on ? "off" : "on");
- LogError(mciSendString(_cmd, null, 0, WindowHandle));
- }
- /// <summary>
- /// Mutes/unmutes all sound on the right channel while continuing to play
- /// </summary>
- /// <param name="on">Flag to enable/disable sound</param>
- public void MuteRight(bool on)
- {
- _cmd = String.Format("setaudio {0} right {1}", _name, on ? "off" : "on");
- LogError(mciSendString(_cmd, null, 0, WindowHandle));
- }
- #endregion
- #region Setters
- /// <summary>
- /// Sets the master volume of the mixer
- /// </summary>
- /// <param name="volume">The volume to set. A value between 0 and 1000.
- /// Values outside this range will be automatically corrected</param>
- public void SetVolume(int volume)
- {
- volume = Clamp<int>(volume, 0, 1000);
- _cmd = String.Format("setaudio {0} volume to {1} notify", _name, volume);
- LogError(mciSendString(_cmd, null, 0, WindowHandle));
- }
- /// <summary>
- /// Sets the left volume of the mixer
- /// </summary>
- /// <param name="volume">The volume to set. A value between 0 and 1000.
- /// Values outside this range will be automatically corrected</param>
- public void SetVolumeLeft(int volume)
- {
- volume = Clamp<int>(volume, 0, 1000);
- _cmd = String.Format("setaudio {0} left volume to {1} notify", _name, volume);
- LogError(mciSendString(_cmd, null, 0, WindowHandle));
- }
- /// <summary>
- /// Sets the right volume of the mixer
- /// </summary>
- /// <param name="volume">The volume to set. A value between 0 and 1000.
- /// Values outside this range will be automatically corrected</param>
- public void SetVolumeRight(int volume)
- {
- volume = Clamp<int>(volume, 0, 1000);
- _cmd = String.Format("setaudio {0} right volume to {1} notify", _name, volume);
- LogError(mciSendString(_cmd, null, 0, WindowHandle));
- }
- /// <summary>
- /// Sets the playback speed of the mixer
- /// </summary>
- /// <param name="volume">The speed ratio to set. A value between 0 and 2000, where 1000 is normal.
- /// Values outside this range will be automatically corrected</param>
- public void SetSpeed(int speed)
- {
- speed = Clamp<int>(speed, 0, 2000);
- _cmd = String.Format("set {0} speed {1} notify", _name, speed);
- LogError(mciSendString(_cmd, null, 0, WindowHandle));
- }
- /// <summary>
- /// Sets the treble of the mixer
- /// </summary>
- /// <param name="volume">The treble value to set. A value between 0 and 2000, where 1000 is normal.
- /// Values outside this range will be automatically corrected</param>
- public void SetTreble(int treble)
- {
- treble = Clamp<int>(treble, 0, 1000);
- _cmd = String.Format("setaudio {0} treble to {1} notify", _name, treble);
- LogError(mciSendString(_cmd, null, 0, WindowHandle));
- }
- /// <summary>
- /// Sets the bass of the mixer
- /// </summary>
- /// <param name="volume">The bass value to set. A value between 0 and 2000, where 1000 is normal.
- /// Values outside this range will be automatically corrected</param>
- public void SetBass(int bass)
- {
- bass = Clamp<int>(bass, 0, 1000);
- _cmd = String.Format("setaudio {0} bass to {1} notify", _name, bass);
- LogError(mciSendString(_cmd, null, 0, WindowHandle));
- }
- /// <summary>
- /// Sets the millisecond of the current playback position
- /// </summary>
- /// <param name="position">The millisecond position</param>
- public void SetPosition(long position)
- {
- long current = GetPosition();
- position = Clamp<long>(position, 0, this.GetLength());
- _cmd = String.Format("{0} {1} from {2} notify", IsPlaying() ? "play" : "seek", _name, position);
- LogError(mciSendString(_cmd, null, 0, WindowHandle));
- OnSeek(new OnSeekEventArgs(current, position));
- }
- #endregion
- #region Getters
- /// <summary>
- /// Gets the master volume (0 - 1000)
- /// </summary>
- /// <returns>The master volume</returns>
- public int GetVolume()
- {
- _buffer.Clear();
- _cmd = String.Format("status {0} volume", _name);
- LogError(mciSendString(_cmd, _buffer, BUFFER_SIZE, IntPtr.Zero));
- string value = _buffer.ToString();
- if (String.IsNullOrEmpty(value))
- return 0;
- return Convert.ToInt32(value);
- }
- /// <summary>
- /// Gets the volume of the left channel only (0 - 1000)
- /// </summary>
- /// <returns>The left channel volume</returns>
- public int GetVolumeLeft()
- {
- _buffer.Clear();
- _cmd = String.Format("status {0} volume left", _name);
- LogError(mciSendString(_cmd, _buffer, BUFFER_SIZE, IntPtr.Zero));
- string value = _buffer.ToString();
- if (String.IsNullOrEmpty(value))
- return 0;
- return Convert.ToInt32(value);
- }
- /// <summary>
- /// Gets the volume of the right channel only (0 - 1000)
- /// </summary>
- /// <returns>The right channel volume</returns>
- public int GetVolumeRight()
- {
- _buffer.Clear();
- _cmd = String.Format("status {0} volume right", _name);
- LogError(mciSendString(_cmd, _buffer, BUFFER_SIZE, IntPtr.Zero));
- string value = _buffer.ToString();
- if (String.IsNullOrEmpty(value))
- return 0;
- return Convert.ToInt32(value);
- }
- /// <summary>
- /// Gets the speed of playback (1000 = normal speed)(0 - 2000)
- /// </summary>
- /// <returns>The speed of playback</returns>
- public int GetSpeed()
- {
- _buffer.Clear();
- _cmd = String.Format("status {0} speed", _name);
- LogError(mciSendString(_cmd, _buffer, BUFFER_SIZE, IntPtr.Zero));
- string value = _buffer.ToString();
- if (String.IsNullOrEmpty(value))
- return 0;
- return Convert.ToInt32(value);
- }
- /// <summary>
- /// Gets the treble volume (0 - 2000)
- /// </summary>
- /// <returns>The treble volume</returns>
- public int GetTreble()
- {
- _buffer.Clear();
- _cmd = String.Format("status {0} treble", _name);
- LogError(mciSendString(_cmd, _buffer, BUFFER_SIZE, IntPtr.Zero));
- string value = _buffer.ToString();
- if (String.IsNullOrEmpty(value))
- return 0;
- return Convert.ToInt32(value);
- }
- /// <summary>
- /// Gets the bass volume (0 - 2000)
- /// </summary>
- /// <returns>The bass volume</returns>
- public int GetBass()
- {
- _buffer.Clear();
- _cmd = String.Format("status {0} bass", _name);
- LogError(mciSendString(_cmd, _buffer, BUFFER_SIZE, IntPtr.Zero));
- string value = _buffer.ToString();
- if (String.IsNullOrEmpty(value))
- return 0;
- return Convert.ToInt32(value);
- }
- /// <summary>
- /// Gets the current position of playback in milliseconds
- /// </summary>
- /// <returns>The current position</returns>
- public long GetPosition()
- {
- _buffer.Clear();
- if (IsPlaying() || IsPaused())
- {
- _cmd = String.Format("status {0} position", _name);
- LogError(mciSendString(_cmd, _buffer, BUFFER_SIZE, IntPtr.Zero));
- string value = _buffer.ToString();
- if (String.IsNullOrEmpty(value))
- return 0L;
- return Convert.ToInt64(value);
- }
- return 0L;
- }
- /// <summary>
- /// Gets the length of the currently opened file in milliseconds
- /// </summary>
- /// <returns>The number of milliseconds of the file as <paramref name="System.Int64"/></returns>
- public long GetLength()
- {
- _buffer.Clear();
- _cmd = String.Format("status {0} length", _name);
- LogError(mciSendString(_cmd, _buffer, BUFFER_SIZE, IntPtr.Zero));
- string value = _buffer.ToString();
- if (String.IsNullOrEmpty(value))
- return 0L;
- return Convert.ToInt64(value);
- }
- /// <summary>
- /// Gets the volume of the left channel
- /// </summary>
- /// <returns>The volume of the left channel as a <paramref name="System.Int32"/></returns>
- public int GetLeftVolume()
- {
- _buffer.Clear();
- _cmd = String.Format("status {0} left volume", _name);
- LogError(mciSendString(_cmd, _buffer, BUFFER_SIZE, IntPtr.Zero));
- string value = _buffer.ToString();
- if (String.IsNullOrEmpty(value))
- return 0;
- return Convert.ToInt32(value);
- }
- /// <summary>
- /// Gets the volume of the right channel
- /// </summary>
- /// <returns>The volume of the right channel as a <paramref name="System.Int32"/></returns>
- public int GetRightVolume()
- {
- _buffer.Clear();
- _cmd = String.Format("status {0} right volume", _name);
- LogError(mciSendString(_cmd, _buffer, BUFFER_SIZE, IntPtr.Zero));
- string value = _buffer.ToString();
- if (String.IsNullOrEmpty(value))
- return 0;
- return Convert.ToInt32(value);
- }
- #endregion
- #region Status
- /// <summary>
- /// Gets the "playing" state of the mixer
- /// </summary>
- /// <returns>The "plaing" state of the mixer as <paramref name="System.Bool"/></returns>
- public bool IsPlaying()
- {
- return this.GetStatus() == MciStatus.Playing;
- }
- /// <summary>
- /// Gets the "pause" state of the mixer
- /// </summary>
- /// <returns>The "pause" state of the mixer as <paramref name="System.Bool"/></returns>
- public bool IsPaused()
- {
- return this.GetStatus() == MciStatus.Paused;
- }
- /// <summary>
- /// Gets the "recording" state of the mixer
- /// </summary>
- /// <returns>The "recording" state of the mixer as <paramref name="System.Bool"/></returns>
- public bool IsRecording()
- {
- return this.GetStatus() == MciStatus.Recording;
- }
- /// <summary>
- /// Gets the current status of the mixer
- /// </summary>
- /// <returns>The current state of the mixer as a <paramref name="MCI_Player.MciStatus"/></returns>
- public MciStatus GetStatus()
- {
- _buffer.Clear();
- _cmd = String.Format("status {0} mode", _name);
- LogError(mciSendString(_cmd, _buffer, BUFFER_SIZE, IntPtr.Zero));
- switch (_buffer.ToString().Trim())
- {
- case "playing": return MciStatus.Playing;
- case "not ready": return MciStatus.NotReady;
- case "paused": return MciStatus.Paused;
- case "recording": return MciStatus.Recording;
- case "seeking": return MciStatus.Seeking;
- case "parked": return MciStatus.Parked;
- case "open": return MciStatus.Open;
- default: return MciStatus.Stopped;
- }
- }
- #endregion
- #region Utilities
- /// <summary>
- /// IComparable interface. Simply compares alias names used by MCI
- /// </summary>
- /// <param name="other">MCIPlayer to compare to</param>
- /// <returns>Result of comparison</returns>
- public int CompareTo(MciPlayer other)
- {
- return _name.CompareTo(other._name);
- }
- /// <summary>
- /// Clamp to values of type T within a defined range
- /// </summary>
- /// <typeparam name="T">The <see cref="System.Type"/> of the that will be passed and returned. Must implement the <see cref="System.IComparable"/> interface</typeparam>
- /// <param name="val">The value to clamp</param>
- /// <param name="min">The minimum allowed value</param>
- /// <param name="max">The maximum allowed value</param>
- /// <returns>The value clamped between the minimum and maximum</returns>
- public static T Clamp<T>(T val, T min, T max) where T : IComparable<T>
- {
- if (val.CompareTo(min) < 0) return min;
- else if (val.CompareTo(max) > 0) return max;
- else return val;
- }
- /// <summary>
- /// Returns the length of the file as a string formatted as M:SS.
- /// </summary>
- /// <returns>The formatted string</returns>
- public string FormattedLength()
- {
- long length = GetLength() / 1000;
- return String.Format("{0}:{1:d2}", length / 60, length % 60);
- }
- /// <summary>
- /// Returns the current postion of playback as a string formatted as M:SS.
- /// </summary>
- /// <returns>The formatted string</returns>
- public string FormattedPosition()
- {
- long pos = GetPosition() / 1000;
- return String.Format("{0}:{1:d2}", pos / 60, pos % 60);
- }
- /// <summary>
- /// Evaluates an MCI command and returns any data received
- /// </summary>
- /// <param name="command">The <paramref name="System.String"/> MCI command</param>
- /// <returns>Any data that is returned by result of the command, else an empty string</returns>
- public string MciEvaluate(string command)
- {
- _buffer.Clear();
- LogError(mciSendString(command, _buffer, BUFFER_SIZE, WindowHandle));
- return _buffer.ToString();
- }
- #endregion
- #region Logging
- /// <summary>
- /// Clears the log buffer.
- /// </summary>
- public void ClearLog()
- {
- _log.Clear();
- }
- /// <summary>
- /// Saves the log to disk
- /// </summary>
- /// <param name="filename">The path to the file to writw</param>
- /// <returns>Flag if save was successful</returns>
- public bool SaveLog(string filename)
- {
- try
- {
- File.WriteAllText(filename, _log.ToString());
- return true;
- }
- catch { return false; }
- }
- /// <summary>
- /// Evaluates and adds an entry to the log
- /// </summary>
- /// <param name="error">The MCI error code to evaluate</param>
- [MethodImpl(MethodImplOptions.NoInlining)]
- private void LogError(long error)
- {
- if (LoggingEnabled && error != 0)
- {
- _errorBuffer.Clear();
- mciGetErrorString((int)error, _errorBuffer, BUFFER_SIZE);
- _errorMessage = _errorBuffer.ToString();
- if (_errorMessage != "The specified command was carried out.")
- {
- string function = new StackFrame(1, true).GetMethod().Name;
- _log.AppendFormat("{0} in \"{1}\"\n{2}\n\n", DateTime.Now, function, _errorMessage);
- Console.WriteLine(_errorBuffer.ToString());
- }
- }
- }
- #endregion
- #region Delegates
- public delegate void OnOpenEventHandler(object sender, OnOpenEventArgs e);
- public delegate void OnPlayEventHandler(object sender, OnPlayEventArgs e);
- public delegate void OnPauseEventHandler(object sender, EventArgs e);
- public delegate void OnStopEventHandler(object sender, EventArgs e);
- public delegate void OnCloseEventHandler(object sender, EventArgs e);
- public delegate void OnSeekEventHandler(object sender, OnSeekEventArgs e);
- public delegate void OnRecordEventHandler(object sender, OnRecordEventArgs e);
- #endregion
- #region Events
- /// <summary>
- /// Occurs when a file is opened by the player
- /// </summary>
- public event OnOpenEventHandler OnOpenEvent;
- /// <summary>
- /// Occurs when playback begins
- /// </summary>
- public event OnPlayEventHandler OnPlayEvent;
- /// <summary>
- /// Occurs when playback is paused or resumed
- /// </summary>
- public event OnPauseEventHandler OnPauseEvent;
- /// <summary>
- /// Occurs when the player is stopped
- /// </summary>
- public event OnStopEventHandler OnStopEvent;
- /// <summary>
- /// Occurs when the player is closed
- /// </summary>
- public event OnCloseEventHandler OnCloseEvent;
- /// <summary>
- /// Occurs when the seek function is used
- /// </summary>
- public event OnSeekEventHandler OnSeekEvent;
- /// <summary>
- /// Occurs when the player begins recording
- /// </summary>
- public event OnRecordEventHandler OnRecordEvent;
- protected virtual void OnOpen(OnOpenEventArgs e)
- {
- if (OnOpenEvent != null) OnOpenEvent(this, e);
- }
- protected virtual void OnPlay(OnPlayEventArgs e)
- {
- if (OnPlayEvent != null) OnPlayEvent(this, e);
- }
- protected virtual void OnPause(EventArgs e)
- {
- if (OnPauseEvent != null) OnPauseEvent(this, e);
- }
- protected virtual void OnStop(EventArgs e)
- {
- if (OnStopEvent != null) OnStopEvent(this, e);
- }
- protected virtual void OnClose(EventArgs e)
- {
- if (OnCloseEvent != null) OnCloseEvent(this, e);
- }
- protected virtual void OnSeek(OnSeekEventArgs e)
- {
- if (OnSeekEvent != null) OnSeekEvent(this, e);
- }
- protected virtual void OnRecord(OnRecordEventArgs e)
- {
- if (OnRecordEvent != null) OnRecordEvent(this, e);
- }
- #endregion
- }
- #region Event Arguments
- public class OnOpenEventArgs : EventArgs
- {
- /// <summary>
- /// Gets the full path to the opened file
- /// </summary>
- public string Filepath { get { return _filename; } }
- /// <summary>
- /// Gets the name of the file opened
- /// </summary>
- public string Filename { get { return Path.GetFileName(_filename); } }
- /// <summary>
- /// Gets the name of the file opened without file extension
- /// </summary>
- public string FilenameWithouExtension
- {
- get { return Path.GetFileNameWithoutExtension(_filename); }
- }
- /// <summary>
- /// Gets the file extension of the opened file
- /// </summary>
- public string Extension { get { return Path.GetExtension(_filename); } }
- /// <summary>
- /// Gets the directory of the opened file
- /// </summary>
- public string Directory { get { return Path.GetDirectoryName(_filename); } }
- private string _filename;
- /// <summary>
- /// Event arguments for opening a file
- /// </summary>
- /// <param name="filename">The path to the file</param>
- public OnOpenEventArgs(string filename)
- {
- _filename = filename;
- }
- }
- public class OnPlayEventArgs : EventArgs
- {
- /// <summary>
- /// The path to the file being played
- /// </summary>
- public string Filename { get { return _filename; } }
- /// <summary>
- /// The length of the file in milliseconds
- /// </summary>
- public long Length { get { return _length; } }
- private string _filename;
- private long _length;
- /// <summary>
- /// Event arguments for playing
- /// </summary>
- /// <param name="filename">The path to the file being played</param>
- /// <param name="length">The length of the file in milliseconds</param>
- public OnPlayEventArgs(string filename, long length)
- {
- _filename = filename;
- _length = length;
- }
- }
- public class OnPauseEventArgs : EventArgs
- {
- /// <summary>
- /// The current position in milliseconds of playback
- /// </summary>
- public long Position { get { return _position; } }
- /// <summary>
- /// Flag if file is being paused or resumed
- /// </summary>
- public bool Resuming { get { return _resuming; } }
- private long _position;
- private bool _resuming;
- /// <summary>
- /// Event arguments for pausing and resuming
- /// </summary>
- /// <param name="position">The current position in milliseconds of playback</param>
- /// <param name="resuming">Flag if file is being paused or resumed</param>
- public OnPauseEventArgs(long position, bool resuming)
- {
- _position = position;
- _resuming = resuming;
- }
- }
- public class OnSeekEventArgs : EventArgs
- {
- /// <summary>
- /// Gets the position in milliseconds of playback before the change
- /// </summary>
- public long CurrentPosition { get { return _current; } }
- /// <summary>
- /// Gets the position in milliseconds of playback after the change
- /// </summary>
- public long TargetPosition { get { return _target; } }
- private long _current;
- private long _target;
- /// <summary>
- /// Event arguments for seeking
- /// </summary>
- /// <param name="current">The position in milliseconds of playback before the change</param>
- /// <param name="target">The position in milliseconds of playback after the change</param>
- public OnSeekEventArgs(long current, long target)
- {
- _current = current;
- _target = target;
- }
- }
- public class OnRecordEventArgs : EventArgs
- {
- /// <summary>
- /// Gets the number of bits per sample of the recording
- /// </summary>
- public int BitsPerSample { get { return _bitsPerSample; } }
- /// <summary>
- /// Gets the samplerate of the recording
- /// </summary>
- public int SampleRate { get { return _sampleRate; } }
- /// <summary>
- /// Gets the number of channels used for the recording
- /// </summary>
- public int Channels { get { return _channels; } }
- private int _bitsPerSample;
- private int _sampleRate;
- private int _channels;
- /// <summary>
- /// Event arguments for recording
- /// </summary>
- /// <param name="bitsPerSample">The number of bits used per sample</param>
- /// <param name="sampleRate">The sample rate</param>
- /// <param name="channels">The number of channels used for recording</param>
- public OnRecordEventArgs(int bitsPerSample, int sampleRate, int channels)
- {
- _bitsPerSample = bitsPerSample;
- _sampleRate = sampleRate;
- _channels = channels;
- }
- }
- #endregion
- # region Enums
- public enum MciNotify
- {
- Notify = 0x03b9,
- Success = 0x01,
- Superseded = 0x02,
- Aborted = 0x04,
- Failure = 0x08
- }
- public enum MciStatus
- {
- Playing,
- Stopped,
- Paused,
- Recording,
- NotReady,
- Open,
- Parked,
- Seeking
- }
- #endregion
- }
Advertisement
Add Comment
Please, Sign In to add comment