Ticket #343 (closed defect: worksforme)

Opened 3 years ago

Last modified 3 years ago

bsnes does not play well with pulseaudio

Reported by: belegdol Owned by: lennart
Milestone: Component: daemon
Keywords: Cc:

Description

Hi, this is most probably a bsnes issue, but I'm posting here so that experts in the field could express their opinion on the problem. Anyway, bsnes is a super nintendo emulator which focuses on accuracy. It has a few sound drivers (alsa, openal, oss and libao). Most of these do not work well with pulseaudio, neither through compat layers (alsa plugin, padsp) nor natively (libao pulse driver). I was able to capture the output of pulseaudio -vvv (attached, multiple occurrences of D: memblock.c: Pool full removed). My bet is that bsnes abuses PA in some way, but I have no idea how. Hopefully these issues can be somehow resolved. This is on PA 0.9.10 on Fedora 9, x86_64 using the default configuration.

Attachments

bsnes-pulseaudio.log (14.3 kB) - added by belegdol 3 years ago.

Change History

Changed 3 years ago by belegdol

Changed 3 years ago by belegdol

As on the latest version (0.038), bsnes got itself a native Pulseaudio driver. It works quite well, but it causes the emulation to stop for a moment every few moments. Such behavour is also present in case openal → sdl → pa path is used, but it is a little less visible then. Uptream claims that the PA driver is extremely simple, and should work well:

    device.spec.format   = PA_SAMPLE_S16LE;
    device.spec.channels = 2;
    device.spec.rate     = settings.frequency;
    device.handle = pa_simple_new(
      0,                   //default server
      "ruby::pulseaudio",  //application name
      PA_STREAM_PLAYBACK,  //direction
      0,                   //default device
      "audio",             //stream description
      &device.spec,        //sample format
      0,                   //default channel map
      0,                   //default buffering attributes
      &error               //error code
    );
    //...
    pa_simple_write(device.handle, (const void*)buffer.data, buffer.offset * sizeof(uint32_t), &error);

Any ideas what goes wrong here? This is with PA 0.9.13 on Fedora 10 x86_64.

Changed 3 years ago by belegdol

byuu (the bsnes author) was kind enough to provide a simple test case. It needs some love before it compiles, though.

#include <stdint.h>
#include <pulse/simple.h>
#include <pulse/error.h>

//PulseAudio simple test -- no error handling
int main() {
  pa_simple *handle;
  pa_sample_spec spec;
  uint32_t buffer[64];

  spec.format   = PA_SAMPLE_S16LE;
  spec.channels = 2;
  spec.rate     = 32000;

  int error = 0;
  handle = pa_simple_new(
    0,                   //default server
    "ruby::pulseaudio",  //application name
    PA_STREAM_PLAYBACK,  //direction
    0,                   //default device
    "audio",             //stream description
    &spec,               //sample format
    0,                   //default channel map
    0,                   //default buffering attributes
    &error               //error code
  );

  while(true) {
    for(unsigned i = 0; i < 64; i++) {
      int16_t sample = sin(i * 2 * M_PI / 64) * 0x2000;  //may need tweaking
      buffer[buffer.offset++] = (sample << 16) | sample;  //left and right
    }
    int error = 0;
    pa_simple_write(handle, (const void*)buffer, 64 * sizeof(uint32_t), &error);
  }

  pa_simple_flush(handle, &error);
  pa_simple_free(handle);
  return 0;
}

Changed 3 years ago by belegdol

  • status changed from new to closed
  • resolution set to worksforme

This seems to work with latest bsnes. Closing.

Note: See TracTickets for help on using tickets.