Re: [LAD] starting out with tux audio

From: Jens M Andreasen <jens.andreasen@email-addr-hidden>
Date: Sun Jun 15 2008 - 19:10:01 EEST

On Sun, 2008-06-15 at 09:38 +0530, AlgoMantra wrote:
> Whoo, that text is from 2000, when Bill Clinton was president.
> A lot
> has changed since then.
>
>
> ....but we still play musical instruments that are 5000 years old.
> Some things
> don't have to change much to survive. Lets just say I have a
> retro-fetish...
>

Uhmm ... But if you want to do raw sinewaves big time, you'll really
need another approach if you are not to run out of CPU. That piece of
code you linked to is in desperate need of an update, so that it will
auto-vectorize and so that we can get rid of the expensive call to
sin(). The following should do just about the same but without mathlib
and generally accellerated by some insane percentage:

-8<-- sound.c
-----------------------------------------------------------

// Compile with for example
// gcc4.3 -O3 -msse -ftree-vectorize -o sound sound.c

#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/soundcard.h>

#define PI 3.14159f

/* Inverse of the odd factorials (n!) 1 - 9
 */
#define IF_1 (1.f)
#define IF_3 (1.f/6.f)
#define IF_5 (1.f/120.f)
#define IF_7 (1.f/5040.f)
#define IF_9 (1.f/362880.f)

/* -------------------------------------
 * 16 bit Taylor approximation of sin()
 * ------------------------------------ */

float tsin(float x)
{
  float x2 = x*x;
  float rt = IF_9;

  rt *= x2;
  rt -= IF_7;
  rt *= x2;
  rt += IF_5;
  rt *= x2;
  rt -= IF_3;
  rt *= x2;
  rt += IF_1;
  rt *= x;

  return rt;
}

int main(void)
{
  unsigned short int wave[44100*5]; /* our wavetable */
  int i,j; /* two counters */
  int out; /* audio out */
  /* open /dev/dsp for write only */
  out = open("/dev/dsp",O_WRONLY);
  /* now we use ioctl to set audio quality */
  i=16; /* 16 bits */
  ioctl(out,SOUND_PCM_WRITE_BITS,&i);
  i=1; /* 1 channel */
  ioctl(out,SOUND_PCM_WRITE_CHANNELS,&i);
  i=44100; /* 44.1KHz */
  ioctl(out,SOUND_PCM_WRITE_RATE,&i);

 

#define OSC 4

  float x[OSC] = {0,0,0,0};
  float y[OSC] = {1,1,1,1};
  float w[OSC] = {220, 277,330,440};
  float a[OSC] = {8000,7000,6000,5000};
  float r[OSC];

  for (i = 0; i < OSC;++i)
    w[i] = tsin(w[i]*2*PI/44100);

  for(i = 0;i < (44100*5); ++i)
    {
      for(j=0;j < OSC; ++j)
        {
          x[j] -= w[j] * y[j];
          y[j] += w[j] * x[j];
          r[j] = x[j] * a[j];
        }
      wave[i] = r[0] + r[1] + r[2] + r[3];
    }

  /* now we write the wavetable to /dev/dsp
   * as though writing to a simple file
   * we'll loop for 5 seconds of sheer joy
   */

  write(out, wave, sizeof(wave));
  close(out); /* close /dev/dsp ! */
  return 0; /* satisfy gcc */
}

_______________________________________________
Linux-audio-dev mailing list
Linux-audio-dev@email-addr-hidden
http://lists.linuxaudio.org/mailman/listinfo/linux-audio-dev
Received on Sun Jun 15 20:15:02 2008

This archive was generated by hypermail 2.1.8 : Sun Jun 15 2008 - 20:15:03 EEST