GP2X 940-based Ogg Decoding


Dzz

stmia r0!, {r2-r9}
Joined
Jan 30, 2006
Messages
1,098
Website
Visit site
Hello all. As promised, here is the source to the port of the tremor library running on the 940.

http://gp2xgamer.com/ogg940.zip

To test it, copy test.gpe, code940.bin, and test.ogg to the gp2x, then run test.gpe

Controls in the test app:

START: exit
A: pause and unpause the music playback
B: reset the music back to the beginning
X: reload the music (demonstrates loading a new music clip from a file)

The source is basically as simple as I can make it. In the "940" subfolder the file "vorbis.c" contains a hacked-up version of the tremor library, which includes some junk I added such as a memory allocator tailored to the needs of the vorbis code that I observed when doing the music I needed.

This code is released under the following license:

Do anything you want with it (consistent with the fact that it includes the tremor library which is under basically a BSD license meaning you give them credit [as I am doing here -- I did not write the super-cool code to decode the ogg vorbis data]). Don't blame me if you can't get it to work. If it burns your house down, that's your problem. I am not responsible for your failure to understand how to adapt it to your purposes and I am likely to ignore all questions about it. All complaints will be ignored. You're on your own. Good luck.

My advice is that if you aren't willing to spend significant time figuring it out and adapting it to your purposes, forget about it. Perhaps somebody will be willing to make it even simpler to use, though I did my best with only spending about four hours pulling it out of Vektar and making it reasonably self-contained. I don't have more time to give than that, since I'm working on games.

Have fun.
 
Puck2099 posted on Aug 19 2006 at 08:40 PM said:
Thanks a lot, Dzz, I can't wait to study your code in order to understand how to use the 940 for other purpouses :)

Thanks again

ditto :)
 
Last edited by a moderator:
PokeParadox posted on Aug 20 2006 at 11:48 AM said:
Cool something else to look into... might be able to include this in PKAGE :)

Thanks DZZ


*BUMP* Anyone tried implementing this into their own games yet? I gave it a quick go tonight but I figure there's a clash somewhere with SDL, problably memory. I just 'threw it in' and had a quick mess around. Works fine on it's own, just not with SDL. It could of course be a conflict related to the SDL_Mixer. I need to spend some time looking at the code I think.

EDIT: Is the shared memory 0xF80000 in size and located at 0x3000000? Or am I completely barking up the wrong tree here?

EDIT2: Never mind, I guess I need to read up on mmap first...
 
Last edited by a moderator:
It worked fine in Stargazer but it dropped my speed from 112 to 50-60 FPS ... that's a horrible slowdown. Is the MMU hack REQUIRED for improved performance, seeing as it's utilizing the upper 32MB of RAM for the deocding? (to eliminate the possibility of slowdown from streaming data from SD, I loaded the .ogg from the temp filesystem (/tmp) in RAM. No improvement. I thought Vektar used this in demos long before the MMU hack was announced by Squidge, and I'm sure it wouldn't be used if it slowed the game down.

Anyone know the cause of this?
 
Make sure the 940 has buffered/cached access to its own memory? It could cause some performance impact on the 920 if it's always hitting memory. Then again, without cache, I don't expect it would be fast enough to decode realtime, but maybe.

Also you could try replacing the decoding with some dummy code that either does nothing, or does some level of memory access, just to gauge how much it affects performance. The fact that your performance seemed to drop by exactly half suggests that your game is waiting on vsync or a timer, and if it's not fully ready by the time it occurs, it waits another cycle. I don't see how the 940 could affect the 920's performance that badly otherwise, as long as caching is on.
 
That was my suspicion so I tried integrating the MMU hack, to no success- it caused a crash a lot of the time at runtime, so I got the kernel module instead. I added this bit of code into my program and put the .o file in the dir with my GPE:
Code:
int mmufd = open("/dev/mmuhack", O_RDWR);
	if(mmufd < 0)
	{
		system("/sbin/insmod mmuhack.o");
		mmufd = open("/dev/mmuhack", O_RDWR);
	}
	if(mmufd < 0) return 0;

	close(mmufd);
	return 1;
.. at the start of main() after SDL loads. I also tried after the 940T code runs since that uses mmap and supposedly the MMU hack should be done AFTER all mmap calls. When it finishes it's no faster than it was before. :(

Although, there is more in the mmubench.cpp file; like this main():
Code:
	int memfd = open("/dev/mem", O_RDWR);
	if(memfd < 0) return 0;

	volatile unsigned int *myBuf = (volatile unsigned int *)mmap((void *)0, 65536, PROT_READ | PROT_WRITE, MAP_SHARED, memfd, 0x03000000);
	volatile unsigned int *myBuf2 = (volatile unsigned int *)mmap((void *)0, 65536, PROT_READ | PROT_WRITE, MAP_SHARED, memfd, 0x02000000);
	volatile unsigned int *secbuf = (unsigned int *)malloc (204800);

	mmuhack();

	memset ((void *)myBuf, 0x55, 65536);
	memset ((void *)myBuf2, 0x55, 65536);
	memset ((void *)secbuf, 0x55, 65536);

	printf("mmaped 0x03000000 buffer @ VA: %08X\n\n", myBuf);
	benchmark ((void*)myBuf);
	printf("\nmmaped 0x02000000 buffer @ VA: %08X\n\n", myBuf2);
	benchmark ((void*)myBuf2);
	printf("\nmalloc'd buffer @ VA: %08X\n\n", secbuf);
	benchmark ((void*)secbuf);

	printf ("\nClosing files...\n");
	free((void *)secbuf);
	close (memfd);
	printf ("Exiting...\n");

	return 0;

What's this about making buffers? Do I need to make one before setting up the 940T code somehow? Pardon my newbishness; I don't generally work on such a low level. Wasn't the whole idea of the hack as a kernel module that its benefits should be felt instantly once it's insmod'ed into the kernel? So why do I seem to need to do all this extra BS? :(

Or am I doing this all wrong and the MMU hack is the wrong approach? Thanks. :)
 
