Thread: something funny going on here...

  1. #1
    Registered User
    Join Date
    Aug 2001
    Posts
    202

    something funny going on here...

    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;
    }

  2. #2
    Registered User moi's Avatar
    Join Date
    Jul 2002
    Posts
    946
    compile with all extra line info and crapola then figure out where your program is seg faulting from the eip.

    (i dont actually know how to do this myself so forgive the muddy explination)

  3. #3
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    A couple of things:

    >int BUFFSIZE = 0;
    >unsigned char buffer[BUFFSIZE];
    What size is that array? Looks like it's zero bytes to me.

    >char *file = argv[1];
    >if ((sffd = open(file, O_RDONLY)) < 0)
    You haven't verified that argc is greater than 1. Therefore, argv[1] could well be NULL if you don't pass any parameters on the command line.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  4. #4
    Registered User
    Join Date
    Aug 2001
    Posts
    202

    int BUFFSIZE = 0;
    unsigned char buffer[BUFFSIZE];
    What size is that array? Looks like it's zero bytes to me.
    See below in the program; an ioctl call gets the buffer size that /dev/dsp wants. That should be the second if statement.

    And I know that I don't check argc; but I promise I am giving it a wav file as a CL arg.

    starX
    www.axisoftime.com

  5. #5
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    >See below in the program; an ioctl call gets the buffer size that /dev/dsp wants. That should be the second if statement.
    Yes, you are updating the BUFFSIZE variable during runtime. But that's irrelevant, as the size of the buffer array is created a compile time, and it's zero.

    Compile this and run it to see what I mean:
    Code:
    #include <stdio.h>
    
    int main(void)
    {
    	int i = 0;
    	unsigned char buffer[i];	
    	printf ("sizeof buffer:%d\n", sizeof buffer);
    	i = 10;
    	printf ("sizeof buffer:%d\n", sizeof buffer);
    	return 0;
    }
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  6. #6
    Registered User moi's Avatar
    Join Date
    Jul 2002
    Posts
    946
    Originally posted by starX


    See below in the program; an ioctl call gets the buffer size that /dev/dsp wants. That should be the second if statement.

    And I know that I don't check argc; but I promise I am giving it a wav file as a CL arg.

    starX
    www.axisoftime.com
    try:

    unsigned char *buffer;

    once you have figgured out BUFFSIZE:

    buffer = (char *) malloc (sizeof (char) * BUFFSIZE);

    then do the rest of your code as normal

    then once you're done

    free (buffer);

  7. #7
    Registered User
    Join Date
    Aug 2001
    Posts
    202
    thanks guys, just goes to show you can always learn something new. One question though... why might this have worked under my old installation.

    starX
    www.axisoftime.com

  8. #8
    Registered User moi's Avatar
    Join Date
    Jul 2002
    Posts
    946
    you got lucky. code that refers to random memory space can work if you're lucky, and more often under windows then other os'es

  9. #9
    Registered User
    Join Date
    Aug 2001
    Posts
    202
    exteremly unlucky you mean, especially considering that I'm doing this on Linux

    starX
    www.axisoftime.com

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Funny Windows Error Codes (I rofled...)
    By Sentral in forum A Brief History of Cprogramming.com
    Replies: 10
    Last Post: 06-01-2006, 09:38 AM
  2. funny things
    By Benzakhar in forum A Brief History of Cprogramming.com
    Replies: 4
    Last Post: 01-10-2004, 11:06 AM
  3. Object Oriented - Funny story
    By MethodMan in forum A Brief History of Cprogramming.com
    Replies: 5
    Last Post: 09-26-2002, 02:21 PM
  4. Funny
    By Imperito in forum A Brief History of Cprogramming.com
    Replies: 9
    Last Post: 08-21-2002, 05:41 PM
  5. For some reason, it prints funny characters ???
    By Nutshell in forum C Programming
    Replies: 8
    Last Post: 01-14-2002, 04:27 PM