int main(int argc, char ** argv) { if ( argc == 2 || argc == 3 ) { int32_t sample_rate; state = (unsigned char *) malloc(usf_get_state_size()); usf_clear(state); if ( psf_load( argv[1], &stdio_callbacks, 0x21, usf_loader, 0, usf_info, 0, 1 ) <= 0 ) return 1; usf_set_compare(state, enable_compare); usf_set_fifo_full(state, enable_fifo_full); if (argc == 3) usf_set_hle_audio(state, 1); usf_render(state, 0, 0, &sample_rate); usf_render(state, 0, length_ms * sample_rate / 1000, &sample_rate); usf_shutdown(state); free(state); } return 0; }
USFPlayer(const std::string &fileName) { usf_state = new usf_loader_state; usf_state->emu_state = malloc( usf_get_state_size() ); usf_clear( usf_state->emu_state ); sample_rate = 0; char temp[fileName.length()+1]; strcpy(temp, fileName.c_str()); LOGD("Trying to load USF %s", string(temp)); if ( psf_load( temp, &psf_file_system, 0x21, usf_loader, usf_state, usf_info, usf_state, 1 ) < 0 ) throw player_exception(); usf_set_hle_audio(usf_state->emu_state, 1); PSFFile psf { fileName }; if(psf.valid()) { auto &tags = psf.tags(); int seconds = psf.songLength(); setMeta("composer", tags["artist"], "sub_title", tags["title"], "game", tags["game"], "format", "Nintendo 64", "length", seconds ); } usf_set_compare( usf_state->emu_state, usf_state->enable_compare ); usf_set_fifo_full( usf_state->emu_state, usf_state->enable_fifo_full ); const char *err = usf_render(usf_state->emu_state, 0, 0, &sample_rate); if(err) LOGD("ERROR %s", err); LOGD("######### RATE %d", sample_rate); resampler_init(); for(auto &r : resampler) { r = resampler_create(); resampler_set_quality(r, RESAMPLER_QUALITY_CUBIC); resampler_set_rate(r, (float)sample_rate / 44100.0); //resampler_set_rate(r, 44100.0 / (float)sample_rate); resampler_clear(r); } }
void* Init(const char* strFile, unsigned int filecache, int* channels, int* samplerate, int* bitspersample, int64_t* totaltime, int* bitrate, AEDataFormat* format, const AEChannel** channelinfo) { USFContext* result = new USFContext; result->pos = 0; result->state = new char[usf_get_state_size()]; usf_clear(result->state); if (psf_load(strFile, &psf_file_system, 0x21, 0, 0, psf_info_meta, result, 0) <= 0) { delete result->state; delete result; return NULL; } if (psf_load(strFile, &psf_file_system, 0x21, usf_load, result->state, 0, 0, 0) < 0) { delete result->state; delete result; return NULL; } *totaltime = result->len; usf_set_compare(result->state, 0); usf_set_fifo_full(result->state, 0); usf_set_hle_audio(result->state, 1); static enum AEChannel map[3] = { AE_CH_FL, AE_CH_FR, AE_CH_NULL }; *format = AE_FMT_S16NE; *channelinfo = map; *channels = 2; *bitspersample = 16; *bitrate = 0.0; int32_t srate; usf_render(result->state, NULL, 0, &srate); *samplerate = result->sample_rate = srate; result->len = srate*4*(*totaltime)/1000; return result; }
void usf_clear(void * state) { size_t offset; memset(state, 0, usf_get_state_size()); offset = 4096 - (((uintptr_t)state) & 4095); USF_STATE_HELPER->offset_to_structure = offset; //USF_STATE->enablecompare = 0; //USF_STATE->enableFIFOfull = 0; //USF_STATE->enable_hle_audio = 0; // Constants, never written to USF_STATE->trunc_mode = 0xF3F; USF_STATE->round_mode = 0x33F; USF_STATE->ceil_mode = 0xB3F; USF_STATE->floor_mode = 0x73F; #ifdef DYNAREC USF_STATE->precomp_instr_size = sizeof(precomp_instr); #endif // USF_STATE->g_rom = 0; // USF_STATE->g_rom_size = 0; USF_STATE->save_state = calloc( 1, 0x80275c ); USF_STATE->save_state_size = 0x80275c; for (offset = 0; offset < 0x10000; offset += 4) { USF_STATE->EmptySpace[offset / 4] = (uint32_t)((offset << 16) | offset); } USF_STATE->resampler = resampler_create(); #ifdef DEBUG_INFO USF_STATE->debug_log = fopen("/tmp/lazyusf.log", "w"); #endif }