Esempio n. 1
0
void SPU_struct::KeyOn(int channel)
{
	channel_struct &thischan = channels[channel];

    thischan.init_resampler();
    resampler_clear(thischan.resampler);
    resampler_set_quality(thischan.resampler, thischan.format == 3 ? RESAMPLER_QUALITY_BLEP : spuInterpolationMode(state));

	adjust_channel_timer(&thischan);

	//   LOG("Channel %d key on: vol = %d, datashift = %d, hold = %d, pan = %d, waveduty = %d, repeat = %d, format = %d, source address = %07X, timer = %04X, loop start = %04X, length = %06X, cpu->state->MMUARM7_REG[0x501] = %02X\n", channel, chan->vol, chan->datashift, chan->hold, chan->pan, chan->waveduty, chan->repeat, chan->format, chan->addr, chan->timer, chan->loopstart, chan->length, T1ReadByte(MMU->ARM7_REG, 0x501));
	switch(thischan.format)
	{
	case 0: // 8-bit
		thischan.buf8 = (s8*)&state->MMU->MMU_MEM[1][(thischan.addr>>20)&0xFF][(thischan.addr & state->MMU->MMU_MASK[1][(thischan.addr >> 20) & 0xFF])];
	//	thischan.loopstart = thischan.loopstart << 2;
	//	thischan.length = (thischan.length << 2) + thischan.loopstart;
		thischan.sampcnt = 0;
		break;
	case 1: // 16-bit
		thischan.buf16 = (s16 *)&state->MMU->MMU_MEM[1][(thischan.addr>>20)&0xFF][(thischan.addr & state->MMU->MMU_MASK[1][(thischan.addr >> 20) & 0xFF])];
	//	thischan.loopstart = thischan.loopstart << 1;
	//	thischan.length = (thischan.length << 1) + thischan.loopstart;
		thischan.sampcnt = 0;
		break;
	case 2: // ADPCM
		{
			thischan.buf8 = (s8*)&state->MMU->MMU_MEM[1][(thischan.addr>>20)&0xFF][(thischan.addr & state->MMU->MMU_MASK[1][(thischan.addr >> 20) & 0xFF])];
			thischan.pcm16b = (s16)((thischan.buf8[1] << 8) | thischan.buf8[0]);
			thischan.pcm16b_last = thischan.pcm16b;
			thischan.index = thischan.buf8[2] & 0x7F;
			thischan.lastsampcnt = 7;
			thischan.sampcnt = 8;
			thischan.loop_index = K_ADPCM_LOOPING_RECOVERY_INDEX;
		//	thischan.loopstart = thischan.loopstart << 3;
		//	thischan.length = (thischan.length << 3) + thischan.loopstart;
			break;
		}
	case 3: // PSG
		{
			thischan.x = 0x7FFF;
			break;
		}
	default: break;
	}

	if(thischan.format != 3)
	{
		if(thischan.double_totlength_shifted == 0)
		{
			printf("INFO: Stopping channel %d due to zero length\n",channel);
			thischan.status = CHANSTAT_STOPPED;
		}
	}
	
	thischan.double_totlength_shifted = (double)(thischan.totlength << format_shift[thischan.format]);
}
Esempio n. 2
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. 3
0
void usf_restart(void * state)
{
    if ( USF_STATE->MemoryState )
    {
        r4300_end(USF_STATE);
        if (USF_STATE->enable_trimming_mode)
        {
            bit_array_destroy(USF_STATE->barray_rom);
            bit_array_destroy(USF_STATE->barray_ram_read);
            bit_array_destroy(USF_STATE->barray_ram_written_first);
            USF_STATE->barray_rom = 0;
            USF_STATE->barray_ram_read = 0;
            USF_STATE->barray_ram_written_first = 0;
        }
        USF_STATE->MemoryState = 0;
    }
    
    USF_STATE->samples_in_buffer = 0;
    USF_STATE->samples_in_buffer_2 = 0;
    
    resampler_clear(USF_STATE->resampler);
}
Esempio n. 4
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;
}