/// <summary> /// Decodes the mp3 file /// </summary> public WaveFile Decode(Stream input) { //TODO: Still AWFUL playback quality Mp3Stream mp3 = new Mp3Stream(input); mp3.Seek(0, SeekOrigin.Begin); mp3.DecodeFrames(1); WaveFile wf = new WaveFile(); wf.Bits = 16; wf.Channels = mp3.ChannelCount; wf.Frequency = mp3.Frequency; System.Console.WriteLine(mp3.Length); MemoryStream data = new MemoryStream(); int buffersize = 4*4096; byte[] buffer = new byte[buffersize]; int result = 1; while(true) { result = mp3.Read(buffer, 0, buffersize); data.Write(buffer, 0, result); if(result != buffersize) { break; } } data.Seek(0, SeekOrigin.Begin); wf.Data = data; Axiom.Core.LogManager.Instance.Write("SoundSystem: File is MPEG Layer III "+wf.Frequency+"Hz, "+wf.Channels+" channels"); return wf; }
private void LoadMp3(object state) { // create mp3 using (FileStream f_stream = new FileStream(filename, FileMode.Open)) { Mp3Stream stream = new Mp3Sharp.Mp3Stream(f_stream, 65536); MemoryStream convertedAudioStream = new MemoryStream(); byte[] buffer = new byte[65536]; int bytesReturned = -1; int totalBytesReturned = 0; while (bytesReturned != 0) { bytesReturned = stream.Read(buffer, 0, buffer.Length); convertedAudioStream.Write(buffer, 0, bytesReturned); totalBytesReturned += bytesReturned; this.progress = (int)(((float)stream.Position / (float)stream.Length) * 100); this.progress = Mathf.Clamp(this.progress, 0, 100); } Debug.Log("MP3 file has " + stream.ChannelCount + " channels with a frequency of " + stream.Frequency); byte[] convertedAudioData = convertedAudioStream.ToArray(); Debug.Log("Converted Data has " + convertedAudioData.Length + " bytes of data"); MP3_data = new float[convertedAudioData.Length / 2]; for (int i = 0; i < MP3_data.Length; i++) { MP3_data[i] = (float)(BitConverter.ToInt16(convertedAudioData, i * 2) / (float)short.MaxValue); } MP3_freq = stream.Frequency; stream.Dispose(); loaded = true; } }
public void PlayWithEndNotifacation(Stream audio, IntPtr hwnd) { Mp3Stream mp3Stream = new Mp3Sharp.Mp3Stream(audio); mp3Stream.Position = 0; dev = new Microsoft.DirectX.DirectSound.Device(); dev.SetCooperativeLevel(hwnd, Microsoft.DirectX.DirectSound.CooperativeLevel.Normal); ApplicationStreamedSound = new StreamedMp3Sound(dev, mp3Stream); ApplicationStreamedSound.BufferNotification += ApplicationStreamedSound_BufferNotificationSendPostback; ApplicationStreamedSound.Play(); }
public MP3Player(string path) { Stream = new Mp3Stream(path); Stream.DecodeFrames(1); //let's get started... DecodeNext = new AutoResetEvent(true); BufferDone = new AutoResetEvent(false); Inst = new DynamicSoundEffectInstance(Stream.Frequency, AudioChannels.Stereo); Inst.IsLooped = false; Inst.BufferNeeded += SubmitBufferAsync; SubmitBuffer(null, null); SubmitBuffer(null, null); NextBuffers = new List<byte[]>(); NextSizes = new List<int>(); Requests = 1; MainThread = Thread.CurrentThread; DecoderThread = new Thread(() => { try { while (MainThread.IsAlive) { DecodeNext.WaitOne(128); bool go; lock (this) go = Requests > 0; while (go) { var buf = new byte[524288]; var read = Stream.Read(buf, 0, buf.Length); lock (this) { Requests--; NextBuffers.Add(buf); NextSizes.Add(read); if (read == 0) { EndOfStream = true; return; } BufferDone.Set(); } lock (this) go = Requests > 0; } } } catch (Exception e) { } }); DecoderThread.Start(); }
public void Play(Stream audio, IntPtr hwnd) { if (!IsPlaying) { IsPlaying = true; _mp3Stream = new Mp3Sharp.Mp3Stream(audio); MyMp3Sream.Position = 0; dev = new Microsoft.DirectX.DirectSound.Device(); dev.SetCooperativeLevel(hwnd, Microsoft.DirectX.DirectSound.CooperativeLevel.Normal); ApplicationStreamedSound = new StreamedMp3Sound(dev, MyMp3Sream); ApplicationStreamedSound.BufferNotification += ApplicationStreamedSound_BufferNotification; ApplicationStreamedSound.Play(); } }
/// <summary> /// Sample showing how to read through an MP3 file and obtain its contents as a PCM byte stream. /// </summary> public static void ReadAllTheWayThroughMp3File() { Mp3Stream stream = new Mp3Stream(Mp3FilePath); // Create the buffer int numberOfPcmBytesToReadPerChunk = 512; byte[] buffer = new byte[numberOfPcmBytesToReadPerChunk]; int bytesReturned = -1; int totalBytes = 0; while (bytesReturned != 0) { bytesReturned = stream.Read(buffer, 0, buffer.Length); totalBytes += bytesReturned; } Console.WriteLine("Read a total of " + totalBytes + " bytes."); }
protected override void OnBufferInitializing() { Mp3Stream stream = Stream as Mp3Stream; if (stream == null) { throw new ApplicationException("The stream used by the StreamedMp3Sound class should be of type Mp3Stream."); } if (stream.Frequency < 0) { stream.DecodeFrames(1); } if (stream.Frequency > 0 && stream.ChannelCount > 0) { this.WaveFormat = SoundUtil.CreateWaveFormat(stream.Frequency, 16, stream.ChannelCount); } }
/// <summary> /// Sample showing how to read through an MP3 file and obtain its contents as a PCM byte stream. /// </summary> public static void ReadAllTheWayThroughMp3File() { Mp3Stream stream = new Mp3Stream(Mp3FilePath); // Create the buffer int numberOfPcmBytesToReadPerChunk = 512; byte[] buffer = new byte[numberOfPcmBytesToReadPerChunk]; int bytesReturned = -1; int totalBytes = 0; while (bytesReturned != 0) { bytesReturned = stream.Read(buffer, 0, buffer.Length); totalBytes += bytesReturned; } Console.WriteLine("Read a total of " + totalBytes + " bytes."); }
public static bool TryPlay(Stream audio, IntPtr hwnd) { try { Mp3Stream mp3Stream = new Mp3Sharp.Mp3Stream(audio); mp3Stream.Position = 0; if (mp3Stream.DecodeFrames(1) == 0) { throw new Exception("Could not decode"); } Device dev = new Microsoft.DirectX.DirectSound.Device(); dev.SetCooperativeLevel(hwnd, Microsoft.DirectX.DirectSound.CooperativeLevel.Normal); StreamedMp3Sound ApplicationStreamedSound = new StreamedMp3Sound(dev, mp3Stream); ApplicationStreamedSound.Play(); ApplicationStreamedSound.Stop(); return(true); } catch (Exception ex) { return(false); } }
public StreamedMp3Sound(Device device, Mp3Stream mp3SourceStream) : base(device, mp3SourceStream, SoundUtil.CreateWaveFormat(22050, 16, 2)) { }
public MP3AudioFeed(string File) { this._Stream = new Mp3Stream(File); this._Init(); }
public MP3AudioFeed(Stream Source) { this._Stream = new Mp3Stream(Source); this._Init(); }
/// /// Starts playing the next file, or returns false if the queue /// is empty (or other errors occur) /// bool _InternalStartNextFile() { while (true) { // Queue empty? Queue synced = Queue.Synchronized( _playFilesQueue ); if (synced.Count == 0) { Trace.WriteLine( "_InternalStartNextFile: queue empty" ); if (_mp3Stream != null) { _mp3Stream.Close(); _mp3Stream = null; } return false; } // It is assumed we own the config mutex here. TrackInfo info = null; try { Trace.WriteLine( "_InternalStartNextFile" ); info = (TrackInfo)synced.Dequeue(); _playingTrack.path = info.path; _playingTrack.index = info.index; FileStream stream = new FileStream( _playingTrack.path, FileMode.Open, FileAccess.Read ); // Note: there is a handy Mp3Stream(FileName) constructor, // but if it throws an exception (say, file not found), // the _mp3Stream class leaves around stray threads and // the program won't exit! // If the old _mp3Stream was around, it's going away now! if (_mp3Stream != null) _mp3Stream.Close(); _mp3Stream = new Mp3Stream( stream, _mp3ChunkSize ); if (null != OnTrackPlayed) OnTrackPlayed( _playingTrack.index, _playingTrack.path ); return true; } catch (Exception e) { // An exception could simply mean that the _playFilesQueue is // empty, in this case trackInfo should still be null. if (null == info) { Trace.WriteLine( "Queue is empty: " + e.ToString() ); } else { Trace.WriteLine( "Error opening file: " + e.ToString() ); // We dequeued a track but couldn't play it. Notify // the player of the track's "finished with error" status. /// /// \todo differentiate between file-not-found errors /// and problems with the mp3 playback engine /// if (null != OnTrackFinished) { OnTrackFinished( new TrackFinishedInfo( info.index, e, TrackFinishedInfo.Reason.OPEN_ERROR ) ); } } // If anything went wrong, park the playback engine and // pass the buck. if (null != _mp3Stream) { _mp3Stream.Close(); // be sure to free resources _mp3Stream = null; } } } }
/// /// This is the entry point for the buffer processing thread. /// /// \todo This needs exception handling. /// void _Mp3ReaderThread() { Trace.WriteLine( "Hello", "MP3" ); Thread audioThread = null; try { audioThread = new Thread( new ThreadStart( _AudioThread ) ); audioThread.Priority = ThreadPriority.AboveNormal; audioThread.Start(); Trace.WriteLine( "Entering main loop", "MP3" ); _configMutex.WaitOne(); while (true) { // Execution will stop here if the parent thread tries to // change the configuration in some way. _configMutex.ReleaseMutex(); _configMutex.WaitOne(); switch (_state) { case State.STOP: Trace.WriteLine( " State.STOP", "MP3" ); // In case we were playing or whatever, be sure files and // streams are closed: if (_mp3Stream != null) { _mp3Stream.Close(); _mp3Stream = null; } // Stop the audio writer while we delete the estream. if (false == _audioThreadMutex.WaitOne( AUDIO_TIMEOUT, false )) { // If this happened, we probably want to kill the // audio thread and restart esd. :( throw new ApplicationException( "Timed out waiting for the audio mutex" ); } try { _ShutDownEstream(); } finally { _audioThreadMutex.ReleaseMutex(); } // Wait until the parent wakes us up. _configMutex.ReleaseMutex(); _fileToPlayEvent.WaitOne(); Trace.WriteLine( "STOP -> " + _state.ToString(), "MP3" ); _configMutex.WaitOne(); // We've got the _configMutex, so no race condition exists. // I think. Maybe. _fileToPlayEvent.Reset(); break; case State.PLAY_FILE_REQUEST: Trace.WriteLine( " State.PLAY_FILE_REQUEST", "MP3" ); if (_bufferSizeChanged || null == _estream) { // Stop the audio writer stream to handle buffer resize. if (false == _audioThreadMutex.WaitOne( AUDIO_TIMEOUT, false )) { // If this happened, we probably want to kill the // audio thread and restart esd. :( throw new ApplicationException( "Timed out waiting for the audio mutex" ); } try { if (!_StartUpEstream()) { _state = State.STOP; // stop! break; // * BREAK OUT ** } _CreateMp3Buffers(); _underflowEvent.Set(); _bufferSizeChanged = false; // no longer } finally { _audioThreadMutex.ReleaseMutex(); } } // Start playing if we can. if (_InternalStartNextFile() == false) _state = State.STOP; // Nothing in the queue else _state = State.PLAYING; break; case State.PLAYING: // Trace.WriteLine( " State.PLAYING", "MP3" ); Debug.Assert( null != _estream, "not created in PLAY_FILE_REQUEST?" ); // Wait for a free audio buffer Buffer buffer = _WaitForAndPopFreeBuffer(); // The Mp3Stream wrapper is still a bit flaky. Especially // it seems to throw exceptions at end-of-file sometimes, // probably trying to read garbage. Encase it in a // try/catch block: Exception playbackException = null; try { // Fill the buffer with goodness. buffer.validBytes = _mp3Stream.Read( buffer.mp3Buffer, 0, buffer.mp3Buffer.Length ); if (null != OnReadBuffer) OnReadBuffer( buffer.mp3Buffer, buffer.validBytes ); } catch (Exception e) { // I'm not sure, but I think we may have to destroy // and recreate the Mp3Stream to get it working again // here. Trace.WriteLine( "Problem Reading from MP3:" + e.ToString(), "MP3" ); // Flag the stream as finished. Heh! buffer.validBytes = 0; playbackException = e; // save for reporting } if (buffer.validBytes <= 0) { _PushFreeBuffer( buffer ); // Done with prev file: notify any listeners. Send them // the exception if something went wrong TrackFinishedInfo info; if (null == playbackException) { info = new TrackFinishedInfo( _playingTrack.index, TrackFinishedInfo.Reason.NORMAL ); } else { info = new TrackFinishedInfo ( _playingTrack.index, playbackException, TrackFinishedInfo.Reason.PLAY_ERROR ); } if (null != OnTrackFinished) OnTrackFinished( info ); if (_InternalStartNextFile() == false) _state = State.STOP; // end of file } else { _PushMp3Buffer( buffer ); // Loaded with sample goodness } break; case State.SHUTDOWN_REQUEST: Trace.WriteLine( " State.SHUTDOWN_REQUEST", "MP3" ); _configMutex.ReleaseMutex(); // Handle cleanup in the "finally" block return; default: break; } } } catch (Exception reasonForCrashing) { Trace.WriteLine( reasonForCrashing.ToString(), "MP3" ); } finally { if (null != audioThread) { // Try to get the audio thread mutex, but eventually give up // so we can clean up regardless. if (false == _audioThreadMutex.WaitOne( AUDIO_TIMEOUT, false )) { // Couldn't get mutex. This is bad. audioThread.Abort(); // Just kill the thread. } else { try { /// /// \todo Shut down audioThread properly (Join it) /// instead of calling Abort(). /// audioThread.Abort(); } finally { _audioThreadMutex.ReleaseMutex(); } } } if (null != _estream) { _estream.FreeWriteBuffer(); _estream.Close(); } // Don't want to exit the thread while holding this mutex, // do we? It's possible we aren't holding it, but certainly // we don't have to worry about releasing other threads' // claim. _configMutex.ReleaseMutex(); Trace.WriteLine( "bye", "MP3" ); } }
public StreamedMp3Sound(Device device, Mp3Stream mp3SourceStream) : base(device, mp3SourceStream, SoundUtil.CreateWaveFormat(22050, 16, 2)) { }
public void Stop() { if (mp3Stream == null) { return; } if (secondaryBuffer == null) { return; } Playing = false; bufferDescription.Dispose(); secondaryBuffer.Dispose(); mp3Stream.Dispose(); mp3Stream = null; }
void Load(System.IO.Stream stream) { //if (secondaryBuffer == null) //{ // return; //} //if (secondaryBuffer.Disposed) //{ // return; //} if (Playing) { secondaryBuffer.Stop(); Playing = false; } mp3Stream = new Mp3Stream(stream); mp3Stream.Read(buff, 0, 512); mp3Stream.Position = 0; waveFormat.BitsPerSample = 16; waveFormat.Channels = mp3Stream.ChannelCount; waveFormat.SamplesPerSecond = mp3Stream.Frequency; waveFormat.FormatTag = WaveFormatTag.Pcm; waveFormat.BlockAlign = (short)(waveFormat.Channels * (waveFormat.BitsPerSample / 8)); waveFormat.AverageBytesPerSecond = waveFormat.SamplesPerSecond * waveFormat.BlockAlign; wholeSize = (int)(waveFormat.AverageBytesPerSecond * TimeSpan.FromSeconds(0.2).TotalSeconds); bufferDescription = new BufferDescription(waveFormat); bufferDescription.BufferBytes = wholeSize; bufferDescription.GlobalFocus = true; bufferDescription.ControlVolume = true; secondaryBuffer = new SecondaryBuffer(bufferDescription, game.Devices.DSoundDev); secondaryBuffer.Volume = volum; #region useless code area //autoResetEvent = new System.Threading.AutoResetEvent(false); //notify = new Notify(secondaryBuffer); //System.Reflection.MethodInfo methodInfo; //methodInfo = typeof(SoundManager).GetMethod("fillBack"); //bufferPositionNotify = new BufferPositionNotify[2]; //bufferPositionNotify[0] = new BufferPositionNotify(); //bufferPositionNotify[0].Offset = 0; //bufferPositionNotify[0].EventNotifyHandle = this.GetType().GetMethod("fillBack", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).MethodHandle.Value; //bufferPositionNotify[1] = new BufferPositionNotify(); //bufferPositionNotify[1].Offset = halfSize; //bufferPositionNotify[1].EventNotifyHandle = this.GetType().GetMethod("fillFore", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).MethodHandle.Value; //bufferPositionNotify = new BufferPositionNotify[2]; //bufferPositionNotify[0] = new BufferPositionNotify(); //bufferPositionNotify[0].Offset = 0; //bufferPositionNotify[0].EventNotifyHandle = autoResetEvent.Handle; //bufferPositionNotify[1] = new BufferPositionNotify(); //bufferPositionNotify[1].Offset = halfSize; //bufferPositionNotify[1].EventNotifyHandle = autoResetEvent.Handle; //notify.SetNotificationPositions(bufferPositionNotify); #endregion }