?
Solved

Sound

Posted on 2003-03-28
11
Medium Priority
?
487 Views
Last Modified: 2007-12-19
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
0
Comment
Question by:downatone
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
11 Comments
 
LVL 3

Expert Comment

by:tosch
ID: 8230183
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
 

Author Comment

by:downatone
ID: 8231296
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
 
LVL 3

Accepted Solution

by:
tosch earned 80 total points
ID: 8240140
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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 3

Expert Comment

by:tosch
ID: 8240214
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
 

Author Comment

by:downatone
ID: 8240572
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
 

Author Comment

by:downatone
ID: 8240597
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
 
LVL 3

Expert Comment

by:tosch
ID: 8244038
> 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
 

Author Comment

by:downatone
ID: 8248534
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
 
LVL 3

Expert Comment

by:tosch
ID: 8286529
> 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
 
LVL 20

Expert Comment

by:jmcg
ID: 10187225
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

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
The goal of this video is to provide viewers with basic examples to understand and use structures in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use switch statements in the C programming language.

801 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question