Template to develop audio DSP using the (OSS) API + GNU/Linux

Gabriel Rivas February 6, 2011 Coded in C

This is a template to develop audio DSP applications in GNU/Linux using the OSS (Open Sound System) driver, this can allow us to use any regular PC as DSP processors, I hav tested it on pentium 3 and 4 PC's, and it works fine, theres even not noticeable audio latencies if you want  to use it for real time processing. I will explain a little more in my blog.

#include <stdio.h>
#include <fcntl.h>
#include <sys/soundcard.h>

#define BUF_SIZE 2

/*buffers for sound device*/
unsigned char devbuf[BUF_SIZE];

/*File descriptor for device*/
int audio_fd;

/*The sound card is known as the DSP*/
char DEVICE_NAME[]="/dev/dsp";

/*Device Settings*/
int format;
int channels;
int fs;
int len;
int frag;
int devcaps;

int main()
{
    unsigned int temp;
    unsigned int yout;

    /*Samples format is 16 bit unsigned*/
    format = AFMT_U16_LE;
    /*1 Channel, MONO*/
    channels = 1;
    /*Sampling Rate is 16 KHz*/
    fs = 16000;
    /*This is a parameter used to set the DSP for low latencies*/
    frag = 0x00020004;

	/******************************************************
          Set parameters in sound card device
    *****************************************************/

	/*Open sound card device*/
	if ((audio_fd = open(DEVICE_NAME,O_RDWR, 0)) == -1) {
		/* Open of device failed */
		perror(DEVICE_NAME);
		exit(1);
	}	

	if (ioctl (audio_fd, SNDCTL_DSP_SETFRAGMENT, &frag) == -1)
	{
	    perror ("SNDCTL_DSP_SETFRAGMENT");
	    exit (-1);
	}

	/*Set audio format*/
	if (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format) == -1) {
		/* fatal error */
		perror("SNDCTL_DSP_SETFMT");
		exit(1);
	}
	/*Set number of channels*/
	if (ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &channels) == -1) {
		/* Fatal error */
		perror("SNDCTL_DSP_CHANNELS");
		exit(1);
	}
	
	/*Set sampling rate*/
	if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &fs)==-1) {
		/* Fatal error */
		perror("SNDCTL_DSP_SPEED");
		exit(1);
	}

	if (ioctl(audio_fd, SNDCTL_DSP_SYNC) == -1) {
		/* fatal error */
		perror("SNDCTL_DSP_SYNC");
		exit(1);
	}	

	/******************************************************
          This is the infinite loop to:
          1. Read a sample
          2. Process the sample
          3. Write the sample to soundcard output
    *****************************************************/
    while(1) {
        /* This is a blocking read function, the application will wait
           until the sound card captures a sample
        */
        if ((len = read(audio_fd,devbuf, sizeof(devbuf))) == -1) {
	        perror("audio read");
	        exit(1);
	    }

        /* We can pass this variable to a temporary value, 
           in this case as unsigned 16 value, and then use this value 
           for processing
        */  
	    temp = (devbuf[0])|(devbuf[1]<<8);

        /* In this case no processing is done so the value is passed to the output. You can also use this sample to build an audio file, or send it trought a communications interface, etc.
        */
	    yout = temp;

	    devbuf[0] = yout&0xFF;
	    devbuf[1] = (yout>>8)&0xFF;
		
        /* This is the way the output samples are sent to the soundcard            
        */
        if ((len = write(audio_fd,devbuf,sizeof(devbuf)) == -1)) {
	        perror("audio write");
	        exit(1);
        }
    }	
    return 0;
}

Comments:

There are no comments yet!


Sorry, you need javascript enabled to post any comments.