Sign in to follow this  
tppramod

Background sound support in C for PC Speaker

Recommended Posts

tppramod    122
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 this post


Link to post
Share on other sites
doynax    850
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 this post


Link to post
Share on other sites
tppramod    122
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 this post


Link to post
Share on other sites
doynax    850
Quote:
Original post by tppramod
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.
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 this post


Link to post
Share on other sites
tppramod    122
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 this post


Link to post
Share on other sites
doynax    850
Quote:
Original post by tppramod
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?
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 this post


Link to post
Share on other sites
doynax    850
Quote:
Original post by try_catch_this
that 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 this post


Link to post
Share on other sites
tppramod    122
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 this post


Link to post
Share on other sites
doynax    850
Quote:
Original post by try_catch_this
Is 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_this
Who even has turbo c?
The OP?

Share this post


Link to post
Share on other sites
tppramod    122
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 this post


Link to post
Share on other sites
paulecoyote    1065
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 this post


Link to post
Share on other sites
pex22    139
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 start reading it.
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 EOF
second_number = read_file(INT);
CMS = clock();
sound(first_number);
// Draw
if (clock()-CMS>=second_number)
{
first_number=read_file(INT);
second_number=read_file(INT);
CMS = clock();
sound(first_number);
}
// Draw the next something
if (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 this post


Link to post
Share on other sites
doynax    850
Quote:
Original post by tppramod
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.
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 this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
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 this post


Link to post
Share on other sites
tppramod    122
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 this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this