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

📄 play_audio.c

📁 Sample code for use on smp 863x processor.
💻 C
📖 第 1 页 / 共 5 页
字号:
		}		RMDBGLOG((ENABLE, "\n****************\nAUDIO_IN enabled\n***************\n"));		DCCSTCSetTime(dcc_info.pStcSource, 0, 90000);		DCCSTCPlay(dcc_info.pStcSource); 		// Send Play command to audio playback		err = DCCPlayMultipleAudioSource(dcc_info.pMultipleAudioSource);		if (RMFAILED(err)) {			fprintf(stderr, "Cannot play audio decoder %d\n", err);			goto cleanup;		}				if (1) {						RMbool AVSyncEnable = FALSE;			struct DCCAudioSourceHandle audioHandle1;						// wait until audio decoder has started the delayed playback			RMMicroSecondSleep(context.audio_opt[0].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(dcc_info.pMultipleAudioSource, 0, &audioHandle1);			if (RMFAILED(err)) {				audioHandle1.moduleID = dcc_info.audio_decoder;			}			err = RUASetProperty(dcc_info.pRUA, audioHandle1.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"));			}		}				// Start audio capture		err = StartAudioCapture(&dcc_info, audio_capture, &(context.audio_opt[0]), &context);		if (RMFAILED(err)) {			fprintf(stderr, "Error starting audio capture! %s\n", RMstatusToString(err));			goto cleanup;		}				context.play_opt->waitexit = TRUE; // Force wait on exit							if(!context.fp_capture){			goto cleanup;		}else{			goto capture_loop;		}	} else {		file = open_stream(context.play_opt->filename, RM_FILE_OPEN_READ, 0);		if (file == NULL) {			fprintf(stderr, "Cannot open file %s\n", context.play_opt->filename);			goto cleanup;		}		context.f_bitstream = file;		RMSizeOfOpenFile(file, &context.fileSize);		if (context.audio_opt[0].skip_first_n_bytes) {			context.skipFirstNBytes = context.audio_opt[0].skip_first_n_bytes;			RMDBGLOG((ENABLE, ">> skip first %lu bytes, adjust file size from %llu to %llu\n",				  context.skipFirstNBytes,				  context.fileSize,				  context.fileSize - context.skipFirstNBytes));			context.fileSize -= context.skipFirstNBytes;		}					if (context.audio_opt[0].send_n_bytes) {			context.sendNBytes = context.audio_opt[0].send_n_bytes;			RMDBGLOG((ENABLE, ">> send up to %lu bytes only, adjust file size from %llu to %lu\n",				  context.sendNBytes,				  context.fileSize,				  context.sendNBytes));			// pcm should start at the correct sample position			if (context.audio_opt[0].Codec == AudioDecoder_Codec_PCM) {				context.sendNBytes -= context.sendNBytes % context.PCMblockSize;				RMDBGLOG((ENABLE, "aligned to %lu\n", context.sendNBytes));			}				  			context.fileSize = context.sendNBytes;		}	  		RMDBGLOG((ENABLE, "file: %s, size %llu, duration %llu\n", context.play_opt->filename, context.fileSize, context.play_opt->duration / 1000));		context.Duration = context.play_opt->duration / 1000;		context.audio_vop_tir = 90000;		dcc_info.RM_PSM_commands = RM_PSM_ENABLE_PLAY;		dcc_info.RM_PSM_commands |= RM_PSM_ENABLE_STOP;		dcc_info.RM_PSM_commands |= RM_PSM_ENABLE_PAUSE;		if (context.Duration)			fprintf(stderr, "duration %llu secs\n", context.Duration);		if ((context.play_opt->duration > 1000) && (context.fileSize > 0)) {			RMDBGLOG((ENABLE, "seek and ffwd trick mode enabled\n"));			dcc_info.RM_PSM_commands |= RM_PSM_ENABLE_SPEED;			dcc_info.RM_PSM_commands |= RM_PSM_ENABLE_FASTER;			dcc_info.RM_PSM_commands |= RM_PSM_ENABLE_SLOWER;			dcc_info.RM_PSM_commands |= RM_PSM_ENABLE_SEEK;			dcc_info.RM_PSM_commands |= RM_PSM_ENABLE_REWIND;			dcc_info.seek_supported = TRUE;		}	}	context.dcc_info = &dcc_info;	context.PSMcontext = &PSMContext;	PSMContext.validPSMContexts = 1;	PSMContext.currentActivePSMContext = 1;	PSMContext.keyflags = KEYFLAGS;#if DUMP_DATA	RMDBGLOG((ENABLE, "\t\t\t***** OPEN SAVE DATA FILE ****\n"));	context.saveFile = fopen("ec3_transcoded_ac3.with_pushLibrary.dump", "wb");#endif	if (context.audio_opt[0].transcode_ec3_to_ac3) {		struct RMEC3subParams_struct subParams;		RMuint32 ch;		RMDBGLOG((ENABLE, "init ec3 transcoding lib\n"));		context.transcodeEC3toAC3 = TRUE;		subParams.compMode = RMEC3_COMP_LINE;		subParams.outLFE = RMEC3_LFEOUT_ON;		subParams.outChanConfig = RMEC3_MODE32;		subParams.pcmScale = RMEC3_DEFAULTSCALEFACTOR;		subParams.stereoMode = RMEC3_STEREOMODE_AUTO;		subParams.dualMode = RMEC3_DUAL_STEREO;		subParams.dynScaleHigh = RMEC3_DEFAULTSCALEFACTOR;		subParams.dynScaleLow = RMEC3_DEFAULTSCALEFACTOR;		for (ch = 0; ch < RMEC3_MAXPCMCHANS; ch++)			subParams.chanRouting[ch] = ch;		subParams.subStream = RMEC3_DEFAULTSUBSTREAMID;#if defined(KCAPABLE)		subParams.karaokeMode = RMEC3_BOTH_VOCALS;#endif /* defined(KCAPABLE) */		context.ec3TranscoderHandle = RMEC3OpenTranscoder(subParams);		if (!context.ec3TranscoderHandle) {			fprintf(stderr, "couldnt init ec3 transcoding library\n");			goto cleanup;		}		context.readBuffer = (RMuint8*)RMMalloc((1<<context.play_opt->dmapool_log2size) * sizeof(RMuint8));		if (!context.readBuffer) {			fprintf(stderr, "couldnt init read buffer required by ec3 lib\n");			goto cleanup;		}		RMDBGLOG((ENABLE, "allocated %lu bytes of read buffer\n", (1<<context.play_opt->dmapool_log2size)));	}	/***************************************************************	Play_audio does NOT have PTS to sync		****************************************************************/	// Disable AV-Sync (for now, because STC is running on asynchronous clock, which breaks the passthrough after some time.)	{		struct DCCAudioSourceHandle audioHandle1;		RMbool sync_stc = FALSE;		err = DCCMultipleAudioSourceGetSingleDecoderHandleForInstance(dcc_info.pMultipleAudioSource, 0, &audioHandle1);		if (RMSUCCEEDED(err))  {			err = RUASetProperty(dcc_info.pRUA, audioHandle1.moduleID, RMAudioDecoderPropertyID_SyncSTCEnable, &sync_stc, sizeof(RMbool), 0);		}		else		{			err = RUASetProperty(dcc_info.pRUA, dcc_info.audio_decoder, RMAudioDecoderPropertyID_SyncSTCEnable, &sync_stc, sizeof(RMbool), 0);		}		if (RMFAILED(err)) {			fprintf(stderr, "Error disabling AV-Sync! %s\n", RMstatusToString(err));			return err;		}	}	////////////////////////////////////////////////////////////////////////	// main playback loop	////////////////////////////////////////////////////////////////////////	do {		enum RM_PSM_State PlaybackStatus;		RMDBGLOG((ENABLE, "do-while\n"));		if (context.play_opt->start_pause) 			RM_PSM_SetState(context.PSMcontext, &(context.dcc_info), RM_PSM_Paused);		else			RM_PSM_SetState(context.PSMcontext, &(context.dcc_info), RM_PSM_Playing);		context.play_opt->start_pause = FALSE;	mainloop:		RMDBGLOG((ENABLE, "mainloop\n"));		file_offset = 0;		if (RMSeekFile(file, context.skipFirstNBytes, RM_FILE_SEEK_START) != RM_OK) {			perror("seeking file to beginning\n");			goto cleanup;		}	mainloop_no_seek:		RMDBGLOG((ENABLE, "mainloop no seek\n"));				context.FirstPTS = 0;		// pcm should start at the correct sample position		if ((context.audio_opt[0].Codec == AudioDecoder_Codec_PCM) && (!context.skipFirstNBytes)) {			RMint64 filePos = 0;			RMint64 seekPos;			RMGetCurrentPositionOfFile(file, &filePos);			seekPos = filePos;			seekPos -= seekPos % context.PCMblockSize;			RMDBGLOG((ENABLE, "filePos %lld, blockSize %lu, new seekPos %lld\n", filePos, context.PCMblockSize, seekPos));			RMSeekFile(file, seekPos, RM_FILE_SEEK_START);		}	mainloop_seek:				context.lastSTC = 0;		context.FirstSystemTimeStamp = TRUE;		context.trickMode = FALSE;		context.dcc_info->state = RM_PLAYING;		DCCSTCSetSpeed(dcc_info.pStcSource, 1, 1);		PlaybackStatus = RM_PSM_GetState(context.PSMcontext, &(context.dcc_info));		if ((PlaybackStatus != RM_PSM_Paused) && (PlaybackStatus != RM_PSM_Stopped)) {			RMDBGLOG((ENABLE, "setting play state\n"));			RM_PSM_SetState(context.PSMcontext, &(context.dcc_info), RM_PSM_Playing);			}		else 			PROCESS_KEY(FALSE, TRUE);				// the following call will configure the decoders, after that we can 'pause' them		err = Play(&context, RM_DEVICES_AUDIO);		if (err != RM_OK)			goto cleanup;		/* do prebufferization only when in playing state */		if (RM_PSM_GetState(context.PSMcontext, &(context.dcc_info)) == RM_PSM_Playing) {			Pause(&context, RM_DEVICES_STC | RM_DEVICES_AUDIO);					RM_PSM_SetState(context.PSMcontext, &(context.dcc_info), RM_PSM_Prebuffering);			fprintf(stderr, "prebuffering\n");		}#ifdef WITH_MONO		RMDCCInfo(&dcc_info); // pass DCC context to application#endif		/* wake up disks if necessary */		switch (context.play_opt->disk_ctrl_state) {		case DISK_CONTROL_STATE_DISABLE:		case DISK_CONTROL_STATE_RUNNING:			break;		case DISK_CONTROL_STATE_SLEEPING:			if(context.play_opt->disk_ctrl_callback && context.play_opt->disk_ctrl_callback(DISK_CONTROL_ACTION_RUN) == RM_OK)				context.play_opt->disk_ctrl_state = DISK_CONTROL_STATE_RUNNING;			break;		}#ifdef WITH_BSAC		bsac_frame_size = 0;		DMA_buf_size = 0;		bsac_get_info_done = 0;#endif		while (1) { // additional 'while' used for taking care of commands issued during EOSWait			while (1) {				RMuint32 count;				RMuint32 bufferSize = (1<<context.play_opt->dmapool_log2size);				RMstatus status = RM_OK;				struct emhwlib_info Info;				struct emhwlib_info *pInfo = &Info;				RMuint32 Info_size = sizeof(Info);				RMint32 lastOKinstance = -1;				if ((context.sendNBytes) && (!context.trickMode)) {					RMint64 current_file_offset;										RMGetCurrentPositionOfFile(file, &current_file_offset);					if (current_file_offset - context.skipFirstNBytes > context.sendNBytes) {						RMDBGLOG((ENABLE, "a seek beyond the sendable data occurred\n"));						RMDBGLOG((ENABLE, "stop sending data at %llu (sendNBytes %lu, skipNBytes %lu)\n", 							  current_file_offset,							  context.sendNBytes,							  context.skipFirstNBytes));						break;					}					bufferSize = context.sendNBytes - (RMuint32)current_file_offset - context.skipFirstNBytes;										bufferSize = RMmin( (RMuint32)(1<<context.play_opt->dmapool_log2size), (RMuint32)bufferSize);					if (!bufferSize) {						RMDBGLOG((ENABLE, "stop sending data at %llu (sendNBytes %lu, skipNBytes %lu)\n", 							  current_file_offset,							  context.sendNBytes,							  context.skipFirstNBytes));						break;					}				}				else					bufferSize = (1<<context.play_opt->dmapool_log2size);												PROCESS_KEY(FALSE, TRUE);							update_hdmi_audio(context.dcc_info, &(context.audio_opt[0]));								if (buf)					RMDBGLOG((ENABLE, "*************unreleased buffer found!\n"));							get_buffer:				switch (context.play_opt->disk_ctrl_state) {				case DISK_CONTROL_STATE_DISABLE:				case DISK_CONTROL_STATE_SLEEPING:					break;				case DISK_CONTROL_STATE_RUNNING:					if (context.dmabuffer_index > 0) {						context.dmabuffer_index--;						buf = context.dmabuffer_array[context.dmabuffer_index];						RMDBGLOG((ENABLE, "fill buffer phase: got buffer %p (index %lu, level %lu, count %lu)\n", 							  buf,							  context.dmabuffer_index,							  context.play_opt->disk_ctrl_low_level,							  context.play_opt->dmapool_count));												goto fill_buffer;					}					break;				}		      				while (RUAGetBuffer(context.pDMA, &buf,  GETBUFFER_TIMEOUT_US) != RM_OK) {					check_prebuf_state(&context, 0);					/* fprintf(stderr, "Wait for a buffer\n"); */					switch (context.play_opt->disk_ctrl_state) {					case DISK_CONTROL_STATE_DISABLE:					case DISK_CONTROL_STATE_SLEEPING:						break;					case DISK_CONTROL_STATE_RUNNING:						if(context.play_opt->disk_ctrl_callback && context.play_opt->disk_ctrl_callback(DISK_CONTROL_ACTION_SLEEP) == RM_OK)							context.play_opt->disk_ctrl_state = DISK_CONTROL_STATE_SLEEPING;						break;					}					PROCESS_KEY(FALSE, TRUE);					update_hdmi_audio(context.dcc_info, &(context.audio_opt[0]));				}						check_prebuf_state(&context, bufferSize);				switch (context.play_opt->disk_ctrl_state) {				case DISK_CONTROL_STATE_DISABLE:				case DISK_CONTROL_STATE_RUNNING:					break;				case DISK_CONTROL_STATE_SLEEPING:					context.dmabuffer_array[context.dmabuffer_index] = buf;					context.dmabuffer_index ++;					if (context.dmabuffer_index + context.play_opt->disk_ctrl_low_level >= context.play_opt->dmapool_count) {						if(context.play_opt->disk_ctrl_callback && context.play_opt->disk_ctrl_callback(DISK_CONTROL_ACTION_RUN) == RM_OK)							context.play_opt->disk_ctrl_state = DISK_CONTROL_STATE_RUNNING;					}					RMDBGLOG((ENABLE, "recycle buffer phase: got buffer %p (index %lu, level %lu, count %lu)\n", 						  buf,						  context.dmabuffer_index,

⌨️ 快捷键说明

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