Example #1
0
int
InitClockRate(void)
{
	if ((kmem = open("/dev/kmem", O_RDWR)) == -1) {
		msyslog(LOG_ERR, "open(/dev/kmem): %m");
		perror("adjtimed: open(/dev/kmem)");
		return (-1);
	}

	nlist("/hp-ux", nl);

	if (nl[0].n_type == 0) {
		fputs("adjtimed: /hp-ux has no symbol table\n", stderr);
		msyslog(LOG_ERR, "/hp-ux has no symbol table");
		return (-1);
	}
	/*
	 * Set the default to the system's original value
	 */
	default_rate = GetClockRate();
	if (default_rate == UNKNOWN_RATE) default_rate = DEFAULT_RATE;
	tick_rate = (MILLION / default_rate);
	slew_rate = TICK_ADJ * tick_rate;
	fprintf(stderr,"default_rate=%ld, tick_rate=%ld, slew_rate=%ld\n",default_rate,tick_rate,slew_rate);

	return (0);
} /* InitClockRate */
Example #2
0
/*
 * Reset the clock rate to the default value.
 */
void
ResetClockRate(void)
{
	struct itimerval it;

	it.it_value.tv_sec = it.it_value.tv_usec = 0L;
	setitimer(ITIMER_REAL, &it, (struct itimerval *)0);

	if (verbose > 2) puts("adjtimed: resetting the clock");
	if (sysdebug > 2) msyslog(LOG_INFO, "resetting the clock");

	if (GetClockRate() != default_rate) {
		if (SetClockRate(default_rate) == -1) {
			msyslog(LOG_ERR, "set clock rate: %m");
			perror("adjtimed: set clock rate");
		}
	}

	oldrate = 0.0;
} /* ResetClockRate */
Example #3
0
USHORT CHalSampleClock::Set( long lRate, long lSource, long lReference, BOOLEAN bForce )
/////////////////////////////////////////////////////////////////////////////
{
	PLLCLOCKINFO	ClockInfo;
	PHAL8420		pCS8420 = m_pHalAdapter->Get8420();
	PHAL4114		pAK4114 = m_pHalAdapter->Get4114();
	PHALMIXER		pMixer = m_pHalAdapter->GetMixer();
	USHORT			usDeviceID = m_pHalAdapter->GetDeviceID();
	long			lOriginalSource = m_lSource;
	ULONG			bWideWireIn;

	// correct any code that isn't AES16 aware
	if( pAK4114 && (lSource < MIXVAL_AES16_CLKSRC_INTERNAL) )
		lSource += MIXVAL_AES16_CLKSRC_INTERNAL;

	// if there is no change from current setting, just return.
	if( (m_lRate == lRate)
	 && (m_lSource == lSource)
	 && (m_lReference == lReference)
	 && !bForce )	// if Force is set, always run the entire routine
	{
		return( HSTATUS_OK );
	}

	// if this firmware doesn't support P16, then the lowest sample rate is 11025, not 8000
	if( !m_pHalAdapter->HasP16() )
		if( lRate < 11025 )
			lRate = 11025;

	// the lowest sample rate for the AES16 is 32kHz, highest is 192kHz
	if( pAK4114 )
	{
		if( lRate < 32000 )
		{
			lRate = 32000;
		}
		if( lRate > 192000 )
		{
			lRate = 192000;
		}
		
		// read the wide wire bit for use later on...
		pAK4114->GetWideWireIn( &bWideWireIn );
	}

	// if the requested sample rate is less than the minimum rate, set it at the minimum
	if( lRate < MIN_SAMPLE_RATE )
	{
		lRate = MIN_SAMPLE_RATE;
	}
	
	// if the requested sample rate is greater than the maximum rate, set it at the maximum
	if( lRate > MAX_SAMPLE_RATE )
	{
		lRate = MAX_SAMPLE_RATE;
	}

	if( !bForce )
	{
		// if we are trying to clock from an external input, make sure that input is running at the correct rate
		if( GetClockRate( &lRate, &lSource, &lReference ) )
		{
			DPF(("CHalSampleClock::GetClockRate Failed!\n"));
			return( HSTATUS_INVALID_MODE );
		}

		// make sure all the devices are idle
		if( m_pHalAdapter->GetNumActiveWaveDevices() )
		{
			DPF(("CHalSampleClock::Set: Device in use. Cannot change sample rate.\n"));
			return( HSTATUS_ALREADY_IN_USE );
		}
	}

	//DPF(("CHalSampleClock::Set %ld\n", lRate ));

	// start off with everything turned off
	RtlZeroMemory( &ClockInfo, sizeof( PLLCLOCKINFO ) );

	if( pAK4114 )	ClockInfo.ulClkSrc = lSource - MIXVAL_AES16_CLKSRC_INTERNAL;
	else			ClockInfo.ulClkSrc = lSource;

	switch( lSource )
	{
	case MIXVAL_L2_CLKSRC_INTERNAL:
	case MIXVAL_AES16_CLKSRC_INTERNAL:
		//DPF(("MIXVAL_L2_CLKSRC_INTERNAL\n"));
		lReference = MIXVAL_CLKREF_AUTO;
		if( m_pHalAdapter->Has40MHzXtal() )
			GetClockInfo( &lRate, tbl40MHzClk, &ClockInfo, ARRAYSIZE(tbl40MHzClk) );
		else
			GetClockInfo( &lRate, tbl32MHzClk, &ClockInfo, ARRAYSIZE(tbl32MHzClk) );
		break;
	case MIXVAL_L2_CLKSRC_EXTERNAL:
	case MIXVAL_L2_CLKSRC_HEADER:
	case MIXVAL_AES16_CLKSRC_EXTERNAL:
	case MIXVAL_AES16_CLKSRC_HEADER:
		//DPF(("MIXVAL_L2_CLKSRC_EXTERNAL/HEADER\n"));
		// make sure we allow the change from INTERNAL or DIGITAL
		if( lReference == MIXVAL_CLKREF_AUTO )
			lReference = MIXVAL_CLKREF_27MHZ;

		switch( lReference )
		{
		case MIXVAL_CLKREF_WORD:
			//DPF(("MIXVAL_CLKREF_WORD\n"));
			// Just set the word bit here, the rest will get taken care of later.
			ClockInfo.ulWord	= 1;
			break;
		case MIXVAL_CLKREF_WORD256:
			//DPF(("MIXVAL_CLKREF_WORD256\n"));
						
			//Set M,N,P for quad, single, double speed
			if( lRate > 100000 )		{ ClockInfo.ulM	= 96;	ClockInfo.ulN	= 96;	ClockInfo.ulP	= SR_P2; }
			else if( lRate > 50000 )	{ ClockInfo.ulM	= 48;	ClockInfo.ulN	= 96;	ClockInfo.ulP	= SR_P2; }
			else						{ ClockInfo.ulM	= 24;	ClockInfo.ulN	= 96;	ClockInfo.ulP	= SR_P4; }
			
			break;
		case MIXVAL_CLKREF_13p5MHZ:
			//DPF(("MIXVAL_CLKREF_13p5MHZ\n"));
			GetClockInfo( &lRate, tbl13p5MHzClk, &ClockInfo, ARRAYSIZE(tbl13p5MHzClk) );
			break;
		case MIXVAL_CLKREF_27MHZ:
			//DPF(("MIXVAL_CLKREF_27MHZ\n"));
			GetClockInfo( &lRate, tbl27MHzClk, &ClockInfo, ARRAYSIZE(tbl27MHzClk) );
			break;
		default:
			DPF(("Invalid lReference [%08lx]\n", lReference ));
			return( HSTATUS_INVALID_MIXER_VALUE );
		}
		break;
	case MIXVAL_L2_CLKSRC_VIDEO:
		//DPF(("MIXVAL_L2_CLKSRC_VIDEO\n"));
		if( usDeviceID == PCIDEVICE_LYNX_L22 )
			return( HSTATUS_INVALID_MIXER_VALUE );

		lReference	= MIXVAL_CLKREF_AUTO;
		if( m_pHalAdapter->HasTIVideoPLL() )
			GetClockInfo( &lRate, tblTIPll_27MHzClk, &ClockInfo, ARRAYSIZE(tblTIPll_27MHzClk) );
		else
			GetClockInfo( &lRate, tbl24MHzClk, &ClockInfo, ARRAYSIZE(tbl24MHzClk) );
		break;
	case MIXVAL_L2_CLKSRC_LSTREAM_PORT1:
	case MIXVAL_L2_CLKSRC_LSTREAM_PORT2:
	case MIXVAL_AES16_CLKSRC_LSTREAM:
		//DPF(("MIXVAL_L2_CLKSRC_LSTREAM_PORTX\n"));
		lReference = MIXVAL_CLKREF_WORD;	// force to word
		// Just set the word bit here, the rest will get taken care of later.
		ClockInfo.ulWord	= 1;
		break;
	case MIXVAL_AES16_CLKSRC_DIGITAL_2:
	case MIXVAL_AES16_CLKSRC_DIGITAL_3:
		// rev NC AES16 boards can only sync to digital in 1 & 2
		if( pAK4114 && !m_pHalAdapter->GetPCBRev() )
			return( HSTATUS_INVALID_MIXER_VALUE );
	case MIXVAL_L2_CLKSRC_DIGITAL:
	case MIXVAL_AES16_CLKSRC_DIGITAL_0:
	case MIXVAL_AES16_CLKSRC_DIGITAL_1:
		//DPF(("MIXVAL_L2_CLKSRC_DIGITAL\n"));
		lReference	= MIXVAL_CLKREF_AUTO;	// force to auto
		// Just set the word bit here, the rest will get taken care of later.
		ClockInfo.ulWord	= 1;
		break;
	default:
		DPF(("Invalid lSource [%08lx]\n", lSource ));
		return( HSTATUS_INVALID_MIXER_VALUE );
	}

	// if this is a word clock, limit the sample rate
	if( lReference == MIXVAL_CLKREF_WORD )
	{
		if( m_lReference != lReference )
		{
			if( lRate < 24000 )
				lRate = 44100;
		}
		if( lRate < 24000 )
		{
			//DPF(("Invalid Sample Rate for Word Clock!\n"));
			DPF(("SetSampleRate: Word Clock Below 24000!\n")); 
			return( HSTATUS_INVALID_SAMPLERATE );
		}
	}

	// Set the speed based on the sample rate
	if( lRate > 100000 )		ClockInfo.ulSpeed	= SR_SPEED_4X;
	else if( lRate > 50000 )	ClockInfo.ulSpeed	= SR_SPEED_2X;
	else						ClockInfo.ulSpeed	= SR_SPEED_1X;

	// if the word bit is set, make sure the M, N & P registers are correct for the speed setting
	if( ClockInfo.ulWord )
	{
		ClockInfo.ulM		= 1;		// Ignored
		ClockInfo.ulBypassM	= 1;

		switch( ClockInfo.ulSpeed )
		{
		case SR_SPEED_1X:
			ClockInfo.ulN		= 1024;
			ClockInfo.ulP		= SR_P4;
			break;
		case SR_SPEED_2X:
			ClockInfo.ulN		= 512;
			ClockInfo.ulP		= SR_P2;
			break;
		case SR_SPEED_4X:
			ClockInfo.ulN		= 256;
			ClockInfo.ulP		= SR_P2;
			break;
		}
	}
	
	// if this is an AES16, and the speed isn't 1X, and widewire is on, and the digital input is the sample clock source
	// NOTE: WideWire has already been read above
	if( pAK4114 && (lRate > 50000) && bWideWireIn && ((lSource >= MIXVAL_AES16_CLKSRC_DIGITAL_0) || ((lSource == MIXVAL_AES16_CLKSRC_EXTERNAL) && (lReference == MIXVAL_CLKREF_WORD))) )
	{
		ClockInfo.ulN *= 2;	// double the N value
	}
	
	// change the sample rate in hardware
	//DPF(("Changing Sample Rate in Hardware\n"));
	if( (usDeviceID == PCIDEVICE_LYNXTWO_A) && !m_pHalAdapter->GetPCBRev() )	// is this a Model A rev NC board?
		m_RegPLLCTL = MAKE_PLLCTL_L2AREVNC( ClockInfo.ulM, ClockInfo.ulBypassM, ClockInfo.ulN, ClockInfo.ulP, ClockInfo.ulClkSrc, ClockInfo.ulWord, ClockInfo.ulSpeed );
	else
		m_RegPLLCTL = MAKE_PLLCTL( ClockInfo.ulM, ClockInfo.ulBypassM, ClockInfo.ulN, ClockInfo.ulP, ClockInfo.ulClkSrc, ClockInfo.ulWord, ClockInfo.ulSpeed );

	//set speed in A/D and D/A
	// since these writes are slow, update only if there is a speed change.
	if( m_ulSpeed != ClockInfo.ulSpeed )
	{
		m_pHalAdapter->SetConverterSpeed( lRate );
	}

	// if auto-recalibration is on (which is the default)
	if( m_pHalAdapter->GetAutoRecalibrate() )
	{
		// if P changed or the sample clock changed, recalibrate the converters
		if( (m_lSource != lSource) || (m_lReference != lReference) || (m_ulP != ClockInfo.ulP ) )
		{
			m_pHalAdapter->CalibrateConverters();
		}
	}

	// save the new values
	if( m_lSource != lSource )			pMixer->ControlChanged( LINE_ADAPTER, LINE_NO_SOURCE, CONTROL_CLOCKSOURCE );
	if( m_lReference != lReference )	pMixer->ControlChanged( LINE_ADAPTER, LINE_NO_SOURCE, CONTROL_CLOCKREFERENCE );
	if( m_lRate != lRate )				pMixer->ControlChanged( LINE_ADAPTER, LINE_NO_SOURCE, CONTROL_CLOCKRATE );

	m_lSource		= lSource;
	m_lReference	= lReference;
	m_lRate			= lRate;
	m_ulSpeed		= ClockInfo.ulSpeed;
	m_ulP			= ClockInfo.ulP;
	
	// if the Sample Clock Source is Digital, then we must set the 8420 to Mode 3
	if( pCS8420 && (m_lSource == MIXVAL_L2_CLKSRC_DIGITAL) )
	{
		// only make the change if the original source was internal
		if( lOriginalSource == MIXVAL_L2_CLKSRC_INTERNAL )
		{
			pCS8420->SetMode( MIXVAL_SRCMODE_SRC_OFF );
		}
	}

	// let the 8420 update the digital out channel status.  Since the 8420 is opened after 
	// the sample clock, make sure we don't call the 8420 until after the adapter is opened.
	if( m_pHalAdapter->IsOpen() )
	{
		if( pCS8420 )	pCS8420->SampleClockChanged( m_lRate );
		if( pAK4114 )	pAK4114->SampleClockChanged( m_lRate, m_lSource );
		m_pHalAdapter->GetLStream()->SampleClockChanged( m_lRate, m_lSource, m_lReference );
	}

	return( HSTATUS_OK );
}
Example #4
0
HRESULT Scheduler::ProcessSample(IMFSample *pSample, LONG *plNextSleep)
{
  HRESULT hr = S_OK;

  LONGLONG hnsPresentationTime = 0;
  LONGLONG hnsTimeNow = 0;
  MFTIME   hnsSystemTime = 0;

  BOOL bPresentNow = TRUE;
  LONG lNextSleep = 0;
  LONGLONG hnsDelta = 0;

  if (m_pClock)
  {
    // Get the sample's time stamp. It is valid for a sample to
    // have no time stamp.
    hr = pSample->GetSampleTime(&hnsPresentationTime);

    // Get the clock time. (But if the sample does not have a time stamp, 
    // we don't need the clock time.)
    if (SUCCEEDED(hr))
    {
      hr = m_pClock->GetCorrelatedTime(0, &hnsTimeNow, &hnsSystemTime);
    }

    // Calculate the time until the sample's presentation time. 
    // A negative value means the sample is late.
    hnsDelta = hnsPresentationTime - hnsTimeNow;
    float fCurrentRate = GetClockRate();
    if (fCurrentRate < 0)
    {
      // For reverse playback, the clock runs backward. Therefore the delta is reversed.
      hnsDelta = -hnsDelta;
    }

    if (abs(fCurrentRate) > 2)
    {
      if (abs(hnsDelta) > m_PerFrameInterval * GetFrameDropThreshold())
      {
        //TRACE((L"ProcessSample:  drop sample hnsDelta=%I64d m_PerFrameInterval=%I64d", hnsDelta, m_PerFrameInterval*10));
        return hr;
      }
    }

    if (hnsDelta < -m_PerFrame_1_4th)
    {
      // This sample is late. 
//TRACE((L"ProcessSample: sample is late hnsDelta=%I64d", hnsDelta));
      bPresentNow = TRUE;
    }
    else if (hnsDelta >(3 * m_PerFrame_1_4th))
    {
      // This sample is still too early. Go to sleep.
      lNextSleep = MFTimeToMsec(hnsDelta - (3 * m_PerFrame_1_4th));

      // Adjust the sleep time for the clock rate. (The presentation clock runs
      // at m_fRate, but sleeping uses the system clock.)
      lNextSleep = (LONG)(lNextSleep / fabsf(fCurrentRate));

      // Don't present yet.
      bPresentNow = FALSE;
    }
  }

  if (bPresentNow)
  {
    hr = m_pCB->PresentSample(pSample, hnsPresentationTime, hnsDelta, m_ScheduledSamples.Count(), m_PerFrame_1_4th);
  }
  else
  {
    // The sample is not ready yet. Return it to the queue.
    hr = m_ScheduledSamples.PutBack(pSample);
  }


  *plNextSleep = lNextSleep;

  return hr;
}