public void ReceiveTransportPlayingDuringUpdate(bool transportPlaying)
        {
            Debug.Assert(this.CurrentlyUpdating == true);

            this.UpdatedFieldsInLastUpdate |= HostInfoFields.TransportPlaying;

            if (this.TransportPlayingIsInitialized == false ||
                this.TransportPlaying != transportPlaying)
            {
                this.ChangedFieldsInLastUpdate |= HostInfoFields.TransportPlaying;
                this.TransportPlaying = transportPlaying;

                this.TransportPlayingIsInitialized = true;
            }
        }
        /// <summary>
        /// This function must be called before any information is recieved through the
        /// Receive...DuringUpdate() functions.
        /// </summary>
        public void StartUpdate()
        {
            Debug.Assert(this.CurrentlyUpdating == false);

            CurrentlyUpdating = true;
            this.UpdatedFieldsInLastUpdate = HostInfoFields.None;
            this.ChangedFieldsInLastUpdate = HostInfoFields.None;
        }
        public void ReceiveTimeSignatureDuringUpdate(int numerator, int denominator)
        {
            Debug.Assert(this.CurrentlyUpdating == true);

            this.UpdatedFieldsInLastUpdate |= HostInfoFields.TimeSignature;

            if (this.TimeSignatureIsInitialized == false ||
                this.TimeSignatureNumerator != numerator ||
                this.TimeSignatureDenominator != denominator)
            {
                this.ChangedFieldsInLastUpdate |= HostInfoFields.TimeSignature;
                this.TimeSignatureNumerator = numerator;
                this.TimeSignatureDenominator = denominator;

                this.TimeSignatureIsInitialized = true;
            }
        }
        public void ReceiveTempoDuringUpdate(double tempo)
        {
            Debug.Assert(this.CurrentlyUpdating == true);

            this.UpdatedFieldsInLastUpdate |= HostInfoFields.Tempo;

            if (this.TempoIsInitialized == false || this.Tempo != tempo)
            {
                this.ChangedFieldsInLastUpdate |= HostInfoFields.Tempo;
                this.Tempo = tempo;

                this.TempoIsInitialized = true;
            }
        }
        public void ReceiveSampleRateDuringUpdate(double sampleRate)
        {
            Debug.Assert(this.CurrentlyUpdating == true);

            this.UpdatedFieldsInLastUpdate |= HostInfoFields.SampleRate;

            if (this.SampleRateIsInitialized == false || this.SampleRate != sampleRate)
            {
                this.ChangedFieldsInLastUpdate |= HostInfoFields.SampleRate;
                this.SampleRate = sampleRate;

                this.SampleRateIsInitialized = true;
            }
        }
        public void ReceiveBarPositionDuringUpdate(double barPos, long sampleTime)
        {
            Debug.Assert(this.CurrentlyUpdating == true);

            this.UpdatedFieldsInLastUpdate |= HostInfoFields.BarPos;

            if (this.BarPosIsInitialized == false ||
                this.barPosOnLastUpdate != barPos || this.sampleTimeAtLastUpdate != sampleTime)
            {
                this.ChangedFieldsInLastUpdate |= HostInfoFields.BarPos;
                this.barPosOnLastUpdate = barPos;
                this.sampleTimeAtLastUpdate = sampleTime;

                this.BarPosIsInitialized = true;
            }
        }
        /// <summary>
        /// Triggers events for subscribers to this relay's output port which will notify them of 
        /// changes made to the information in this relay. This function should be called after a
        /// subscriber to this relay's input port is done sending information.
        /// </summary>
        public void FinishUpdate()
        {
            Debug.Assert(this.CurrentlyUpdating == true);

            //Finish any updates that are dependant on multiple fields.

            if (this.TempoIsInitialized == true &&
                this.TimeSignatureIsInitialized == true &&
                this.BarPosIsInitialized == true &&
                this.SampleRateIsInitialized == true)
            {
                //If anything has changed that could have changed the position of the calculated
                //bar 0 then it will be updated (as will this.samplesPerBar).
                if (this.ChangedFieldsInLastUpdate.HasFlag(HostInfoFields.Tempo) ||
                    this.ChangedFieldsInLastUpdate.HasFlag(HostInfoFields.TimeSignature) ||
                    this.ChangedFieldsInLastUpdate.HasFlag(HostInfoFields.BarPos) ||
                    this.ChangedFieldsInLastUpdate.HasFlag(HostInfoFields.SampleRate))
                {
                    double timeSig = (double)this.TimeSignatureNumerator / this.TimeSignatureDenominator;
                    double beatsPerBar = timeSig / (1 / 4d);
                    this.samplesPerBar = (beatsPerBar / this.Tempo) * (this.SampleRate * 60);

                    long newCalculatedBarZeroSampleTime = this.sampleTimeAtLastUpdate -
                            (long)System.Math.Round(this.barPosOnLastUpdate * samplesPerBar);
                    if (this.CalculatedBarZeroSampleTime != newCalculatedBarZeroSampleTime)
                    {
                        this.CalculatedBarZeroSampleTime = newCalculatedBarZeroSampleTime;
                        this.ChangedFieldsInLastUpdate |= HostInfoFields.CalculatedBarZero;
                    }

                    this.UpdatedFieldsInLastUpdate |= HostInfoFields.CalculatedBarZero;
                    this.CalculatedBarZeroIsInitialized = true;
                }
            }

            CurrentlyUpdating = false;

            //Send Events
            if (this.HostUpdateFinished != null)
            {
                HostUpdateFinished(this.ChangedFieldsInLastUpdate);
            }

            if (this.ChangedFieldsInLastUpdate.HasFlag(HostInfoFields.SampleRate) &&
                SampleRateChanged != null)
            {
                SampleRateChanged(this.SampleRate);
            }

            if (this.ChangedFieldsInLastUpdate.HasFlag(HostInfoFields.Tempo) &&
                TempoChanged != null)
            {
                TempoChanged(this.Tempo);
            }

            if (this.ChangedFieldsInLastUpdate.HasFlag(HostInfoFields.TimeSignature) &&
                TimeSignatureChanged != null)
            {
                TimeSignatureChanged(this.TimeSignatureNumerator, this.TimeSignatureDenominator);
            }

            if (this.ChangedFieldsInLastUpdate.HasFlag(HostInfoFields.TransportPlaying) &&
                TransportPlayingChanged != null)
            {
                TransportPlayingChanged(this.TransportPlaying);
            }

            if (this.ChangedFieldsInLastUpdate.HasFlag(HostInfoFields.CalculatedBarZero) &&
                CalculatedBarZeroChanged != null)
            {
                CalculatedBarZeroChanged(this.CalculatedBarZeroSampleTime);
            }
        }