Provides a view of the sequence of bytes that are produced during the conversion of an MP3 stream into a 16-bit PCM-encoded ("WAV" format) stream.
Inheritance: Stream
        /// <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;
        }
Beispiel #2
0
    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;
        }
    }
Beispiel #3
0
        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();
        }
Beispiel #4
0
        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();
        }
Beispiel #5
0
 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();
     }
 }
Beispiel #6
0
        /// <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.");
        }
Beispiel #7
0
        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);
            }
        }
Beispiel #8
0
        /// <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.");
        }
Beispiel #9
0
 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);
     }
 }
Beispiel #10
0
 public StreamedMp3Sound(Device device, Mp3Stream mp3SourceStream)
     : base(device, mp3SourceStream, SoundUtil.CreateWaveFormat(22050, 16, 2))
 {
 }
Beispiel #11
0
 public MP3AudioFeed(string File)
 {
     this._Stream = new Mp3Stream(File);
     this._Init();
 }
Beispiel #12
0
 public MP3AudioFeed(Stream Source)
 {
     this._Stream = new Mp3Stream(Source);
     this._Init();
 }
Beispiel #13
0
        ///
        /// 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;
               }
            }
             }
        }
Beispiel #14
0
        ///
        /// 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" );
             }
        }
Beispiel #15
0
 public StreamedMp3Sound(Device device, Mp3Stream mp3SourceStream)
     : base(device, mp3SourceStream, SoundUtil.CreateWaveFormat(22050, 16, 2))
 {
 }
Beispiel #16
0
 public void Stop()
 {
     if (mp3Stream == null)
     {
         return;
     }
     if (secondaryBuffer == null)
     {
         return;
     }
     Playing = false;
     bufferDescription.Dispose();
     secondaryBuffer.Dispose();
     mp3Stream.Dispose();
     mp3Stream = null;
 }
Beispiel #17
0
        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
        }