I think the mmu hack is only for cases where the 920 accesses the high memory, which shouldn't happen a lot here, except for copying the ogg data to the 940, and copying the decoded audio back (if it works this way, maybe it plays it directly?).

It would be more of a thing in the 940 code, which I would think would already be there... maybe dzz could give some info. It could probably be configured via the 920 program also, but it seems more natural that the code running on that processor would configure itself.
 
Epicenter posted on Aug 23 2006 at 11:30 PM said:
Dzz said he'd probably ignore all questions about it, so I'm not holding out much hope for that. I guess it can't hurt to ask though ...
I'm not sure what your question is...

The 'mmuhack' is not going to help the performance of this.

I don't know the cause of your performance problems, but I assumed it would be nontrivial to apply this to a new application. If I were to guess I'd guess something like memory contention. I'll think about it and let you know if anything strikes me. Probably I'll have to spend a bunch of time trying different things, which I might not get to very soon.
 
Last edited by a moderator:
I was referring to how the 940's cache/buffer was enabled (that is, for the 940 accessing its 'own' memory), and assumed that was part of the code loaded into the 940. If it had to be done manually in the 920 (and if the sample code doesn't demonstrate), that could cause performance problems.
 
I suppose memory contention seems the most likely suspect; I am doing a TON of blitting and all my surfaces are in the upper 32mb, so is the framebuffer, and I imagine so is the data the OGG decoder is working with. I wonder if there'd be an improvement if more of the components involved were using the lower 32MB, but for all I know, it's just one memory bus and utilization of the 2 banks in any configuration will result in the same bandwidth limitations..

If you can lend a hand it would mean a lot to me; thanks. Of course I understand as well as anyone if you can't fit it into your schedule, though.
 
Epicenter posted on Aug 24 2006 at 08:12 AM said:
I suppose memory contention seems the most likely suspect; I am doing a TON of blitting and all my surfaces are in the upper 32mb, so is the framebuffer, and I imagine so is the data the OGG decoder is working with. I wonder if there'd be an improvement if more of the components involved were using the lower 32MB, but for all I know, it's just one memory bus and utilization of the 2 banks in any configuration will result in the same bandwidth limitations..

If you can lend a hand it would mean a lot to me; thanks. Of course I understand as well as anyone if you can't fit it into your schedule, though.
The only thing I can do is add stress-testing code to my sample app and instrumentation code to measure some things and mess around with that hoping to reproduce an issue. As you can probably imagine, that's not really the most fun thing for an amateur game developer to do in his play time, but I'll try to look at it in the next few weeks.
 
Last edited by a moderator:
It's possible that the tremor "inner loops" are not very 4k-cache-friendly in which case they would be hammering the memory bus pretty hard. The games I write tend to do some per-pixel processing in most cases (Vektar drawing subpixel-accurate anti-aliased lines with clamped color arithmetic for example) meaning that their memory bandwidth is not as huge as something blitting as fast as possible. If that's the cause there might not be anything that can be done about it. However, it's hard to believe that the vorbis decoding code would be hitting memory so hard as to cut your performance in half.

As I say, I'll see what I can figure out, but not for a little while. Do you have a release date for Stargazer?
 
It's quite a distance off, so there isn't a rush. Thanks for helping. :) If you could just PM me when/if you get around to it, that'd be awesome. You'll definitely be getting credit (and a nice chunk of donation money) :)
 
Awesome, I was trying to get this to work, now to figure out what was wrong in my code :rolleyes:
 
Back
Top