# Background sound support in C for PC Speaker

This topic is 4669 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I am just finishing a pacman game written in C (not C++). I need to provide some sound support to the game using PC Speaker for which i want to know how to play a sound in the background' so that the my sprites moves smoothly without waiting for the sound to play at the foreground and then continue. i need some simple code only in C for background sound support for PC speaker. As an example i liked the simple sound supports used in PCMAN by Greg Kuperberg. I am using Turbo C. Please post any codes available. I would be grateful if someone can help. Thanks Pramod Kumar INDIA

##### Share on other sites
This seems like a decent tutorial on using the PC-speaker.

Instead of the BASIC-ish IN/OUT functions refered to in the tutorial you need to use TurboC's inportb/outportb functions instead to program IO ports.
This is a direct translation of some of the tutorial's code:
int value;outportb(0x43, 0xb6);outportb(0x42, 54);outportb(ox42, 124);value = inportb(0x61);value |= 3;outportb(0x61, value);
You'll only be able to play simple tones with this method, playing digital samples is a lot more work.

##### Share on other sites
thanks, doynax.

Whether the code will work for playing the tones in the background? i am more concerned about this. what methods were used in classic games like paratrooper, pcman etc. any idea? Any source code availble for such games or any detailed documentation for this with sample codes.

thanks

pramod

##### Share on other sites
Quote:
 Original post by tppramodWhether the code will work for playing the tones in the background? i am more concerned about this. what methods were used in classic games like paratrooper, pcman etc. any idea? Any source code availble for such games or any detailed documentation for this with sample codes.
That shouldn't a problem.

The tutorial theaches you to begin playing a note at a specific frequency. Your program will regain control without any delay and the tone will continue to play in the background until you stop it manually.

I can't guarantee that it'll work but the following code should play tones at the frequency:
#include <dos.h>void playTone(unsigned int freq) { unsigned char reg; unsigned int period; period = 1193180UL / freq; outportb(0x43, 0xb6); outportb(0x42, period); outportb(0x42, period >> 8); reg = inportb(0x61); reg |= 3; outportb(0x61, reg);}void stopTone(void) { unsigned char reg; reg = inportb(0x61); reg &= ~3; outportb(0x61, reg);}

[Edited by - doynax on March 28, 2005 4:50:04 AM]

##### Share on other sites
thankx.... i will try this out. but i have not understood the line reg &= ~3;' what is ~3'?. also have you ever tried the methods given in the said tutorial?

pramod

##### Share on other sites
Quote:
 Original post by tppramodthankx.... i will try this out. but i have not understood the line reg &= ~3;' what is ~3'?. also have you ever tried the methods given in the said tutorial?
reg &= ~3 is equivalent to "VALUE = VALUE AND 252" in the tutorial.

I've used this method before but's been a long time ago since I've last used it.

##### Share on other sites
that code does not compile.

##### Share on other sites
Quote:
 Original post by try_catch_thisthat code does not compile.
Well, that wouldn't surprise me..
Could you give me any more specific information on the error?

I haven't got Turbo C to compile it with so I can't test it myself.

edit: I found at least one bug. I had managed to use a 0 instead of an O in the prefix of a hexadecimal constant.

##### Share on other sites
thanks for the nice help. right now i am in my office. i will incorporate the code and see if it works tomorrow. catch u later. thanks once again.

pramod

##### Share on other sites
Is there a standard c++ version of that code that will work?
Who even has turbo c?

##### Share on other sites
Quote:
 Original post by try_catch_thisIs there a standard c++ version of that code that will work?
No, it relies on writing directly to IO ports. Few operating systems allow this, and even if they did it would only work on IBM-PCs.
You could of course rewrite it for use in other DOS compilers, or try to find some WIN32 facility to do the same (I assume one exists).
Quote:
 Original post by try_catch_thisWho even has turbo c?
The OP?

##### Share on other sites
Hi doynax,

i have the following working code which is similar to what you have suggested.
URL is http://216.239.63.104/search?q=cache%3Aguideme.itgo.com/atozofc/ch24.pdf

i have complied this and is working. But the delay() used in the code worries me as i think this will halt the graphic routines. I have yet to check this out in my game.

how can we put delay with sound happening in the background? can u suggest any way out in the following code.

#define ON (1)
#define OFF (0)

//Website URL - http://216.239.63.104/search?q=cache%3Aguideme.itgo.com/atozofc/ch24.pdf

