vmix and oss_sblive

OSS specific Linux discussion (x86/amd64)

Moderators: hannu, dev, cesium, kodachi

vmix and oss_sblive

Postby adamk » Mon Aug 16, 2010 10:15 pm

Any chance of seeing vmix and oss_sblive working well together? :-) In addition to the vmware problem (viewtopic.php?f=3&t=3405&p=13622) I'm also getting the same kind of distortion with old game called MarbleBlast:

http://thorn.visualtech.com/marbleblast-with-vmix.ogg

Adam
adamk
 
Posts: 78
Joined: Fri Jun 11, 2004 1:50 pm

Re: vmix and oss_sblive

Postby cesium » Tue Aug 17, 2010 7:01 pm

Discussed on IRC. Game uses a very low fragment value... We found some ways around that.
cesium
 
Posts: 903
Joined: Sun Aug 12, 2007 12:51 am

Re: vmix and oss_sblive

Postby adamk » Wed Aug 18, 2010 11:16 am

For anyone interested, you want to compile this code (courtesy of cesium) and then LD_PRELOAD the resulting library:

Code: Select all
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include "/usr/lib/oss/include/sys/soundcard.h"

static int (*next_ioctl)(int fd, int request, void *data) = NULL;

static char buf[PATH_MAX], x[65535] = { 0 }, s[255];
static pid_t pid;

#define IOCTL(x) case x: fprintf(stderr, #x " ioctl")

#define PRINTINT() \
  do { \
    if (data != NULL) fprintf(stderr, " with %d arg.", *(int *)data); \
    else fprintf(stderr, " with arg == NULL.\n"); \
    fflush(stderr); \
    ret = next_ioctl(fd, request, data); \
    if (data != NULL) fprintf(stderr, " Returned with %d arg\n", *(int *)data); \
    fflush(stderr); \
  } while(0); \
  break

#define PRINTFRAG() \
  do { \
    if (data == NULL) goto cont; \
    fprintf(stderr, "maxfrags: %d, fragsize : %d. Overriden to inf/16384.", *(int *)data & 0xFFFF0000, 1 << (*(int *)data & 0xFFFF)); \
    fflush(stderr); \
    *(int *)data = (0x7fff << 16) | 14; \
    ret = next_ioctl(fd, request, data); \
    fprintf(stderr, " Returned: maxfrags: %d, fragsize : %d.\n", *(int *)data & 0xFFFF0000, 1 << (*(int *)data & 0xFFFF)); \
    fflush(stderr); \
  } while(0); \
  break

#define FORMAT(f) case f: fprintf(stderr, " with " #f " format\n"); break

#define PRINTFORMAT() \
  do { \
    if (data != NULL) \
      switch (*(int *)data) { \
      FORMAT(AFMT_QUERY); \
      FORMAT(AFMT_MU_LAW); \
      FORMAT(AFMT_A_LAW); \
      FORMAT(AFMT_IMA_ADPCM); \
      FORMAT(AFMT_U8); \
      FORMAT(AFMT_S16_LE); \
      FORMAT(AFMT_S16_BE); \
      FORMAT(AFMT_S8); \
      FORMAT(AFMT_U16_LE); \
      FORMAT(AFMT_U16_BE); \
      FORMAT(AFMT_MPEG); \
      FORMAT(AFMT_AC3); \
      FORMAT(AFMT_VORBIS); \
      FORMAT(AFMT_S32_LE); \
      FORMAT(AFMT_S32_BE); \
      FORMAT(AFMT_FLOAT); \
      FORMAT(AFMT_S24_LE); \
      FORMAT(AFMT_S24_BE); \
      FORMAT(AFMT_SPDIF_RAW); \
      FORMAT(AFMT_S24_PACKED); \
      default: fprintf(stderr, "with format == %d\n", *(int *)data); \
    } \
    else fprintf(stderr, "with format == NULL??\n"); \
    fflush(stderr); \
  } while(0); \
  break

int ioctl(int fd, int request, void *data) {
  int ret;

  if (next_ioctl == NULL) {
    char *msg;

    next_ioctl = dlsym(RTLD_NEXT, "ioctl");
    if ((msg = dlerror()) != NULL) {
      fprintf(stderr, "ioctl: dlopen failed : %s\n", msg);
      fflush(stderr);
      exit(1);
    } else {
      fprintf(stderr, "ioctl: wrapping done\n");
      fflush(stderr);
    }
    pid = getpid();
  }
  if (x[fd % 65535] == 2) goto cont;
  else if (x[fd % 65535] == 1) goto found;
  snprintf(s, sizeof(s), "/proc/%d/fd/%d", pid, fd);
  readlink(s, buf, sizeof(buf)-1);
  if (strstr(buf, "/dev/oss/") != NULL) x[fd % 65535] = 1;
  else if (strstr(buf, "/dev/dsp") != NULL) x[fd % 65535] = 1;
  else {
    x[fd % 65535] = 2;
    goto cont;
  }
found:
  switch (request) {
    IOCTL(SNDCTL_DSP_BIND_CHANNEL); PRINTINT();
    IOCTL(SNDCTL_DSP_CHANNELS); PRINTINT();
    IOCTL(SNDCTL_DSP_COOKEDMODE); PRINTINT();
    IOCTL(SNDCTL_DSP_CURRENT_IPTR); PRINTINT();
    IOCTL(SNDCTL_DSP_CURRENT_OPTR); PRINTINT();
    IOCTL(SNDCTL_DSP_GETBLKSIZE); PRINTINT();
    IOCTL(SNDCTL_DSP_GETCAPS); PRINTINT();
    IOCTL(SNDCTL_DSP_GETCHANNELMASK); PRINTINT();
    IOCTL(SNDCTL_DSP_GET_CHNORDER); PRINTINT();
    IOCTL(SNDCTL_DSP_GETERROR); PRINTINT();
    IOCTL(SNDCTL_DSP_GETFMTS); PRINTINT();
    IOCTL(SNDCTL_DSP_GETIPEAKS); PRINTINT();
    IOCTL(SNDCTL_DSP_GETIPTR); PRINTINT();
    IOCTL(SNDCTL_DSP_GETISPACE); PRINTINT();
    IOCTL(SNDCTL_DSP_GETODELAY); PRINTINT();
    IOCTL(SNDCTL_DSP_GETOPEAKS); PRINTINT();
    IOCTL(SNDCTL_DSP_GETOPTR); PRINTINT();
    IOCTL(SNDCTL_DSP_GETOSPACE); PRINTINT();
    IOCTL(SNDCTL_DSP_GET_PLAYTGT_NAMES); PRINTINT();
    IOCTL(SNDCTL_DSP_GET_PLAYTGT); PRINTINT();
    IOCTL(SNDCTL_DSP_GETPLAYVOL); PRINTINT();
    IOCTL(SNDCTL_DSP_GET_RECSRC_NAMES); PRINTINT();
    IOCTL(SNDCTL_DSP_GET_RECSRC); PRINTINT();
    IOCTL(SNDCTL_DSP_GETRECVOL); PRINTINT();
    IOCTL(SNDCTL_DSP_GETTRIGGER); PRINTINT();
    IOCTL(SNDCTL_DSP_LOW_WATER); PRINTINT();
    IOCTL(SNDCTL_DSP_NONBLOCK); PRINTINT();
    IOCTL(SNDCTL_DSP_POLICY); PRINTINT();
    IOCTL(SNDCTL_DSP_POST); PRINTINT();
    IOCTL(SNDCTL_DSP_PROFILE); PRINTINT();
    IOCTL(SNDCTL_DSP_READCTL); PRINTINT();
    IOCTL(SNDCTL_DSP_RESET_INPUT); PRINTINT();
    IOCTL(SNDCTL_DSP_RESET_OUTPUT); PRINTINT();
    IOCTL(SNDCTL_DSP_RESET); PRINTINT();
    IOCTL(SNDCTL_DSP_SET_CHNORDER); PRINTINT();
    IOCTL(SNDCTL_DSP_SETDUPLEX); PRINTINT();
    IOCTL(SNDCTL_DSP_SETFMT); PRINTFORMAT();
    IOCTL(SNDCTL_DSP_SETFRAGMENT); PRINTFRAG();
    IOCTL(SNDCTL_DSP_SET_PLAYTGT); PRINTINT();
    IOCTL(SNDCTL_DSP_SETPLAYVOL); PRINTINT();
    IOCTL(SNDCTL_DSP_SET_RECSRC); PRINTINT();
    IOCTL(SNDCTL_DSP_SETRECVOL); PRINTINT();
    IOCTL(SNDCTL_DSP_SETSYNCRO); PRINTINT();
    IOCTL(SNDCTL_DSP_SILENCE); PRINTINT();
    IOCTL(SNDCTL_DSP_SKIP); PRINTINT();
    IOCTL(SNDCTL_DSP_SPEED); PRINTINT();
    IOCTL(SNDCTL_DSP_STEREO); PRINTINT();
    IOCTL(SNDCTL_DSP_SUBDIVIDE); PRINTINT();
    IOCTL(SNDCTL_DSP_SYNCGROUP); PRINTINT();
    IOCTL(SNDCTL_DSP_SYNC); PRINTINT();
    IOCTL(SNDCTL_DSP_SYNCSTART); PRINTINT();
    IOCTL(SNDCTL_DSP_WRITECTL); PRINTINT();
    default:
      if (data != NULL)
       fprintf(stderr, "unknown ioctl with arg == %d\n", *(int *)data);
      else fprintf(stderr, "unknown ioctl with arg == NULL\n");
      fflush(stderr);
      goto cont;
  }
cont:
  return next_ioctl(fd, request, data);
}


Marbleblast works great, though vmware still experiences problems, so I assume that's a different issue.

Adam
adamk
 
Posts: 78
Joined: Fri Jun 11, 2004 1:50 pm


Return to Linux

Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 3 guests