Re: [linux-audio-dev] Audio-Quality-HOWTO updated

New Message Reply About this list Date view Thread view Subject view Author view Other groups

Subject: Re: [linux-audio-dev] Audio-Quality-HOWTO updated
From: David Olofson (audiality_AT_swipnet.se)
Date: to loka   07 1999 - 19:07:04 EDT


On Thu, 07 Oct 1999, Paul Winkler wrote:
> The Audio-Quality-HOWTO has been updated. The new version is 0.0.8.
>
> There are a few new juicy tidbits of soundcard information, some more
> info on 60-cycle hum, and a notice about kernel patches for improved
> realtime performance.
>
> http://www.ulster.net/~abigoo/pw_linux/Audio-Quality-HOWTO.html

:-)

Just two notes on RTLinux and POSIX:

1) The new API is based on the "Minimal Realtime System Profile",
   which means it has the open/read/write/... calls, but just basic
   device I/O rather than full file system support. That's not
   "completely different from posix", as stated by Eric S. Teidemann.
   (See example below from my DPI package. Note that the kernel
   module specific stuff could be replaced with some nice stdio style
   wrapper if desired.)

2) The Driver Programming Interface I'm working on (not very much
   time for that lately...) is using the same API as the standard
   RTLinux distro. It affects only drivers - not applications. The
   POSIX I/O layer is already there. (BTW, I was too slow to hack one
   before the NMT guys did... ;-)

Some RTLinux "application" code:
(Beta, of course, and not very well tested... It runs rock solid with
'buffer=32 prewrite=4 fragshift=5' here. :-)

---8<------------------------------------------------------------
#include <linux/module.h>
#include <linux/kernel.h>
#include <rtl_fifo.h>
#include <rtl_time.h>
#include <rtl_sched.h>
#include <asm/io.h>
#include <linux/cons.h>
#include "dpi_posixio.h"

#include <linux/soundcard.h>

#define MAX_BUFFER 16384

int buffer = 1024;
int prewrite = 0;
int fragshift = 8;
int test = 0;
MODULE_PARM(buffer,"i");
MODULE_PARM(prewrite,"i");
MODULE_PARM(fragshift,"i");
MODULE_PARM(test,"i");

char *buf;

pthread_t thread;

int fd;

int monitor(void)
{
        while(1)
        {
                if(read(fd, buf, buffer)<=0)
                        return -1;
                if(prewrite)
                {
                        /* Note: This will drop the first input buffer */
                        memset(buf, 0, prewrite);
                        write(fd, buf, prewrite);
                        prewrite = 0;
                }
                if(write(fd, buf, buffer)<=0)
                        return -1;
        }
}

int siren(void)
{
        static int a = 0;
        static int f_lo = 300<<8;
        static int f;
        static int f_hi = 500<<8;
        static int d = 1;
        int j;
        int samples;
        short *dest = (short *)buf;

        samples = buffer * sizeof(char) / sizeof(dest[0]);
        f = (f_lo + f_hi) / 2;

        while(1)
        {
                for(j = 0; j<samples; j+=2)
                {
                        dest[j] = a&0x7fff;
                        dest[j+1] = -a&0x7fff;
                        a+=f>>8;
                        f+=d;
                        if(f>f_hi || f<f_lo)
                                d=-d;
                }
                if(write(fd, buf, buffer)<=0)
                        return -1;
        }
}

void *thread_code(void *t)
{
        int val,r;

        /*
         * This is very dangerous with the es1370 driver.
         * Wrong settings and you get a kernel panic...
         * (Can this really happen if done from user space?)
         */
        val = 0x7fff000 | (fragshift & 0xffff);
        r = ioctl(fd,SNDCTL_DSP_SETFRAGMENT,&val);
        if(r<0) goto fail;

        r = ioctl(fd,SNDCTL_DSP_RESET,NULL);
        if(r<0) goto fail;
        val = 16;
        r = ioctl(fd,SNDCTL_DSP_SAMPLESIZE,&val);
        if(r<0) goto fail;
        val = AFMT_S16_LE;
        r = ioctl(fd,SNDCTL_DSP_SETFMT,&val);
        if(r<0) goto fail;
        val = 1;
        r = ioctl(fd,SNDCTL_DSP_STEREO,&val);
        if(r<0) goto fail;
        val = 44100;
        r = ioctl(fd,SNDCTL_DSP_SPEED,&val);
        if(r<0) goto fail;
        r = ioctl(fd,SNDCTL_DSP_SETDUPLEX,NULL);
        if(r<0)
        {
        fail: rtl_printf("Failed to initialize sound device!\n");
                return (void *)-1;
        }

        switch(test)
        {
        case 0: return (void *)monitor();
        default: return (void *)siren();
        }
}

int init_module(void)
{
        buffer &= 0xfffffffc;
        if(buffer>MAX_BUFFER)
        {
                buffer=MAX_BUFFER;
                printk("Buffer can't be bigger than %d bytes.\n", MAX_BUFFER);
                return -1;
        }

        prewrite &= 0xfffffffc;
        if(prewrite>MAX_BUFFER)
        {
                prewrite=MAX_BUFFER;
                printk("Can't prewrite more than %d bytes.\n", MAX_BUFFER);
                return -1;
        }

        if( !(buf = kmalloc(buffer,GFP_KERNEL)) )
        {
                printk("Couldn't allocate buffer!\n");
                return -1;
        }

        if((fd = open("/dev/dsp0", O_RDWR)) < 0 )
        {
                printk("Couldn't open device! (%d)\n",fd);
                kfree(buf);
                return -1;
        }

        if( pthread_create(&thread, NULL, thread_code, (void *)1) )
        {
                printk("Failed to create RT thread!\n");
                close(fd);
                kfree(buf);
                return -1;
        }

        return 0;
}

void cleanup_module(void)
{
        pthread_delete_np (thread);
        close(fd);
        kfree(buf);
}
---8<------------------------------------------------------------

 ·A·U·D·I·A·L·I·T·Y· P r o f e s s i o n a l L i n u x A u d i o
- - ------------------------------------------------------------- - -
    ·Rock Solid David Olofson:
    ·Low Latency www.angelfire.com/or/audiality ·Audio Hacker
    ·Plug-Ins audiality_AT_swipnet.se ·Linux Advocate
    ·Open Source ·Singer/Composer


New Message Reply About this list Date view Thread view Subject view Author view Other groups

This archive was generated by hypermail 2b28 : pe maalis 10 2000 - 07:27:13 EST