//Turn speaker on or off. */

void ChangeSpeaker(int status)
{
int portval;
portval = inportb( 0x61 );
if ( status==ON )
portval |= 0x03;
else
portval &=~ 0x03;

outportb( 0x61, portval );
}

void Sound(int hertz)
{
unsigned divisor = 1193180L / hertz;
ChangeSpeaker( ON );
outportb( 0x43, 0xB6 );
outportb( 0x42, divisor & 0xFF ) ;
outportb( 0x42, divisor >> 8 ) ;
}

void NoSound( void )
{
ChangeSpeaker( OFF );
}

int main( void )
{
Sound( 355 );
delay( 1000 );
NoSound( );
return(0);
}

thanks

pramod

##### Share on other sites
I have done this, unfortunetly it was for a commerical product that I don't own the copyright to so I can't help you with the code.

However, I can tell you my approach. I created a beep message / queueing system for the beeping. I had the main thread launch another thread that contained the message loop. this message loop either processes a message or Sleep for a few cycles so it doesn't hog the cpu.

There are two approaches to handling delay - you can either just use Sleep and put that message thread to sleep for at least Sleep(x) amount of time (but this is not very exact). Or when dealing with a delay command message take it off the queue, add time passed to time waiting, and put it back on the front of the queue again until the time has passed.

That way when you want to play a tune in the background from the main thread, you just post a ton of messages to the queue which will process them for you. This system could easily be extended to include priority too (so some beeps can skip to the front of the queue if they are more important).

##### Share on other sites
if anyone has the working code?

##### Share on other sites
Why don't you just use the sound functions from the compiler?
#include <dos.h>sound(100);delay(55);nosound();

thats all, that will make a sound with 100Hz tone for 55 ms, and then close the sound.
if you want it as a background music, first you need a music.
lets say you made a file that contains the music data.
(e.g. 100 2 500 6 699 32 ... where the first number is the tone in Hz and the second is the ms, and then the tone again and so on.).
you sound(first_number); and keep the current ms as CMS.
and always check if second_number - current ms is equal or more than CMS.
if it is, then you read the next number as first_number and jump to the next sound(first_number); // now its not really the first number, its just the next number in the file. but its the tone too.
then you keep the current ms as CMS and bla bla bla.
I never tried it but it seems to me like a solution.
Example (the io functions are not real, its just to make it more clear):
open_file(data);while (gameloop){first_number = read_file(INT); // reads an integer until a space or EOFsecond_number = read_file(INT);CMS = clock();sound(first_number);// Drawif (clock()-CMS>=second_number){first_number=read_file(INT);second_number=read_file(INT);CMS = clock();sound(first_number);}// Draw the next somethingif (clock()-CMS>=second_number){// ... you know what to do here.}// and here.}close_file(data);`

Why dont you want to google up for Sound Blaster, Adlib, or something? they sound better i think.
Hope I helped,

##### Share on other sites
Quote:
 Original post by tppramodHi doynax,i have the following working code which is similar to what you have suggested. URL is http://216.239.63.104/search?q=cache%3Aguideme.itgo.com/atozofc/ch24.pdfi have complied this and is working. But the delay() used in the code worries me as i think this will halt the graphic routines. I have yet to check this out in my game.
The delay in that code isn't problem for you.
It's just a small delay for the demo otherwise the sound would've been way to short to be heard. In your game you'd play the sound for a number of frames instead (requesting to start playing at at one frame and calling the stop function several frames later).
No need to use any complicated timing methods or busy-waiting.

##### Share on other sites
Hi,
i have got a very good link that has got all i wanted. The URL is http://www.cs.umu.se/~isak/Snippets. "Demo of bacground music functions for PC Speaker". Here are the list of files:
1. sound.h
2. uclock.h
3. playdemo.c
4. mktone.c
5. uclock.c
6. playlib.c
and many more are there.................. Please give your comments on the files as I have not yet compiled any of the files.

Thanks & Regards,

pramod

##### Share on other sites
Hi,
i have got a very good link that has got all i wanted. The URL is http://www.cs.umu.se/~isak/Snippets. "Demo of bacground music functions for PC Speaker". Here are the list of files:
1. sound.h
2. uclock.h
3. playdemo.c
4. mktone.c
5. uclock.c
6. playlib.c
and many more are there.................. Please give your comments on the files as I have not yet compiled any of the files.

Thanks & Regards,

pramod

##### Share on other sites

This topic is 4669 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.