• C

Sound

I need to get an mp3 playing in a C program.
Does anyone have a clue where I might start to
go about doing this, I have NO clue...
any thoughts would be really helpful
cheers
David
downatoneAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

toschCommented:
what platform are you on ?

on windows i would use OLE/COM automation to let the mediaplayer do it.

on unix use some library (libmpg123 for example) to decode the mp3 and pump it to /dev/dsp (setting channels/rate/depth is done using ioctrl - writing data is as simple as writing to a file).

of course you can decode the mp3 data and use directsound to play it on windows, too. there is a standardized codec interface for windows, i believe (but i have not used it yet - so i don't know too much about it).
0
downatoneAuthor Commented:
Yeah I'm in unix (more specifically if it helps, Red Hat 7.3) This: "on unix use some library (libmpg123 for example) to decode the mp3 and pump it to /dev/dsp (setting channels/rate/depth is done using ioctrl - writing data is as simple as writing to a file)."
Sounds good, would you be able to give me more detail on how one might go about doing this, I'm pretty new to the unix enviroment and C, so bare with me. But any pointers or little code snippets would always be appreciated.
Thanks
cheers
David
0
toschCommented:
i haven't used libmpg123 myself so you will have to rtfm on this.

making sound output

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <linux/soundcard.h>


void fail(char *msg)
{
fprintf(stderr,"%s\n",msg); exit(1);
}
int main(void)
{
   int fd;
   fd = open("/dev/dsp", O_RDWR);

   if (fd < 0)
    fail("open of /dev/dsp failed using stdout for output");
   /* device handling */
   arg = 16;      /* sample size */
   status = ioctl(fd, SOUND_PCM_WRITE_BITS, &arg);
   if (status == -1)
     fail("SOUND_PCM_WRITE_BITS ioctl failed");
   if (arg != SIZE)
     fail("unable to set sample size");
   arg = 2;  /* mono or stereo */
   status = ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &arg);
   if (status == -1)
      fail("SOUND_PCM_WRITE_CHANNELS ioctl failed");
   if (arg != CHANNELS)
      fail("unable to set number of channels");
   arg = 22000;      /* sampling rate */
   status = ioctl(fd, SOUND_PCM_WRITE_RATE, &arg);
   if (status == -1)
      fail("SOUND_PCM_WRITE_WRITE ioctl failed");
   
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Creating Active Directory Users from a Text File

If your organization has a need to mass-create AD user accounts, watch this video to see how its done without the need for scripting or other unnecessary complexities.

toschCommented:
i haven't used libmpg123 myself so you will have to rtfm on this.

making sound output itself is pretty simple (this program is untested because i'm under windows in the moment):

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <linux/soundcard.h>


void fail(char *msg)
{
   fprintf(stderr,"%s\n",msg); exit(1);
}
int main(void)
{
   int fd,arg,status,i;

   /* open sound device */

   fd = open("/dev/dsp", O_RDWR);
   if (fd < 0) fd = open("/dev/dsp/0",O_RDWR); // devfs


   /* send sound format to 16 bit / mono / 22kHz */

   if (fd < 0) fail("open of /dev/dsp failed using stdout for output");

   arg = 16;      /* 16 bit */
   status = ioctl(fd, SOUND_PCM_WRITE_BITS, &arg);
   if (status == -1) fail("SOUND_PCM_WRITE_BITS ioctl failed");

   arg = 1;       /* mono */
   status = ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &arg);
   if (status == -1) fail("SOUND_PCM_WRITE_CHANNELS ioctl failed");

   arg = 22000;   /* 22kHz */
   status = ioctl(fd, SOUND_PCM_WRITE_RATE, &arg);
   if (status == -1) fail("SOUND_PCM_WRITE_WRITE ioctl failed");


   /* play some real evil noise */

   short noise[22000];
   for (i = 0; i < 22000; i++)
   {
      noise[i] = ((i % 400) - 200) * 100;
   }
   write(fd,noise,22000 * sizeof(short));


   /* close sound device */

   close(fd);
}
0
downatoneAuthor Commented:
Ok, code compiled fine and seems to run (oh yeah just in case you or someone else reading this cares I had to put the short noise[22000]; before the for loop at the top with the other declarations). But when I run it I get the first error: "open of /dev/dsp failed using stdout for output" ! What does this mean, and is there a way I can fix it so that it works???
cheers
David
0
downatoneAuthor Commented:
Sorry, just realized you said you actually haven't used this before, so if you don't have an answer to my question, just let me know so I can look elsewhere, that would be appreciated. Otherwise, continued help would be more than appreciated.
cheers
David
0
toschCommented:
> I had to put the short noise[22000]; before the for loop at the top with the other declarations).

