home *** CD-ROM | disk | FTP | other *** search
- #include<conio.h>
- #include<stdlib.h>
- #include<stdio.h>
- #include<string.h>
- #include<math.h>
- #include"timer.h"
- extern "C"
- {
- #include<forte.h>
- #include<gf1proto.h>
- #include<extern.h>
- #include<ultraerr.h>
- }
-
- enum Command {TC_TONESTART,TC_TONEEND,TC_WAIT,TC_END};
-
- struct toneCommand
- {Command tc;
- float fParam;
- int iParam1,iParam2;
- };
-
- struct toneDef
- {struct toneCommand *tcoms;
- char key;
- char name[40];
- };
-
- #define MAXNMTONEDEFS 50
- #define SINESIZE 100
-
- int nmToneDefs;
- struct toneDef *toneDef[MAXNMTONEDEFS];
- int basePort;
- int masterVolume;
-
- void readToneFile(char *name)
- {FILE *ifile;
- int nmTcomms;
- char line[80];
- char toneName[50];
- char command[50];
- char key[5];
- int lineNm;
- int iParam1,iParam2;
- float fParam;
- ifile=fopen(name,"r");
- if (!ifile)
- {printf("Can't open %s\n",name);
- exit(-1);
- }
- lineNm=-1;
- nmToneDefs=0;
- while ((lineNm++,fgets(line,80,ifile)))
- {if (sscanf(line," start %50s %5s ",toneName,key)==2)
- {struct toneDef *newTD;
- newTD=new (struct toneDef);
- if (!newTD)
- {printf("Out of memory!\n");
- exit(-1);
- }
- strcpy(newTD->name,toneName);
- newTD->key=key[0];
- newTD->tcoms=(struct toneCommand *)
- malloc(sizeof(struct toneCommand)*100);
- if (nmToneDefs>MAXNMTONEDEFS)
- {printf("Too many tone definitions\n");
- exit(-1);
- }
- toneDef[nmToneDefs++]=newTD;
- nmTcomms=0;
- while (1)
- {if (nmTcomms>=100)
- {printf("Tone definition too complex\n");
- exit(-1);
- }
- if (!(lineNm++,fgets(line,80,ifile)))
- {printf("Unexpected end of file.\n");
- exit(-1);
- }
- sscanf(line, " %50s ",command);
- if (!strcmp(command,"tstart"))
- {if (sscanf(line," %50s %d %d ",command,&iParam1,&iParam2)!=3)
- {printf("Error parsing line %d\n",lineNm);
- exit(-1);
- }
- newTD->tcoms[nmTcomms].tc=TC_TONESTART;
- newTD->tcoms[nmTcomms].iParam1=iParam1;
- newTD->tcoms[nmTcomms].iParam2=iParam2;
- nmTcomms++;
- continue;
- }
- if (!strcmp(command,"tend"))
- {if (sscanf(line," %50s %d ",command,&iParam1)!=2)
- {printf("Error parsing line %d\n",lineNm);
- exit(-1);
- }
- newTD->tcoms[nmTcomms].tc=TC_TONEEND;
- newTD->tcoms[nmTcomms].iParam1=iParam1;
- nmTcomms++;
- continue;
- }
- if (!strcmp(command,"wait"))
- {if (sscanf(line," %50s %f ",command,&fParam)!=2)
- {printf("Error parsing line %d\n",lineNm);
- exit(-1);
- }
- newTD->tcoms[nmTcomms].tc=TC_WAIT;
- newTD->tcoms[nmTcomms].fParam=fParam;
- nmTcomms++;
- continue;
- }
- if (!strcmp(command,"end"))
- {newTD->tcoms[nmTcomms].tc=TC_END;
- nmTcomms++;
- newTD->tcoms=(struct toneCommand *)realloc(newTD->tcoms,
- sizeof(struct toneCommand)*nmTcomms);
- break;
- }
- printf("Error parsing line %d\n",lineNm);
- exit(-1);
- }
- }
- }
- }
-
- int UltraGetCfg(ULTRA_CFG *config)
- {char *ptr;
- config->base_port = 0x220;
- config->dram_dma_chan = 1;
- config->adc_dma_chan = 1;
- config->gf1_irq_num = 11;
- config->midi_irq_num = 5;
- ptr = getenv("ULTRASND");
- if (!ptr)
- return(0);
- sscanf(ptr,"%x,%d,%d,%d,%d",&config->base_port,
- &config->dram_dma_chan,
- &config->adc_dma_chan,
- &config->gf1_irq_num,
- &config->midi_irq_num);
- return(1);
- }
-
- void setupUltrasound(void)
- {ULTRA_CFG config;
- int i;
- float f;
- if (!UltraGetCfg(&config))
- {printf("ULTRASND environment variable not defined.\n");
- exit(-1);
- }
- if (UltraProbe(config.base_port) == NO_ULTRA)
- {printf("Couldn't initialize GUS.\n");
- exit(-1);
- }
- basePort=config.base_port;
- if (UltraOpen(&config,14) == NO_ULTRA)
- {printf("Couldn't initialize GUS.\n");
- exit(-1);
- }
- int w;
- for (i=0;i<SINESIZE+5;i++)
- {f=3.1415926535*2.0*(((float)i)/((float)SINESIZE));
- w=15000.0*sin(f);
- UltraPokeData(basePort,i*2,w & 0x0f);
- UltraPokeData(basePort,i*2+1,w>>8);
- }
- }
-
- void doTone(char c)
- {struct toneDef *td;
- int i;
- volatile int timer=0;
- for (i=0;i<nmToneDefs && toneDef[i]->key!=c;i++) ;
- if (i==nmToneDefs)
- return;
- td=toneDef[i];
- globalTimers.addTimerExact(&timer,1);
- for (i=0;;i++)
- {switch (td->tcoms[i].tc)
- {case TC_TONESTART:
- UltraSetLinearVolume(td->tcoms[i].iParam1,masterVolume);
- UltraVoiceOn(td->tcoms[i].iParam1,0,0,2*SINESIZE-2,8+4,
- ((long)td->tcoms[i].iParam2)*((long)SINESIZE));
- break;
- case TC_TONEEND:
- UltraVoiceOff(td->tcoms[i].iParam1,1);
- break;
- case TC_WAIT:
- timer=td->tcoms[i].fParam*582.5422;
- while (timer) ;
- break;
- case TC_END:
- globalTimers.removeTimer(&timer);
- return;
- }
- }
- }
-
- void closeUltrasound(void)
- {UltraClose();
- }
-
- void printList(void)
- {int i;
- for (i=0;i<nmToneDefs;i++)
- {printf("%c - %-20s ",toneDef[i]->key,toneDef[i]->name);
- if (i%3==2)
- printf("\n");
- }
- printf("\n");
- printf(" ... and `x' to quit.\n");
- }
-
- void go(void)
- {char input[80],*c;
-
- while (1)
- {gotoxy(1,24);
- clreol();
- printf(">");
- input[0]=70;
- cgets(input);
- for (c=input+2;*c;c++)
- {if (*c=='x')
- return;
- doTone(*c);
- }
- }
- }
-
- void main(int argc, char **argv)
- {int i;
- char fname[40];
- clrscr();
- printf("Tone Master - v1.0\n");
- printf(" sine wave synthesis for the Gravis Ultrasound.\n");
- strcpy(fname,"tone.def");
- masterVolume=300;
- for (i=1;i<argc;i++)
- {if (argv[i][0]!='-' && argv[i][0]!='/')
- strcpy(fname,argv[i]);
- else
- {switch (argv[i][1])
- {case 'v':
- masterVolume=atoi(argv[i]+2);
- if (masterVolume<0) masterVolume=0;
- if (masterVolume>500) masterVolume=500;
- break;
- case '?':
- printf("Usage: %s [tone file] [-v# volume 0-500]\n",argv[0]);
- exit(0);
- break;
- }
- }
- }
- readToneFile(fname);
- setupUltrasound();
- printf("\n");
- printList();
- go();
- closeUltrasound();
- }
-
-