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

📄 play_audio.c

📁 Sample code for use on smp 863x processor.
💻 C
📖 第 1 页 / 共 5 页
字号:
						  context.play_opt->disk_ctrl_low_level,						  context.play_opt->dmapool_count));					goto get_buffer;				}							fill_buffer:				{					RMint64 currentTime;					RMuint64 stc;									DCCSTCGetTime(context.dcc_info->pStcSource, &stc, context.audio_vop_tir);					currentTime = (RMint64)stc;					if ((currentTime > (RMint64)(context.lastSTC + context.audio_vop_tir)) ||					    (currentTime < (RMint64)(context.lastSTC - context.audio_vop_tir))){						context.lastSTC = currentTime;						currentTime /= context.audio_vop_tir;						if (context.Duration) {							RMDBGLOG((ENABLE, "stc time = %llu/%llu secs (%lld/100)\n", currentTime, context.Duration, (currentTime * 100)/context.Duration));						}						else							RMDBGLOG((ENABLE, "stc time = %llu secs\n", currentTime));					}				}				if (context.trickMode) {					RMint64 currentTime;					RMuint64 stc;					DCCSTCGetTime(context.dcc_info->pStcSource, &stc, context.audio_vop_tir);					currentTime = (RMint64)stc;					status = RM_SKIP_DATA; // dont send the buffers					if ((currentTime > (RMint64)(context.lastSTC + context.audio_vop_tir)) ||					    (currentTime < (RMint64)(context.lastSTC - context.audio_vop_tir))){						context.lastSTC = currentTime;					}					currentTime /= context.audio_vop_tir;					if ((currentTime > (RMint64)context.Duration) || (currentTime < 0)) {						fprintf(stderr, "end of file\n");						status = RM_ERRORENDOFFILE;					}					usleep(100000); // to prevent high CPU usage				}				else {					if (!context.transcodeEC3toAC3) {#ifndef WITH_BSAC						status = RMReadFile(file, buf, bufferSize, &count);#else // WITH_BSAC						if(context.audio_opt[0].Codec != AudioDecoder_Codec_BSAC)							status = RMReadFile(file, buf, bufferSize, &count);						else {								RMuint32 val;								RMuint8 *bsac_buf = buf;								RMuint8 *bsac_bts_buf = context.bsac_bts_buf;								bsac_bts_buf = (RMuint8*)(((RMuint32)bsac_bts_buf+3) & (~0x3));//libbsac only work with dword aligned buf																status = RMReadFile(file, bsac_bts_buf, 2, &count);								//fprintf(stdout, "%ld bytes are read  ", count);								if (status == RM_ERRORREADFILE || status == RM_ERRORENDOFFILE)									goto audio_file_eos;																file_offset += count;								val = ((RMuint32)bsac_bts_buf[0]<<3) | (((RMuint32)bsac_bts_buf[1]>>5) & 0x07);    // get 11 bits frame_length								// fprintf(stdout, "Frame length = %lu\n", val);																status = RMReadFile(file, bsac_bts_buf+2, val-2, &count);    // get one frame data,								if (status == RM_ERRORREADFILE)									goto audio_file_eos;																file_offset += count;								bsac_frame_size = val;																if(!bsac_get_info_done)	{									GetBitstreamInfo(bsac_bts_buf, context.audio_opt[0].SampleRate, (int*)&context.bsac_bitrate, (int*)&context.bsac_profile);									RMDBGLOG((ENABLE, "MPEG-4 BSAC format\n sample_rate = %ld\t bit_rate = %ld kbps\n Profile = %ld \n",										  (RMuint32)context.audio_opt[0].SampleRate, (RMuint32)context.bsac_bitrate, (RMuint32)context.bsac_profile));																		AllocDecBuff(BSAC_NCH);                 // BSAC init...									bsac_get_info_done = 1;								}								// !!! One frame bit BSAC bits should be in bsac_bts_buf								Mp4AudioDecodeFrame(bsac_bts_buf, context.bsac_bitrate, context.bsac_profile, BSAC_NCH, (BSAC_DSP_Info *)bsac_buf); 								DMA_buf_size = BSAC_DSP_LENGTH;								//fprintf(stdout, "buf available = %ld bytes\n", DMA_buf_size);						}#endif // WITH_BSAC					}					else if (!context.getNewBufferForEC3)						status = RMReadFile(file, context.readBuffer, bufferSize, &count);					else						status = RM_OK;				}#ifdef WITH_BSACaudio_file_eos:#endif // WITH_BSAC				if (status == RM_ERRORREADFILE) {					perror("reading file");					RUAReleaseBuffer(context.pDMA, buf);					buf = NULL;					goto cleanup;				}				else if (status == RM_ERRORENDOFFILE) {					RMDBGLOG((ENABLE, "end of file\n"));					RUAReleaseBuffer(context.pDMA, buf);					buf = NULL;					break;				}				else if (status == RM_SKIP_DATA) {					RMDBGLOG((DISABLE, "skip data\n"));					RUAReleaseBuffer(context.pDMA, buf);					buf = NULL;					continue;				}				else if (status != RM_OK) {					RMDBGLOG((ENABLE, "unhandled error %s\n", RMstatusToString(status)));					RUAReleaseBuffer(context.pDMA, buf);					buf = NULL;					break;				}				file_offset += count;				if (context.FirstSystemTimeStamp) {					RMDBGLOG((ENABLE, "first PTS : %lu\n", context.FirstPTS));					DCCSTCSetTime(dcc_info.pStcSource, context.FirstPTS, 90000);					//DCCSTCPlay(dcc_info.pStcSource);										context.FirstSystemTimeStamp = FALSE;					Info.ValidFields = TIME_STAMP_INFO;					Info.TimeStamp = context.FirstPTS;				}				else {					pInfo = NULL;					Info_size = 0;				}								if (RM_PSM_GetState(context.PSMcontext, &(context.dcc_info)) == RM_PSM_Prebuffering)					RMDBGPRINT((ENABLE, "."));								if (context.transcodeEC3toAC3) {					RMuint32 offset = 0;					RMuint32 bufSize = (1<<context.play_opt->dmapool_log2size);					RMuint32 sizeLeft = bufSize;					RMuint32 frames = 0;										if (!context.getNewBufferForEC3) {						status = RMEC3SetInputBuffer(context.ec3TranscoderHandle, context.readBuffer, count);						if (status == RM_ERROR) {							RMDBGLOG((ENABLE, "error preparing data for ec3 transcoding lib\n"));							goto cleanup;						}						else if (status == RM_SKIP_DATA) {							RMDBGLOG((ENABLE, "not in sync yet\n"));							goto fill_buffer;						}						else if (status == RM_NEED_MORE_DATA) {							RMDBGLOG((ENABLE, "inputBuffer requires more data\n"));							goto fill_buffer;						}					}										context.getNewBufferForEC3 = FALSE;					while(1) {						RMuint32 frameSize = 0;												frames++;												status = RMEC3GetTranscodedFrame(context.ec3TranscoderHandle, buf + offset, sizeLeft, &frameSize, &count); 						RMDBGLOG((DISABLE, "status = (%s)\n", RMstatusToString(status)));						RMDBGLOG((ENABLE, "[%lu] transcoded size %lu\n", frames, count));						offset += count;						sizeLeft -= count;						if (status == RM_BUFFERTOOSMALL) {							RMDBGLOG((ENABLE, "buffer too small\n"));							context.getNewBufferForEC3 = TRUE;							break;						}						else if (status == RM_NEED_MORE_DATA) {							RMDBGLOG((ENABLE, "incomplete frame\n"));							break;						}						else if (status != RM_OK) {							RMDBGLOG((ENABLE, "no more frames\n"));							break;						}												PROCESS_KEY(TRUE, TRUE);												update_hdmi_audio(context.dcc_info, &(context.audio_opt[0]));					}					RMDBGLOG((ENABLE, "total transcoded size %lu\n", offset));					count = offset;				}				if (!count)					goto fill_buffer;				#if DUMP_DATA				RMDBGLOG((ENABLE, "dumping %lu bytes\n", count));				fwrite(buf, count, 1, context.saveFile);#else									RMDBGLOG((DISABLE, "sending %lu bytes\n", count));#ifdef WITH_BSAC				if(context.audio_opt[0].Codec == AudioDecoder_Codec_BSAC)					count = DMA_buf_size;#endif								//RMDBGLOG((ENABLE, "############## Audio audioInstances = %lu\n", context.audioInstances));				//RMDBGLOG((ENABLE, "############## Audio lsbfirst = %s\n", context.audio_opt->PcmCdaParams.MsbFirst?"FALSE":"TRUE"));				// This is just an example to do byte swapping from 16bit little endian to big endian				// Note: Apply it to AC3 and DTS test vectors, they are usually in little endian format.				// David, 5/9/2007				if(context.audio_opt->Codec != AudioDecoder_Codec_PCM && context.audio_opt->PcmCdaParams.MsbFirst == FALSE)				{					RMuint32 i;					for(i=0; i<count; i+=2)					{						RMuint8 tmp = buf[i];						buf[i] = buf[i+1];						buf[i+1] = tmp;					}				}				while (DCCMultipleAudioSendData(dcc_info.pMultipleAudioSource, context.pDMA, buf, count, pInfo, Info_size, &lastOKinstance) != RM_OK) {					struct RUAEvent e;					struct DCCAudioSourceHandle audioHandle;					check_prebuf_state(&context, 0);																PROCESS_KEY(TRUE, TRUE);										update_hdmi_audio(context.dcc_info, &(context.audio_opt[0]));										if (lastOKinstance == -1) {						fprintf(stderr, "cant wait on unknown instance!!\n");						goto cleanup;					}					status = DCCMultipleAudioSourceGetSingleDecoderHandleForInstance(dcc_info.pMultipleAudioSource, lastOKinstance, &audioHandle);					if (status != RM_OK)							goto cleanup;											e.ModuleID = audioHandle.moduleID;					e.Mask = RUAEVENT_XFER_FIFO_READY;					while (RUAWaitForMultipleEvents(dcc_info.pRUA, &e, 1, SENDDATA_TIMEOUT_US, NULL) != RM_OK) {						PROCESS_KEY(TRUE, TRUE);						fprintf(stderr, "wait for xfer fifo ready\n");						update_hdmi_audio(context.dcc_info, &(context.audio_opt[0]));					}				}				#endif									/* Get profiling value */				{										RMuint32 profile;					struct DCCAudioSourceHandle audioHandle1;					DCCMultipleAudioSourceGetSingleDecoderHandleForInstance(dcc_info.pMultipleAudioSource, 0, &audioHandle1);					err = RUAGetProperty(dcc_info.pRUA,							     audioHandle1.moduleID,							     RMGenericPropertyID_Profile,							     &profile,							     sizeof(profile));					if (err == RM_OK) 						RMDBGLOG((ENABLE,"DSP Usage = %lu%%\n", profile));									}				RUAReleaseBuffer(context.pDMA, buf);				buf = NULL;			} // while(1)			check_prebuf_state(&context, 0);						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;			}			// in case we're still in pause state, wait for a key			PROCESS_KEY(FALSE, TRUE);			update_hdmi_audio(context.dcc_info, &(context.audio_opt[0]));			//wait_eos: // fix bugct 1956 but will hurt HDD optimisation, find another way			fprintf(stderr, "File ready %ld times, waiting for EOS\n", context.NTimes+1);			err = WaitForEOS(&context, &context.actions);			{				RMuint64 stc;				DCCSTCGetTime(dcc_info.pStcSource, &stc, 90000);								RMDBGLOG((ENABLE, "Timer duration %llu ms\n", stc/90));			}			if (err == RM_KEY_WHILE_WAITING_EOS) {				RMDBGLOG((ENABLE, "command while waiting for EOS\n"));				err = RM_OK;				PROCESS_KEY(FALSE, FALSE);				update_hdmi_audio(context.dcc_info, &(context.audio_opt[0]));				//goto wait_eos;			}			else 				break; // EOS		}		if (context.play_opt->loop_count > 0)			context.play_opt->loop_count --;		/* if there is another loop, stop devices... */		if ((context.play_opt->loop_count > 0) || (context.play_opt->waitexit != TRUE) || (context.play_opt->infinite_loop))			Stop(&context, RM_DEVICES_AUDIO | RM_DEVICES_STC);		context.NTimes++;	} while ((context.play_opt->loop_count > 0) || (context.play_opt->infinite_loop));		goto cleanup;	////////////////////////////////////////////////////////////////////////	// capture loop	//////////////////////////////////////////////////////////////////////// capture_loop:	// file capture loop	while(1) {		err = process_command(context.PSMcontext, &(context.dcc_info), &(context.actions));		if (RMFAILED(err)) {			fprintf(stderr, "Error while processing key %d\n", err);			break;		}		if ((context.actions.cmd == RM_QUIT) && (!context.actions.cmdProcessed)) {			RMDBGLOG((ENABLE, "Got quit command\n"));			break;		}				update_hdmi_audio(context.dcc_info, &(context.audio_opt[0]));				while(RUAReceiveData(dcc_info.pRUA,audio_capture, context.pDMA, &buf, &size,NULL,NULL) != RM_OK) {			struct RUAEvent e;			e.ModuleID = audio_capture;			e.Mask = SOFT_IRQ_EVENT_XFER_RECEIVE_READY;			err = RUAWaitForMultipleEvents(dcc_info.pRUA, &e, 1, 1000 /*RECEIVEDATA_TIMEOUT_US*/, NULL);			if (RMFAILED(err)){				//RMDBGLOG((ENABLE, "%d, %p 0x%x %d\n", audio_capture, context.pDMA, buf, size));			}		}				if(!buf) {			RMDBGLOG((ENABLE, "error, RUAReceiveData returned no buffer!\n"));			continue;		}else{						if ((size > 0) && (context.fp_capture >= 0)) {				fwrite(buf, size, 1, context.fp_capture);			}			RUAReleaseBuffer(context.pDMA, buf);		}		}	goto cleanup_2; cleanup:	if (file != NULL) 		RMCloseFile(file);#if DUMP_DATA	RMDBGLOG((ENABLE, "\t\t\t***** CLOSE SAVE DATA FILE ****\n"));	fclose(context.saveFile);#endif	if (context.transcodeEC3toAC3) {		if (context.ec3TranscoderHandle)			RMEC3CloseTranscoder(context.ec3TranscoderHandle);		if (context.readBuffer)			RMFree(context.readBuffer);	}	if( context.play_opt->waitexit ) {		if (context.audio_opt[0].AudioIn) {			fprintf(stderr, "press q k

⌨️ 快捷键说明

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