Пример #1
0
        /// <summary>
        /// Retrieve a tag with an arbitrary name.
        /// Returns an empty tag if the value isn't found or if no Xiph tags are present.
        /// </summary>
        /// <param name="TagName">
        /// A <see cref="System.String"/> containing the name of the tag to find
        /// </param>
        /// <returns>
        /// An <see cref="OggTag"/> containing the returned tag
        /// </returns>
        public OggTag GetTag(string TagName)
        {
            if (TagName.Length <= 0)
            {
                return(OggUtilities.GetEmptyTag());
            }                                                                         // Save some processing time and just exit if we haven't been given a tag name
            // Based on tasty examples @ "Accessing Hidden Gems": http://developer.novell.com/wiki/index.php/TagLib_Sharp:_Examples
            XiphComment XC = (XiphComment)m_TagLibFile.GetTag(TagTypes.Xiph);

            if (XC != null)
            {
                string[] TagValue = XC.GetField(TagName);
                if (TagValue.Length == 0)
                {
                    // Tag doesn't exist, return empty
                    return(OggUtilities.GetEmptyTag());
                }
                else
                {
                    OggTag tmpTag;
                    tmpTag.Name    = TagName;
                    tmpTag.IsArray = (TagValue.Length > 1);
                    tmpTag.IsEmpty = false;
                    tmpTag.Values  = TagValue;
                    tmpTag.Value   = TagValue[0];
                    return(tmpTag);
                }
            }
            else
            {
                // No valid Xiph tags found
                return(OggUtilities.GetEmptyTag());
            }
        }
Пример #2
0
        /// <summary>
        /// Retrieve an array of all tag values
        /// Returns a zero-length array if no Xiph tags are found
        /// </summary>
        /// <returns>
        /// An <see cref="OggTag[]"/> containing the returned values
        /// </returns>
        public OggTag[] GetTags()
        {
            XiphComment XC = (XiphComment)m_TagLibFile.GetTag(TagTypes.Xiph);

            if (XC != null)
            {
                if (XC.FieldCount > 0)
                {
                    OggTag[] tmpOggTag = new OggTag[XC.FieldCount];
                    int      Index     = 0;
                    foreach (string FieldName in XC)
                    {
                        string[] TagValue = XC.GetField(FieldName);
                        if (TagValue.Length == 0)
                        {
                            tmpOggTag[Index] = OggUtilities.GetEmptyTag();                                      // This should never happen, but I bet if I don't check it it will!
                        }
                        else
                        {
                            // Populate this tag
                            tmpOggTag[Index].Name    = FieldName;
                            tmpOggTag[Index].IsArray = (TagValue.Length > 1);
                            tmpOggTag[Index].IsEmpty = false;
                            tmpOggTag[Index].Values  = TagValue;
                            tmpOggTag[Index].Value   = TagValue[0];
                        }
                        ++Index;                                // Increment the index so we know which OggTag we're molesting
                    }
                    // Done! Return the heap of tags
                    return(tmpOggTag);
                }
                else
                {
                    // Xiph tags contain no items
                    return(new OggTag[0]);
                }
            }
            else
            {
                // No valid Xiph tags found
                return(new OggTag[0]);
            }
        }
Пример #3
0
 protected void StateChange(OggPlayerStatus NewState, OggPlayerStateChanger Reason)
 {
     if (StateChanged != null)
     {
         StateChanged(this, new OggPlayerStateChangedArgs(m_PlayerState, NewState, Reason));
     }
                 #if (DEBUG)
     Console.WriteLine(DateTime.Now.ToLongTimeString() + "\tOggPlayer::StateChange -- From: " + OggUtilities.GetEnumString(m_PlayerState) + " -- To: " + OggUtilities.GetEnumString(NewState));
                 #endif
     m_PlayerState = NewState;
 }
