GP32 I Guess I Found The Cause Of The Gp32 Sound Bug

Discussion in 'General Discussions' started by SvOlli, Jul 4, 2004.

  1. SvOlli

    SvOlli Certified Guru

    Joined:
    May 4, 2004
    Messages:
    161
    Location:
    Hannover, Germany
    Hi there!

    During the discussion with a co-worker from the hardware department we maybe found the cause of the always annoying gp32 sound bug.

    The main problem seems to be that the (memory?) bus can't handle all the data, there's just too much traffic. And then the sound dma will not be able to get the needed data in time.

    I did some experiments with my OggVorbis Player (Project Bluescreen from the beta board). If I throttle my graphics output down, there's no "static noise" anymore. My next step there will be to replace the loop calling GpPointSet() function with an own graphics routine that'll always write 4 pixels (32 bit) at a time to reduce load on the memory bus.

    So maybe the rule "only access the memory on 32bit boundry" can help avoid the sound bug.

    I'll keep you informed.

    Greetings & good night from Germany,
    SvOlli
     
    Tags:
  2. Squidge

    Squidge Certified Guru

    Joined:
    Nov 16, 2003
    Messages:
    8,495
    Location:
    UK
    Yes, I think most of the developers know why the sound bugs exists and how to get around it. Some methods are described in the arm documentation - eg. by placing an instruction that doesn't access the memory in the middle of tight memory copying loops and the like to release the bus for dma etc. Unfortunately, it only describes the problems in arm assembly code and the ways around it, so people who don't understand assembler and only know C are pretty much stuck.

    I believe Mirko has found a solution in his own SDK though. I've not looked at his code to see how he does it (not particularly interested to be honest), but just from what he says in his SDK thread.
     
  3. MojoJojo

    MojoJojo Member

    Joined:
    Jun 19, 2003
    Messages:
    165
    I've always thought there should be a sticky on this... Most people don't go looking through the technical specs very often, and on a few occasions people asking why their sound is crackly get a rather snotty reply about it being covered before and a link to that 300 page document.
     
  4. generalnmx

    generalnmx Playful/Fascist Mod

    Joined:
    Apr 18, 2003
    Messages:
    2,128
    Location:
    Maryland, USA
    Ask and you shall receive.
     
  5. mr.mirko

    mr.mirko Certified Guru

    Joined:
    Nov 24, 2003
    Messages:
    471
    Location:
    Germany
    My experience with the Soundbug :



    > What is the best setting ???

    It depends on how mutch you use the bus, try both ...

    >mr.mirko, I don't really get the difference between a much lower access to the
    memory bus, and increasing the speed...

    once again, youre disabling the cache on the sound DMA buffer, or any other buffer, with fast memory acces, to get a clean sound, and not to speed up something. Disabling cache on a memory region, will slow down the access. And why do we do this? Couse the design of the gp32 soundhardware ( no real soundchip ), needs this.

    There is no A-B-C cook book for a work around on the gp32 soundbug.
    I found out, that this helped me, developing the modplayer:

    - disable write back cache on main sound loop buffer, and all sound related buffers.
    - fill the soundbuffer with soundbuffer[x] = *buffer++;
    - dont use malloc/free with newlib, the garbage collection will result in sound crap...
    - If you still suffer from soundbug, compile memory expensive part with -O0
    - try using a high memory region for the main sampleloop, ( near framebuffer )

    Sound on gp32 is a real hell, it took me 3 Month developing a clean modplayer, i had to
    rewrite all memory access in source...
     
  6. skeezix

    skeezix Internal Development

    Joined:
    Mar 11, 2003
    Messages:
    8,058
    I find it usualtyl comes down to very specific parts of your code causing the bus to fill up; ie: the trick for me was to find out *where* I was filling up the bus, and then to adjust to fit.

    Tricks..

    1) #if'ing; just #if 0 out some blocks of code until the problem goes away; ie: Turn off your rendering code, as its usually the culprit; if that works, then start turning off smaller and smaller chunks until you go aha! and know where it is

    2) Break the code into more files, then use different -O optimizaiton levels on them until the noise goes away; ie: compiel with all the optimizations you can, and if the problem shows up, turn it down to -O0 on one file at a time until it goes away.. then you know which file to narrow in on, and go back to (1)

    //etc

    In my case, it always came down to tight rendering loops, so futzing with them, or breakign up rendering into additional passes, or refactoring etc, would solve the problem...

    jeff
     
  7. Reesy

    Reesy Guest

    I had really crackly sound on DrMD. I found it was caused by my screen rendering code writing outside of the frame buffer :| ( Sloppy, Sloppy I know :) )
     
  8. Lina_Inverse

    Lina_Inverse Still Fresh

    Joined:
    Nov 9, 2004
    Messages:
    76
    Location:
    Toronto
    Thanks for telling us about the GP32 sound bug :)
     
  9. M-.-n

    M-.-n Member

    Joined:
    May 28, 2005
    Messages:
    160
    Location:
    Brussels, Belgium
    Hi there,

    In my app, I was suffering of the infamous sound bug where if I started playing with the app's UI while it played sound, mini clicks would pop in. After tracing the code a little, I discovered the main problem came when clearing the framebuffer to display the UI. To clear my 8-bit framebuffer, I would simply do

    Code:
      memset(framebuffer_[currentBuffer_],currentColor_,320*240);
    
    After reading the thread on the sound bug, I ended up trying to 'relax' the bus by sending a few bytes, waiting, then going on.. and finished with a code like this:

    Code:
            // We're going to fill memory with ints
    
            unsigned int intColor=0;
            for (int i=0;i<4;i++) {
                 intColor=(intColor<<8)+currentColor_;  
            }
            unsigned int *dst=(unsigned int *)framebuffer_[currentBuffer_];
    
            for (int i=0;i<480;i++) {
                for (int j=0;j<40;j++) {
                 *dst++=intColor;
                }
                int k=0;
                for (int j=0;j<2000;j++) {
                    k++;
                } 
            } 
    
    Now, I don't mind a little hack but it seems strange to me that I'm not able to play 44.1Khz stereo sound and can't clear the screen at the same time without noticing crackz & clickz. Plus this is possibly slowing down the interactivity level of my UI which is a bit of a bugger.

    So is there any authority over here to tell me if this is my only option or is there anything else I could do ?

    On another -but related- note, does anyone knows if, using GCC, I call memset & memcpy using the normal system calls I'll get performance optimization if my buffers position & size are 4_bytes aligned or do I have to code it myself ?

    Huge thanks guys !
     
  10. pea

    pea developer

    Joined:
    Oct 3, 2004
    Messages:
    1,086
    Location:
    New Zealand
    Hi,

    Don't know about the sound bug, but there is an ASM version of memcpy on my site (snippet: unknown author - Fast assembler memcpy routine) which much MUCH faster than the standard one.

    Yes, memcpy definately suffers from copying when not on a 4-byte boundary. To give you an idea, I implemented my own blitting routine that was up to 40 times faster than the standard Mr.Mirko one in certain conditions. About half of this was due to the memcpy.

    EDIT:
    Old thread here:
    http://www.gp32x.de/board/index.php?showtopic=15954&st=0
    Sorry, I made a mistake - it was up to 75 times faster than Mr.Mirkos original (running on geepee32 though).
     
    Last edited by a moderator: Dec 19, 2015
  11. M-.-n

    M-.-n Member

    Joined:
    May 28, 2005
    Messages:
    160
    Location:
    Brussels, Belgium
    Thanks pea,

    I had the routine ready to use on my desktop already and my question was directly related towards wheter or not I should include it. I don't do much copy/fill (after all, music apps are more about calculations) but already filling memory by ints rather than chars made me gain a few % of cpu usage so I'm going to add that one too. Maybe I'll use it too to display caracters.

    Ceerio,
    Marc.
     
  12. pea

    pea developer

    Joined:
    Oct 3, 2004
    Messages:
    1,086
    Location:
    New Zealand
    Trust me, it's worth it :)
     
  13. Optimus

    Optimus Member

    Joined:
    May 8, 2005
    Messages:
    339
    Location:
    Greece
    I've just encountered the sound bug too and it would be interesting to say that I solved the problem with something I did randomly and I am still not sure why it works. And it's nothing like those solutions here. Perhaps my solution would give more explanations about the sound bug?

    I have been coding a 3d engine on GP32 and now I had some 3d object wtih gouraud shading and z-buffering. For the z-buffering I had a big array and there was the problem. While I thought that the most overhead is happening on the polygon rendering routines (comparing the z of the current pixel with the z-buffer, if closer then write both to the screen and z-buffer ram, too much writting in two big arrays),it wasn't. There were a lot of calculations between the writtings in the polygon rendering that served as a good delay between memory writtings and so the problem didn't really appeared there!

    The problem was on the much more simpler code which cleans the big z-buffer array.

    What I had was:
    int i;
    for (i=0; i<GP32_Width*GP32_Height; i++)
    zbuffer = 2147483647;

    At the beginning I did a test:
    int i;
    for (i=0; i<GP32_Width*GP32_Height; i+=2)
    zbuffer = 2147483647;

    And that was just to test if writting less data would cure the problem. And it worked well without sound bug! But I wasn't filling my whole table as I wanted.

    This one didn't worked even if it copies the same ammount of data:
    int i;
    for (i=0; i<GP32_Width*GP32_Height/2; i++)
    zbuffer = 2147483647;

    So I said. Wtf? It's not about data ammount!

    And it was about jumping one int per write, the sound bug dissapeared because I wasn't filling the big table serially?

    So, I made this one which does the same job with not less speed than the very first code. My z-buffer table is filled by not writting each next int but jumping one int and writting one int and again from the beginning to fill the other half! And absolutelly no sound bug with every complex or simple 3d object I have here in my code!

    int i;
    for (i=0; i<GP32_Width*GP32_Height; i+=2)
    zbuffer = 2147483647;
    for (i=1; i<GP32_Width*GP32_Height; i+=2)
    zbuffer = 2147483647;

    So. I avoided putting a useless code to delay my inner loop. I didn't slowed down the cache or underclocked the GP32. I did nothing of what written here (except from the suggestion to // pieces of code till I found the main core that cause the problem ;). I just filled my big array not as serially as I should, jumping int, writting int, jumping int, writting int. I was amazed that it worked..

    WHY DID THIS WORKED?

    I am just curious to learn but other than that I am happy because now everything works perfectly without having to slow down my 3d engine! =)))

    Just so you know.
     
  14. Optimus

    Optimus Member

    Joined:
    May 8, 2005
    Messages:
    339
    Location:
    Greece
    Why would that work, my thoughts?

    1) And it was 32bit copy. Do the compilers automatically allign your arrays? I don't think that was the problem because in both cases the writtings would be the same..
    2) I really don't know what compilers generate. What if the second code generated quite diferrent machine code which prevented the bug to occure?
    3) Cache? Is it that when you are not writting exactly the next int serially but do it in the second way, suddenly the cache works in another way?
    4) Slightly more delay between the writtings, because i++ could be a bit faster than i+=2? But I think the speed diferrence between the two would be almost inexistant..
    5) Maybe I should see the produced code. How can I see the produced assembly code from the compiler? Maybe a dissassembler or another tool? Gotta check it..
     

Share This Page

Loading...