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

📄 play_capture_audio.c

📁 1. 8623L平台
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * * Copyright (c) 2001-2007 Sigma Designs, Inc.  * All Rights Reserved. Proprietary and Confidential. * *//**	@file   play_capture_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 0#define LOCALDBG ENABLE#else#define LOCALDBG DISABLE#endif#include "sample_os.h"#define ALLOW_OS_CODE 1#include "../rua/include/rua.h"#include "../rua/include/rua_property.h"#include "../dcc/include/dcc.h"#include "../rmcore/include/rmstatustostring.h"#include "../rmlibcw/include/rmlibcw.h"#include "common.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)//#include "play_capture_main.h"#include "play_capture_audio.h"struct capsam_audio_instance {	// Access	struct dcc_context *dcc_info;	struct capsam_audio_setup Setup;		// State	struct audio_cmdline *audio_opt;  // options for the audio playback (used because code in apply_audio_engine_options/apply_audio_decoder_options should not be duplicated)	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 capsam_audio_open(	struct dcc_context *dcc_info, 	struct capsam_audio_instance **ppAudio){	struct capsam_audio_instance *pAudio;	RMDBGLOG((FUNCNAME, "%s\n",__func__));		// Sanity checks	if (ppAudio == NULL) return RM_FATALINVALIDPOINTER;	*ppAudio = NULL;	if (dcc_info == NULL) return RM_FATALINVALIDPOINTER;		// Allocate and clear local instance	pAudio = (struct capsam_audio_instance *)RMMalloc(sizeof(struct capsam_audio_instance));	if (pAudio == NULL) {		fprintf(stderr, "FATAL! Not enough memory for struct capsam_audio_instance!\n");		return RM_FATALOUTOFMEMORY;	}	RMMemset(pAudio, 0, sizeof(struct capsam_audio_instance));	*ppAudio = pAudio;		// Set default and non-zero startup values	pAudio->dcc_info = dcc_info;	pAudio->Setup.STCTimerNumber = 1;	pAudio->Setup.AudioInAlign = 1;	pAudio->Setup.audio_free_run = TRUE;	pAudio->audio_state = audio_state_off;		return RM_OK;}/* destroy the audio instance, close open chips */RMstatus capsam_audio_close(	struct capsam_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	if (pAudio->audio_opt != NULL) {		err = capsam_audio_stop_passthrough(pAudio);	} else {		err = capsam_audio_stop_capture(pAudio);	}		RMFree(pAudio);		return err;}/* provide setup info to the audio capture */RMstatus capsam_audio_setup(	struct capsam_audio_instance *pAudio, 	struct capsam_audio_setup *pSetup,  // necessary info for the audio capture	struct audio_cmdline *audio_opt) // reference to the app's audio_opt, to set up the audio playback{	RMDBGLOG((FUNCNAME, "%s\n",__func__));	// Sanity checks	if (pAudio == NULL) return RM_FATALINVALIDPOINTER;	if (pSetup == NULL) return RM_FATALINVALIDPOINTER;		pAudio->Setup = *pSetup;  // copy	pAudio->audio_opt = audio_opt;  // reference, can be NULL		return RM_OK;}/* calculate SI_CONF matching the current setup */static RMstatus get_SI_CONF(	struct capsam_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 {		fprintf(stderr, "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->audio_opt != NULL) {			if (pAudio->audio_opt->Codec == AudioDecoder_Codec_PCM) {				switch (pAudio->audio_opt->SubCodec) {					default: BitsPerSample = pAudio->audio_opt->PcmCdaParams.BitsPerSample; break;					case  1: BitsPerSample = pAudio->audio_opt->LpcmVobParams.BitsPerSample; break;					case  2: BitsPerSample = pAudio->audio_opt->LpcmAobParams.BitsPerSampleGroup1; break;					case  3: BitsPerSample = pAudio->audio_opt->PcmCdaParams.BitsPerSample; break;				}			}		} else {			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 capsam_audio_get_spdif_channel_status(	struct capsam_audio_instance *pAudio, 	struct AudioEngine_InputSPDIFStatus_type *pStat){	RMstatus err;	struct AudioEngine_InputSPDIFStatus_type stat;	RMDBGLOG((FUNCNAME, "%s\n",__func__));		err = RUAGetProperty(pAudio->dcc_info->pRUA, 		EMHWLIB_MODULE(AudioEngine, pAudio->Setup.AudioEngineID), 		RMAudioEnginePropertyID_InputSPDIFStatus, 		&stat, sizeof(stat));	if (RMSUCCEEDED(err)) {		if (pStat) {			*pStat = stat;		} else {			fprintf(stderr, "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 capsam_audio_stop_capture(	struct capsam_audio_instance *pAudio){	enum AudioCapture_Capture_type cmd = AudioCapture_Capture_Off;	RMuint32 dummy = 0;	RMstatus err;	RMDBGLOG((FUNCNAME, "%s\n",__func__));		err = RUASetProperty(pAudio->dcc_info->pRUA, 		EMHWLIB_MODULE(AudioCapture, pAudio->Setup.AudioCaptureID), 		RMAudioCapturePropertyID_Capture, &cmd, sizeof(cmd), 0);	if (RMFAILED(err)) 		fprintf(stderr, "Error sending capture OFF command. %s\n", RMstatusToString(err));		err = RUASetProperty(pAudio->dcc_info->pRUA, 		EMHWLIB_MODULE(AudioCapture, pAudio->Setup.AudioCaptureID), 		RMAudioCapturePropertyID_Close, &dummy, sizeof(dummy), 0);	if (RMFAILED(err)) {		fprintf(stderr, "Error closing capture module! %s\n", RMstatusToString(err));	}		return err;}/* Initializes and starts capture */RMstatus capsam_audio_start_capture(	struct capsam_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->dcc_info->pRUA, pAudio->Setup.VideoCaptureModuleID, 			RMGenericPropertyID_CaptureDelay, &CaptureDelay, sizeof(CaptureDelay));		if (RMFAILED(err) || (CaptureDelay == 0)) {			CaptureDelay = 6004; // NTSC			// CaptureDelay = 7200; // PAL		}		else fprintf(stderr, "Audio Delay from Video Passthrough: %ld PTS, %ld mSec\n", CaptureDelay, CaptureDelay / 90);	}	fprintf(stderr, "Audio Delay: %ld PTS, %ld ms\n", CaptureDelay, CaptureDelay / 90);		memset(&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)) {		fprintf(stderr, "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;	}		//printf("capture source = %lx  spdif=%x SI_CONF = %lx\n", pAudio->Setup.CaptureSource, pAudio->audio_opt->Spdif, capture_open.SI_CONF);	err = RUASetProperty(pAudio->dcc_info->pRUA, 		EMHWLIB_MODULE(AudioCapture, pAudio->Setup.AudioCaptureID), 		RMAudioCapturePropertyID_Open, 		&capture_open, sizeof(capture_open), 0);	if (RMFAILED(err)) {		fprintf(stderr, "Error opening audio capture module! %s\n", RMstatusToString(err));		return err;	}		err = RUASetProperty(pAudio->dcc_info->pRUA, 		EMHWLIB_MODULE(AudioCapture, pAudio->Setup.AudioCaptureID), 		RMAudioCapturePropertyID_Source, 		&(src), sizeof(src), 0);	if (RMFAILED(err)) {		fprintf(stderr, "Error setting audio capture source! %s\n", RMstatusToString(err));		return err;	}		err = RUASetProperty(pAudio->dcc_info->pRUA, 		EMHWLIB_MODULE(AudioCapture, pAudio->Setup.AudioCaptureID), 		RMAudioCapturePropertyID_SpdifBitstreamNumber, 		&(pAudio->Setup.CaptureBitstream), sizeof(pAudio->Setup.CaptureBitstream), 0);	if (RMFAILED(err)) {		fprintf(stderr, "Error setting audio capture bitstream number! %s\n", RMstatusToString(err));		return err;	}		err = RUASetProperty(pAudio->dcc_info->pRUA, 		EMHWLIB_MODULE(AudioCapture, pAudio->Setup.AudioCaptureID), 		RMAudioCapturePropertyID_SpdifDataType, 		&(pAudio->Setup.CaptureType), sizeof(pAudio->Setup.CaptureType), 0);	if (RMFAILED(err)) {		fprintf(stderr, "Error setting audio capture type! %s\n", RMstatusToString(err));		return err;	}		cmd = AudioCapture_Capture_On;	err = RUASetProperty(pAudio->dcc_info->pRUA, 		EMHWLIB_MODULE(AudioCapture, pAudio->Setup.AudioCaptureID),		RMAudioCapturePropertyID_Capture, 		&cmd, sizeof(cmd), 0);	if (RMFAILED(err)) {		fprintf(stderr, "Error sending capture ON command. %s\n", RMstatusToString(err));	}		if (pAudio->Setup.audio_free_run) {		RMbool AVSyncEnable = FALSE;		struct DCCAudioSourceHandle AudioHandle;				// 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 = DCCMultipleAudioSourceGetSingleDecoderHandleForInstance(pAudio->dcc_info->pMultipleAudioSource, 0, &AudioHandle);		if (RMFAILED(err)) {			AudioHandle.moduleID = pAudio->dcc_info->audio_decoder;		}		err = RUASetProperty(pAudio->dcc_info->pRUA, AudioHandle.moduleID, 			RMAudioDecoderPropertyID_SyncSTCEnable, 			&AVSyncEnable, sizeof(AVSyncEnable), 0);		if (RMFAILED(err)) {			fprintf(stderr, "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 capsam_audio_print_bitstream_fifo_info(struct dcc_context *dcc_info, RMuint32 threshold){	RMstatus err;	struct DataFIFOInfo audio_info;	RMDBGLOG((FUNCNAME, "%s\n",__func__));		err = RUAGetProperty(dcc_info->pRUA, dcc_info->audio_decoder, 		RMGenericPropertyID_DataFIFOInfo, 		&audio_info, sizeof(audio_info));	if (RMFAILED(err)) {		fprintf(stderr, "Cannot retreive A.FIFO!\n");	} else {		if (audio_info.Readable * 100 / audio_info.Size >= threshold) 			fprintf(stderr, "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) {			fprintf(stderr, "FATAL ERROR: audio playback has crashed!\n");		}	}}/* Stops capture, and playback of captured audio */RMstatus capsam_audio_stop_passthrough(	struct capsam_audio_instance *pAudio){

⌨️ 快捷键说明

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