--- /dev/null
+// \r
+// Radegast Metaverse Client\r
+// Copyright (c) 2009, Radegast Development Team\r
+// All rights reserved.\r
+// \r
+// Redistribution and use in source and binary forms, with or without\r
+// modification, are permitted provided that the following conditions are met:\r
+// \r
+// * Redistributions of source code must retain the above copyright notice,\r
+// this list of conditions and the following disclaimer.\r
+// * Redistributions in binary form must reproduce the above copyright\r
+// notice, this list of conditions and the following disclaimer in the\r
+// documentation and/or other materials provided with the distribution.\r
+// * Neither the name of the application "Radegast", nor the names of its\r
+// contributors may be used to endorse or promote products derived from\r
+// this software without specific prior written permission.\r
+// \r
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\r
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\r
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\r
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+//\r
+// $Id: Sound.cs 502 2010-03-14 23:13:46Z latifer $\r
+//\r
+using System;\r
+using System.Runtime.InteropServices;\r
+using FMOD;\r
+using OpenMetaverse;\r
+\r
+namespace Radegast.Media\r
+{\r
+\r
+ public class BufferSound : MediaObject\r
+ {\r
+ /// <summary>\r
+ /// Is sound currently playing\r
+ /// </summary>\r
+ public bool Playing { get { return playing; } }\r
+ private bool playing = false;\r
+\r
+ /// <summary>\r
+ /// Is sound currently paused\r
+ /// </summary>\r
+ public bool Paused { get { return paused; } }\r
+ private bool paused = false;\r
+\r
+ private bool soundcreated = false;\r
+ private System.Timers.Timer timer;\r
+\r
+ private FMOD.CREATESOUNDEXINFO extendedInfo;\r
+\r
+ /// <summary>\r
+ /// Creates a new sound object\r
+ /// </summary>\r
+ /// <param name="system">Sound system</param>\r
+ public BufferSound()\r
+ :base()\r
+ {\r
+ timer = new System.Timers.Timer();\r
+ timer.Interval = 50d;\r
+ timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);\r
+ timer.Enabled = false;\r
+ }\r
+\r
+\r
+ /// <summary>\r
+ /// Releases resources of this sound object\r
+ /// </summary>\r
+ public override void Dispose()\r
+ {\r
+ if (timer != null)\r
+ {\r
+ timer.Enabled = false;\r
+ timer.Dispose();\r
+ timer = null;\r
+ }\r
+\r
+ if (sound != null)\r
+ {\r
+ sound.release();\r
+ sound = null;\r
+ }\r
+ base.Dispose();\r
+ }\r
+\r
+ /// <summary>\r
+ /// Plays audio buffer\r
+ /// </summary>\r
+ /// <param name="url">URL of the stream</param>\r
+ public void Play( byte[] buffer, bool loop)\r
+ {\r
+ extendedInfo.format = SOUND_FORMAT.PCM16;\r
+\r
+ invoke(new SoundDelegate(delegate\r
+ {\r
+ MediaManager.FMODExec(system.createSound(buffer,\r
+ (MODE.HARDWARE | MODE._3D | MODE.NONBLOCKING),\r
+ ref extendedInfo,\r
+ ref sound));\r
+ }));\r
+ }\r
+\r
+ /// <summary>\r
+ /// Toggles sound pause\r
+ /// </summary>\r
+ public void TogglePaused()\r
+ {\r
+ if (channel != null)\r
+ {\r
+ channel.getPaused(ref paused);\r
+ channel.setPaused(!paused);\r
+ }\r
+ }\r
+\r
+ void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)\r
+ {\r
+ OPENSTATE openstate = 0;\r
+ uint percentbuffered = 0;\r
+ bool starving = false;\r
+\r
+ try\r
+ {\r
+ if (soundcreated)\r
+ {\r
+ MediaManager.FMODExec(sound.getOpenState(ref openstate, ref percentbuffered, ref starving));\r
+\r
+ if (openstate == OPENSTATE.READY && channel == null)\r
+ {\r
+ MediaManager.FMODExec(system.playSound(CHANNELINDEX.FREE, sound, false, ref channel));\r
+ MediaManager.FMODExec(channel.setVolume(volume));\r
+ }\r
+ }\r
+\r
+ if (system != null)\r
+ {\r
+ system.update();\r
+ }\r
+ }\r
+ catch (Exception ex)\r
+ {\r
+ playing = paused = false;\r
+ timer.Enabled = false;\r
+ Logger.Log("Error playing sound: ", Helpers.LogLevel.Debug, ex);\r
+ }\r
+ }\r
+ }\r
+}\r
using System.Collections.Generic;
using System.Text;
using FMOD;
+using System.Threading;
using OpenMetaverse;
namespace Radegast.Media
/// </summary>
public bool SoundSystemAvailable { get { return soundSystemAvailable; } }
private bool soundSystemAvailable = false;
+ private Thread soundThread;
private List<MediaObject> sounds = new List<MediaObject>();
- /// <summary>
- /// Parcel music stream player
- /// </summary>
- public Sound ParcelMusic { get { return parcelMusic; } set { parcelMusic = value; } }
- private Sound parcelMusic;
-
public MediaManager(RadegastInstance instance)
- : base(null)
+ : base()
+ {
+ // Start the background thread that does all the FMOD calls.
+ soundThread = new Thread(new ThreadStart(CommandLoop));
+ soundThread.IsBackground = true;
+ soundThread.Name = "SoundThread";
+ soundThread.Start();
+ }
+
+ private void CommandLoop()
+ {
+ SoundDelegate action;
+
+ InitFMOD();
+ if (!this.soundSystemAvailable) return;
+
+ // Initialize the command queue.
+ queue = new Queue<SoundDelegate>();
+
+ try
+ {
+ while (true)
+ {
+ // Wait for something to show up in the queue.
+ lock (queue)
+ {
+ while (queue.Count == 0)
+ {
+ Monitor.Wait(queue);
+ }
+
+ action = queue.Dequeue();
+ }
+
+ // We have an action, so call it.
+ action();
+ }
+ }
+ catch (Exception e)
+ {
+ System.Console.WriteLine("Sound shutdown " + e.Message);
+ }
+ }
+
+ private void InitFMOD()
{
try
{
FMODExec(system.getVersion(ref version));
if (version < FMOD.VERSION.number)
- throw new MediaException("You are using an old version of FMOD " + version.ToString("X") + ". This program requires " + FMOD.VERSION.number.ToString("X") + ".");
+ throw new MediaException("You are using an old version of FMOD " +
+ version.ToString("X") +
+ ". This program requires " +
+ FMOD.VERSION.number.ToString("X") + ".");
// Assume no special hardware capabilities except 5.1 surround sound.
FMOD.CAPS caps = FMOD.CAPS.NONE;
public override void Dispose()
{
- if (parcelMusic != null)
- {
- if (!parcelMusic.Disposed)
- parcelMusic.Dispose();
- parcelMusic = null;
- }
-
- lock(sounds)
+ lock (sounds)
{
- for (int i=0; i<sounds.Count; i++)
+ for (int i = 0; i < sounds.Count; i++)
{
if (!sounds[i].Disposed)
sounds[i].Dispose();
using System;
using System.Collections.Generic;
using System.Text;
+using System.Threading;
+using FMOD;
namespace Radegast.Media
{
/// </summary>
public bool Disposed { get { return disposed; } }
private bool disposed = false;
+
+ /// All commands are made through queued delegate calls, so they
+ /// are guaranteed to take place in the same thread. FMOD requires this.
+ public delegate void SoundDelegate();
+
+ /// Queue of sound commands
+ ///
+ /// </summary>
+ protected static Queue<SoundDelegate> queue;
+
+ /// <summary>
+ /// FMOD channel controller, should not be used directly, add methods to Radegast.Media.Sound
+ /// </summary>
+ public Channel FMODChannel { get { return channel; } }
+ protected Channel channel = null;
+
+ /// <summary>
+ /// FMOD sound object, should not be used directly, add methods to Radegast.Media.Sound
+ /// </summary>
+ public FMOD.Sound FMODSound { get { return sound; } }
+ protected FMOD.Sound sound = null;
public FMOD.System FMODSystem { get { return system; } }
/// <summary>
- /// Base FMOD system object
+ /// Base FMOD system object, of which there is only one.
/// </summary>
- protected FMOD.System system = null;
+ protected static FMOD.System system = null;
- public MediaObject(FMOD.System system)
+ public MediaObject()
{
- this.system = system;
}
public virtual void Dispose()
{
+ if (sound != null)
+ {
+ sound.release();
+ sound = null;
+ }
+
disposed = true;
}
+
+ public bool Active { get { return (sound != null); } }
+
+ /// <summary>
+ /// Put a delegate call on the command queue.
+ /// </summary>
+ /// <param name="action"></param>
+ protected void invoke(SoundDelegate action)
+ {
+ // Do nothing if queue not ready yet.
+ if (queue == null) return;
+
+ // Put that on the queue and wake up the background thread.
+ lock (queue)
+ {
+ queue.Enqueue( action );
+ Monitor.Pulse(queue);
+ }
+
+ }
+
+ /// <summary>
+ /// Common actgions for all sound types.
+ /// </summary>
+ protected float volume = 0.5f;
+ public float Volume {
+ get
+ {
+ return volume;
+ }
+ set
+ {
+ invoke(new SoundDelegate(delegate
+ {
+ MediaManager.FMODExec(channel.setVolume(value));
+ volume = value;
+ }));
+ }
+ }
}
}
--- /dev/null
+// \r
+// Radegast Metaverse Client\r
+// Copyright (c) 2009, Radegast Development Team\r
+// All rights reserved.\r
+// \r
+// Redistribution and use in source and binary forms, with or without\r
+// modification, are permitted provided that the following conditions are met:\r
+// \r
+// * Redistributions of source code must retain the above copyright notice,\r
+// this list of conditions and the following disclaimer.\r
+// * Redistributions in binary form must reproduce the above copyright\r
+// notice, this list of conditions and the following disclaimer in the\r
+// documentation and/or other materials provided with the distribution.\r
+// * Neither the name of the application "Radegast", nor the names of its\r
+// contributors may be used to endorse or promote products derived from\r
+// this software without specific prior written permission.\r
+// \r
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\r
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\r
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\r
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+//\r
+// $Id: Sound.cs 502 2010-03-14 23:13:46Z latifer $\r
+//\r
+using System;\r
+using System.Runtime.InteropServices;\r
+using FMOD;\r
+using OpenMetaverse;\r
+\r
+namespace Radegast.Media\r
+{\r
+ public class Speech : MediaObject\r
+ {\r
+ /// <summary>\r
+ /// Is sound currently playing\r
+ /// </summary>\r
+ public bool Playing { get { return playing; } }\r
+ private bool playing = false;\r
+\r
+ /// <summary>\r
+ /// Is sound currently paused\r
+ /// </summary>\r
+ public bool Paused { get { return paused; } }\r
+ private bool paused = false;\r
+\r
+ /// <summary>\r
+ /// Fired when a stream meta data is received\r
+ /// </summary>\r
+ /// <param name="sender">Sender</param>\r
+ /// <param name="e">Key, value are sent in e</param>\r
+ public delegate void StreamInfoCallback(object sender, StreamInfoArgs e);\r
+\r
+ private bool soundcreated = false;\r
+ private System.Timers.Timer timer;\r
+\r
+ /// <summary>\r
+ /// Creates a new sound object\r
+ /// </summary>\r
+ /// <param name="system">Sound system</param>\r
+ public Speech()\r
+ :base()\r
+ {\r
+ timer = new System.Timers.Timer();\r
+ timer.Interval = 50d;\r
+ timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);\r
+ timer.Enabled = false;\r
+ }\r
+\r
+\r
+ /// <summary>\r
+ /// Releases resources of this sound object\r
+ /// </summary>\r
+ public override void Dispose()\r
+ {\r
+ if (timer != null)\r
+ {\r
+ timer.Enabled = false;\r
+ timer.Dispose();\r
+ timer = null;\r
+ }\r
+\r
+ if (sound != null)\r
+ {\r
+ sound.release();\r
+ sound = null;\r
+ }\r
+ base.Dispose();\r
+ }\r
+\r
+ /// <summary>\r
+ /// Plays audio stream\r
+ /// </summary>\r
+ /// <param name="filename">Name of a WAV file created by the synthesizer</param>\r
+ public void Play(string filename)\r
+ {\r
+ if (!soundcreated)\r
+ {\r
+ MediaManager.FMODExec(system.createSound(filename,\r
+ (MODE.HARDWARE | MODE._2D | MODE.CREATESTREAM | MODE.NONBLOCKING),\r
+ ref sound));\r
+ soundcreated = true;\r
+ timer.Enabled = true;\r
+ timer_Elapsed(null, null);\r
+ }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Toggles sound pause\r
+ /// </summary>\r
+ public void TogglePaused()\r
+ {\r
+ if (channel != null)\r
+ {\r
+ channel.getPaused(ref paused);\r
+ channel.setPaused(!paused);\r
+ }\r
+ }\r
+\r
+ void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)\r
+ {\r
+ OPENSTATE openstate = 0;\r
+ uint percentbuffered = 0;\r
+ bool starving = false;\r
+\r
+ try\r
+ {\r
+ if (soundcreated)\r
+ {\r
+ MediaManager.FMODExec(sound.getOpenState(ref openstate, ref percentbuffered, ref starving));\r
+\r
+ if (openstate == OPENSTATE.READY && channel == null)\r
+ {\r
+ MediaManager.FMODExec(system.playSound(CHANNELINDEX.FREE, sound, false, ref channel));\r
+ MediaManager.FMODExec(channel.setVolume(volume));\r
+ }\r
+ }\r
+\r
+ if (system != null)\r
+ {\r
+ system.update();\r
+ }\r
+ }\r
+ catch (Exception ex)\r
+ {\r
+ playing = paused = false;\r
+ timer.Enabled = false;\r
+ Logger.Log("Error playing speech: ", Helpers.LogLevel.Debug, ex);\r
+ }\r
+ }\r
+ }\r
+}\r
--- /dev/null
+// \r
+// Radegast Metaverse Client\r
+// Copyright (c) 2009, Radegast Development Team\r
+// All rights reserved.\r
+// \r
+// Redistribution and use in source and binary forms, with or without\r
+// modification, are permitted provided that the following conditions are met:\r
+// \r
+// * Redistributions of source code must retain the above copyright notice,\r
+// this list of conditions and the following disclaimer.\r
+// * Redistributions in binary form must reproduce the above copyright\r
+// notice, this list of conditions and the following disclaimer in the\r
+// documentation and/or other materials provided with the distribution.\r
+// * Neither the name of the application "Radegast", nor the names of its\r
+// contributors may be used to endorse or promote products derived from\r
+// this software without specific prior written permission.\r
+// \r
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\r
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\r
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\r
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+//\r
+// $Id: Sound.cs 502 2010-03-14 23:13:46Z latifer $\r
+//\r
+using System;\r
+using System.Runtime.InteropServices;\r
+using FMOD;\r
+using OpenMetaverse;\r
+\r
+namespace Radegast.Media\r
+{\r
+ public class StreamInfoArgs : EventArgs\r
+ {\r
+ public string Key;\r
+ public string Value;\r
+\r
+ public StreamInfoArgs(string key, string value)\r
+ {\r
+ Key = key;\r
+ Value = value;\r
+ }\r
+ }\r
+\r
+ public class Stream : MediaObject\r
+ {\r
+ /// <summary>\r
+ /// Returns current position of the sound played in ms\r
+ /// Do not confuse with the spatial Position on other suonds.\r
+ /// </summary>\r
+ public uint Position { get { return position; } }\r
+ private uint position = 0;\r
+\r
+ /// <summary>\r
+ /// Is sound currently playing\r
+ /// </summary>\r
+ public bool Playing { get { return playing; } }\r
+ private bool playing = false;\r
+\r
+ /// <summary>\r
+ /// Is sound currently paused\r
+ /// </summary>\r
+ public bool Paused { get { return paused; } }\r
+ private bool paused = false;\r
+\r
+ /// <summary>\r
+ /// Fired when a stream meta data is received\r
+ /// </summary>\r
+ /// <param name="sender">Sender</param>\r
+ /// <param name="e">Key, value are sent in e</param>\r
+ public delegate void StreamInfoCallback(object sender, StreamInfoArgs e);\r
+\r
+ /// <summary>\r
+ /// Fired when a stream meta data is received\r
+ /// </summary>\r
+ public event StreamInfoCallback OnStreamInfo;\r
+\r
+ private System.Timers.Timer timer;\r
+\r
+ /// <summary>\r
+ /// Creates a new sound object\r
+ /// </summary>\r
+ /// <param name="system">Sound system</param>\r
+ public Stream()\r
+ :base()\r
+ {\r
+ timer = new System.Timers.Timer();\r
+ timer.Interval = 50d;\r
+ timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);\r
+ timer.Enabled = false;\r
+ }\r
+\r
+\r
+ /// <summary>\r
+ /// Releases resources of this sound object\r
+ /// </summary>\r
+ public override void Dispose()\r
+ {\r
+ if (timer != null)\r
+ {\r
+ timer.Enabled = false;\r
+ timer.Dispose();\r
+ timer = null;\r
+ }\r
+\r
+ base.Dispose();\r
+ }\r
+\r
+ /// <summary>\r
+ /// Plays audio stream\r
+ /// </summary>\r
+ /// <param name="url">URL of the stream</param>\r
+ public void PlayStream(string url)\r
+ {\r
+ if (!Active)\r
+ {\r
+ invoke( new SoundDelegate(\r
+ delegate {\r
+ MediaManager.FMODExec(system.createSound(url,\r
+ (MODE.HARDWARE | MODE._2D | MODE.CREATESTREAM | MODE.NONBLOCKING), ref sound));\r
+ \r
+ timer.Enabled = true;\r
+ timer_Elapsed(null, null);\r
+ }));\r
+ }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Toggles sound pause\r
+ /// </summary>\r
+ public void TogglePaused()\r
+ {\r
+ invoke(new SoundDelegate(delegate\r
+ {\r
+ if (channel != null)\r
+ {\r
+ channel.getPaused(ref paused);\r
+ channel.setPaused(!paused);\r
+ }\r
+ }));\r
+ }\r
+\r
+ void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)\r
+ {\r
+ OPENSTATE openstate = 0;\r
+ uint percentbuffered = 0;\r
+ bool starving = false;\r
+\r
+ try\r
+ {\r
+ if (Active)\r
+ {\r
+ // Query what the sound is doing.\r
+ MediaManager.FMODExec(sound.getOpenState(ref openstate, ref percentbuffered, ref starving));\r
+\r
+ // If a channel is not allocated yet, ask for one.\r
+ if (openstate == OPENSTATE.READY && channel == null)\r
+ {\r
+ // Allocate a channel and set initial volume.\r
+ MediaManager.FMODExec(system.playSound( CHANNELINDEX.FREE, sound, false, ref channel));\r
+ volume = 0.5f;\r
+ MediaManager.FMODExec(channel.setVolume(volume));\r
+ }\r
+ }\r
+\r
+ if (channel != null)\r
+ {\r
+ // Do not try to get MP3 tags om Unix. It breaks.\r
+ if (Environment.OSVersion.Platform != PlatformID.Unix)\r
+ {\r
+ for (; ; )\r
+ {\r
+ TAG tag = new TAG();\r
+ if (sound.getTag(null, -1, ref tag) != RESULT.OK)\r
+ {\r
+ break;\r
+ }\r
+ if (tag.datatype != TAGDATATYPE.STRING)\r
+ {\r
+ break;\r
+ }\r
+ else\r
+ {\r
+ if (OnStreamInfo != null)\r
+ try { OnStreamInfo(this, new StreamInfoArgs(tag.name.ToLower(), Marshal.PtrToStringAnsi(tag.data))); }\r
+ catch (Exception) { }\r
+ }\r
+ }\r
+ }\r
+\r
+ // Get pause/play status\r
+ MediaManager.FMODExec(channel.getPaused(ref paused));\r
+ MediaManager.FMODExec(channel.isPlaying(ref playing));\r
+ MediaManager.FMODExec(channel.getPosition(ref position, TIMEUNIT.MS));\r
+ }\r
+\r
+ if (system != null)\r
+ {\r
+ system.update();\r
+ }\r
+ }\r
+ catch (Exception ex)\r
+ {\r
+ playing = paused = false;\r
+ timer.Enabled = false;\r
+ Logger.Log("Error playing stream: ", Helpers.LogLevel.Debug, ex);\r
+ }\r
+ }\r
+ }\r
+}\r
private const int saveConfigTimeout = 3000;
private bool playing;
private string currentURL;
- private MediaManager mngr;
+ //private MediaManager mngr;
+ private Media.Stream parcelStream;
private readonly object parcelMusicLock = new object();
Disposed += new EventHandler(MediaConsole_Disposed);
this.instance = instance;
- this.mngr = instance.MediaManager;
+ this.parcelStream = new Media.Stream();
s = instance.GlobalSettings;
lock (parcelMusicLock)
{
playing = false;
- if (mngr.ParcelMusic != null)
- mngr.ParcelMusic.Dispose();
- mngr.ParcelMusic = null;
+ if (parcelStream != null)
+ parcelStream.Dispose();
+ parcelStream = null;
lblStation.Tag = lblStation.Text = string.Empty;
txtSongTitle.Text = string.Empty;
}
{
Stop();
playing = true;
- mngr.ParcelMusic = new Sound(mngr.FMODSystem);
- mngr.ParcelMusic.Volume = audioVolume;
- mngr.ParcelMusic.PlayStream(currentURL);
- mngr.ParcelMusic.OnStreamInfo += new Sound.StreamInfoCallback(ParcelMusic_OnStreamInfo);
+ parcelStream = new Media.Stream();
+ parcelStream.Volume = audioVolume;
+ parcelStream.PlayStream(currentURL);
+ parcelStream.OnStreamInfo += new Media.Stream.StreamInfoCallback(ParcelMusic_OnStreamInfo);
}
}
{
configTimer.Change(saveConfigTimeout, System.Threading.Timeout.Infinite);
lock (parcelMusicLock)
- if (mngr.ParcelMusic != null)
- mngr.ParcelMusic.Volume = volAudioStream.Value/50f;
+ if (parcelStream != null)
+ parcelStream.Volume = volAudioStream.Value/50f;
}
private void txtAudioURL_TextChanged(object sender, EventArgs e)