Mail Archives: djgpp/1994/04/21/06:24:19
Hello everybody,
I'm trying to find a way to use the soundblaster under djgpp
without crashing the system (don't we all...)
As interrupt programming turned out to be buggy, I tried the
brute force method : Reset the clock speed, wait until it
changes (the clock, that is) in a loop and then send the
next byte. This is ugly, probably not very precise and it
works perfectly. Under Turbo-C 2.0.
Unfortunately it gives only unpredictable delays, sometimes
a kind of slow motion playing or crashes as soon as I compile
with djgcc :-(
As the code is rather short, I will post it. Only a few
includes changed compared to the working TC version.
Does anyone see why this, again, does not work ? Will we ever
be able to safely play sounds under djgcc ? Will I be
saved from nervous breakdown ?
Bye, Koma
P.S. Ooops, text was written in a 4-space-tab editor, if it looks
strange on you screen try to change this...
#include <time.h>
#include <dos.h>
#include <std.h>
#include <pc.h>
#define lowbyte(address) ((address) & 255)
#define highbyte(address) (((address)>>8) & 255)
extern int BASE; /* The soundcard address, usually 0x220 */
void write_dsp(unsigned char value,int base);
void SoundPlay(unsigned long rate, char *Data, unsigned long length)
{
struct time Start_time;
unsigned long Start_clock;
unsigned long Ticks_during_action;
int hund_seconds;
int timer_value;
int i;
unsigned long oldclock, newclock;
gettime(&Start_time); /* Save time to reset clock at end */
Start_clock = clock();
timer_value = 1193180 / rate; /* timer signals per second / rate */
outportb(0x40, lowbyte(timer_value));
outportb(0x40, highbyte(timer_value)); /* set new clock rate */
sb_voice(1);
for(i=0; i<length;) {
if((newclock = clock()) != oldclock) {
oldclock = newclock;
write_dsp(0x10,BASE); /* prepare dsp port */
write_dsp(Data[i],BASE); /* send value */
outportb(0x20,0x20); /* acknowledge action */
i++;
}
}
sb_voice(0);
timer_value = 0x0FFFF; /* reset timer */
outportb(0x40, lowbyte(timer_value));
outportb(0x40, highbyte(timer_value));
/* now calculate how much time passed and reset clock, this is */
/* necessary as the bending of the timer also bends the clock */
Ticks_during_action = clock() - Start_clock;
hund_seconds = (double)Ticks_during_action / ((double)rate/100) + .5;
Start_time.ti_hund += hund_seconds;
if(Start_time.ti_hund > 99) {
Start_time.ti_sec += Start_time.ti_hund / 100;
Start_time.ti_hund %= 100;
if(Start_time.ti_sec > 59) {
Start_time.ti_min += Start_time.ti_sec / 60;
Start_time.ti_sec %= 60;
if(Start_time.ti_min > 59) {
Start_time.ti_hour += Start_time.ti_min / 60;
Start_time.ti_min %= 60;
if(Start_time.ti_hour > 23) {
Start_time.ti_hour -= 24;
}
}
}
}
settime(&Start_time);
}
void write_dsp(unsigned char value,int base)
{
int i;
for(i=0;i<10000;i++) { /* poll write status up to 10000 */
if(!(inportb(base+0x0C) & 0x80))/* times until 'not ready' signal */
break; /* 0x80 disappears */
}
outportb(base+0x0C,value); /* now write actual port value */
}
- Raw text -