⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 audio.c

📁 1. 8623L平台
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * * Copyright (c) 2001-2007 Sigma Designs, Inc.  * All Rights Reserved. Proprietary and Confidential. * *//**	@file   audio.c	@brief  functions to set up the emhwlib audio passthrough (no external chip interaction)		@author Christian Wolff Sean.Sekwon.Choi*/// to enable or disable the debug messages of this source file, put 1 or 0 below#if 1#define LOCALDBG ENABLE#else#define LOCALDBG DISABLE#endif#include "common.h"#include "audio.h"// TODO:#define AUDIO_GUARD_TIME 2  // wait 2 seconds after audio has been set up until audio passtrough can be restarted#define AUDIO_FIFO_SIZE (2048*1024)#define XFER_FIFO_COUNT (32)struct cap_audio_instance {	// Access	struct RUA *pRUA;	struct DCC *pDCC;	struct DCCAudioSource *pAudioSource;	struct rmcapture_options *cap_opt;		// State	struct cap_audio_setup Setup;	enum audio_state audio_state;	RMuint64 audio_guard_time;	RMbool audio_pll_locked;   // stability of audio clock	RMbool auto_detect_codec;  // TRUE: codec of the incoming audio needs to be determined	RMuint32 CurrChStat;	RMuint16 CurrPc;};/* create the audio instace */RMstatus cap_audio_open(	struct RUA *pRUA, 	struct DCC *pDCC, 	struct rmcapture_options *cap_opt, 	struct cap_audio_instance **ppAudio){	struct cap_audio_instance *pAudio;	RMDBGLOG((FUNCNAME, "%s\n",__func__));		// Sanity checks	if (ppAudio == NULL) return RM_FATALINVALIDPOINTER;	*ppAudio = NULL;	if (pRUA == NULL) return RM_FATALINVALIDPOINTER;	if (pDCC == NULL) return RM_FATALINVALIDPOINTER;	if (cap_opt == NULL) return RM_FATALINVALIDPOINTER;		// Allocate and clear local instance	pAudio = (struct cap_audio_instance *)RMMalloc(sizeof(struct cap_audio_instance));	if (pAudio == NULL) {		RMDBGLOG((ENABLE, "FATAL! Not enough memory for struct cap_audio_instance!\n"));		return RM_FATALOUTOFMEMORY;	}	RMMemset(pAudio, 0, sizeof(struct cap_audio_instance));	*ppAudio = pAudio;		// Set default and non-zero startup values	pAudio->cap_opt = cap_opt;	pAudio->Setup.STCTimerNumber = cap_opt->STCTimerNumber;	pAudio->Setup.AudioInAlign = cap_opt->AudioInAlign;	pAudio->Setup.audio_free_run = cap_opt->audio_free_run;	pAudio->Setup.AudioEngineID = cap_opt->AudioEngineID;	pAudio->Setup.AudioDecoderID = cap_opt->AudioDecoderID;	// TODO honor rest of cap_opt audio options	pAudio->audio_state = audio_state_off;		return RM_OK;}/* destroy the audio instance, close open chips */RMstatus cap_audio_close(	struct cap_audio_instance *pAudio){	RMstatus err = RM_OK;	RMDBGLOG((FUNCNAME, "%s\n",__func__));		// Sanity checks	if (pAudio == NULL) return RM_OK;  // already closed		// Free all available ressources	err = cap_audio_stop_capture(pAudio);		RMFree(pAudio);		return err;}/* provide setup info to the audio capture */RMstatus cap_audio_setup(	struct cap_audio_instance *pAudio, 	struct cap_audio_setup *pSetup)  // necessary info for the audio capture{	RMDBGLOG((FUNCNAME, "%s\n",__func__));	// Sanity checks	if (pAudio == NULL) return RM_FATALINVALIDPOINTER;	if (pSetup == NULL) return RM_FATALINVALIDPOINTER;		pAudio->Setup = *pSetup;  // copy		return RM_OK;}/* calculate SI_CONF matching the current setup */static RMstatus get_SI_CONF(	struct cap_audio_instance *pAudio, 	RMuint32 *pSI_CONF){	RMDBGLOG((FUNCNAME, "%s\n",__func__));	// Capture from I2S, 32 bit frames	if (pAudio->Setup.CaptureSource == 0) {		// *pSI_CONF = 0x009;  // 16 bit I2S frames		*pSI_CONF = 0x007 |  // SerialIn Configuration, 32 bit frames			((pAudio->Setup.AudioInAlign & 0x1F) << 3) | 			(pAudio->Setup.AudioInSClkNegEdge ? 0x000 : 0x100) | 			(pAudio->Setup.AudioInLSBfirst    ? 0x200 : 0x000) | 			(pAudio->Setup.AudioInFrameInvert ? 0x400 : 0x000);	} else 	// Capture from SPDIF, always 16 bit frames#ifdef RMFEATURE_HAS_SPDIF_INPUT  // in 8622/24 Tango 1.5 and 8634 Tango 2, spdif is dedicated line. use it with source=1	if (pAudio->Setup.CaptureSource == 1) {		*pSI_CONF = 0x800 |  // capture from SI_SPDIF			(pAudio->Setup.AudioInSClkNegEdge ? 0x000 : 0x100);	} else #endif	if (pAudio->Setup.CaptureSource <= 2) {		*pSI_CONF = 0x000 |  // capture from SI_DATA			(pAudio->Setup.AudioInSClkNegEdge ? 0x000 : 0x100);	} else {		RMDBGLOG((ENABLE, "Error, unsupported audio source: %lu\n", pAudio->Setup.CaptureSource));		return RM_ERROR;	}		*pSI_CONF |= 0x80000000;  // extended info in unused bits of SI_CONF	if (pAudio->Setup.CaptureSource == 0) {  // only I2S supports more than 16 bits per sample		RMuint32 BitsPerSample = 16;				if (pAudio->cap_opt->Codec == AudioDecoder_Codec_PCM) {			switch (pAudio->cap_opt->SubCodec) {				case  0: BitsPerSample = pAudio->cap_opt->PcmCdaParams.BitsPerSample; break;				case  1: BitsPerSample = pAudio->cap_opt->LpcmVobParams.BitsPerSample; break;				case  2: BitsPerSample = pAudio->cap_opt->LpcmAobParams.BitsPerSampleGroup1; break;				case  3: BitsPerSample = pAudio->cap_opt->PcmCdaParams.BitsPerSample; break;				default: BitsPerSample = pAudio->Setup.BitsPerSample;			}		}		if (BitsPerSample >= 24) {			*pSI_CONF |= 0x40000000;  // don't truncate 24 bit PCM samples to 16 bits		}	}		return RM_OK;}/* retreive current SPDIF channel status and payload header info from em8xxx */RMstatus cap_audio_get_spdif_channel_status(	struct cap_audio_instance *pAudio, 	struct AudioEngine_InputSPDIFStatus_type *pStat){	RMstatus err;	struct AudioEngine_InputSPDIFStatus_type stat;	RMDBGLOG((FUNCNAME, "%s\n",__func__));		err = RUAGetProperty(pAudio->pRUA, 		EMHWLIB_MODULE(AudioEngine, pAudio->Setup.AudioEngineID), 		RMAudioEnginePropertyID_InputSPDIFStatus, 		&stat, sizeof(stat));	if (RMSUCCEEDED(err)) {		if (pStat) {			*pStat = stat;		} else {			RMDBGLOG((ENABLE, "Audio Input channel status [18:0]: 0x%05lX Pc:%04X Pd:%04X Pe:%04X Pf:%04X\n", stat.ChannelStatus, stat.Pc, stat.Pd, stat.Pe, stat.Pf));		}	}		return err;}/* Stops capture */RMstatus cap_audio_stop_capture(	struct cap_audio_instance *pAudio){	enum AudioCapture_Capture_type cmd = AudioCapture_Capture_Off;	RMuint32 dummy = 0;	RMstatus err;	RMDBGLOG((FUNCNAME, "%s\n",__func__));		err = RUASetProperty(pAudio->pRUA, 		EMHWLIB_MODULE(AudioCapture, pAudio->Setup.AudioCaptureID), 		RMAudioCapturePropertyID_Capture, &cmd, sizeof(cmd), 0);	if (RMFAILED(err)) 		RMDBGLOG((ENABLE, "Error sending capture OFF command. %s\n", RMstatusToString(err)));		err = RUASetProperty(pAudio->pRUA, 		EMHWLIB_MODULE(AudioCapture, pAudio->Setup.AudioCaptureID), 		RMAudioCapturePropertyID_Close, &dummy, sizeof(dummy), 0);	if (RMFAILED(err)) {		RMDBGLOG((ENABLE, "Error closing capture module! %s\n", RMstatusToString(err)));	}		return err;}/* Initializes and starts capture */RMstatus cap_audio_start_capture(	struct cap_audio_instance *pAudio){	struct AudioCapture_Open_type capture_open;	enum AudioCapture_Capture_type cmd;	enum AudioCapture_Source_type src;	RMuint32 CaptureDelay;	RMstatus err;	RMDBGLOG((FUNCNAME, "%s\n",__func__));		// Sanity checks	if (pAudio == NULL) return RM_FATALINVALIDPOINTER;	//pAudio->Setup.CaptureDelay = 6004;		// Retreive video delay and apply to audio, unless specified on command line	if (pAudio->Setup.CaptureDelay) {		CaptureDelay = pAudio->Setup.CaptureDelay;	} else {		// actual video delay is plus/minus one field duration of this value, depending on input-to-output vsync phase		err = RUAGetProperty(pAudio->pRUA, pAudio->Setup.VideoCaptureModuleID, 			RMGenericPropertyID_CaptureDelay, &CaptureDelay, sizeof(CaptureDelay));		if (RMFAILED(err) || (CaptureDelay == 0)) {			CaptureDelay = 6004; // NTSC			// CaptureDelay = 7200; // PAL		}		else RMDBGLOG((ENABLE, "Audio Delay from Video Passthrough: %ld PTS, %ld mSec\n", CaptureDelay, CaptureDelay / 90));	}	RMDBGLOG((ENABLE, "Audio Delay: %ld PTS, %ld ms\n", CaptureDelay, CaptureDelay / 90));		RMMemset(&capture_open, 0, sizeof(struct AudioCapture_Open_type));	capture_open.CaptureMode = 1; // Pass-through	capture_open.Delay = CaptureDelay / 2; // Delay is 45000 Hz based start PTS		err = get_SI_CONF(pAudio, &(capture_open.SI_CONF));	if (RMFAILED(err)) {		RMDBGLOG((ENABLE, "Error setting up audio input! %s\n", RMstatusToString(err)));		return err;	}		if (pAudio->Setup.CaptureSource == 0) {		src = AudioCapture_Source_I2S;	} else {		src = AudioCapture_Source_SPDIF;	}		//RMDBGLOG((LOCALDBG, "capture source = %lx  spdif=%x SI_CONF = %lx\n", pAudio->Setup.CaptureSource, pAudio->audio_opt->Spdif, capture_open.SI_CONF));	err = RUASetProperty(pAudio->pRUA, 		EMHWLIB_MODULE(AudioCapture, pAudio->Setup.AudioCaptureID), 		RMAudioCapturePropertyID_Open, 		&capture_open, sizeof(capture_open), 0);	if (RMFAILED(err)) {		RMDBGLOG((ENABLE, "Error opening audio capture module! %s\n", RMstatusToString(err)));		return err;	}		err = RUASetProperty(pAudio->pRUA, 		EMHWLIB_MODULE(AudioCapture, pAudio->Setup.AudioCaptureID), 		RMAudioCapturePropertyID_Source, 		&(src), sizeof(src), 0);	if (RMFAILED(err)) {		RMDBGLOG((ENABLE, "Error setting audio capture source! %s\n", RMstatusToString(err)));		return err;	}		err = RUASetProperty(pAudio->pRUA, 		EMHWLIB_MODULE(AudioCapture, pAudio->Setup.AudioCaptureID), 		RMAudioCapturePropertyID_SpdifBitstreamNumber, 		&(pAudio->Setup.CaptureBitstream), sizeof(pAudio->Setup.CaptureBitstream), 0);	if (RMFAILED(err)) {		RMDBGLOG((ENABLE, "Error setting audio capture bitstream number! %s\n", RMstatusToString(err)));		return err;	}		err = RUASetProperty(pAudio->pRUA, 		EMHWLIB_MODULE(AudioCapture, pAudio->Setup.AudioCaptureID), 		RMAudioCapturePropertyID_SpdifDataType, 		&(pAudio->Setup.CaptureType), sizeof(pAudio->Setup.CaptureType), 0);	if (RMFAILED(err)) {		RMDBGLOG((ENABLE, "Error setting audio capture type! %s\n", RMstatusToString(err)));		return err;	}		cmd = AudioCapture_Capture_On;	err = RUASetProperty(pAudio->pRUA, 		EMHWLIB_MODULE(AudioCapture, pAudio->Setup.AudioCaptureID),		RMAudioCapturePropertyID_Capture, 		&cmd, sizeof(cmd), 0);	if (RMFAILED(err)) {		RMDBGLOG((ENABLE, "Error sending capture ON command. %s\n", RMstatusToString(err)));	}		if (pAudio->Setup.audio_free_run) {		RMbool AVSyncEnable = FALSE;				// wait until audio decoder has started the delayed playback		RMMicroSecondSleep(CaptureDelay * 200 / 9);  // actual delay in uSec: CaptureDelay * 100 / 9				// Disable AV-Sync (for now, because STC is running on asynchronous clock, which breaks the passthrough after some time.)		err = RUASetProperty(pAudio->pRUA, 			EMHWLIB_MODULE(AudioDecoder, pAudio->Setup.AudioDecoderID), 			RMAudioDecoderPropertyID_SyncSTCEnable, 			&AVSyncEnable, sizeof(AVSyncEnable), 0);		if (RMFAILED(err)) {			RMDBGLOG((ENABLE, "Error disabling AV-Sync! %s\n", RMstatusToString(err)));			return err;		} else {			RMDBGLOG((ENABLE, "\n*********\n AUDIO sync is %s\n*********\n", AVSyncEnable ? "enabled" : "disabled"));		}	}		return err;}void cap_audio_print_bitstream_fifo_info(struct cap_audio_instance *pAudio, RMuint32 threshold){	RMstatus err;	struct DataFIFOInfo audio_info;	RMDBGLOG((FUNCNAME, "%s\n",__func__));		err = RUAGetProperty(pAudio->pRUA, 		EMHWLIB_MODULE(AudioDecoder, pAudio->Setup.AudioDecoderID), 		RMGenericPropertyID_DataFIFOInfo, 		&audio_info, sizeof(audio_info));	if (RMFAILED(err)) {		RMDBGLOG((ENABLE, "Cannot retreive A.FIFO!\n"));	} else {		if (audio_info.Readable * 100 / audio_info.Size >= threshold) 			RMDBGLOG((ENABLE, "A.FIFO: St.0x%08lX Sz.0x%08lX Wr.0x%08lX Rd.0x%08lX %3lu%% full, %lu readable\n", 				audio_info.StartAddress, audio_info.Size, audio_info.Writable, audio_info.Readable, 				audio_info.Readable * 100 / audio_info.Size, audio_info.Readable));		if (audio_info.Readable > audio_info.Size) {			RMDBGLOG((ENABLE, "FATAL ERROR: audio playback has crashed!\n"));		}	}}// Set up the audio clock on the audio engine, settings from pAudio->Setupstatic RMstatus cap_audio_set_sample_clock(	struct cap_audio_instance *pAudio){	struct AudioEngine_SampleFrequencyFromSource_type sf;		sf.GeneratorNumber = 3;	sf.SampleFrequency = pAudio->Setup.SampleRate;	if (pAudio->Setup.ExternalClk) {  // external clock source		sf.Source = 4;  // RClkIn0		if (pAudio->Setup.ExternalClkFreq) {			sf.SourceFrequency = pAudio->Setup.ExternalClkFreq;		} else {			sf.SourceFrequency = sf.SampleFrequency * ((pAudio->cap_opt->mclk == MClkFactor_256Xfs) ? 256 : 128);		}		sf.IntermediateFrequency = sf.SourceFrequency * 8;	} else {  // internal clock source		sf.Source = 1;  // XTalIn		sf.SourceFrequency = 27000000;		sf.IntermediateFrequency = 148500000;  // dummy value	}	return RUASetProperty(pAudio->pRUA, 		EMHWLIB_MODULE(AudioEngine, pAudio->Setup.AudioEngineID), 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -