Results 1 to 4 of 4
  1. #1
    Failed Homebrewer
    Join Date
    Feb 2008
    Location
    Minnesota
    Posts
    10

    New audio plugin (libao) ?

    I've b
    een messing with the SDL audio plugin in order to make it less fail. Unfortunately, it's harder than it might seem. Here's why:

    • The Nintendo 64 code builds chunks of audio, then sends the chunk out out to the hardware when finished (which then calls a function in the audio plugin)
    • SDL maintains two buffers of audio (let's call each buffer a chunk). It plays from one chunk at a time. When the chunk empties, it switches to the other chunk and calls a function in the program (plugin) to fill the empty chunk.


    Do you see the problem? The problem is, both the emulator and SDL are calling the plugin when they have or want audio! This doesn't happen at the same time, so we can't just take audio from the emulator and drop it right into SDL.

    The plugin's solution is a big buffer. Each time the Nintendo 64 sends out audio, it appends it to the buffer. Each time SDL wants audio, some audio is pulled out of the buffer.

    The problem with this approach is both SDL and the emulator want fairly large chunks - that means our buffer should be able to hold at least a couple of these to prevent dropouts. Unfortunately, buffer sizes add up fast, and when you are buffering too much audio you have a major problem: lag.

    Take for example the default jttl_audio settings (I think these are default, anyway).

    The main buffer is set to hover between 16384 and 32768 bytes (on my machine, I bump the upper limit to 65536 to avoid problems). Each buffer SDL buffer is 4096 bytes. Let's assume best case scenario of one SDL buffer being empty, and a sample rate of 48khz. Then the lag can be calculated as ((32768+4096)/(bytes per sample: 4))/48000 (sampling frequency) = 0.192 seconds. This might not seem like a whole lot, but it is... 1/5 of a second already will cause lip sync issues. In addition, the N64 itself adds a bit of lag, as well as sound output. In reality, I estimate the situation on my own computer to be much worse, with about 0.5 s lag.

    The obvious solution I see here is to write an audio plugin that uses a blocking-call based output, like libao. Here, when the N64 calls our function with audio, we just pass it right into the audio output function (which hopefully uses the audio driver / sound card's buffer, therefore bypassing both the plugin's buffer and SDL's buffer). In addition, most of these libraries have a blocking call, which should keep our program from spitting out audio too fast. I'm not totally sure if libao's functions are blocking or not.



    Any thoughts? I'm very tempted to write this plugin but I want to make sure my efforts are not a waste of time.


    • Advertising

      advertising
      EmuTalk.net
      has no influence
      on the ads that
      are displayed
        
       

  2. #2
    EmuTalk Member
    Join Date
    Aug 2005
    Posts
    103
    Unless your computer is reaaaaaly slow, you shouldn't really have to worry about blocking issues... I know mine empties the hardware buffer faster than the N64 can fill it.

    Resampling is a better answer, and JttL already does that.

    With writing directly to the hardware buffer you have no control over what happens if an access fails. With blocking mode (to my knowledge) either the sound data would be dumped leaving the user with a skip in the audio, or the whole program would slow until the sound card catches up and allows the data into it's buffer.

    This is why there is also a software buffer.
    This also helps when a hardware buffer is too small for one 'chunk' to be written to it in whole (my onboard sound for example gives me all kinds of hell).

    From what I understand, blocking mode is more to ensure that an audio stream does not overwrite itself in the ring buffer (for example when playing from a file), not to regulate generated audio that comes in on the fly.




    The technique you're referring to there with 'chunks' is double buffering, and is very doubtful the source of your problem.
    Last edited by Pyromanik; February 18th, 2009 at 03:13.

  3. #3
    Superman Azimer's Avatar
    Join Date
    Nov 2001
    Location
    USA
    Posts
    837
    Quote Originally Posted by TD-Linux View Post
    I've b
    The obvious solution I see here is to write an audio plugin that uses a blocking-call based output, like libao. Here, when the N64 calls our function with audio, we just pass it right into the audio output function (which hopefully uses the audio driver / sound card's buffer, therefore bypassing both the plugin's buffer and SDL's buffer). In addition, most of these libraries have a blocking call, which should keep our program from spitting out audio too fast. I'm not totally sure if libao's functions are blocking or not.

    Any thoughts? I'm very tempted to write this plugin but I want to make sure my efforts are not a waste of time.
    You are wasting you time. I know this thread is two months old but I have just come acrossed it.
    -Azimer

    "I am not a teacher: only a fellow traveler of whom you asked the way.
    I pointed ahead -- ahead of myself as well as of you." (George Bernard Shaw)

  4. #4
    C/C++ programmer, emacs user
    Join Date
    Mar 2009
    Posts
    32
    The libao is cross-plataform too and have modules for pulseaudio, oss, alsa, esd and others. I think this can help the plugin use the same code for more time. Another thing: The pandora (openpandora.org) folk plan use the Mupen64plus as base for their N64 emulator, and if this can help the speed, can help the pandora folk. The pandora will be the most powerfull game handheld device console, but yet will be very less powerful than a PC.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •