Template to develop audio DSP using the (OSS) API + GNU/Linux
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;
}