virtual int getSamples(int16_t *target, int noSamples) override { static int16_t temp[8192]; int sr; int samples_written = 0; while(samples_written < noSamples) { auto free_count = resampler_get_free_count(resampler[0]); if(free_count > 0) { const char *err = usf_render(usf_state->emu_state, temp, free_count, &sr); if(err) { LOGD("ERROR %s", err); return 0; } } if(sr != sample_rate) { resampler_set_rate(resampler[0], 44100.0 / (float)sample_rate); resampler_set_rate(resampler[1], 44100.0 / (float)sample_rate); sample_rate = sr; LOGD("######### NEW RATE %d", sample_rate); } uint32_t avg = 0; for(int i = 0; i<free_count; i++) { resampler_write_sample(resampler[0], temp[i*2]); resampler_write_sample(resampler[1], temp[i*2+1]); avg += (std::abs(temp[i*2]) + std::abs(temp[i*2+1])); } while(samples_written < noSamples && resampler_get_sample_count(resampler[0]) > 0) { auto s0 = resampler_get_sample(resampler[0]); resampler_remove_sample(resampler[0]); auto s1 = resampler_get_sample(resampler[1]); resampler_remove_sample(resampler[1]); target[samples_written++] = s0; target[samples_written++] = s1; } } return samples_written; }
int opl3class::fm_init(unsigned int rate) { OPL3_Reset(&chip, rate); memset(command,0,sizeof(command)); memset(time, 0, sizeof(time)); memset(samples, 0, sizeof(samples)); counter = 0; lastwrite = 0; strpos = 0; endpos = 0; resampler = resampler_create(); if (!resampler) return 0; resampler_set_rate(resampler, 49716.0 / (double)rate); return 1; }
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); } }
const char * usf_render_resampled(void * state, int16_t * buffer, size_t count, int32_t sample_rate) { if ( !buffer ) { unsigned long samples_buffered = resampler_get_sample_count( USF_STATE->resampler ); resampler_clear(USF_STATE->resampler); if (samples_buffered) { unsigned long samples_to_remove = samples_buffered; if (samples_to_remove > count) samples_to_remove = count; while (samples_to_remove--) resampler_remove_sample(USF_STATE->resampler); if (!count) return 0; } count = (size_t)((uint64_t)count * USF_STATE->SampleRate / sample_rate); if (count > USF_STATE->samples_in_buffer_2) { count -= USF_STATE->samples_in_buffer_2; USF_STATE->samples_in_buffer_2 = 0; } else if (count) { USF_STATE->samples_in_buffer_2 -= count; memmove(USF_STATE->samplebuf2, USF_STATE->samplebuf2 + 8192 - USF_STATE->samples_in_buffer_2 * 2, USF_STATE->samples_in_buffer_2 * sizeof(short) * 2); return 0; } return usf_render(state, buffer, count, NULL); } while ( count ) { const char * err; while ( USF_STATE->samples_in_buffer_2 && resampler_get_free_count(USF_STATE->resampler) ) { int i = 0, j = resampler_get_free_count(USF_STATE->resampler); if (j > USF_STATE->samples_in_buffer_2) j = (int)USF_STATE->samples_in_buffer_2; for (i = 0; i < j; ++i) { resampler_write_sample(USF_STATE->resampler, USF_STATE->samplebuf2[i*2], USF_STATE->samplebuf2[i*2+1]); } memmove(USF_STATE->samplebuf2, USF_STATE->samplebuf2 + i * 2, (USF_STATE->samples_in_buffer_2 - i) * sizeof(short) * 2); USF_STATE->samples_in_buffer_2 -= i; } while ( count && resampler_get_sample_count(USF_STATE->resampler) ) { resampler_get_sample(USF_STATE->resampler, buffer, buffer + 1); resampler_remove_sample(USF_STATE->resampler); buffer += 2; --count; } if (!count) break; if (USF_STATE->samples_in_buffer_2) continue; err = usf_render(state, USF_STATE->samplebuf2, 4096, 0); if (err) return err; USF_STATE->samples_in_buffer_2 = 4096; resampler_set_rate(USF_STATE->resampler, (float)USF_STATE->SampleRate / (float)sample_rate); } return 0; }