📄 play_audio.c
字号:
/* * * Copyright (c) Sigma Designs, Inc. 2002. All rights reserved. * *//** @file dcc_demo.c @brief sample application to access the Mambo chip and test DMA transfers @author Julien Soulier @ingroup dccsamplecode*//* ****************************************************************************************** This file is part of libsamples library, therefore *NO* static variables should be defined *******************************************************************************************/#define USE_TWO_INSTANCES 1#include <ctype.h>#include "sample_os.h"#define ALLOW_OS_CODE 1#include "../rua/include/rua.h"#include "../rua/include/rua_property.h"#include "../rmcore/include/rmstatustostring.h"#include "../emhwlib_hal/pll/include/pll_hal.h"#include "../rmlibcw/include/rmtime.h"#include "../dcc/include/dcc.h"#include "common.h"#include "../rmec3transcoder/include/rmec3transcoderapi.h"#define NUM_DBC 4 // how many DBCs to allocate#define GETBUFFER_TIMEOUT_US (TIMEOUT_10MS * 10)#define SENDDATA_TIMEOUT_US (TIMEOUT_10MS * 10)#define DMA_BUFFER_SIZE_LOG2 15#define DMA_BUFFER_COUNT 32#define AUDIO_FIFO_SIZE ((1<<DMA_BUFFER_SIZE_LOG2)*DMA_BUFFER_COUNT) // 1Mb, matches dma_buffer_count * 2^dma_buffer_size_log2 which is a requirement in standalone#define XFER_FIFO_COUNT (32)#define KEYFLAGS (SET_KEY_PLAYBACK | SET_KEY_AUDIO)#define DUMP_DATA 0#define RM_DEVICES_STC 0x1#define RM_DEVICES_AUDIO 0x4#ifdef WITH_BSAC#include "../libbsac/porting_typedef.h"#include "../libbsac/porting.h"#define BSAC_NCH 2#define BSAC_DSP_LENGTH sizeof(BSAC_DSP_Info)#endif // WITH_BSACstruct audio_context { struct RUABufferPool *pDMA; RMbool FirstSystemTimeStamp; RMuint32 FirstPTS; struct dcc_context *dcc_info; struct RM_PSM_Context *PSMcontext; struct RM_PSM_Actions actions; RMuint32 NTimes; struct playback_cmdline *play_opt; struct audio_cmdline *audio_opt; RMuint32 audioInstances; RMfile f_bitstream; RMint64 fileSize; RMbool audio_decoder_initialized; RMbool trickMode; RMuint32 audio_vop_tir; RMuint64 Duration; RMuint64 lastSTC; RMuint32 prebufferedBytes; RMuint32 PCMblockSize; RMuint32 skipFirstNBytes; RMuint32 sendNBytes; RMbool transcodeEC3toAC3; RMEC3TranscoderHandle ec3TranscoderHandle; RMuint8 *readBuffer; RMbool getNewBufferForEC3;#ifdef WITH_BSAC RMuint8 bsac_bts_buf[4096]; RMuint32 bsac_bitrate, bsac_profile;#endif#if DUMP_DATA FILE *saveFile;#endif void **dmabuffer_array; RMuint32 dmabuffer_index; RMuint32 capture_cached_addr; RMuint32 capture_uncached_addr; FILE *fp_capture;};#define PROCESS_KEY(release, getkey) \do { \ RMDBGLOG((DISABLE, "process_key\n")); \ if (getkey) { \ enum RM_PSM_State FSMstate = RM_PSM_GetState(context.PSMcontext, &(context.dcc_info)); \ if ((FSMstate == RM_PSM_Stopped) || (FSMstate == RM_PSM_Paused)) { \ 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; \ } \ } \ err = process_command(context.PSMcontext, &(context.dcc_info), &(context.actions)); \ if (RMFAILED(err)) { \ fprintf(stderr, "Error while processing key %d\n", err); \ goto cleanup; \ } \ } \ if (context.actions.toDoActions & RM_PSM_FIRST_PTS) { \ RMDBGLOG((ENABLE, "firstPTS\n")); \ context.FirstSystemTimeStamp = TRUE; \ } \ if (context.actions.performedActions & RM_PSM_AUDIO_STOPPED) { \ RMDBGLOG((ENABLE, "audio stopped\n")); \ context.audio_decoder_initialized = FALSE; \ if ((release) && (buf)) { \ RUAReleaseBuffer(context.pDMA, buf); \ RMDBGLOG((ENABLE, "release a buffer\n")); \ buf = NULL; \ /* needed for no dram copy version on standalone */ \ err = RUAResetPool(context.pDMA); \ if (RMFAILED(err)) { \ RMDBGLOG((ENABLE, "Error cannot reset dmapool\n")); \ goto cleanup; \ } \ } \ } \ if (context.actions.performedActions & RM_PSM_STC_STOPPED) { \ RMDBGLOG((ENABLE, "stc stopped\n")); \ context.actions.performedActions &= ~RM_PSM_STC_STOPPED; \ } \ if ((RM_PSM_GetState(context.PSMcontext, &(context.dcc_info)) == RM_PSM_Playing) && \ (context.trickMode)) { \ RMDBGLOG((ENABLE, "got play after trickmode\n")); \ if ((release) && (buf)) { \ RUAReleaseBuffer(context.pDMA, buf); \ RMDBGLOG((ENABLE, "release a buffer\n")); \ buf = NULL; \ /* needed for no dram copy version on standalone */ \ err = RUAResetPool(context.pDMA); \ if (RMFAILED(err)) { \ RMDBGLOG((ENABLE, "Error cannot reset dmapool\n")); \ goto cleanup; \ } \ } \ resumeFromTrick(&context); \ context.trickMode = FALSE; \ } \ if (((RM_PSM_GetState(context.PSMcontext, &(context.dcc_info)) == RM_PSM_Slow) || \ (RM_PSM_GetState(context.PSMcontext, &(context.dcc_info)) == RM_PSM_Fast) || \ (RM_PSM_GetState(context.PSMcontext, &(context.dcc_info)) == RM_PSM_NextPic) || \ (RM_PSM_GetState(context.PSMcontext, &(context.dcc_info)) == RM_PSM_Rewind)) && \ (context.actions.cmdProcessed) && (!context.trickMode)) { \ RMDBGLOG((ENABLE, ">> trick mode\n")); \ if ((release) && (buf)) { \ RUAReleaseBuffer(context.pDMA, buf); \ RMDBGLOG((ENABLE, "release a buffer\n")); \ buf = NULL; \ /* needed for no dram copy version on standalone */ \ err = RUAResetPool(context.pDMA); \ if (RMFAILED(err)) { \ RMDBGLOG((ENABLE, "Error cannot reset dmapool\n")); \ goto cleanup; \ } \ } \ context.trickMode = TRUE; \ context.FirstSystemTimeStamp = TRUE; \ } \ if ((RM_PSM_GetState(context.PSMcontext, &(context.dcc_info)) == RM_PSM_Stopped) && (context.actions.cmdProcessed)) { \ RMDBGLOG((ENABLE,"Got stop command\n")); \ if ((release) && (buf)) { \ RUAReleaseBuffer(context.pDMA, buf); \ RMDBGLOG((ENABLE, "release a buffer\n")); \ buf = NULL; \ /* needed for no dram copy version on standalone */ \ err = RUAResetPool(context.pDMA); \ if (RMFAILED(err)) { \ RMDBGLOG((ENABLE, "Error cannot reset dmapool\n")); \ goto cleanup; \ } \ } \ context.trickMode = FALSE; \ goto mainloop_no_seek; \ } \ if ((context.actions.cmd == RM_QUIT) && (!context.actions.cmdProcessed)) { \ RMDBGLOG((ENABLE, "Got quit command\n")); \ if ((release) && (buf)) { \ RUAReleaseBuffer(context.pDMA, buf); \ RMDBGLOG((ENABLE, "release a buffer\n")); \ buf = NULL; \ /* needed for no dram copy version on standalone */ \ err = RUAResetPool(context.pDMA); \ if (RMFAILED(err)) { \ RMDBGLOG((ENABLE, "Error cannot reset dmapool\n")); \ goto cleanup; \ } \ } \ goto cleanup; \ } \ if ((context.actions.cmd == RM_STOP_SEEK_ZERO) && (!context.actions.cmdProcessed)) { \ RMDBGLOG((ENABLE, "Got stop seek zero command\n")); \ if ((release) && (buf)) { \ RUAReleaseBuffer(context.pDMA, buf); \ RMDBGLOG((ENABLE, "release a buffer\n")); \ buf = NULL; \ /* needed for no dram copy version on standalone */ \ err = RUAResetPool(context.pDMA); \ if (RMFAILED(err)) { \ RMDBGLOG((ENABLE, "Error cannot reset dmapool\n")); \ goto cleanup; \ } \ } \ Stop(&context, RM_DEVICES_AUDIO | RM_DEVICES_STC); \ RM_PSM_SetState(context.PSMcontext, &(context.dcc_info), RM_PSM_Stopped); \ context.trickMode = FALSE; \ goto mainloop; \ } \ if ((context.actions.cmd == RM_SEEK) && (!context.actions.cmdProcessed)){ \ RMDBGLOG((ENABLE, "Got seek command\n")); \ if ((release) && (buf)) { \ RUAReleaseBuffer(context.pDMA, buf); \ RMDBGLOG((ENABLE, "release a buffer\n")); \ buf = NULL; \ /* needed for no dram copy version on standalone */ \ err = RUAResetPool(context.pDMA); \ if (RMFAILED(err)) { \ RMDBGLOG((ENABLE, "Error cannot reset dmapool\n")); \ goto cleanup; \ } \ } \ \ if (dcc_info.seek_supported) \ seek(&context, context.dcc_info->seek_time); \ else \ fprintf(stderr, "Unsuported command\n"); \ context.trickMode = FALSE; \ goto mainloop_seek; \ } \ if(context.actions.cmd == RM_DUALMODE_CHANGE) { \ fprintf(stderr, "Changing DualMode to :"); \ switch(context.audio_opt[0].OutputDualMode) { \ case DualMode_LeftMono: \ fprintf(stderr, " RightMono\n"); \ context.audio_opt[0].OutputDualMode = DualMode_RightMono; \ break; \ case DualMode_RightMono: \ fprintf(stderr, " MixMono\n"); \ context.audio_opt[0].OutputDualMode = DualMode_MixMono; \ break; \ case DualMode_MixMono: \ fprintf(stderr, " Stereo\n"); \ context.audio_opt[0].OutputDualMode = DualMode_Stereo; \ break; \ case DualMode_Stereo: \ fprintf(stderr, " LeftMono\n"); \ context.audio_opt[0].OutputDualMode = DualMode_LeftMono; \ break; \ default: \ fprintf(stderr, " Unknown dual mode\n"); \ break; \ } \ for (i = 0; i < context.audioInstances; i++) { \ context.audio_opt[i].OutputDualMode = context.audio_opt[0].OutputDualMode; \ \ err = apply_audio_decoder_options_onthefly(&dcc_info, &(context.audio_opt[i])); \ if (RMFAILED(err)) { \ fprintf(stderr, "Error applying audio decoder options on the fly %d\n", err); \ } \ } \ } \} while(0)#ifndef WITH_MONOstatic void show_usage(char *progname){ show_playback_options(); show_audio_options(); fprintf(stderr, "--------------------------------\n"); fprintf(stderr, "Minimum cmd line: %s <file name>\n", progname); fprintf(stderr, "--------------------------------\n"); exit(1);}static void parse_cmdline(struct audio_context *pSendContext, int argc, char *argv[], RMuint32 *currentInstance){ int i; RMstatus err; if (argc < 2) show_usage(argv[0]); i = 1; while ((argc > i)) { if (argv[i][0] != '-') { if (pSendContext->play_opt->filename == NULL) { pSendContext->play_opt->filename = argv[i]; i++; } else show_usage(argv[0]); } else { err = parse_playback_cmdline(argc, argv, &i, pSendContext->play_opt); if (err == RM_ERROR) show_usage(argv[0]); if (err != RM_PENDING) continue; RMDBGLOG((ENABLE, "option[%lu] %s\n", i, argv[i])); err = parse_audio_cmdline2(argc, argv, &i, pSendContext->audio_opt, MAX_AUDIO_DECODER_INSTANCES, currentInstance); if (RMFAILED(err)) show_usage(argv[0]); } } if ((pSendContext->play_opt->filename == NULL) && (! pSendContext->audio_opt[0].AudioIn)) show_usage(argv[0]);}#endifstatic RMstatus WaitForEOS(struct audio_context *pSendContext, struct RM_PSM_Actions *pActions){ RMuint32 eos_bit_field = 0; enum RM_PSM_State PlaybackStatus = RM_PSM_GetState(pSendContext->PSMcontext, &(pSendContext->dcc_info)); if (pSendContext == NULL || pActions == NULL) return RM_ERROR; if ((PlaybackStatus == RM_PSM_Playing) || (PlaybackStatus == RM_PSM_Prebuffering)) eos_bit_field |= EOS_BIT_FIELD_AUDIO; return WaitForEOSWithCommand(pSendContext->PSMcontext, &(pSendContext->dcc_info), pActions, eos_bit_field);}static RMstatus StartAudioCapture(struct dcc_context *dcc_info, RMuint32 audio_capture, struct audio_cmdline *audio_opt, struct audio_context* p_context){ struct AudioCapture_Open_type capture_open; enum AudioCapture_Source_type capture_source; enum AudioCapture_SpdifDataType_type capture_type; enum AudioCapture_Capture_type cmd = AudioCapture_Capture_On; struct AudioCapture_DRAMSize_in_type dram_in; struct AudioCapture_DRAMSize_out_type dram_out; RMstatus err; RMuint32 capture_mode; // check if this is for pass through or file capture if( (p_context->audio_opt[0].AudioIn) && (p_context->play_opt->filename ) ){ capture_mode = 0; // file capture p_context->fp_capture = fopen(p_context->play_opt->filename, "w+b"); }else{ capture_mode = 1; // pass through }#if (EM86XX_CHIP == EM86XX_CHIPID_TANGO2){ struct PLL_Frequency_type f; RMuint32 SampleClock; //printf("start set RCLK2...\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -