Csound Csound-dev Csound-tekno Search About

Re: new entry

Date1999-05-19 08:47
FromThomas Huber
SubjectRe: new entry
> With my pentium II 400 I can reach a polyphony of 200 oscilis with
> envelopes in realtime using DirectCsound at sr=44100 (more than 300 when
> using oscil opcode). Maybe Linux version is slower in realtime tasks? (I
> never tested it).

Were you using just an enveloped oscili (no filters etc) ? Because my
polyphony of 1-3 referred to a full instrument using 'moogvcf', an
envelope, lfo's and a global reverb. I havn't tested simple oscili's with
envelope yet.


Date1999-05-19 15:06
FromPaul Barton-Davis
SubjectRe: realtime polyphony
In message <199905190747.JAA18558@klee.iamexwi.unibe.ch>you write:
>> With my pentium II 400 I can reach a polyphony of 200 oscilis with
>> envelopes in realtime using DirectCsound at sr=44100 (more than 300 when
>> using oscil opcode). Maybe Linux version is slower in realtime tasks? (I
>> never tested it).

the linux version is a little slower: see the benchmark page hanging
off the Csound Front Page. it has to be slower: there is preemptive
scheduling going on while Csound is running, which isn't true for the
Windows or the Mac versions.

even so, there is a nice (simple) benchmark program that I got from the net
called "oscillates" (below) that i've used to check speed before, and
it has a hard time getting above 70 oscillators without dropouts on my
PII-450 (well, 1 processor thereof). So either Csound is way smarter
than this program (quite likely), or Linux really does take a big hit
in this area (not so likely, but by no means impossible).

I'll do some more experiments.

--p

#include 
#include 
#include 
#include 
#include 

#define BUFSIZE 8192
#define SR_RATE 44100
#define NBUFS 4
#define WTABLESIZE 1000
#define FREQ 278.0
#define NOSCILS 1000
#define PI 3.1415926

void makewave(short wtable[])
{
  int i;

  for(i = 0; i < WTABLESIZE; i++) {
    wtable[i] = sin((double) (2*PI * (float)i/WTABLESIZE)) * 32767.0;
  }
  return;
}

short oscil(float si, short wave[], float *phs)
{
  int i;

  i = *phs;
  *phs += si;
  if(*phs >= WTABLESIZE) *phs -= WTABLESIZE;
  return(wave[i]);
}

main ()
{
  int len,format,stereo,speed,cycle,frag_size;
  int audio_fd;
  int arg;
  short waveform[WTABLESIZE];
  short sampbuff[NBUFS][BUFSIZE];
  int i,j,k,bufno;
  int active;
  float si[NOSCILS],phase[NOSCILS];

  /* Open the audio port */
  if ((audio_fd = open("/dev/dsp", O_WRONLY, 0)) == -1) {
    perror("/dev/dsp");
    exit(1);
  }

  /* Set the fragment size */
  arg = 0x777f000d;
  if (ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &arg)==-1) {
    perror("incorrect fragment size");
    exit(1);
  }

  /* Put the audio port in "sync" mode */
  ioctl(audio_fd, SNDCTL_DSP_SYNC, 0);

  /* Set the format for output samples */
  format = AFMT_S16_LE;
  if (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format)==-1) {
    perror("SNDCTL_DSP_SETFMT");
    exit(1);
  }

  /* Set stereo / mono (1/0) */
  stereo = 0;
  if (ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo)==-1) {
    perror("SNDCTL_DSP_STEREO");
    exit(1);
  }

  /* Set sample rate */
  speed = SR_RATE;
  if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &speed)==-1)
    { /* Fatal error */
      perror("SNDCTL_DSP_SPEED");
      exit(1);
    }

  /* Get the size of the audio buffer */
  /* Note that the driver computes this optimally */
  if (ioctl(audio_fd, SNDCTL_DSP_GETBLKSIZE, &frag_size) == -1) {
    exit(1);
  }
  printf("Audio buffer:  %d\n",frag_size);

  /* make a wavetable for the oscillator */
  makewave(waveform);

  /* load buffers and write them to the audio port */

  for (i = 0; i < NOSCILS; i++) {
    si[i] = (FREQ + (i*5)) * WTABLESIZE/SR_RATE;
    phase[i] = 0.0;
  }

  bufno = 0;
  active = 1;
  for (i = 0; i < 99999; i++) {

    /* fill a buffer with sound */
    for (k = 0; k < active; k++) {

      if (k == 0) {
        for (j = 0; j < BUFSIZE; j++) {
          sampbuff[bufno][j] = oscil(si[k],waveform,&phase[k]) * 1.0/active;
        }
      }
      else {
        for (j = 0; j < BUFSIZE; j++) {
          sampbuff[bufno][j] += oscil(si[k],waveform,&phase[k]) * 1.0/active;
        }
      }

    }

    if ((len = write(audio_fd, sampbuff[bufno], 2*BUFSIZE)) == -1) {
      perror("audio write");
      exit(1);
    }

    /* shift to the next buffer */
    if (++bufno > 3) {
      if (++active > NOSCILS)
        active -= 1;
      printf("%d oscillators, daddy-oh!\n",active);
      bufno = 0;
    }
  }

  /* Close the audio port */
  close(audio_fd);
}




Date1999-05-19 20:15
FromLarry Troxler
SubjectRe: realtime polyphony
On Wed, 19 May 1999, Paul Barton-Davis wrote:

> In message <199905190747.JAA18558@klee.iamexwi.unibe.ch>you write:
> >> With my pentium II 400 I can reach a polyphony of 200 oscilis with
> >> envelopes in realtime using DirectCsound at sr=44100 (more than 300 when
> >> using oscil opcode). Maybe Linux version is slower in realtime tasks? (I
> >> never tested it).
> 
> the linux version is a little slower: see the benchmark page hanging
> off the Csound Front Page. it has to be slower: there is preemptive
> scheduling going on while Csound is running, which isn't true for the
> Windows or the Mac versions.
> 

Are you running as root with Posix real-time priority? If so, then any
speed
differences would have to be do the sound card driver, I would think, no?

I don't see how there could be this much of a difference, if the SCHED_RT
is working.

Ah, I see that the program below doesn't take SCHED_RT priority - that is
probably why it is so slow. 

Larry


> even so, there is a nice (simple) benchmark program that I got from the net
> called "oscillates" (below) that i've used to check speed before, and
> it has a hard time getting above 70 oscillators without dropouts on my
> PII-450 (well, 1 processor thereof). So either Csound is way smarter
> than this program (quite likely), or Linux really does take a big hit
> in this area (not so likely, but by no means impossible).
> 
> I'll do some more experiments.
> 
> --p
> 
> #include 
> #include 
> #include 
> #include 
> #include 
> 
> #define BUFSIZE 8192
> #define SR_RATE 44100
> #define NBUFS 4
> #define WTABLESIZE 1000
> #define FREQ 278.0
> #define NOSCILS 1000
> #define PI 3.1415926
> 
> void makewave(short wtable[])
> {
>   int i;
> 
>   for(i = 0; i < WTABLESIZE; i++) {
>     wtable[i] = sin((double) (2*PI * (float)i/WTABLESIZE)) * 32767.0;
>   }
>   return;
> }
> 
> short oscil(float si, short wave[], float *phs)
> {
>   int i;
> 
>   i = *phs;
>   *phs += si;
>   if(*phs >= WTABLESIZE) *phs -= WTABLESIZE;
>   return(wave[i]);
> }
> 
> main ()
> {
>   int len,format,stereo,speed,cycle,frag_size;
>   int audio_fd;
>   int arg;
>   short waveform[WTABLESIZE];
>   short sampbuff[NBUFS][BUFSIZE];
>   int i,j,k,bufno;
>   int active;
>   float si[NOSCILS],phase[NOSCILS];
> 
>   /* Open the audio port */
>   if ((audio_fd = open("/dev/dsp", O_WRONLY, 0)) == -1) {
>     perror("/dev/dsp");
>     exit(1);
>   }
> 
>   /* Set the fragment size */
>   arg = 0x777f000d;
>   if (ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &arg)==-1) {
>     perror("incorrect fragment size");
>     exit(1);
>   }
> 
>   /* Put the audio port in "sync" mode */
>   ioctl(audio_fd, SNDCTL_DSP_SYNC, 0);
> 
>   /* Set the format for output samples */
>   format = AFMT_S16_LE;
>   if (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format)==-1) {
>     perror("SNDCTL_DSP_SETFMT");
>     exit(1);
>   }
> 
>   /* Set stereo / mono (1/0) */
>   stereo = 0;
>   if (ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo)==-1) {
>     perror("SNDCTL_DSP_STEREO");
>     exit(1);
>   }
> 
>   /* Set sample rate */
>   speed = SR_RATE;
>   if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &speed)==-1)
>     { /* Fatal error */
>       perror("SNDCTL_DSP_SPEED");
>       exit(1);
>     }
> 
>   /* Get the size of the audio buffer */
>   /* Note that the driver computes this optimally */
>   if (ioctl(audio_fd, SNDCTL_DSP_GETBLKSIZE, &frag_size) == -1) {
>     exit(1);
>   }
>   printf("Audio buffer:  %d\n",frag_size);
> 
>   /* make a wavetable for the oscillator */
>   makewave(waveform);
> 
>   /* load buffers and write them to the audio port */
> 
>   for (i = 0; i < NOSCILS; i++) {
>     si[i] = (FREQ + (i*5)) * WTABLESIZE/SR_RATE;
>     phase[i] = 0.0;
>   }
> 
>   bufno = 0;
>   active = 1;
>   for (i = 0; i < 99999; i++) {
> 
>     /* fill a buffer with sound */
>     for (k = 0; k < active; k++) {
> 
>       if (k == 0) {
>         for (j = 0; j < BUFSIZE; j++) {
>           sampbuff[bufno][j] = oscil(si[k],waveform,&phase[k]) * 1.0/active;
>         }
>       }
>       else {
>         for (j = 0; j < BUFSIZE; j++) {
>           sampbuff[bufno][j] += oscil(si[k],waveform,&phase[k]) * 1.0/active;
>         }
>       }
> 
>     }
> 
>     if ((len = write(audio_fd, sampbuff[bufno], 2*BUFSIZE)) == -1) {
>       perror("audio write");
>       exit(1);
>     }
> 
>     /* shift to the next buffer */
>     if (++bufno > 3) {
>       if (++active > NOSCILS)
>         active -= 1;
>       printf("%d oscillators, daddy-oh!\n",active);
>       bufno = 0;
>     }
>   }
> 
>   /* Close the audio port */
>   close(audio_fd);
> }
> 
> 
> 
> 
> 

Date1999-05-19 21:39
FromPaul Barton-Davis
SubjectRe: realtime polyphony
>Are you running as root with Posix real-time priority? If so, then any
>speed
>differences would have to be do the sound card driver, I would think, no?
>
>I don't see how there could be this much of a difference, if the SCHED_RT
>is working.
>
>Ah, I see that the program below doesn't take SCHED_RT priority - that is
>probably why it is so slow. 

Adding SCHED_FIFO priority and MLOCKALL to lock all current and future
pages in physical memory makes no visible difference to the program,
except that it locks the machine more solidly when we get up close to
breaking point (65-70 oscillators).

I'll have to try the ALSA driver and see if it can do better.