Пример #4
0
        // Player thread
        private void PlayerThread()
        {
            bool Running = true; bool ReachedEOF = false; bool UnderRun = false;

            while (Running)
            {
                // See what we're doing
                if (m_PlayerState == OggPlayerStatus.Playing)
                {
                    // Check number of buffers
                    int QueuedBuffers = 0;
                    AL.GetSource(m_Source, ALGetSourcei.BuffersQueued, out QueuedBuffers);
                    // EOF stuff
                    if (ReachedEOF)
                    {
                        // We've come to the end of the file, just see if there are any buffers left in the queue
                        if (QueuedBuffers > 0)
                        {
                            // We want to remove the buffers, so carry on to the usual playing section
                        }
                        else
                        {
                            lock (OALLocker)
                            {
                                // End of file & all buffers played, exit.
                                Running = false;
                                // Stop the output device if it isn't already
                                if (AL.GetSourceState(m_Source) != ALSourceState.Stopped)
                                {
                                    AL.SourceStop(m_Source);
                                }

                                m_CurrentFile.ResetFile();
                                // Reset file's internal pointer
                                // De-allocate all buffers
                                for (int i = 0; i < m_Buffers.Length; i++)
                                {
                                    AL.DeleteBuffer(ref m_Buffers[i]);
                                }
                                m_Buffers = new uint[m_BufferCount];
                            }
                            // Set state stuff & return
                            StateChange(OggPlayerStatus.Stopped, OggPlayerStateChanger.EndOfFile);
                            SendMessage(OggPlayerMessageType.PlaybackEndOfFile);
                            return;
                        }
                    }

                    // If the number of buffers is greater than 0 & the source isn't playing, poke it so it does
                    if ((!ReachedEOF) && (QueuedBuffers > 0) && (AL.GetError() == ALError.NoError))
                    {
                        if (AL.GetSourceState(m_Source) != ALSourceState.Playing)
                        {
                            AL.SourcePlay(m_Source);
                        }
                    }

                    // Check for buffer underrun
                    int ProcessedBuffers = 0; uint BufferRef = 0;
                    lock (OALLocker)
                    {
                        AL.GetSource(m_Source, ALGetSourcei.BuffersProcessed, out ProcessedBuffers);
                    }
                    if (ProcessedBuffers >= m_BufferCount)
                    {
                        UnderRun = true;
                        SendMessage(OggPlayerMessageType.BufferUnderrun);
                    }
                    else
                    {
                        UnderRun = false;
                    }

                    // Unbuffer any processed buffers
                    while (ProcessedBuffers > 0)
                    {
                        OggBufferSegment obs;
                        lock (OALLocker)
                        {
                            // For each buffer thats been processed, reload and queue a new one
                            AL.SourceUnqueueBuffers(m_Source, 1, ref BufferRef);
                                                        #if (DEBUG)
                            if (AL.GetError() != ALError.NoError)
                            {
                                Console.WriteLine("SourceUnqueueBuffers: ALError: " + OggUtilities.GetEnumString(AL.GetError()));
                            }
                                                        #endif
                            if (ReachedEOF)
                            {
                                --ProcessedBuffers; continue;
                            }                                                                                   // If we're at the EOF loop to the next buffer here - we don't want to be trying to fill any more
                            obs = m_CurrentFile.GetBufferSegment(m_BufferSize);                                 // Get chunk of tasty buffer data with the configured segment
                        }
                        // Check the buffer segment for errors
                        if (obs.ReturnValue > 0)
                        {
                            lock (OALLocker)
                            {
                                // No error, queue data
                                AL.BufferData((int)BufferRef, m_CurrentFile.Format, obs.Buffer, obs.ReturnValue, obs.RateHz);
                                                                #if (DEBUG)
                                if (AL.GetError() != ALError.NoError)
                                {
                                    Console.WriteLine("BufferData: ALError: " + OggUtilities.GetEnumString(AL.GetError()));
                                }
                                                                #endif
                                AL.SourceQueueBuffers(m_Source, 1, ref BufferRef);
                                                                #if (DEBUG)
                                if (AL.GetError() != ALError.NoError)
                                {
                                    Console.WriteLine("SourceQueueBuffers: ALError: " + OggUtilities.GetEnumString(AL.GetError()));
                                }
                                                                #endif
                            }
                        }
                        else
                        {
                            if (obs.ReturnValue == 0)
                            {
                                // End of file
                                SendMessage(OggPlayerMessageType.BufferEndOfFile);
                                ReachedEOF = true;
                                break;
                            }
                            else
                            {
                                // Something went wrong with the read
                                lock (OALLocker)
                                {
                                    m_PlayerState = OggPlayerStatus.Error;
                                    AL.SourceStop(m_Source);
                                    Running = false;
                                }
                                SendMessage(OggPlayerMessageType.FileReadError);
                                break;
                            }
                        }
                        // Check for errors
                        m_LastError = AL.GetError();
                        if (m_LastError != ALError.NoError)
                        {
                            StateChange(OggPlayerStatus.Error, OggPlayerStateChanger.Error);
                            lock (OALLocker) { AL.SourceStop(m_Source); }
                            SendMessage(OggPlayerMessageType.OpenALError, m_LastError);
                            Running = false;
                            break;
                        }

                        --ProcessedBuffers;
                    }

                    // If we under-ran, restart the player
                    if (UnderRun)
                    {
                        lock (OALLocker) { AL.SourcePlay(m_Source); }
                    }

                    // Do stuff with the time values & tick event
                    if (m_CurrentFile != null)
                    {
                        m_PlayingOffset = m_CurrentFile.GetTime();
                    }

                    if (m_TickEnabled)
                    {
                        if (m_PlayingOffset >= m_LastTick + m_TickInterval)
                        {
                            m_LastTick = m_PlayingOffset;
                            SendTick(m_PlayingOffset, m_PlayingOffset);
                        }
                    }
                }
                else if (m_PlayerState == OggPlayerStatus.Seeking)
                {
                    // Just wait for us to finish seeking
                }
                else if (m_PlayerState == OggPlayerStatus.Paused)
                {
                    // Just wait for us to un-pause
                }
                else
                {
                    // Some other state, abort the playback 'cos we shouldn't
                    // be in the PlayerThread in this case
                    Running = false;
                }
                // Allow other shizzle to execute
                if (m_UpdateDelay > 0)
                {
                    Thread.Sleep(m_UpdateDelay);
                }
            }
        }
Пример #5
0
 protected void SendMessage(OggPlayerMessageType Message, object Params)
 {
     if (PlayerMessage != null)
     {
         PlayerMessage(this, new OggPlayerMessageArgs(Message, Params));
     }
                 #if (DEBUG)
     Console.WriteLine(DateTime.Now.ToLongTimeString() + "\tOggPlayer::SendMessage -- Message: " + OggUtilities.GetEnumString(Message));
                 #endif
 }