home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 11 Util
/
11-Util.zip
/
setpas.zip
/
PAS.C
next >
Wrap
C/C++ Source or Header
|
1994-04-15
|
13KB
|
432 lines
/*
* Utilty to set the mixer values of Mediavision Pro Audio 16
*
* Platform: IBM OS/2 2.x , IBM C-Set ( V1.0 used )
*
* Mediavision Device-Driver 'mvprodd' required.
*
* Written by Johannes Deisenhofer (S_DEISENH@rzmain.rz.uni-ulm.de)
*
* Version 1.00 24.02.94
*
* This software works by sending DevIOCtl-commands to the 'PAS161$' device.
*
* Freeware. Use at your own risk.
*
*/
#include <stdio.h>
#include <string.h>
#define INCL_BASE
#include <os2.h>
/* MVPRODD-specific Constants */
#define DEVNAME "PAS161$" /* Name of the Device */
#define MIXER_CAT 0x81 /* This IOCtl-Category is used for mixing */
/* Device Commands defined by the device driver. */
/* There are more of them , but I don't know what they do */
typedef enum {
PAS_GetState = 0x47,
PAS_SetState = 0x48,
PAS_GetValue = 0x4d,
PAS_SetValue = 0x4e
} DEVCMD;
/* Audio channels, do not reorder */
typedef enum { FM=0, /* FM-Chip */
RecMon, /* Record Monitor */
Aux, /* Aux */
CD, /* CD Input */
Mic, /* Microphone */
W16, /* 16-Bit DA */
Spkr, /* PC Speaker */
SB, /* Soundblaster */
Global=256, /* Global Volume and Settings */
Input=0xc5 /* Input Level */
} CHAN;
/* 'Global' channel has these Subcommands */
typedef enum { G_Volume = 1,
G_Sound = 8,
G_Loud = 0x20,
G_Enhance = 0x100
} SCMD;
/* channel mode flags */
typedef enum {
noflags=0,
isbass, /* Is Bass or Treble : trigger special handling */
istreble,
switchable = 0x20, /* Record/Play selectable */
stereo = 0x40 /* Stereo channel */
} SFLAG;
/* This table binds keywords to channels and their flags */
struct {
char *devstr; /* Commandline keyword */
CHAN channel; /* channel number */
SCMD subcmd; /* sub-command */
SFLAG flag; /* flags */
}
devtbl[] =
{
{ "BASS", Global, G_Sound, isbass },
{ "TREBLE" , Global, G_Sound, istreble },
{ "FM", FM, 1, switchable | stereo },
{ "Synth", FM, 1, switchable | stereo },
{ "MON", RecMon, 1, stereo },
{ "INT", CD, 1, switchable | stereo },
{ "CD", CD, 1, switchable | stereo },
{ "EXT", Aux, 1, switchable | stereo },
{ "AUX", Aux, 1, switchable | stereo },
{ "MIC", Mic, 1, switchable | stereo },
{ "PCM", W16, 1, switchable | stereo },
{ "WAVE", W16, 1, switchable | stereo },
{ "SPEAKER", Spkr, 1, switchable | stereo },
{ "SPKR", Spkr, 1, switchable | stereo },
{ "SB", SB, 1, switchable | stereo },
{ "SoundBlaster", SB, 1, switchable | stereo },
{ "VOLUME", Global, G_Volume, stereo },
{ "VOL", Global, G_Volume, stereo },
{ "MASTER", Global, G_Volume, stereo },
{ "INPUT", Input, 1, stereo },
{ "LOUDNESS", Global, G_Loud, noflags },
{ "ENHANCE", Global, G_Enhance,noflags }
};
/* Values used by PAS_Set/GetValue */
typedef enum { Monitor = 1,
Record = 2
} MONCMD;
/* Globals */
HFILE filehandle; /* Filehandle of Device-Driver. Used globally */
extern const char *helptext; /* I want to have this one at the end of the program */
typedef ULONG CTRL_PACKET[6]; /* Values are passed back in this structure */
/* Set a value
* Args: CHAN ch : channel
* SCMD sc : subchannel
* USHORT left,
* right : Value, 0 min, 0xffff max
*/
int pas_setval(CHAN ch, SCMD sc,USHORT left, USHORT right)
{
return pas_mix_cmd(PAS_SetValue,ch,sc, left<<16 | right );
}
/* Get a value
* Args: CHAN ch : channel
*/
ULONG pas_getval(CHAN ch,SCMD sc)
{
ULONG retval;
/* Pass Adress as a 16:16 Pointer - CSet Syntax */
pas_mix_cmd(PAS_GetValue,ch,sc,(ULONG)(ULONG * _Seg16)&retval);
return retval;
}
/* Set a switch
* Args: CHAN ch : channel
* MONCMD cmd : new state of switch
*/
int pas_setmon(CHAN ch, MONCMD cmd)
{
return pas_mix_cmd(PAS_SetState,ch,cmd);
}
/* Get a switch
* Args: CHAN ch : channel
* Ret : MONCMD cmd : new state of switch
*/
MONCMD pas_getmon(CHAN ch)
{
ULONG retval;
/* Pass Adress as a 16:16 Pointer - CSet Syntax */
pas_mix_cmd(PAS_GetState,ch,(ULONG)(ULONG * _Seg16)&retval,0);
return retval;
}
/*
* pas_mix_cmd : Send Command to Driver
*
* uses global 'filehandle'
*
* Assembles ULONG values into a packet and sends it to the DD
*
*/
int pas_mix_cmd(DEVCMD function, ULONG arg1, ULONG arg2, ULONG arg3)
{
APIRET rc;
CTRL_PACKET ctrl;
ULONG size1, size2;
memset(&ctrl,0,sizeof(CTRL_PACKET));
ctrl[0]=arg1;
ctrl[1]=arg2;
ctrl[2]=arg3;
size2=0;
size1=sizeof(CTRL_PACKET);
rc = DosDevIOCtl(filehandle,MIXER_CAT,function,
&ctrl,sizeof(ctrl),&size1,
NULL,0,&size2);
return rc;
}
/* Macros for converting USHORT values to percentages and back */
#define TOPROC(a) ((((a)*100/0x7fff)+1)/2)
#define TOSHORT(a)((((a)*0xffff/50)+1)/2)
/* Parse Command Line */
int do_proc(int argc,char** argv)
{
int argptr=1,k;
enum { LEFT,RIGHT,BOTH } chansel = BOTH; /* Flag for selected channel */
if (argc<3) return (-1);
while (argptr<argc) {
/* GET Values */
if (!stricmp(argv[argptr],"GET"))
{
ULONG value;
MONCMD mode;
argptr++;
if (argptr+1>argc) return -1;
/* Find string in Table */
for(k=0;k<sizeof(devtbl)/sizeof(*devtbl);k++)
if(!stricmp(argv[argptr],devtbl[k].devstr)) break;
if(k==sizeof(devtbl)/sizeof(*devtbl)) return -1; /* Not found */
/* Get value if found */
value=pas_getval(devtbl[k].channel,devtbl[k].subcmd);
/* Format output for BASS and TREBLE */
if (devtbl[k].flag==istreble || devtbl[k].flag==isbass)
printf("Level of %s is %d%%",
devtbl[k].devstr,
devtbl[k].flag==isbass
? TOPROC((value>>16)*256)
: TOPROC((value&0xffff)*256)
);
/* Format output for stereo channels */
else if (devtbl[k].flag & stereo)
printf("Level of %s is %d%% (L:%d%% R:%d%%)",
devtbl[k].devstr,
(TOPROC(value>>16)+TOPROC(value&0xffff))/2,
TOPROC(value>>16),
TOPROC(value&0xffff)
);
/* Format output for all other (mono) devices */
else
printf("Level of %s is %d%%",
devtbl[k].devstr,
(TOPROC(value>>16)+TOPROC(value&0xffff))/2
);
/* print 'mode' if defined and a CR */
if ((devtbl[k].flag & switchable) == switchable ) {
mode=pas_getmon(devtbl[k].channel);
printf(" Mode: %s\n", (mode==Record ? "Record" : "Monitor") );
}
else printf("\n");
argptr++;
}
/* SET Values */
else if(!stricmp(argv[1],"SET"))
{
ULONG value=0;
argptr++;
if (argptr+1>argc) return -1;
/* check for LEFT/RIGHT keywords */
if (!stricmp(argv[argptr],"LEFT")) { chansel=LEFT; argptr++; }
else if (!stricmp(argv[argptr],"RIGHT")) { chansel=RIGHT;argptr++; }
if (argptr>argc) return -1;
/* Find string in Table */
for(k=0;k<sizeof(devtbl)/sizeof(*devtbl);k++)
if(!stricmp(argv[argptr],devtbl[k].devstr)) break;
if(k==sizeof(devtbl)/sizeof(*devtbl)) return -1; /* Not found */
argptr++;
if(argptr+1>argc) return -1;
if (!stricmp(argv[argptr],"TO"))
{
argptr++;
if(argptr+1>argc) return -1;
/* Get and check value */
value= atol(argv[argptr]);
if(value<0 || value > 100 ) return -1;
/* Convert to USHORT */
value=TOSHORT(value);
/* Special treatment for Bass and Treble */
if (devtbl[k].flag==isbass ) {
chansel=LEFT; /* Bass */
value/=256;
}
if (devtbl[k].flag==istreble) {
chansel=RIGHT; /* Treble */
value/=256;
}
/* No left/right keyword given */
if (chansel==BOTH)
/* Set left and right channel to equal values */
pas_setval(devtbl[k].channel,devtbl[k].subcmd,value,value);
/* Left channel */
else if (chansel==LEFT)
pas_setval(devtbl[k].channel,devtbl[k].subcmd,value,
pas_getval(devtbl[k].channel,devtbl[k].subcmd)&0xffff);
/* Right channel */
else if (chansel==RIGHT)
pas_setval(devtbl[k].channel,devtbl[k].subcmd,
pas_getval(devtbl[k].channel,devtbl[k].subcmd)>>16, value );
argptr++;
}
/* FOR */
else if (!stricmp(argv[argptr],"FOR"))
{
argptr++;
if(argptr+1>argc) return -1;
/* record or play-mode */
if (!stricmp(argv[argptr],"Record"))
{
if ((devtbl[k].flag&switchable)==switchable)
pas_setmon(devtbl[k].channel,Record);
argptr++;
}
else if (!stricmp(argv[argptr],"Monitor"))
{
if ((devtbl[k].flag& switchable)==switchable)
pas_setmon(devtbl[k].channel,Monitor);
argptr++;
}
else return -1;
}
else return -1; /* Error */
}
else return -1;
}
return 0; /* All Commands processed */
}
int main(int argc, char**argv)
{
APIRET rc;
ULONG action=0;
if(argc==1) { /* Show Help */
puts(helptext);
exit (-1);
}
rc=DosOpen( DEVNAME,&filehandle,&action,0,
FILE_NORMAL,OPEN_ACTION_OPEN_IF_EXISTS,
OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE,
NULL
);
if(rc != NO_ERROR) {
printf("Can't open device %s !\n",DEVNAME);
exit(-1);
}
if(do_proc(argc,argv)!=0) /* Do Processing */
puts("Syntax error. Type PAS without parameter for help\n");
DosClose(filehandle);
return (0);
}
/* Helptext. */
const char *helptext =
"\n"
"PAS -- Pro AudioSpectrum Mixer and Volume Control Utility, Version 01.00\n"
"by Johannes Deisenhofer '94. No Rights Reserved. Use at your own risk.\n"
"\n"
" PAS ─┬─>┬── GET <SETTING> ───────────────────────>──────────────┐ \n"
" ^ └── SET ──┬─ [LEFT/RIGHT] <SETTING> TO <Level> ─────────┼───>─┬──┤\n"
" │ └─ <SETTING> FOR [RECORD/MONITOR] ────────────┘ │\n"
" └────────────────<────────────────────────────────<──────────────┘\n"
" <SETTING> : \n"
" - FM : Synth Chip volume │ - MON : Record monitor volume\n"
" - MIC : Microphone volume │ - VOLUME : Master Volume\n"
" - AUX : Aux Input volume │ - ENHANCE : Stereo Enhance\n"
" - CD : CD Input volume │ - BASS : Bass\n"
" - PCM : 16-Bit DAC volume │ - TREBLE : Treble\n"
" - SB : Soundblaster volume │ - INPUT : Input Level (PAS Studio ?)\n"
" - SPKR : PC Speaker volume │ - LOUDNESS : Loudness level\n"
" <LEVEL> is a Number from 0 to 100\n"
"\n"
"Examples:\n"
"\n"
" pas set left volume to 100 set right volume to 80 set enhance to 0 set cd to 0\n"
" pas get volume\n";