Dingoo Gngb Game Boy Emulator Dingux Port Help With Audio Problems Please


dgame

Active Member
Joined
Oct 1, 2006
Messages
945
New game boy emulator Dingux port need help with sound problems please

I am no programmer, I took a C class in undergrad and that is it.
I learned how to compile from the A320 forum and Google.

***This is not a formal release I am seeking development help***

I cross compiled "gngb" a Game Boy/ Game Boy Color Emulator. I use this dmenu entry:

MenuItem Gngb
{
Icon = "res/emulators/gnuboy.png"
Name = " Gngb"
Executable = "./gngb"
WorkDir = "/usr/local/emulators/gngb"
Selector = yes
}


Keys:
L: brings up the Menu
Start: enter menus, toggle or select menu items
R: exit menus, Exit gngb

The Menu:
Load/Save State: can choose 8 different slots, has little thumbnail for saves
Video: can toggle Color Filter and enter the Filter sub-menu,
Filter Sub-menu: Select Filter 2 for 150% scaling (my temp default), none for native game boy resolution
Frameskip: Toggle frameskip, show fps meter
Sound: Toggle sound on/off (temp defaults off because of poor performance with sound on)
Reset: Resets Gameboy

Gngb can open/run zipped (.zip) roms.

It has audio problems though. With gngb the sound is choppy.
Press L to open menu, scroll down to Sound, and press start to turn on sound (it is currently off by default.)

Gngb uses AUDIO_S8 format which I only changed the name to AUDIO_S16 in sound.c, line 933.

Does this require some additional conversion?

Lowering the sample rate helped a bit but the sound is still choppy.

I have included the complete source code for suggestions/help/explanations.

Things I have done:
I changed the default conf.sample_rate=44100; to conf.sample_rate=16000; and remapped the default keys to match the Dingoo in emu.c.

The makefile is setup to use booboo’s 20090916 toolchain with the /opt/mipsel-linux-uclibc/usr prefix.

I temporarily repurposed the filter blit_std_with_scanline50 function in video_std.c to use the SDL_StretchSurface_23 function which gives 150% scale.
I am learning as I go and I will eventually put my own filter entry in. This is my first attempt.

How can the sound be fixed/improved?

Thanks!!!


Compiler note:
If you configure with:
./configure --host=mipsel-linux --target=mipsel-linux --with-sdl-prefix=/opt/mipsel-linux-uclibc/usr --enable-static
Add:
-lSDL_stretch
to the LIBS = line in the Makefile
Then add:
-I/opt/mipsel-linux-uclibc/usr/include/SDL_stretch
To the CFLAGS = line in the Makefile
Use the Makefile in the gngb/src folder.
A Dingux executable gngb is already in the src folder if you want to try it out.


Get the complete source here:
http://a320.freeforums.org/download/file.php?id=142
 
Im pretty sure the dingux only supports 16 bit sound, so you need to convert the data going into SDL. So if the data is U8 and you need to convert to S16, then you need to rescale from 0 to 255 to -32767 to 32768.
 
Thanks Pickle,

I was hoping one of the masters would chime in to help a padawan . . .

I almost understand how joyrider converted U8 to S16 in sdlgnuboy.
He did it in the audio_callback fuction below:

// ** This is not what I am working on, it is from sdlgnuboy as a reference

static void audio_callback(void *blah, signed short *stream, int len)
{
int teller = 0;
signed short w;
byte * bleh = (byte *) stream;
for (teller = 0; teller < pcm.len; teller++)
{
w = ((pcm.buf[teller] - 128) << 8);
*bleh++ = w & 0xFF ;
*bleh++ = w >> 8;

}

/* memcpy(stream, pcm.buf, len); */
audio_done = 1;
}

Where:
*bleh is a byte pointer to the 16 bit sound buffer used for playback
pcm.buf[teller] is the 8 bit value;
w is the signed short value (signed 16 bit).

// ** The above is not what I am working on, it is from sdlgnuboy as a reference

However gngb does not use the pcm structure and the “byte” is undeclared when I try to use it, is byte a C data type?

So the unconverted function in gngb is:
/* function callback – This is what I need help with */
void update_stream(void *userdata,Uint8 *stream,int snd_len)
{

/* update tous les buffer dans playbuf*/

if (snd_len-(lastpos*2.0)>0) {
// printf("HOHO\n");
update_gb_sound(snd_len-(lastpos*2.0));
// clk=0;
}
get_nb_cycle();

#ifdef LOG_SOUND
fwrite(playbuf,snd_len,1,fsound);
#endif


memcpy(stream,playbuf,snd_len);
memset(playbuf,0,snd_len);


lastpos=curpos=0;


}
Where:
I guess a snd_len amount of playbuf is copied into stream then we hear it.

So how would I approach converting this?

Should I convert the playbuff data each snd_len at a time before it gets sent into the stream?

The sdlgnuboy code referenced above has the buffer in a pcm.buf array where it can step though the chunks in the buffer using the pcm.buf[teller] in the for loop to do the conversion.

The playbuff in gngb is declared like this in sound.c, line 35:

Sint8 *playbuf;

In addition to in update_stream() playbuf is also referenced in:

update_gb_sound(), line 788: Sint8 *pl=playbuf+(int)(lastpos*2)
update_gb_sound(), line 820: for(i=0;i<(snd_len/2) && pl<playbuf+buf_size;i++) {
gbsound_init(), line 942: realloc((void*)playbuf,desired.size+1);
gbsound_init(), line 944: playbuf=(Sint8*)malloc(desired.size+1);
gbsound_init(), line 946: memset(playbuf,0,desired.size);

The gngb update_stream callback function uses Uint8 *stream, suggesting that the stream is Uint8?

So what should my next step be? I am open to suggestions and pointers.

I also don’t mind doing research if pointed in the right direction.

I am trying to learn so I appreciate your patience and explanations.

I also linked sound.c.zip containing only the gngb sound.c source file:
http://a320.freeforums.org/download/file.php?id=143

Thanks!!!
 
Just try things out, you know by hearing the sound if its working correctly.
I woulkd start with doing this:
1. Set SDL to 16 bit
2. Scale the 8 bit value to 16 bit
3. Load the upper 8 bits into SDL buffer then load the lower 8 bits into the buffer
 
Hummm, try this

Code:
/* function callback – This is what I need help with */
void update_stream(void *userdata,Uint8 *stream,int snd_len)
{
/* update tous les buffer dans playbuf*/

if (snd_len-(lastpos*2.0)>0) {
// printf("HOHO\n");
update_gb_sound(snd_len-(lastpos*2.0));
// clk=0;
}
get_nb_cycle();

#ifdef LOG_SOUND
fwrite(playbuf,snd_len,1,fsound);
#endif

for( int i = 0; i < snd_len ; ++i )
{
 ((signed short *)stream)[ i ] = ( playbuf[ i ] ^ 0x80 ) << 8;
}

lastpos=curpos=0;


}
 
Back
Top