home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Best Objectech Shareware Selections
/
UNTITLED.iso
/
boss
/
musi
/
misc
/
017
/
x02.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-05
|
11KB
|
346 lines
#include <dos.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "ruckdac.h"
/*
X02.c 28-Feb-93 chh
Load & Play mod file
*/
/*
The following structures are in ruckdac.h
*/
/*
DACDATA is in DGROUP so could probably get away with a __near here dear
*/
extern struct DacDataArea __pascal DACDATA;
struct SysInfoPack SIP;
struct InitPack IP;
struct XitPack XP;
struct LoadPack LP;
struct SetModPack SMP;
struct SetProPack SPP;
struct PlaybackPack PBP;
int rez, rez2; /* result status codes */
char nums[9] = {7}; /* number buffer for _cgets()*/
char filename[81]; /* pathname to load */
/* typedef unsigned int uint; */
int pick_device(int *devID, unsigned int *HighRate)
{
/*
Just ask for device to use and return it and that device's effective
top-end rate (nothing concrete in the returned top-end...)
*/
int td=0;
*HighRate = 0;
SIP.Func = SysInfoDac;
rez = RUCKDAC(&SIP);
if (rez == 0) {
printf("CPU is a %u/%u\n",SIP.CPU,SIP.MHz);
printf("\n0. End program");
printf("\n1. PC speaker at port 42h");
if (SIP.SD[1].device)
printf("\n2. LPT-DAC on LPT1, port %xh",SIP.SD[1].Port);
if (SIP.SD[2].device)
printf("\n3. Disney Sound Source port %xh",SIP.SD[2].Port);
if (SIP.SD[3].device)
printf("\n\n4. AdLib Music Synthesizer Card, port %xh",SIP.SD[3].Port);
if (SIP.SD[4].device)
printf("\n5. Sound Blaster, port %xh",SIP.SD[4].Port);
if (SIP.SD[5].device)
printf("\n6. Sound Blaster Pro, port %xh\n",SIP.SD[5].Port);
/*
Can't play mods from XMS (well...)
BTW, if this code looks familiar, it's because it is (see X01.C)
*/
printf("\nSelection: ");
td = atoi(_cgets(nums));
td--; /* since devices are numbered 0 to 5 */
if ((td >=0) && (td <=5)) { /* validate device selected available */
if (SIP.SD[td].device == 0)
td = -1;
}
else
td = -1;
switch (td) {
case 0: /* 0 - PC speaker */
*HighRate = 18000; /* 1 - LPT-DAC */
break; /* 2 - Sound Source */
case 1: /* 3 - AdLib */
*HighRate = 23000; /* 4 - Sound Blaster */
break; /* 5 - Sound Blaster Pro ((STEREO)) */
case 2:
*HighRate = 7000;
break;
case 3:
*HighRate = 12000;
break;
case 4:
*HighRate = 23000;
break;
case 5:
*HighRate = 22750; /* ((STEREO)) 2*22750=45500Hz*/
break;
default:
td=-1;
}
}
*devID = td;
return(rez);
}
int init_device(int devID)
{
/*
Initialize RUCKDAC and device and register ExitMod with _atexit.
Mod play does not have a hi-rez mode for PC speaker & AdLib as does Dac.
*/
IP.Func = InitDac;
IP.DeviceID = devID;
IP.IOport = SIP.SD[devID].Port;
IP.IRQline = SIP.SD[devID].IRQ;
IP.DMAch = SIP.SD[devID].DMA;
rez = RUCKDAC(&IP); /* Initialize */
if (rez == 0) {
XP.Func = AtExitMod; /* Try this with based pointers */
rez2 = RUCKDAC(&XP); /* in use...could be a C7 bug */
if (rez2 != 0) { /* since _atexit seems to share */
/* (overwrite) memory used by */
/* the compiler's __based data */
/* Could just be me... ` */
printf("AtExitMod failed, press Enter to continue");
getchar();
}
}
return(rez);
}
int main()
{
int devID=-1;
unsigned int HighRate=5000, SampleRate=5000;
printf("X02.C - RUCKUS-DAC play of MOD file example. [930228]\n");
rez = pick_device(&devID, &HighRate);
if (devID >= 0) {
printf("Initializing devID %u\n",devID);
rez = init_device(devID);
/*
The following load and play example source is coded inline here
to simply readability -- but it's so easy to add things that I just
kept adding stuff, so take it slow if you don't follow at first
*/
if (rez == 0) {
/* load file and setup playback parameters */
printf("\n MOD filename: ");
gets(filename);
printf("\n (5000-%u)",HighRate);
printf("\rPlayback rate: ");
SampleRate = atoi(_cgets(nums));
if (SampleRate < 5000)
SampleRate = 5000;
if (SampleRate > HighRate)
SampleRate = HighRate;
LP.Func = LoadMod;
LP.FilenamePtr = filename;
LP.StartPos = 0L; /* start at first byte */
LP.LoadSize = 0L; /* autoload entire file */
LP.XMMflag = 0; /* LP.XMMflag always=0 */
rez = RUCKDAC(&LP);
if (rez == 0) {
/*
Increase SB Pro main and vol volumes to max (we bad now)
*/
if (devID == 5) {
SPP.Func = SetVolMainSBP;
SPP.Volume = 0x0F0F;
rez2 = RUCKDAC(&SPP);
SPP.Func = SetVolVocSBP;
SPP.VolVoc = 0x0F0F;
rez2 = RUCKDAC(&SPP);
}
/*
set mod channel volumes to max
*/
SMP.VolCh1 = 255;
SMP.VolCh2 = 255;
SMP.VolCh3 = 255;
SMP.VolCh4 = 255;
SMP.Func = SetVolumeMod;
rez2 = RUCKDAC(&SMP); /* always error check! */
/*
if SB Pro play in stereo
*/
if (devID < 5)
SMP.Stereo = 0;
else
SMP.Stereo = 1;
SMP.Func = SetStereoMod;
rez2 = RUCKDAC(&SMP);
SMP.IntRate = SampleRate;
/*
The SB Pro doubles the sample rate when doing stereo output
so here we double the requested rate to rate needed by SBPro.
This should be done _AFTER_ the SetStereoMod call above
*/
if (SMP.Stereo !=0)
/* double rate if stereo */
SMP.IntRate = SampleRate + SampleRate;
SMP.Func = SetIntRateMod;
rez2 = RUCKDAC(&SMP);
/*
SetFastMod can be used to play at higher rates than would
otherwise be possible. The default is FastMod off and
SliceAdj=1. On XTs, FastMod=1 may make the difference
between being able to play mods at all. The SliceAdj is
the number of bytes processed and stuffed into the DMA
buffers per timer interrrupt. The default is typically
sufficient to keep the DMA buffers full on fast machines,
but on slower CPUs, a higher SliceAdj will make for a
higher playback rate allowable. Actually, the code below
doesn't change the defaults so I'll comment it out.
Play around with the settings if you need to. (SliceAdj
is relevant for DMA devices only, like the Sound Blasters.)
*/
SMP.Func = SetFastMod;
SMP.FastMode = -1; /* skip fastmode adjust */
SMP.SliceAdj = 1; /* default = 1, range 1-4096 */
/* rez1 = RUCKDAC(&SMP) */
/*
if DMA device use DMA fore