Esempio n. 1
0
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;
}
Esempio n. 2
0
int ReadPCM(void* context, uint8_t* pBuffer, int size, int *actualsize)
{
  USFContext* usf = (USFContext*)context;
  if (usf->pos >= usf->len)
    return 1;
  if (usf_render(usf->state, (int16_t*)pBuffer, size/4, &usf->sample_rate))
    return 1;
  usf->pos += size;
  *actualsize = size;
  return 0;
}
Esempio n. 3
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);
		}
	}
Esempio n. 4
0
	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;
	}
Esempio n. 5
0
int64_t Seek(void* context, int64_t time)
{
  USFContext* usf = (USFContext*)context;
  if (time*usf->sample_rate*4/1000 < usf->pos)
  {
    usf_restart(usf->state);
    usf->pos = 0;
  }
  
  int64_t left = time*usf->sample_rate*4/1000-usf->pos;
  while (left > 4096)
  {
    usf_render(usf->state, NULL, 1024, &usf->sample_rate);
    usf->pos += 4096;
    left -= 4096;
  }

  return usf->pos/(usf->sample_rate*4)*1000;
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
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;
}