Ejemplo n.º 1
0
        private int CompareSimpleMidi(SimpleMidiMessage lhs, SimpleMidiMessage rhs)
        {
            int first = lhs.Timestamp.CompareTo(rhs.Timestamp);

            if (first != 0)
            {
                return(first);
            }

            int lhsType = (lhs.Data & 0xf0) >> 4;
            int rhsType = (rhs.Data & 0xf0) >> 4;

            int second = lhsType.CompareTo(rhsType);

            return(second);
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Determines whether this instance and another specified <see cref="SimpleMidiMessage"/> object have the same value.
 /// </summary>
 /// <param name="other">The <see cref="SimpleMidiMessage"/> to compare with the current instance. </param>
 /// <returns>
 /// true if <paramref name="other"/> and this instance represent the same value; otherwise, false.
 /// </returns>
 public bool Equals(SimpleMidiMessage other)
 {
     return(Timestamp.Equals(other.Timestamp) && Data == other.Data);
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Returns the next simple midi event to be played from the queue.
        /// It can either block it until it is time to actually play it, or return the current timestamp immediately.
        /// </summary>
        /// <param name="block">Force the BeatScheduler to return immediately</param>
        /// <returns>A simple MIDI event and a timestamp. If nothing exists in the queue, it either
        /// returns an empty message or blocks until one is available.</returns>
        public SimpleMidiMessage GetNextMidiCommand(bool block = true)
        {
            //Try to find a new tone 10 times. Should only run once in most conditions, but
            //we need recycle our wait if the queue gets new things added while we wait.
            //could be while(true) but this way we don't risk an infinite loop
            //which is bad.
            //Probably also possible to do a simpler reset but cannot quite see how
            for (int i = 0; i < 10; i++)
            {
                double nextTime;
                lock (_syncRoot)
                {
                    nextTime = _channelAllocator.NextTimeStamp;
                }

                if (nextTime == ChannelAllocator.NoMessageTime)
                {
                    if (block)
                    {
                        _newDataAdded.WaitOne();
                        continue;
                    }
                    else
                    {
                        return(EmptyMessage);
                    }
                }



                //If we were not interrupted, we assume we arrived in time
                //Console.Write($"{!block} || {GetWaitTimeMs(_channelAllocator.NextTimeStamp):D4}  ~  ");

                //If not set to block or if no new data arrives
                if (!block || !_newDataAdded.WaitOne(GetWaitTimeMs(_channelAllocator.NextTimeStamp)))
                {
                    SimpleMidiMessage message = _channelAllocator.GetNext();
                    //Console.WriteLine($"Fin {message}");

                    if (_channelAllocator.Empty)
                    {
                        //If the emptyHandle is not set, notify that we have finished everything
                        if (!_emptyHandle.WaitOne(0))
                        {
                            _emptyHandle.Set();
                        }
                    }

                    return(message);
                }
            }

            //If working in debug mode knowing that something went wrong is probably preferable
            //but in release we would just as well like it failing silently
            //This being only a single MIDI event it would not impact the overall piece overmuch
#if DEBUG
            throw new TimeoutException("Unable to return anything after too many iterupts. This should (probably) never happen");
#else
            return(new SimpleMidiMessage(0, 0));
#endif
        }