sorry, i'm doing a lot of c++ in the moment (this declaration is valid with c++ but not with c).

> But when I run it I get the first error: "open of /dev/dsp failed using stdout for output"

the error message is not right and sould be "aborting" instead of "using stdout...". i just took the code from one of my archived projects and there it really uses stdout.... the check is should occur before the comment line, too - but that's only cosmetic.

what happens here is:

open tries to open the file (in this case a special file - a character device) and fails (returns a value below zero).

there seems to be no driver loaded for your sound card. i guess you don't get -=any=- sound output so far.

you sould modprobe/insmod the right driver in order to make sound working at all. other sound related programs will fail as well.

there should be a section on making sound work in the redhat intstallation guide - if there isn't there will be a lot of help on the net.

basically all you have to do (on your command line) is:

modprobe <drivername for your soundcard>
or
insmod <path to driver for your soundcard>

(sound drivers are located /lib/modules/`uname -r`/kernel/drivers/sound )
(note: if you are using isa hardware there might be additional steps neccessary)

if you can successfully load the sound driver into your kernel test the configuration using the command line

cat /dev/urandom >/dev/dsp

or

cat /dev/urandom >/dev/dsp/0 # if you are using devfs

should produce noise. if it fails the driver doesn't work.
if it doesn't fail and you don't hear a thing use aumix to check the volume.
if it works press ctrl-c to get rid of the noise terror and try to execute the program again.

> Sorry, just realized you said you actually haven't used this before, so if you don't have an answer to my question, just let me know so I can look elsewhere, that would be appreciated.

well i have done sound output. the only thing i havent't done is using libmpg123 or some other mp3 decoding library.
0
downatoneAuthor Commented:
Ok, great got the sound working now, (much was much fault apologies), and ran the program and it seems to work. I'm getting this funny little buzz beep sound...now I'm assuming this is a start, I was hoping to be able to play a *.wav  or *.mp3 file, can this code be done to do this??? Or will all this code do for me is give me a beep? Because to be honest the is a simple function in the curses.h lib called beep() that does this for me...I'm looking for some real sound if you follow me?! Any further thoughts? By the way, thanks for the help thus far, it really has been appreciated.
cheers
David
0
toschCommented:
> Or will all this code do for me is give me a beep?

all this code does is play a beep sound.

the difference to the curses beep is:
you are outputting real data to the -=sound card=-.

maybe (under X) the terminal emulator will play the beep on the soud card, too - on the console however the pc-speaker will beep. this is caused by a special character written to the terminal - so you won't be able to play music with this.

for example you could change the loop to output a sine wave and it will sound different (or put data in the buffer you read from a .wav file) ;). in fact you could implement a whole synthesizer, mp3 decoder or whatever on top of this.

but i guess this is not the right way for you to go if you want something like playmp3("music.mp3");

you might want to take a look at SDL (simple direct media layer www.libsdl.org) there are routines to load and play wav files.
access to the sound device is abstracted so you can compile and run the same code on windows,serveral unixes (and linux) and mac os x.

if you want to play an mp3 file you need to decode it (for example www.mpg123.de).

take a look at these libs - or if you want to do it yourself be prepared to write -=a lot=- of more code than i posted in order to play an mp3 file (or write a shell script and use the mpg123 binary).
0
jmcgOwnerCommented:
Nothing has happened on this question in more than 9 months. It's time for cleanup!

My recommendation, which I will post in the Cleanup topic area, is to
accept answer by tosch.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

jmcg
EE Cleanup Volunteer
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.