Пример #1
0
signed int ReGBA_AudioUpdate()
{
	u32 i, j;
	s16* audio_buff;
	s16 *dst_ptr, *dst_ptr1;
	u32 n = ds2_checkAudiobuff();
	int ret;

	u8 WasInUnderrun = Stats.InSoundBufferUnderrun;
	Stats.InSoundBufferUnderrun = n == 0 && ReGBA_GetAudioSamplesAvailable() < AUDIO_LEN * 2;
	if (Stats.InSoundBufferUnderrun && !WasInUnderrun)
		Stats.SoundBufferUnderrunCount++;

	// On auto frameskip, sound buffers being full or empty determines
	// whether we're late.
	if (AUTO_SKIP)
	{
		if (n >= 2)
		{
			// We're in no hurry, because 2 buffers are still full.
			// Minimum skip 1
			if(SKIP_RATE > 1)
			{
#if defined TRACE || defined TRACE_FRAMESKIP
				ReGBA_Trace("I: Decreasing automatic frameskip: %u..%u", SKIP_RATE, SKIP_RATE - 1);
#endif
				SKIP_RATE--;
			}
		}
		else
		{
			// Maximum skip 9
			if(SKIP_RATE < 8)
			{
#if defined TRACE || defined TRACE_FRAMESKIP
				ReGBA_Trace("I: Increasing automatic frameskip: %u..%u", SKIP_RATE, SKIP_RATE + 1);
#endif
				SKIP_RATE++;
			}
		}
	}

	/* There must be AUDIO_LEN * 2 samples generated in order for the first
	 * AUDIO_LEN to be valid. Some sound is generated in the past from the
	 * future, and if the first AUDIO_LEN is grabbed before the core has had
	 * time to generate all of it (at AUDIO_LEN * 2), the end may still be
	 * silence, causing crackling. */
	if (ReGBA_GetAudioSamplesAvailable() < AUDIO_LEN * 2)
	{
		// Generate more sound first, please!
		return -1;
	}

	// We have enough sound. Complete this update.
	if (game_fast_forward || temporary_fast_forward)
	{
		if (n >= AUDIO_BUFFER_COUNT)
		{
			// Drain the buffer down to a manageable size, then exit.
			// This needs to be high to avoid audible crackling/bubbling,
			// but not so high as to require all of the sound to be emitted.
			// gpSP synchronises on the sound, after all. -Neb, 2013-03-23
			ReGBA_DiscardAudioSamples(ReGBA_GetAudioSamplesAvailable() - AUDIO_LEN);
			return 0;
		}
	}
	else
	{
		// Wait for at least one buffer to be free for audio.
		// Output assertion: The return value is between 0, inclusive,
		// and AUDIO_BUFFER_COUNT, inclusive, but can also be
		// 4294967295; that's (unsigned int) -1. (DSTWO SPECIFIC HACK)
		unsigned int n2;
		while ((n2 = ds2_checkAudiobuff()) >= AUDIO_BUFFER_COUNT && (int) n2 >= 0);
	}

	audio_buff = ds2_getAudiobuff();
	if (audio_buff == NULL) {
#if defined TRACE || defined TRACE_SOUND
		ReGBA_Trace("Recovered from the lack of a buffer");
#endif
		return -1;
	}

	dst_ptr = audio_buff; // left (stereo)
	dst_ptr1 = dst_ptr + (int) (AUDIO_LEN / OUTPUT_FREQUENCY_DIVISOR); // right (stereo)

	for(i= 0; i < AUDIO_LEN; i += OUTPUT_FREQUENCY_DIVISOR)
	{
		s16 Left = 0, Right = 0, LeftPart, RightPart;
		for (j = 0; j < OUTPUT_FREQUENCY_DIVISOR; j++) {
			ReGBA_LoadNextAudioSample(&LeftPart, &RightPart);

			if      (LeftPart >  2047) LeftPart =  2047;
			else if (LeftPart < -2048) LeftPart = -2048;
			Left += LeftPart / OUTPUT_FREQUENCY_DIVISOR;

			if      (RightPart >  2047) RightPart =  2047;
			else if (RightPart < -2048) RightPart = -2048;
			Right += RightPart / OUTPUT_FREQUENCY_DIVISOR;
		}
		*dst_ptr++ = Left << 4;
		*dst_ptr1++ = Right << 4;
	}

	if (game_fast_forward || temporary_fast_forward)
	{
		// Dampen the sound with the previous samples written
		// (or unitialised data if we just started the emulator)
		StartFastForwardedSound(audio_buff,
			&audio_buff[(int) (AUDIO_LEN / OUTPUT_FREQUENCY_DIVISOR)]);
		// Store the end for the next time
		EndFastForwardedSound(&audio_buff[(int) (AUDIO_LEN / OUTPUT_FREQUENCY_DIVISOR) - DAMPEN_SAMPLE_COUNT],
			&audio_buff[(int) (AUDIO_LEN / OUTPUT_FREQUENCY_DIVISOR) * 2 - DAMPEN_SAMPLE_COUNT]);
	}

	Stats.InSoundBufferUnderrun = 0;
	ds2_updateAudio();
	return 0;
}
Пример #2
0
int doPlay(FILE *fp, int samples_per_trans)
{
	int len;
	int m, n;
	void *audiobuf;
	unsigned int key;
	int flag;
	int vol;
	unsigned short *audio_buffer_addr;

	len = wave_BytePsample * samples_per_trans;

	audiobuf = (void*)malloc(len);
	if(NULL == audiobuf) return -1;

	do {
		audio_buffer_addr = (unsigned short*)ds2_getAudiobuff();
	} while(NULL == audio_buffer_addr);

	vol = 127;

	flag = 1;
	while(flag)
	{
		n = fread(audiobuf, 1, len, fp);
		if(0 == n) break;

		m = (n + len -1)/len;
		m *= len;
		if(n < m)
		{
			memset((char*)((unsigned int)audiobuf + n), 0, m -n);
		}

		//assume 16-bit and stereo audio
   		unsigned short *src;
		unsigned short *dst0;
		unsigned short *dst1;

   		src = (unsigned short*)audiobuf;
		//the audio buffer's front part are left channel's data, behind ate right
		// channel's data, different as the wave file, it's data not interleaved
		dst0 = audio_buffer_addr;
        dst1 = audio_buffer_addr + samples_per_trans;

		n = 0;
		while(n++ < samples_per_trans)
		{
			*dst0++ = *src++;
			*dst1++ = *src++;
		}

		//ther are 4 audio buffers on the ds2sdk, we should not make it overflow
		while(ds2_checkAudiobuff() > 3)
		{
			//128 samples (channles * Bytes Per channel) can play 2.9ms @ 44.1KHz
			//mdelay((samples_per_trans/128)*2.9);
			mdelay(1);
		}

		ds2_updateAudio();

		while(ds2_checkAudiobuff() > 1)
		{
			key = getKey();
			
			switch(key)
			{
				//incread volume
				case KEY_UP:
						vol += 1;
						if(vol > 255) vol = 255;

						ds2_setVolume(vol);
						printf("volume: %d\n", vol);
					break;

				//decreade volume
				case KEY_DOWN:
						vol -= 1;
						if(vol < 0) vol = 0;

						ds2_setVolume(vol);
						printf("volume: %d\n", vol);
					break;

				//exit
				case KEY_B:
						flag = 0;
					break;
			}
		}

		do {
			audio_buffer_addr = (unsigned short*)ds2_getAudiobuff();
		} while(NULL == audio_buffer_addr);
	}

	free(audiobuf);
	return 0;
}