Audio Issues In Mame4All (Sdl)


cosam

Active Member
Joined
Sep 1, 2008
Messages
703
Location
Netherlands
Website
www.cosam.org
If you've been following the beta thread, you may have already heard that there are some niggling sound issues with the current MAME4ALL build for the Pandora. Sound is fine for the majority of games, but some titles suffer from popping/crackling. Sound will often start playing fine, but sooner or later the popping starts and doesn't disappear. Somewhat surprisingly, it's mostly evident in older titles which you wouldn't expect would be difficult to emulate. The prime example is Donkey Kong Jr.

The problem appears to be due to an underrun in the SDL callback - SDL wants X bytes, but MAME can only give it X-Y. I've tried adjusting the number of samples in the SDL audio spec (from <100 to 8192) and the size of the buffer and period in .asoundrc, neither of which have very much effect at all. There are various sound options in the MAME4ALL menu, including overclocking of the emulated sound processor, but these don't seem to make any difference either. This is all kind of outside my comfort zone and I am pretty much out of ideas, so if anyone feels like having a look, here's a snippet of what I have now. This works in most cases, so I have a sneaking suspicion that the problem may be elsewhere (pnd_sound_play is fed from code in src/pandora/sound.cpp, which gets the sound data from the emulation code).

Code:
// Somewhere in src/pandora/minimal.cpp...

void pnd_sound_play(void *buff, int len)
{
	if( pnd_sndlen+len > pnd_audio_buffer_len ) {
		/* Overrun */
		pnd_sndlen = 0;
		return;
	}
	
	SDL_LockAudio();
	memcpy( pnd_audio_spec.userdata + pnd_sndlen, buff, len );
	pnd_sndlen += len;
	SDL_UnlockAudio();
}

static void pnd_sound_callback(void *data, Uint8 *stream, int len)
{
	if( pnd_sndlen < len ) {
#ifdef PND_DEBUG
		printf("Audio underrun (%d/%d bytes)\n", pnd_sndlen, len);
#endif
		memcpy(stream, data, pnd_sndlen );
		pnd_sndlen = 0;
		return;
	}

	memcpy( stream, data, len );
	pnd_sndlen -= len;
	memcpy( data, data + len, pnd_sndlen );
}

void pnd_sound_thread_start(void)
{
	pnd_sndlen=0;

#ifdef PND_DEBUG
	printf("Setting audio to %dKHz %s\n", pnd_sound_rate, pnd_sound_stereo ? "stereo" : "mono");
#endif

    pnd_audio_spec.freq = pnd_sound_rate;
    pnd_audio_spec.channels = pnd_sound_stereo ? 2: 1;

	pnd_audio_buffer_len = pnd_audio_spec.samples * pnd_audio_spec.channels * 2 * 64;
	void *audiobuf = malloc( pnd_audio_buffer_len );
	memset( audiobuf, 0 , pnd_audio_buffer_len );
	pnd_audio_spec.userdata=audiobuf;

	if ( SDL_OpenAudio(&pnd_audio_spec, NULL) < 0 )
		fprintf(stderr, "Unable to open audio: %s\n", SDL_GetError());
	
	SDL_PauseAudio(0);
}

void pnd_sound_thread_stop(void)
{
	SDL_CloseAudio();

	if( pnd_audio_spec.userdata ) {
		free( pnd_audio_spec.userdata );
		pnd_audio_spec.userdata = NULL;
	}
}

Full sources:
SVN: http://sources.cosam.org/svn/mame4all/
Tarball: http://www.cosam.org/computers/pandora/mame4all.tar.gz

Should build easily enough after setting your toolchain stuff in makefile.pandora. This produces the front end (mame-fe) and the mame executable itself. The script pnd/mame.sh can optionally be used to set frame buffer stuff and launch the FE.

Thanks in advance for any pointers.

-Steve
 
Is MAME overrunning the buffer, and then truncating the buffer-size-value? Or is there something causing it to use the wrong type (Stereo vs mono, or 16bit vs 8bit, etc; do these games with popping have anything in common in the sond arena? which sound chip? 8bit mono? stuff like that..)

(Didn't look at the code, on the way out right now)

jeff
 
skeezix said:
Is MAME overrunning the buffer, and then truncating the buffer-size-value?
I'm not sure exactly what's going on, but what I see is that MAME doesn't quite write enough sound to the intermediate buffer from which the SDL callback gets its audio data.

Or is there something causing it to use the wrong type (Stereo vs mono, or 16bit vs 8bit, etc;
AFAIK the format is correct. MAME appears to churn out whatever you ask it to and sound usually plays fine for a while before the popping starts.

do these games with popping have anything in common in the sond arena? which sound chip? 8bit mono? stuff like that..)
That's what's confusing me too. It would appear that all the Donkey Kong games have it, and they use an i8035 for sound. Then you have Q*bert which uses a 6502 and Pac-Man which uses some custom Namco stuff. I do however need to check that those last two are suffering from the same issue as it might be something else. All they really see to have in common is that they're early '80s games :-\ Maybe I need to force 8-bit sound for these games?
 
Last edited by a moderator:
Ask Franxis, for one; he's a good chap :) (ytou'd have to do it on gp32spain I think)

The older code had dozens of buffers, and logic to rotate amongst which buffer to write to and which to pull from (or catenate and pull, or whatever.) Is there perhaps some piece of old logic in pace which ic causing it to bump the write-pointer forward or rotate through buffers that don't exist anymore? is the read logic getting the wrong start of buffer point or something, after awhile? (or are you by chance letting it write off the end of a buffer by a byte or two, eventually buggering up somethign that matters?)

99% probably not it, but you reminded me of something from 15 years ago :)

I forget offhand if such an old MAME does audio emulation over-time or in bursts; ie: in other emus (like retrocade when we were doing it) we were fiddling with timestamped audio requests, and then at audio-render-time we'd try to fill the buffer with audio and using the time-queues to make it hyepr accurate (ie: if you just grabbed sound chip registers every 1s, your music would suck; if you grabbed them too quick, you'd go slow; what we worked on was recording the change sto the chip, and then later, runing the chip to catch up as the audio data was needed, and playing it back with the proper registers at the right times for the audio buffers.) That caused all kinds of tricks 'later' over time, if we got out of sync of the cpy cycle counter versus the audio render counter, etc.

jeff
 
Back
Top