/*
 *  timing.h from ObjectProDSP 0.2
 *  Copyright (C) 1994 1995, Mountain Math Software. All rights reserved.
 *  
 *  This file is part of ObjectProDSP, a tool for Digital Signal
 *  Processing design, development and implementation. It is free
 *  software provided you use and distribute it under the terms of
 *  version 2 of the GNU General Public License as published
 *  by the Free Software Foundation. You may NOT distribute it or
 *  works derived from it or code that it generates under ANY
 *  OTHER terms.  In particular NONE of the ObjectProDSP system is
 *  licensed for use under the GNU General Public LIBRARY License.
 *  Mountain Math Software plans to offer a commercial version of
 *  ObjectProDSP for a fee. That version will allow redistribution
 *  of generated code under standard commercial terms.
 *  
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of version 2 of the GNU General
 *  Public License along with this program. See file COPYING. If not
 *  or if you wish information on commercial versions and licensing
 *  write Mountain Math Software, P. O. Box 2124, Saratoga, CA 95070,
 *  USA, or send us e-mail at: support@mtnmath.com.
 *  
 *  You may also obtain the GNU General Public License by writing the
 *  Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
 *  USA.  However if you received a copy of this program without the
 *  file COPYING or without a copyright notice attached to all text
 *  files, libraries and executables please inform Mountain Math Software.
 *  
 *  ObjectProDSP is a trademark of Mountain Math Software.
 */
/*  timing.h   */
/*  Copyright 1989 Mountain Math Software  */
/*  All Rights Reserved                    */

#ifndef TIMING_DOT_H
#define TIMING_DOT_H

#include "ObjProGui/netenm.h"
#include "ObjProDSP/timenum.h"
class NodeOutChannelHeader;
class TimingAdjustment ;
class DfNodeOutLink ;

struct TimingDescription {
/*
 *  This structure gives the timing relationship between the output  
 *  from the node with which it is asscociated to the timing of a
 *  theroretical data stream that serves as a basis of comparison
 *  for all streams in the network. Every stream in the network
 *  has a sampling rate that is a rational multiple of this base
 *  streams sample rate. Similarly T = 0 for the
 *  base stream represents the time of the earliest sample that
 *  occurs anywhere in the network.
 *  
 */
	int32 NumeratorSampling ;     
	int32 DenominatorSampling ;
		// The rate of this stream relative to the base stream is:
		// NumeratorSampling / DenominatorSampling
		// Numerator and Deonminator are always relatively prime
		// to minimize the possibility of overflow problems.
	double SampleRate ; // absolute sampling rate - if any node in
			// The network sets this it is adjusted througout
			// the network wherever the sampling rate relationship
			// is determinsitic
			    
	// TheTimingType is curently neither used nor set
	// it retained for backward compatability with file headers
	// that write literal copies of this structure
	// It may be used for future expansion.
	// TimingType in class DfNodeOutLink is what is used now.
	TimingType TheTimingType; 
	double FirstSample ;
	double ErrorTolerance ;
		// This is the error tolerance with FixedTimeBase
	double DeltaTimeBase ;
	int ChangeFlags ;
	int ChangeTimingIndex ;

	struct TimingAdjustment * BackAdjustment ;


	class FeedbackLoop * Loop ;

	static TimingAdjustment * set_thread_base ;
	static enum TimingState {not_set,restart,adjusted} state ;


	void Clear();
	void ClearSampling();
	TimingDescription() {Clear();}
	void CheckInitDefault() ;
	TimingCheck CheckConsistent(TimingDescription& Reference,
		class TimingAdjustment& Adjust) ;
	int IsInFeedbackLoop() const { return Loop ? 1 : 0 ;}
	void AddFeedbackNode(class DfNodeInLink * In,class DfNodeOutLink * Out);
	void SetFeedbackLoop();
	int CheckEndFeedback(DfNodeOutLink * CheckEnd);
	int IsTimeBaseFixed() {return ChangeFlags&1 ? 1: 0;}
		// if this is true then ErrorTolerance establishes
		// an upper bound on the time change allowed.
		// If not set ErrorTolerance has no effect.
	void SetFixedTimeBase() {ChangeFlags |= 1 ;}
	int IsSampleRateFixed() {return ChangeFlags&2 ? 1: 0;}
	void SetFixedSampleRate() {ChangeFlags |= 2 ;}
	void UpdateTiming(DfNodeInLink * In, DfNodeOutLink * Out,
		class DfNode * TheNode);
	TimingCheck CheckFeedbackTiming(TimingDescription& NewTiming) ;
	void SetSamplingAdjustment(TimingDescription& Reference,
		TimingAdjustment& Adjust) ;
	void SetFirstSampleAdjustment(TimingDescription& Reference,
		TimingAdjustment& Adjust) ;
	void Display() ;
	void Merge (FeedbackLoop * ToMerge) ;
	double GetSampleRate() const {return SampleRate;}
	// double GetSampleRateFactor() const { return SampleRateFactor; }
	void AdjustSampleRate(TimingDescription& timing);
	void SetFromDisk(const NodeOutChannelHeader& DiskState);
	double GetSamplingRatio() const
		{ return ((double) NumeratorSampling) / DenominatorSampling;}

} ;


struct TimingAdjustment {
	int32 NumeratorFactor ;
	int32 DenominatorFactor ;
	double TimeShift ;
	int ChangeTimingIndex ;
	int CurrentPathFlag ;
	void Clear() {NumeratorFactor=DenominatorFactor=1;
		TimeShift=0.0;CurrentPathFlag=0;}
	TimingAdjustment() {Clear(); ChangeTimingIndex=0;}
	TimingAdjustment(int ChangeIndex) {Clear();
		ChangeTimingIndex = ChangeIndex;}
	void SetCurrentPathFlag(){CurrentPathFlag = 1 ;}
	void Display() ;
	int sampling_unchanged() {return (NumeratorFactor == 1) &&
		(DenominatorFactor == 1) ;}
	void adjust_base(TimingDescription& to_adjust);
} ;

#endif /* #ifdef TIMING_DOT_H */
