📄 play_multiple_audio.c
字号:
static struct dcc_context *pdcc_info[MAX_TASK_COUNT];static struct playback_cmdline playback_options[MAX_TASK_COUNT]; /*access through play_opt*/static struct audio_cmdline audio_options[MAX_TASK_COUNT];/*access through disp_opt*/static struct playback_cmdline *play_opt;static struct audio_cmdline *audio_opt;static struct RM_PSM_Context PSMcontext;static struct RM_PSM_Actions actions;static struct asf_context SendContext[MAX_TASK_COUNT] = {{0,},{0,}};static struct stream_options_s stream_options[MAX_TASK_COUNT];static struct RMfifo wmapro_fifo[MAX_TASK_COUNT];static struct wmapro_buffer_info wmapro_info_array[MAX_TASK_COUNT][MAX_WMAPRO_INFO];/////////////////////////#define db(txt) fprintf(stderr,txt);#ifdef TMP_FIX_MIX_WEIGHT_KEYS //static void mixer_set_weight_index(int decoder, int step){ RMDBGLOG((ENABLE, "mixer_set_weight_index, step=%d\n", step)); if(step < 0) { RMuint32 ch; RMuint32 abs_step = -step; for(ch=0; ch<8; ch++) (weight[decoder][ch] > abs_step) ? weight[decoder][ch]-=abs_step : 0; } else { RMuint32 ch; RMASSERT((step<100)); for(ch=0; ch<8; ch++) (weight[decoder][ch] < (RMuint32)(100 - step)) ? weight[decoder][ch]+=step : 100; }}static void mixer_set_weight(int decoder){ RMuint32 *sweight = weight[decoder]; RMuint32 *pMixerValue = &cmdblock.MixerValue_ch0; RMuint32 ch=0; RMDBGLOG((ENABLE, "mixer_set_weight, decoder=%d\n", decoder)); for(ch=0; ch<8; ch++) { RMASSERT((sweight[ch]>0)); RMASSERT((sweight[ch]<=100)); *pMixerValue++=(RMuint32)0x10000000 / (RMuint32)100 * sweight[ch] ; } RUASetProperty( pdcc_info[decoder]->pRUA, pdcc_info[decoder]->audio_decoder, RMAudioDecoderPropertyID_MixerWeight, &cmdblock, sizeof(cmdblock), 0);}#endifstatic RMstatus OpenPCMXAudioDecoderSource(struct DCC *pDCC, struct DCCAudioProfile *dcc_profile, struct DCCAudioSource **ppAudioSource){ struct AudioDecoder_DRAMSizePCMX_in_type dram_in; struct AudioDecoder_DRAMSizePCMX_out_type dram_out; struct AudioDecoder_OpenPCMX_type profile; RMuint32 audio_decoder, audio_engine; RMuint32 nb_audio_engines, nb_audio_decoders; RMuint32 temp; RMstatus err; RMuint32 tmp = (RMuint32)gMixingMode; /* ************************* */ RMuint32 sample_rate; struct AudioEngine_Volume_type volume; /* ************************* */ *ppAudioSource = (struct DCCAudioSource *) RMMalloc(sizeof(struct DCCAudioSource)); if (*ppAudioSource == NULL) { RMDBGLOG((ENABLE, "ERROR: could not allocate 0x%08lX bytes in system memory %lu!\n", sizeof(struct DCCAudioSource))); return RM_FATALOUTOFMEMORY; } RMMemset((void*)(*ppAudioSource), 0, sizeof(struct DCCAudioSource)); (*ppAudioSource)->pRUA = pDCC->pRUA; // Get number of audio engines and audio decoders temp = AudioEngine; err = RUAExchangeProperty(pDCC->pRUA, Enumerator, RMEnumeratorPropertyID_CategoryIDToNumberOfInstances, &temp, sizeof(temp), &nb_audio_engines, sizeof(nb_audio_engines)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error getting property RMEnumeratorPropertyID_CategoryIDToNumberOfInstances %s\n", RMstatusToString(err))); return err; } else { if (dcc_profile->AudioEngineID < nb_audio_engines) RMDBGLOG((ENABLE, "Number of audio engines: %d%s\n", (int) nb_audio_engines)); else { RMDBGLOG((ENABLE, "Error: audio engine index %d out of range!!! Should be < %d\n", (int) dcc_profile->AudioEngineID, (int) nb_audio_engines)); err = RM_PARAMETER_OUT_OF_RANGE; return err; } } temp = AudioDecoder; err = RUAExchangeProperty(pDCC->pRUA, Enumerator, RMEnumeratorPropertyID_CategoryIDToNumberOfInstances, &temp, sizeof(temp), &nb_audio_decoders, sizeof(nb_audio_decoders)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error getting property RMEnumeratorPropertyID_CategoryIDToNumberOfInstances %s\n", RMstatusToString(err))); return err; } else { if (dcc_profile->AudioDecoderID < (nb_audio_decoders / nb_audio_engines)) RMDBGLOG((ENABLE, "Number of audio decoders: %d%s\n", (int) nb_audio_decoders)); else { RMDBGLOG((ENABLE, "Error: audio decoder index %d out of range!!! Should be < %d\n", (int) dcc_profile->AudioDecoderID, (int) (nb_audio_decoders / nb_audio_engines))); err = RM_PARAMETER_OUT_OF_RANGE; return err; } } audio_engine = EMHWLIB_MODULE(AudioEngine, dcc_profile->AudioEngineID); (*ppAudioSource)->engine_moduleID = audio_engine; { int i=0; for (i = 0; i <= 11; i++) { volume.Channel = i; volume.Volume = 0x10000000; DCCSP(pDCC->pRUA, audio_engine, RMAudioEnginePropertyID_Volume, &volume, sizeof(volume)); } } // !!Hack!! We assume there are an equal amount of decoders per engine; (nb_audio_decoders / nb_audio_engines) // gives the number of decoders per engine. This is always better then hardcoding number to 2 like before. audio_decoder = EMHWLIB_MODULE(AudioDecoder, dcc_profile->AudioEngineID * (nb_audio_decoders / nb_audio_engines) + dcc_profile->AudioDecoderID); (*ppAudioSource)->decoder_moduleID = audio_decoder; RMDBGLOG((ENABLE, "AudioDecoder: 0x%08lX\n", audio_decoder)); sample_rate = 44100; DCCSP(pDCC->pRUA, audio_engine, RMAudioEnginePropertyID_SampleFrequency, &sample_rate, sizeof(sample_rate)); /* we need 8 x 0x300(0x180) for Ac3, 8 x 0xF00 for WMA, 8 x 0x400 for WMAPRO => allocate maximum=8 x 0xF00 */ dram_in.BitstreamFIFOSize0 = dcc_profile->BitstreamFIFOSize; dram_in.XferFIFOCount0 = dcc_profile->XferFIFOCount; dram_in.BitstreamFIFOSize1 = dcc_profile->BitstreamFIFOSize; dram_in.XferFIFOCount1 = dcc_profile->XferFIFOCount; dram_in.BitstreamFIFOSize2 = dcc_profile->BitstreamFIFOSize; dram_in.XferFIFOCount2 = dcc_profile->XferFIFOCount; dram_in.BitstreamFIFOSize3 = dcc_profile->BitstreamFIFOSize; dram_in.XferFIFOCount3 = dcc_profile->XferFIFOCount; dram_in.BitstreamFIFOSize4= dcc_profile->BitstreamFIFOSize; dram_in.XferFIFOCount4 = dcc_profile->XferFIFOCount; dram_in.BitstreamFIFOSize5= dcc_profile->BitstreamFIFOSize; dram_in.XferFIFOCount5 = dcc_profile->XferFIFOCount; dram_in.BitstreamFIFOSize6 = dcc_profile->BitstreamFIFOSize; dram_in.XferFIFOCount6 = dcc_profile->XferFIFOCount; dram_in.BitstreamFIFOSize7 = dcc_profile->BitstreamFIFOSize; dram_in.XferFIFOCount7 = dcc_profile->XferFIFOCount; dram_in.BitstreamFIFOSize8 = dcc_profile->BitstreamFIFOSize; dram_in.XferFIFOCount8 = dcc_profile->XferFIFOCount; err = RUAExchangeProperty(pDCC->pRUA, audio_decoder, RMAudioDecoderPropertyID_DRAMSizePCMX, &dram_in, sizeof(dram_in), &dram_out, sizeof(dram_out)); if (RMFAILED(err)) { RMDBGLOG((ENABLE, "Error getting property RMAudioDecoderPropertyID_DRAMSize! %s\n", RMstatusToString(err))); return err; } profile.BitstreamFIFOSize0 = dram_in.BitstreamFIFOSize0; profile.XferFIFOCount0 = dram_in.XferFIFOCount0; profile.BitstreamFIFOSize1 = dram_in.BitstreamFIFOSize1; profile.XferFIFOCount1 = dram_in.XferFIFOCount1; profile.BitstreamFIFOSize2 = dram_in.BitstreamFIFOSize2; profile.XferFIFOCount2 = dram_in.XferFIFOCount2; profile.BitstreamFIFOSize3 = dram_in.BitstreamFIFOSize3; profile.XferFIFOCount3 = dram_in.XferFIFOCount3; profile.BitstreamFIFOSize4 = dram_in.BitstreamFIFOSize4; profile.XferFIFOCount4 = dram_in.XferFIFOCount4; profile.BitstreamFIFOSize5 = dram_in.BitstreamFIFOSize5; profile.XferFIFOCount5 = dram_in.XferFIFOCount5; profile.BitstreamFIFOSize6 = dram_in.BitstreamFIFOSize6; profile.XferFIFOCount6 = dram_in.XferFIFOCount6; profile.BitstreamFIFOSize7 = dram_in.BitstreamFIFOSize7; profile.XferFIFOCount7 = dram_in.XferFIFOCount7; profile.BitstreamFIFOSize8 = dram_in.BitstreamFIFOSize8; profile.XferFIFOCount8 = dram_in.XferFIFOCount8; profile.UnProtectedAddress = 0; profile.UnProtectedSize = dram_out.UnProtectedSize;// profile.MixingMode = gMixingMode; tmp = (RMuint32)gMixingMode; err = RUASetProperty(pDCC->pRUA, audio_decoder, RMAudioDecoderPropertyID_PCMXMix, &tmp, sizeof(tmp),0); if (profile.UnProtectedSize > 0) { profile.UnProtectedAddress = DCCMalloc(pDCC, pDCC->dram, RUA_DRAM_UNCACHED, profile.UnProtectedSize); if (!profile.UnProtectedAddress) { RMDBGLOG((ENABLE, "ERROR: could not allocate 0x%08lX bytes in uncached DRAM %lu!\n", profile.UnProtectedSize, 0L)); return RM_FATALOUTOFMEMORY; } RMDBGLOG((ENABLE, "(audio decoder : %lu) audio uncached addr: 0x%08lX, size 0x%08lX, end: 0x%08lX\n", (*ppAudioSource)->decoder_moduleID, profile.UnProtectedAddress, profile.UnProtectedSize, profile.UnProtectedAddress + profile.UnProtectedSize)); } (*ppAudioSource)->uncached_address = profile.UnProtectedAddress; DCCSP(pDCC->pRUA, audio_decoder, RMAudioDecoderPropertyID_OpenPCMX, &profile, sizeof(profile)); return RM_OK;}static void init_globals(void){ int i=0; for(i=0 ; i< MAX_TASK_COUNT;i++) SendContext[i].compressed_audio=FALSE; bypass_drm = FALSE; audioStreams = 0;}static void setcmd(struct RM_PSM_Context PSMcontex,RMbool sw){ if(PSMcontext.currentActivePSMContext > 0) { sw?(context[0].cmd_ex |= (RMuint32)(0x01) << (PSMcontext.currentActivePSMContext-1)) : \ (context[0].cmd_ex &= ~((RMuint32)(0x01) << (PSMcontext.currentActivePSMContext-1))); }}static int iscmd(int decoder) { return (context[decoder].status==0x00) && \ ((decoder==0)? (context[0].cmd_ex & 0x01) : (context[0].cmd_ex & 0x02)); } static void show_mixing_options(){ fprintf(stderr,"\n[Audio Mixing and Selection Commands]"); fprintf(stderr,"\n----------------------"); fprintf(stderr,"\nPAUSE: ? <dec#> space"); fprintf(stderr,"\nPLAY: ? <dec#> p"); fprintf(stderr,"\nSTOP: ? <dec#> s"); fprintf(stderr,"\nQUIT: q q"); fprintf(stderr,"\nq k decrease weight 1st decoder"); fprintf(stderr,"\nq l increase weight 1st decoder"); fprintf(stderr,"\nq , decrease weight 2nd decoder"); fprintf(stderr,"\nq . increase weight 2nd decoder\n"); }static void show_usage(char *progname){ show_playback_options(); show_audio_options(); show_mixing_options(); fprintf(stderr, "--------------------------------\n"); fprintf(stderr, "Minimum cmd line: %s -task <task count> -c <codec> <file name>\n", progname); fprintf(stderr, "Minimum cmd line PCMX: %s -task 0 -c pcmx [stream count] [mode1] [bps1] [endian1] [gain1] [panx1] [pany1]... [file1.pcm]... -task 1 -c <codec> <file name>\n", progname); fprintf(stderr, "\t\tNote: Range for gain[i] is [-51, 12], -51 is muting, -50 = -50dB, -49 is -49dB, and so on\n"); fprintf(stderr, "\t\tNote: Range for panx[i] and pany[i] is [-1.0, 1.0]\n"); fprintf(stderr, "\nExample: %s -task 0 -ae 0 -ad 0 -c ac3 /media/elementary/ac3/SUZVGA1.AC3 -task 1 -ae 0 -ad 1 -c wma /media/asf/wma/music.wma", progname); fprintf(stderr, "\n1 channel PCMX/AC3 Mix Example: %s -task 0 -ae 0 -ad 0 -afreq 48000 -c ac3 /media/elementary/ac3/DOLBY.AC3 -task 1 -ae 0 -ad 1 -afreq 48000 -c pcmx 1 1 16 0 0 -1.0 -1.0 /media/elementary/pcm/pcm_greeting_16bit_msb_2ch_48k.pcm", progname); fprintf(stderr, "--------------------------------\n"); exit(1);}static char* pcmx_filenames[9];static int pcmx_fcnt=0;static void parse_cmdline(int argc, char *argv[]){ int i; RMstatus err; if(task_count == 0) { play_opt = &playback_options[0]; context[0].id = 0; } if (argc < 2) show_usage(argv[0]); i = 1; while ((argc > i)) { if (argv[i][0] != '-') { if ((audio_opt->Codec!=AudioDecoder_Codec_PCMX) && (play_opt->filename == NULL)) { play_opt->filename = argv[i]; i++; } else if((audio_opt->Codec==AudioDecoder_Codec_PCMX) && (pcmx_fcnt < 9)) { pcmx_filenames[pcmx_fcnt] = argv[i]; pcmx_fcnt++; i++; } else { fprintf(stderr,"\nError Parse FILE "); fflush(stdout); show_usage(argv[0]); } } else if ( ! strcmp(argv[i], "-mix")) { gMixingMode =TRUE; i++; } else if ( ! strcmp(argv[i], "-task")) { if (argc > i+1) { RMuint32 j = 0, task_index; task_index = strtol(argv[i+1], NULL, 10); i+=2; if (task_count > MAX_TASK_COUNT) { fprintf(stderr,"\nError Parse task-cnt "); fflush(stdout); show_usage(argv[0]); } for (j=0; j < task_count; j++) { if( task_index != context[j].id) continue; } if ( (task_count==0) || (j >= task_count)) { play_opt = &playback_options[task_count]; audio_opt = &audio_options[task_count]; context[task_count].id = task_index; task_count++; } } else { fprintf(stderr,"\nError Parse task "); fflush(stdout); show_usage(argv[0]); } } else { err = parse_playback_cmdline(argc, argv, &i, play_opt); if (err == RM_ERROR) { fprintf(stderr,"\nError Parse play_opt\n"); fflush(stdout); show_usage(argv[0]); } if(!argv[i]) break; err = parse_audio_cmdline(argc, argv, &i, audio_opt); if (RMFAILED(err)) { fprintf(stderr,"\nError Parse audio_opt\n"); fflush(stdout); show_usage(argv[0]); } //Special for PCMX if(audio_opt->Codec==AudioDecoder_Codec_PCMX) { int max_stream= strtol(argv[i], NULL, 10); int k=0; i++; for(k=0;k<max_stream;k++) { context[task_count-1].pcmx_mode[k] = strtol(argv[i], NULL, 10); i++; context[task_count-1].pcmx_bps[k] = strtol(argv[i], NULL, 10); i++; context[task_count-1].pcmx_endian[k] = strtol(argv[i], NULL, 10); i++; context[task_count-1].pcmx_gain[k] = strtol(argv[i], NULL, 10); RMDBGLOG((ENABLE, "^^^^^^^^ Gain[%d]=%ld\n", k, context[task_count-1].pcmx_gain[k])); i++; //context[task_count-1].pcmx_pan[k] = strtol(argv[i], NULL, 10); { float tempf; sscanf((const char*)argv[i], (const char*)"%f", &tempf); context[task_count-1].pcmx_panx[k] = (RMreal)tempf; RMDBGLOG((ENABLE, "^^^^^^^^^^^ pan_x = %f\n", k, context[task_count-1].pcmx_panx[k])); i++; sscanf((const char*)argv[i], (const char*)"%f", &tempf); context[task_count-1].pcmx_pany[k] = (RMreal)tempf; RMDBGLOG((ENABLE, "^^^^^^^^^^^ pan_y = %f\n", k, context[task_count-1].pcmx_pany[k])); i++; } } } if (err != RM_PENDING) continue; } }}static int Process_Key(RMbool release){ RMstatus err = process_command(&PSMcontext, pdcc_info, &actions); #ifdef TMP_FIX_MIX_WEIGH
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -