home *** CD-ROM | disk | FTP | other *** search
/ TAP YIPL / TAP_and_YIPL_Collection_CD.iso / PHREAK / BOXES / EUROBBOX.ZIP / PCM.C < prev    next >
C/C++ Source or Header  |  1992-03-31  |  7KB  |  269 lines

  1. /* compact memory model */
  2.  
  3. #include <stdio.h>
  4. #include <io.h>
  5. #include <dos.h>
  6. #include <fcntl.h>
  7. #include <math.h>
  8. #include <alloc.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11.  
  12. #define PI             3.14159265358979323
  13.  
  14. #define TIMER0CLOCK 1193182L    /* Grundfreqenz des Timerbausteins */
  15. #define TIMER0DIV     70            /* divisor für timer 0 : sample time=30/CLOCK_FREQ = 25.1 uSec */
  16.  
  17. FILE *fpspeich;                    /* zur sofortigen speicherung des PCM-files */
  18. int portadr;                    /* printer port adresse */
  19. #define MAXARRAY 65000            /* maximale an Bytes im abspielfeld */
  20. #define MAXFIELDS 4                /* anzahl an abspielfeldern */
  21. long anzahl;                    /* anzahl im momentanen abspielfeld */
  22. long anzahlfeld[MAXFIELDS];        /* anzahl von zeichen die noch zu spielen sind (pro abspielfeld)*/
  23. char *memadr[MAXFIELDS];        /* zeiger auf alle die apspielfelder */
  24. long tmpanzahlfeld[MAXFIELDS];    /* feld um nur einzelne Stuecke abzuspielen */
  25. char *tmpmemadr[MAXFIELDS];     /* feld um nur einzelne Stuecke abzuspielen */
  26. char *memadr2;                    /* zeiger auf das naechste anzuspielende byte */
  27.  
  28. void interrupt (*old_vec)();    /* Adresse der alten Timerseviceroutine */
  29. void interrupt tic_once();        /* prototyp der abspielroutine */
  30.  
  31. void
  32. wave(f1, f2, tone)
  33. unsigned int f1, f2;    /* zwei freqenzen die sich ueberlagern */
  34. unsigned int tone;        /* dauer in mSekunden */
  35. {
  36.     double dt, dauer;
  37.     double freqtime;
  38.  
  39.     dt = (double)TIMER0DIV/(double)TIMER0CLOCK;    /* dauer eines abtastzeitpunktes */
  40.     dauer = (double)tone/(double)1000;
  41.     for (freqtime = 0; freqtime < dauer; freqtime += dt) {
  42.         if (f1 == 0  &&  f2 == 0)   tone = 0x80;
  43.         else   tone = 64   *   (2  +  (sin(2*PI*freqtime*f1) + sin (2*PI*freqtime*f2)));
  44.         if (tone >= 256)   tone = 255;
  45.         if (tone < 0)   tone = 0;
  46.         fputc(tone, fpspeich);
  47.     }
  48. }
  49.  
  50. void
  51. playtone()
  52. {
  53.     int i;
  54.     char old_0x21;
  55.  
  56.     disable();                    /* alle interrupts abschalten */
  57.  
  58.     old_vec = getvect(0x08);    /* alte Timerserviceroutine retten */
  59.     setvect(0x08, tic_once);    /* timerserviceroutine auf ton abspielen setzen */
  60.  
  61.     outportb(0x43, 0x14);        /* setzen der neuen abtastgeschwindigkeit */
  62.     outportb(0x40, TIMER0DIV);
  63.  
  64.     old_0x21 = inportb(0x21);    /* interrupt maske holen */
  65.     outportb(0x21, 0xFE);        /* nur Timer 0 einschalten */
  66.  
  67.     enable();                    /* jetzt gehts los  */
  68.  
  69.     for (i = 0; i < MAXFIELDS; i++) {    /* alle abspielfelder abspielen */
  70.         anzahl = tmpanzahlfeld[i];
  71.         memadr2 = tmpmemadr[i];
  72.         while (anzahl > 0L)   ;        /* warten bis alles ausgesendet wurde */
  73.     }
  74.  
  75.     disable();                    /* wieder keine Interrupts */
  76.  
  77.     outportb(0x21, old_0x21);    /* alte interrupt maske restaurieren */
  78.  
  79.     outportb(0x43, 0x34);        /* Timer0 wieder auf uebliche Zeitbasis (18.2Sekunden stellen */
  80.     outportb(0x40, 0x68);
  81.     outportb(0x40, 0xFF);
  82.  
  83.     setvect(0x08, old_vec);        /* alte timerserviceroutine wiederherstellen */
  84.  
  85.     enable();                    /* nun wieder normales don mit normalen interrupts */
  86. }
  87.  
  88. void interrupt tic_once()
  89. {
  90.     outportb(portadr, *memadr2);    /* ausgabe des neuen pcm-wertes */
  91.     memadr2++;
  92.     anzahl--;                       /* anzahl verringern */
  93.     outportb(0x20,0x20);            /* end of interrupt klarmachen */
  94. }
  95.  
  96. void readpcm(str)
  97. char *str;
  98. {
  99.     int i;
  100.     FILE *fp;
  101.  
  102.     fp = fopen(str, "rb");
  103.     if (fp != NULL) {
  104.         for (i = 0; i < MAXFIELDS; i++) {
  105.             if (anzahlfeld[i] == 0L) {    /* leeres Feld also File einlesen */
  106.                 while (anzahlfeld[i] < MAXARRAY  &&  !feof(fp)) {
  107.                     memadr[i][anzahlfeld[i]] = fgetc(fp);
  108.                     anzahlfeld[i]++;
  109.                 };
  110.             }
  111.         }
  112.         fclose(fp);
  113.     }
  114. }
  115.  
  116. void playfields()
  117. {
  118.     int i, j;
  119.     printf("-\nPCM-Playmodus...bitte File auswaehlen\n\n");
  120.     j = 0;
  121.     for (i = 0; i < MAXFIELDS; i++) {
  122.         if (anzahlfeld[i] > 0L  &&  (anzahlfeld[i] < MAXARRAY  ||  j == 0)) {
  123.             printf("File:%d\n", i+1);
  124.             j = 0;
  125.         }
  126.         if (anzahlfeld[i] >= MAXARRAY)   j = 1;
  127.     }
  128.     printf("Q = Quit\n");
  129.     do {
  130.  
  131.         for (i = 0; i < MAXFIELDS; i++) {    /* tmpfeld zuruecksetzen */
  132.             tmpanzahlfeld[i] = 0L;
  133.             tmpmemadr[i] = memadr[i];
  134.         }
  135.  
  136.         while(bioskey(1) == 0);
  137.  
  138.         i = bioskey(0);        /* taste einlesen */
  139.         if ((char)i == 'Q'  ||  (char)i == 'q')   return;
  140.         i = (char)i-49;
  141.         if (i < 0)   i = 0;
  142.         if (i >= MAXFIELDS)   i = MAXFIELDS-1;
  143.  
  144.         do {    /* nur das abzuspielende Feld einblenden */
  145.             tmpanzahlfeld[i] = anzahlfeld[i];
  146.             if (anzahlfeld[i] < MAXARRAY)   break;
  147.             i++;
  148.         } while (i < MAXFIELDS);
  149.         printf("playing... %d\r",i+1);
  150.                 fflush(stdout);
  151.         playtone();    /* Feld abspielen */
  152.         printf("             \r");
  153.                 fflush(stdout);
  154.     } while (42);
  155. }
  156.  
  157.  
  158. void main(argc, argv)
  159. int argc;
  160. char *argv[];
  161. {
  162.     char fstr2[80], fstr3[80];
  163.     char playfile[MAXFIELDS][80];
  164.     char string[80];
  165.     unsigned long anz;
  166.     FILE *fp;
  167.     int n, l, s, m, i, j, k;
  168.  
  169.     n = l = s = m = 0;
  170.     portadr = 0x378;
  171.     if (argc <= 1) {
  172.         printf("PCM-Soundprogramm (c) 1991 bei Hacko\n\n");
  173.         printf("-1 oder -2 oder -3 um dem Printerport festzulegen\n");
  174.         printf("-sX = schreiben PCM-File, wobei X der Name der Datei ist\n");
  175.         printf("-lX = lesen PCM-File, wobei X der Name der Dabei ist\n");
  176.         printf("-mX = Makrodatei auswerten und berechnen, wobei X der Name der Datei ist\n");
  177.         printf("      in jeder Zeile der Makrodatei steht 'f1 f2 t' wobei:\n");
  178.         printf("      f1 = Frequenz Nummer1\n");
  179.         printf("      f2 = Frequenz Nummer2\n");
  180.         printf("      t  = Dauer in m Sekunden\n");
  181.         printf("-n  = keinen Sound ausgeben (nur Sound berechnen)\n");
  182.         exit(0);
  183.     }
  184.  
  185.     for (i = 0; i < MAXFIELDS; i++) {    /* spielfiles init */
  186.         playfile[i][0] = '\0';
  187.     }
  188.  
  189.     for (i = 1; i < argc; i++) {        /* komandozeilen auswertung */
  190.         if (argv[i][0] == '-') {
  191.             if (argv[i][1] == '2') {
  192.                 portadr = 0x278;
  193.             }
  194.             if (argv[i][1] == '3') {
  195.                 portadr = 0x3BC;
  196.             }
  197.             if (argv[i][1] == 'n') {
  198.                 n = 1;
  199.             }
  200.             if (argv[i][1] == 'l') {
  201.                 if (l+1 <= MAXFIELDS) {
  202.                     strcpy(playfile[l], &argv[i][2]);
  203.                     l++;
  204.                 }
  205.             }
  206.             if (argv[i][1] == 's') {
  207.                 s = 1;
  208.                 strcpy(fstr2, &argv[i][2]);
  209.             }
  210.             if (argv[i][1] == 'm') {
  211.                 m = 1;
  212.                 strcpy(fstr3, &argv[i][2]);
  213.             }
  214.         }
  215.     }
  216.  
  217.     if ((l >= 1  &&  s == 1) || (l == 0  &&  m == 0)) {
  218.         exit(0);
  219.     }
  220.  
  221.     if (m == 1) {    /* makrofile lesen */
  222.         fp = fopen(fstr3, "r");
  223.         if (s == 1) {
  224.             fpspeich = fopen(fstr2, "wb");
  225.         } else {
  226.             fpspeich = fopen("tmp.pcm", "wb");
  227.         }
  228.         printf("PCM-Berechnungsmodus...bitte warten\n");
  229.         if (fp != NULL  &&  fpspeich != NULL) {
  230.             memadr2 = memadr;
  231.             do {
  232.                 i = j = k = 0;
  233.                 fscanf(fp, "%d %d %d\n", &i, &j, &k);
  234.                 printf("freq1=%d Hz / freq2=%d Hz / timing=%d ms          \r", i, j, k);
  235.                 fflush(stdout);
  236.                 wave(i, j, k);
  237.             } while(!feof(fp));
  238.             fclose(fp);
  239.             fclose(fpspeich);
  240.         }
  241.         printf("Berechnung beendet.                            \n");
  242.     }
  243.  
  244.     if (n == 0) {    /* abspielen der tonfolge */
  245.         if (l >= 1)    ;
  246.         else if (s == 1)   strcpy(playfile[0], fstr2);
  247.         else   strcpy(playfile[0], "tmp.pcm");
  248.  
  249.         for (i = 0; i < MAXFIELDS; i++) {    /* felder init */
  250.             memadr[i] = malloc(MAXARRAY);
  251.             if (memadr[i] == NULL) {
  252.                 printf("kein Speicher mehr da");
  253.                 exit(0);
  254.             }
  255.             anzahlfeld[i] = 0L;
  256.         }
  257.  
  258.         for (i = 0; i < MAXFIELDS; i++) {    /* files einlesen */
  259.             if (strlen(playfile[i]) >= 1)   readpcm(playfile[i]);
  260.         }
  261.  
  262.         playfields();
  263.  
  264.         for (i = 0; i < MAXFIELDS; i++) {    /* felder wieder los werden */
  265.             free(memadr[i]);
  266.         }
  267.     }
  268. }
  269.