static int ogg_is_our_file(char *filename) { char *ext; FILE *file; unsigned long file_length; OggVorbis_File temp_ogg; //check parameters if ((!filename) || (!ogg_file)) { PE_DBG_PRINTF("MusicEngine: ogg_is_our_file() invalid parameter filename or ogg_file! \n"); return FALSE; } ext = strrchr(filename, (int)'.'); if (ext) { if (!strncasecmp(ext, ".OGG", 4)) { #ifndef ENABLE_PE_CACHE file = fopen(filename, "rb"); // is our file, open file if (!file) { return FALSE; } #else ogg_info_cache_id = pe_cache_open(filename, NULL, OGG_CACHE_SIZE, OGG_BLOCK_SIZE); if (ogg_info_cache_id < 0) { libc_printf("<%d> <%s> pe_cache_open failed!\n", __LINE__, __FUNCTION__); return FALSE; } file = (FILE *)(((UINT32)ogg_info_cache_id | PE_CACHE_ID_TAG)); #endif if(ov_test(file, &temp_ogg, NULL, 0) < 0) // 这里跟着调用的文件系统函数,不是pe_cache 接口 { PE_DBG_PRINTF("Input does not appear to be an Ogg bitstream.\n"); #ifndef ENABLE_PE_CACHE fclose(file); // if test not ogg, close file #else pe_cache_close(ogg_info_cache_id); ogg_info_cache_id = -1; #endif return FALSE; } ov_clear(&temp_ogg); // 如果完成,在这里就会调用close return TRUE; } } PE_DBG_PRINTF("Input does not appear to be an Ogg bitstream.\n"); return FALSE; }
static int gif_abort(void) { struct osd_device *osd_dev; /* if(jpeg_file.id > 0) { osal_mutex_lock(jpeg_file.lock, TMO_FEVR); jpeg_file.mp_cb = NULL; osal_mutex_unlock(jpeg_file.lock); imagedec_stop(jpeg_file.id); while(jpeg_file.task_terminated == 1) { osal_task_sleep(10); } } */ //gif_file fh; #ifdef ENABLE_PE_CACHE if(gif_cache_id >= 0) pe_cache_close(gif_cache_id); gif_cache_id = -1; #endif #ifdef ENABLE_PE_CACHE fh = 1; #endif if (gif == NULL) return 0; gif_stop(gif, fh); gif_close(gif); alpha_value_flag = 0; #ifdef DUAL_ENABLE osd_dev = (struct osd_device *)dev_get_by_id(HLD_DEV_TYPE_OSD, 0); OSDDrv_ShowOnOff((HANDLE)osd_dev,FALSE); OSDDrv_Close((HANDLE)osd_dev); tran_use_number = 256; #endif gif = NULL; }
static int ogg_play_file(char *filename, mp_callback_func cb) { OSAL_T_CTSK ogg_engine_play_task_attribute; unsigned long ogg_engine_flag; PE_DBG_PRINTF("MusicEngine: ==> ogg_play_file()! \n"); //check parameters if ((!filename) || (!cb) || (!ogg_file)) { PE_DBG_PRINTF("MusicEngine: ogg_play_file() invalid parameter filename or cb or ogg_file! \n"); return -1; } //init ogg_file #ifdef ENABLE_PE_CACHE ogg_cache_id = pe_cache_open(filename, NULL, OGG_CACHE_SIZE, OGG_BLOCK_SIZE); if(ogg_cache_id < 0) { PE_DBG_PRINTF("MusicEngine: ogg_play_file() pe_cache_open failed! \n"); return -1; } ogg_file->file = (FILE *)((UINT32)ogg_cache_id | PE_CACHE_ID_TAG); //只有在作了这个操作之后,以后的文件系统函数才是pe_cache接口 #else ogg_file->file = fopen(filename, "rb"); if (!ogg_file->file) { PE_DBG_PRINTF("MusicEngine: ogg_play_file() fopen failed! \n"); return -1; } #endif ogg_file->seek_to = 0; ogg_file->command = 0; ogg_file->stop_imm = TRUE; ogg_engine.ogg_engine_flag_id = OSAL_INVALID_ID; ogg_engine.ogg_engine_task_id = OSAL_INVALID_ID; deca_io_control((struct deca_device *)dev_get_by_id(HLD_DEV_TYPE_DECA, 0), DECA_SET_STR_TYPE, AUDIO_OGG ); prev_sp_l = 0; prev_sp_r = 0; g_pcm_sample_num = 0; g_pcm_current_using = 0; g_temp_pcm_buff = (char *)(ogg_file->processed_pcm_buff+ON_PCM_BUFF_LEN*8); //code to create flag ogg_engine_flag = OGG_ENGINE_FLAG_INITIALIZE; ogg_engine.ogg_engine_flag_id = osal_flag_create(ogg_engine_flag); if ( ogg_engine.ogg_engine_flag_id == OSAL_INVALID_ID) { PE_DBG_PRINTF("MusicEngine: ogg_play_file() osal_flag_create failure! \n"); #ifdef ENABLE_PE_CACHE pe_cache_close(ogg_cache_id); ogg_cache_id = -1; #else fclose(ogg_file->file); #endif return -1; } //start thread ogg_engine_play_task_attribute.stksz = OGG_ENGINE_PLAY_TASK_STACKSIZE*8; ogg_engine_play_task_attribute.quantum = OGG_ENGINE_PLAY_TASK_QUANTUM; ogg_engine_play_task_attribute.itskpri = OSAL_PRI_HIGH;//OSAL_PRI_NORMAL ; ogg_engine_play_task_attribute.para1 = (unsigned long)cb; //ogg_engine_play_task_attribute.para2 =; ogg_engine_play_task_attribute.name[0] = 'O'; ogg_engine_play_task_attribute.name[1] = 'G'; ogg_engine_play_task_attribute.name[2] = 'G'; ogg_engine_play_task_attribute.task = (FP)ogg_play_task; ogg_engine.ogg_engine_task_id = osal_task_create(&ogg_engine_play_task_attribute); if(ogg_engine.ogg_engine_task_id == OSAL_INVALID_ID) { PE_DBG_PRINTF("MusicEngine: ogg_play_file() osal_task_create failed! \n"); osal_flag_delete(ogg_engine.ogg_engine_flag_id); ogg_engine.ogg_engine_flag_id = OSAL_INVALID_ID; #ifdef ENABLE_PE_CACHE pe_cache_close(ogg_cache_id); ogg_cache_id = -1; #else fclose(ogg_file->file); #endif return -1; } //code to sync osal_flag_wait(&ogg_engine_flag, ogg_engine.ogg_engine_flag_id, OGG_ENGINE_FLAG_MASK, OSAL_TWF_ORW | OSAL_TWF_CLR, OSAL_WAIT_FOREVER_TIME); if (ogg_engine_flag != OGG_ENGINE_FLAG_SUCCESS) { osal_flag_delete(ogg_engine.ogg_engine_flag_id); ogg_engine.ogg_engine_flag_id = OSAL_INVALID_ID; //fclose(ogg_file->file); return -1; } PE_DBG_PRINTF("MusicEngine: <== ogg_play_file()! \n"); return 0; }
static void ogg_play_task(mp_callback_func cb) { long ret = 0; int current_section = 0; double time_seek_to = 0; vorbis_info *vi; struct snd_device *sound_dev; int *processed_pcm; double song_time; PE_DBG_PRINTF("MusicEngine: ==> ogg_play_task()! \n"); sound_dev = (struct snd_device*)dev_get_by_type(NULL, HLD_DEV_TYPE_SND); processed_pcm = (int*)ogg_file->processed_pcm_buff; if (ov_open(ogg_file->file, &ogg_file->vf, NULL, 0) < 0) { PE_DBG_PRINTF("MusicEngine: ogg_play_task() ov_open failed! \n"); #ifdef ENABLE_PE_CACHE pe_cache_close(ogg_cache_id); // 这个ogg_cache_id是在play_file时打开 ogg_cache_id = -1; #else fclose(ogg_file->file); #endif //FREE(processed_pcm); osal_flag_set(ogg_engine.ogg_engine_flag_id, OGG_ENGINE_FLAG_UNSUCCESSFUL); return; } else { PE_DBG_PRINTF("MusicEngine: ov_opened \n"); { vorbis_info *vi = ov_info(&ogg_file->vf, -1); if (!vi) { PE_DBG_PRINTF("MusicEngine: ov_info failed!\n"); ov_clear(&ogg_file->vf); osal_flag_set(ogg_engine.ogg_engine_flag_id, OGG_ENGINE_FLAG_UNSUCCESSFUL); return; } ogg_file->samplerate = vi->rate; ogg_file->channel = vi->channels; PE_DBG_PRINTF("\nBitstream is %d channel, %ldHz\n", vi->channels, vi->rate); song_time = ov_time_total(&ogg_file->vf, -1); if (song_time <= 0) { PE_DBG_PRINTF("MusicEngine: ov_info failed!\n"); ov_clear(&ogg_file->vf); osal_flag_set(ogg_engine.ogg_engine_flag_id, OGG_ENGINE_FLAG_UNSUCCESSFUL); } } osal_flag_set(ogg_engine.ogg_engine_flag_id, OGG_ENGINE_FLAG_SUCCESS); } //all work success, we can start to play while (ogg_file->command != OGG_CMD_STOP) { if (ogg_file->seek_to != 0) { time_seek_to = ov_time_tell(&ogg_file->vf); time_seek_to = time_seek_to + (ogg_file->seek_to * 1000); if (time_seek_to < 0) { time_seek_to = 0; } else if (time_seek_to > song_time) { time_seek_to = song_time; } ret = ov_time_seek(&ogg_file->vf, time_seek_to); if (ret < 0) { //seek failed } osal_task_dispatch_off(); ogg_file->seek_to = 0; osal_task_dispatch_on(); } if (ogg_file->command == OGG_CMD_NONE) { ret = ov_read(&ogg_file->vf, (void *)ogg_file->pcm_out_buff, 2304, ¤t_section); if (ret == 0) { PE_DBG_PRINTF("file end!\n"); //EOF we need call back osal_task_dispatch_off(); if (ogg_file->command != OGG_CMD_STOP) { ogg_file->command = OGG_CMD_WAIT_FOR_STOP; } osal_task_dispatch_on(); cb(MP_MUSIC_PLAYBACK_END, 0); osal_task_sleep(10); } else if (ret < 0) { PE_DBG_PRINTF("error!!!\n"); /* error in the stream. Not a problem, just reporting it in case we (the app) cares. In this case, we don't. */ osal_task_dispatch_off(); if (ogg_file->command != OGG_CMD_STOP) { ogg_file->command = OGG_CMD_WAIT_FOR_STOP; } osal_task_dispatch_on(); cb(MP_MUSIC_PLAYBACK_END, 0); osal_task_sleep(10); } else { /* we don't bother dealing with sample rate changes, etc, but you'll have to*/ process_ogg_pcm(sound_dev, ret, processed_pcm); } } else { osal_task_sleep(10); } } ov_clear(&ogg_file->vf); ogg_avoid_under_run = 0; snd_io_control(sound_dev, SND_CC_MUTE, 0); snd_stop(sound_dev); //FREE(processed_pcm); osal_flag_set(ogg_engine.ogg_engine_flag_id, OGG_ENGINE_FLAG_TASK_EXIT); // task结束,发出EXIT消息 PE_DBG_PRINTF("MusicEngine: <== ogg_play_task()! \n"); }
static int ogg_get_song_info(char *filename, MusicInfo *music_info) { int status = 3; FILE *file; unsigned long file_length; int bitrate; double song_time; OggVorbis_File temp_ogg; PE_DBG_PRINTF("MusicEngine: ==> ogg_get_song_info()! \n"); if ((!filename) || (!music_info) || (!ogg_file)) { PE_DBG_PRINTF("MusicEngine: ogg_get_song_info() invalid parameter filename or music_info or ogg_file!\n"); return -1; } #ifndef ENABLE_PE_CACHE file = fopen(filename, "rb"); // get_song_info打开文件 if (!file) { PE_DBG_PRINTF("MusicEngine: ogg_get_song_info() fopen failed! \n"); return -1; } fseek(file, 0, SEEK_END); file_length = ftell(file); music_info->file_length = file_length; fseek(file, 0, SEEK_SET); #else ogg_info_cache_id = pe_cache_open(filename, NULL, OGG_CACHE_SIZE, OGG_BLOCK_SIZE); if (0 > ogg_info_cache_id) { libc_printf("<%d><%s> pe_cache_open failed!\n", __LINE__, __FUNCTION__); return -1; } file = (FILE *)(((UINT32)ogg_info_cache_id | PE_CACHE_ID_TAG)); pe_cache_seek(ogg_info_cache_id, 0, SEEK_END); file_length = pe_cache_tell(ogg_info_cache_id); music_info->file_length = file_length; pe_cache_seek(ogg_info_cache_id, 0, SEEK_SET); #endif if(ov_open(file, &temp_ogg, NULL, 0) < 0) // 如果这里紧跟着调用ov的函数,则里面的文件系统函数都是stdio,不是pe_cache { PE_DBG_PRINTF("Input does not appear to be an Ogg bitstream.\n"); #ifndef ENABLE_PE_CACHE fclose(file); #else pe_cache_close(ogg_info_cache_id); ogg_info_cache_id = -1; #endif return -1; } song_time = ov_time_total(&temp_ogg, -1); if (song_time < 0) { PE_DBG_PRINTF("Can not get song time from Ogg bitstream.\n"); song_time = 0; } music_info->time = song_time / 1000; ov_clear(&temp_ogg); // get_song_info完毕,在这里close文件 PE_DBG_PRINTF("MusicEngine: <== ogg_get_song_info()! \n"); return status; }