OK, here's the deal. I wrote this a while back, compiled it, and was satisfied that it worked effectively. Now I want to get back to it add features, and incorporate it into the larger program of which it is a part, but now when I compile it, I get nothing but seg faults again and again. I have since installed a different version of RedHat, and it is likely I am using a different version of GCC.
My question: am I doing anything wrong or non-standard here that would not be supported from one compiler to another, or is the new version (or maybe old version) of my compiler just a little wacky?
Thanks a bunch.
starX
www.axisoftime.com
Code:
/*
* wav_play.c
* A component of soundboard that plays *.wav soundfiles.
*
* As of now, it works for a stereo sample that is 48 KHz in length,
* but using a lesser sample rate is a problem. The next fix this needs is to
* somehow auto-detect the sample rate of the file it wants to play... but
* that is for a later version. Since a 48 KKz sample is the best quality,
* I anticipate that will be the most poular among anyone using this program.
* If not, you'll have to do a bit of hacking to make it work.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/soundcard.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
int main(int argc, char *argv[])
{
int devfd = 0; /* file descriptors for device and sound file */
int sffd = 0;
int length = 0; /* For the return value of read */
int speed = 44100; /* Best sampling speed for a wav */
int stereo = 1; /* need to do this in stereo or it won't work. */
int format = 0;
int BUFFSIZE = 0;
char *dev = "/dev/dsp"; /* Using the /dev/dsp device */
char *file = argv[1];
unsigned char buffer[BUFFSIZE]; /* Write buffer */
/* Open the device for writing. */
if ((devfd = open(dev, O_WRONLY)) < 0)
{
printf("%d\n", devfd);
fprintf(stderr, "Error opening device %s\n", dev);
exit(-1);
}
/* Get the preffered buffer size of the device. */
if((ioctl(devfd, SNDCTL_DSP_GETBLKSIZE, &BUFFSIZE)) < 0)
{
fprintf(stderr, "Error getting preffered buffer size.");
exit(-1);
}
/* Set the format for soundblaster 16; little-endian (intel). */
format = AFMT_S16_LE;
if ((ioctl(devfd, SNDCTL_DSP_SETFMT, &format)) < 0)
{
fprintf(stderr, "Error setting format to %s.\n", format);
exit(-1);
}
/* Set the device channels (stereo or mono smaple). */
if ((0 > (ioctl(devfd, SNDCTL_DSP_STEREO, &stereo))))
{
fprintf(stderr, "Error setting channel.");
exit(-1);
}
/* Set the sample speed. */
if ((0 > (ioctl(devfd, SNDCTL_DSP_SPEED, &speed))))
{
fprintf(stderr, "Error setting sample speed to %d.\n", speed);
exit(-1);
}
/* Open the file we want to play. */
if ((sffd = open(file, O_RDONLY)) < 0)
{
// fprintf(stderr, "Error playing file %s.\n", file);
// printf("Error playing file %s.\n", &file);
exit(-1);
}
/* Read BUFFSIZE of file into buffer, and write that
* data to the device. Do this until we reach the end of the
* file
*/
while ((length = read(sffd, buffer, BUFFSIZE)) > 0)
{
write(devfd, buffer, length);
}
/* Tag 'em and bag 'em */
close(devfd);
close(sffd);
return 0;
}