]> 4ch.mooo.com Git - 16.git/commitdiff
readded my old opl lib
authorsparky4 <sparky4@cock.li>
Wed, 15 Jul 2015 12:22:43 +0000 (07:22 -0500)
committersparky4 <sparky4@cock.li>
Wed, 15 Jul 2015 12:22:43 +0000 (07:22 -0500)
new file:   src/lib/opl2.c
new file:   src/lib/opl2.h

src/lib/opl2.c [new file with mode: 0644]
src/lib/opl2.h [new file with mode: 0644]

diff --git a/src/lib/opl2.c b/src/lib/opl2.c
new file mode 100644 (file)
index 0000000..d78ecb3
--- /dev/null
@@ -0,0 +1,304 @@
+/* C Source File: ADLIB *****************************************************\r
+\r
+Author:            Kevin A. Lee\r
+\r
+Last Amended:      27th March, 1993\r
+\r
+Description:        Low-level interface to the Adlib (or compatible)\r
+FM sound card. All information gleaned from\r
+Jeffrey S. Lee's "Programming the Adlib/Sound\r
+Blaster FM Music Chips". See Lee's document for\r
+further information.\r
+Compiled succesfully under Turbo C, Borland C++,\r
+and Microsoft Quick C (all latest versions).\r
+\r
+****************************************************************************/\r
+#include "src\lib\opl2.h"\r
+
+//sound てすと
+int sq = 0;
+\r
+/* Function: WriteFM ********************************************************\r
+*\r
+*     Parameters:        reg - which FM register to write to.\r
+*                         value - value to write.\r
+*\r
+*     Description:        writes a value to the specified register and\r
+*                         waits for the "official" recommended periods.\r
+*\r
+*/\r
+void WriteFM(int reg, int value){\r
+       int i;\r
+\r
+       outp(ADLIB_FM_ADDRESS, (byte)reg);                              /* set up the register  */\r
+       for (i = 0; i < 6; i++) inp(ADLIB_FM_ADDRESS);  /* wait 12 cycles      */\r
+       outp(ADLIB_FM_DATA, (byte)value);                                       /* write out the value */\r
+       for(i = 0; i < 35; i++) inp(ADLIB_FM_ADDRESS);  /* wait 84 cycles      */\r
+} /* End of WriteFM */\r
+\r
+/* Function: ReadFM *********************************************************\r
+*\r
+*     Returns:            the value in the status register.\r
+*\r
+*     Description:        return a value in the status register.\r
+*\r
+*/\r
+int ReadFM(void){\r
+       return(inp(ADLIB_FM_ADDRESS));\r
+} /* End of ReadFM */\r
+\r
+/* Function: AdlibExists ****************************************************\r
+*\r
+*     Returns:            1 (true) if an Adlib compatible sound card\r
+*                         is present, else 0 (false).\r
+*\r
+*     Description:        determines whether an Adlib (or compatible)\r
+*                         sound card is present.\r
+*\r
+*/\r
+int AdlibExists(void){\r
+       int stat1, stat2;\r
+\r
+       WriteFM(0x04, 0x60);            /* reset both timers        */\r
+       WriteFM(0x04, 0x80);            /* enable timer interrupts  */\r
+       stat1 = ReadFM();                       /* read status register     */\r
+       WriteFM(0x02, 0xFF);\r
+       WriteFM(0x04, 0x21);            /* start timer 1            */\r
+//     wait(80);                               /* could do something useful*/\r
+       stat2 = ReadFM();                       /* read status register     */\r
+       WriteFM(0x04, 0x60);            /* reset both timers        */\r
+       WriteFM(0x04, 0x80);            /* enable timer interrupts  */\r
+\r
+       if(((stat1 & 0xE0) == 0x00) && ((stat2 & 0xE0) == 0xC0)) return(1);\r
+       return(0);\r
+} /* End of AdlibExists */\r
+\r
+/* Function: FMResest *******************************************************\r
+*\r
+*     Description:        quick and dirty sound card reset (zeros all\r
+*                         registers).\r
+*\r
+*/\r
+void FMReset(void/*int percusiveMode*/){\r
+       int i;\r
+\r
+       /* zero all registers */\r
+       for(i = MIN_REGISTER; i < MAX_REGISTER+1; i++) WriteFM(i, 0);\r
+\r
+       /* allow FM chips to control the waveform of each operator */\r
+       WriteFM(0x01, 0x20);\r
+\r
+       /* set rhythm enabled (6 melodic voices, 5 percussive) */\r
+       WriteFM(0xBD, 0x20);\r
+\r
+       //FMSetPercusiveMode(percusiveMode);\r
+} /* End of FMReset */\r
+/*\r
+void FMSetPercusiveMode(int state){\r
+       if(state){\r
+               WriteFM(0xBD, 0x20);\r
+               currentBDContents = 0x20;\r
+               percussiveMode = 1;\r
+               voiceModulator[7] = 16;\r
+               voiceModulator[8] = 14;\r
+               // we have to set the freq of voice 7 & 8 for the white noise gen.\r
+               // these frequency choices could certainly be better\r
+               WriteFM(0xa7, 1844 & 0xff);\r
+               WriteFM(0xb7, 1844 >> 8);\r
+               WriteFM(0xa8, 3764 & 0xff);\r
+               WriteFM(0xb8, 3764 >> 8);\r
+       }else{\r
+               WriteFM(0xBD, 0);\r
+               percussiveMode = 0;\r
+               currentBDContents = 0;\r
+               voiceModulator[7] = 13;\r
+               voiceModulator[8] = 14;\r
+       }\r
+}\r
+*/\r
+/* Function: FMKeyOff *******************************************************\r
+*\r
+*     Parameters:        voice - which voice to turn off.\r
+*\r
+*     Description:        turns off the specified voice.\r
+*\r
+*/\r
+void FMKeyOff(int voice){\r
+       int regNum;\r
+\r
+       /* turn voice off */\r
+       regNum = 0xB0 + voice % NUMVOICE;\r
+       WriteFM(regNum, 0x0E);\r
+} /* End of FMKeyOff */\r
+\r
+/* Function: FMKeyOn *******************************************************\r
+*\r
+*     Parameters:        voice - which voice to turn on.\r
+*                         freq - its frequency (note).\r
+*                         octave - its octave.\r
+*\r
+*     Description:        turns on a voice of specfied frequency and\r
+*                         octave.\r
+*\r
+*/\r
+void FMKeyOn(int voice, int freq, int octave){\r
+       int regNum, tmp;\r
+\r
+       regNum = 0xA0 + voice % NUMVOICE;\r
+       WriteFM(regNum, freq & 0xff);\r
+       regNum = 0xB0 + voice % NUMVOICE;\r
+       tmp = (freq >> 8) | (octave << 2) | 0x20;
+       WriteFM(regNum, tmp);\r
+} /* End of FMKeyOn */\r
+\r
+/* Function: FMVoiceVolume **************************************************\r
+*\r
+*     Parameters:        voice - which voice to set volume of\r
+*                         vol - new volume value (experiment).\r
+*\r
+*     Description:        sets the volume of a voice to the specified\r
+*                         value in the range (0-63)?\r
+*\r
+*/\r
+void FMVoiceVolume(int voice, int vol){\r
+       int regNum;\r
+\r
+       regNum = 0x40 + voice % NUMVOICE;\r
+       WriteFM(regNum, vol);\r
+} /* End of FMVoiceVolume */\r
+\r
+/* Function: FMSetVoice *****************************************************\r
+*\r
+*     Parameters:        voiceNum - which voice to set.\r
+*                         ins - instrument to set voice.\r
+*\r
+*     Description:        sets the instrument of a voice.\r
+*\r
+*/\r
+void FMSetVoice(int voiceNum, FMInstrument *ins){\r
+       int opCellNum, cellOffset;\r
+\r
+       voiceNum %= NUMVOICE;\r
+       cellOffset = voiceNum % 3 + ((voiceNum / 3) << 3);\r
+\r
+       /* set sound characteristic */\r
+       opCellNum = 0x20 + (char)cellOffset;\r
+       WriteFM(opCellNum, ins->SoundCharacteristic[0]);\r
+       opCellNum += 3;\r
+       WriteFM(opCellNum, ins->SoundCharacteristic[1]);\r
+\r
+       /* set level/output */\r
+       opCellNum = 0x40 + (char)cellOffset;\r
+       WriteFM(opCellNum, ins->Level[0]);\r
+       opCellNum += 3;\r
+       WriteFM(opCellNum, ins->Level[1]);\r
+\r
+       /* set Attack/Decay */\r
+       opCellNum = 0x60 + (char)cellOffset;\r
+       WriteFM(opCellNum, ins->AttackDecay[0]);\r
+       opCellNum += 3;\r
+       WriteFM(opCellNum, ins->AttackDecay[1]);\r
+\r
+       /* set Sustain/Release */\r
+       opCellNum = 0x80 + (char)cellOffset;\r
+       WriteFM(opCellNum, ins->SustainRelease[0]);\r
+       opCellNum += 3;\r
+       WriteFM(opCellNum, ins->SustainRelease[1]);\r
+\r
+       /* set Wave Select */\r
+       opCellNum = 0xE0 + (char)cellOffset;\r
+       WriteFM(opCellNum, ins->WaveSelect[0]);\r
+       opCellNum += 3;\r
+       WriteFM(opCellNum, ins->WaveSelect[1]);\r
+\r
+       /* set Feedback/Selectivity */\r
+       opCellNum = (byte)0xC0 + (byte)voiceNum;\r
+       WriteFM(opCellNum, ins->Feedback);\r
+} /* End of FMSetVoice */\r
+\r
+/* Function: LoadSBI ********************************************************\r
+*\r
+*     Parameters:        fileName - name of .SBI file.\r
+*                         ins - variable to place data in.\r
+*\r
+*     Description:        loads a .SBI into the instrument structure.\r
+*\r
+*/\r
+//int LoadSBI(char fileName[], FMInstrument *ins){\r
+//  int i;\r
+//  FILE *fp;\r
+//  size_t structSize = sizeof(FMInstrument);\r
+//\r
+//  if ((fp = fopen(fileName, "rb")) == NULL) return (0);\r
+//\r
+//  /* skip the header - or do we? */\r
+//  for (i = 0; i < 36; i++) fgetc(fp);\r
+//\r
+//  /* read the data */\r
+//  fread(ins, structSize, 1, fp);\r
+//\r
+//  fclose(fp);\r
+//  return (1);\r
+//} /* End of LoadSBI */\r
+
+unsigned short Notes[] = {\r
+        19327 ,        /* C b            */\r
+        18242 ,        /* C              */\r
+        17218 ,        /* C #   ( D b )  */\r
+        16252 ,        /* D              */\r
+        15340 ,        /* D #   ( E b )  */\r
+        14479 ,        /* E     ( F b )  */\r
+        13666 ,        /* F     ( E # )  */\r
+        12899 ,        /* F #   ( G b )  */\r
+        12175 ,        /* G              */\r
+        11492 ,        /* G #   ( A b )  */\r
+        10847 ,        /* A              */\r
+        10238 ,        /* A #   ( B b )  */\r
+        9664 ,         /* B     ( C b )  */\r
+        9121 ,         /* B #            */\r
+        0\r
+};
+\r
+/* test of the routines */\r
+void fmtest(){\r
+       enum SCALE test[] = { D4, E4, F4, G4, A4, B4, C4 };\r
+//     enum SCALE oct4[] = { 493.88, 466.16, 440, 415.3, 392, 369.99, 349.23, 329.63, 311.13, 293.66, 277.18, 261.63 };\r
+       static FMInstrument testInst =\r
+{\r
+0x00, 0x01,    /* modulator frequency multiple... 0x20 */\r
+0x00, 0x00,    /* modulator frequency level...    0x40 */\r
+0xF0, 0xF0,    /* modulator attack/decay...       0x60 */\r
+0x73, 0x73,    /* modulator sustain/release...    0x80 */\r
+0x03, 0x00,    /* output waveform distortion      0xE0 */\r
+0x36,                          /* feedback algorithm and strength 0xC0 */\r
+};\r
+       int i;\r
+       printf("Now testing tune....\n");\r
+//     printf("just hit any key 7 times.\n");\r
+       FMReset();\r
+       FMSetVoice(0, &testInst);
+       //extra
+//     WriteFM(0xB0, 0x09);
+//     WriteFM(0xB3, 0x07);
+       //extra
+       for(i = 0; i < 7; i++){\r
+               FMKeyOn(0, test[i], 4);
+               sound(test[i]);\r
+               wait(20);\r
+//             getche();
+               FMKeyOff(0);
+               nosound();\r
+               wait(1);\r
+       }\r
+}
+
+//sound てすと
+int soundtest(){
+       enum SCALE test[] = { D4, E4, F4, G4, A4, B4, C4 };\r
+       //FMKeyOn(0, test[sq], 4);
+       if(sq < 7){\r
+               sq++;\r
+       }else sq = 0;
+       FMKeyOff(0);
+       return sq;
+}
\ No newline at end of file
diff --git a/src/lib/opl2.h b/src/lib/opl2.h
new file mode 100644 (file)
index 0000000..5c0a1cf
--- /dev/null
@@ -0,0 +1,101 @@
+#ifndef _DOSLIB_SND_H_\r
+#define _DOSLIB_SND_H_\r
+/* C Header File: ADLIB *****************************************************\r
+\r
+Author:   Kevin A. Lee\r
+\r
+Last Amended: 27th April, 1993\r
+\r
+Description:    Low-level interface to the Adlib (or compatible)\r
+    FM sound card. All information gleaned from\r
+    Jeffrey S. Lee's "Programming the Adlib/Sound\r
+    Blaster FM Music Chips". See Lee's document for\r
+    further information.\r
+\r
+Compiled succesfully under Turbo C, Borland C++,\r
+and Microsoft Quick C (all latest versions).\r
+\r
+****************************************************************************/\r
+#include "src\lib\lib_com.h"\r
+\r
+#define NUMVOICE 11\r
+#define FACTOR  1193180\r
+#define OCTAVE  4
+\r
+#define MIN_REGISTER                   0x01\r
+#define MAX_REGISTER                   0xF5\r
+#define ADLIB_FM_ADDRESS       0x388   /* adlib address/status register */\r
+#define ADLIB_FM_DATA          0x389   /* adlib data register           */\r
+\r
+/*\r
+static int percussiveMode = 0,currentBDContents = 0;\r
+//static int opTable[18] = {0,1,2,3,4,5,8,9,10,11,12,13,16,17,18,19,20,21};\r
+static int voiceModulator[11] = {0,1,2,6,7,8,12,16,14,17,13};\r
+static int voiceCarrier[9] = {3,4,5,9,10,11,15,16,17};\r
+*/\r
+\r
+/*\r
+* FM Instrument definition for .SBI files - SoundBlaster instrument\r
+* - these are the important parts - we will skip the header, but since\r
+*   I am not sure where it starts and ends so I have had to guess.\r
+*   However it SEEMS! to work. Each array has two values, one for\r
+*   each operator.\r
+*/\r
+typedef struct{\r
+       byte SoundCharacteristic[2];    /* modulator frequency multiple...  */\r
+       byte Level[2];                  /* modulator frequency level...     */\r
+       byte AttackDecay[2];            /* modulator attack/decay...        */\r
+       byte SustainRelease[2];         /* modulator sustain/release...     */\r
+       byte WaveSelect[2];             /* output waveform distortion       */\r
+       byte Feedback;                  /* feedback algorithm and strength  */\r
+} FMInstrument;\r
+\r
+/*\r
+* Enumerated F-Numbers (in octave 4) for the chromatic scale.\r
+*/\r
+/*enum oct{\r
+       B4 = 493.88,\r
+       B4b = 466.16,\r
+       A4 = 440,\r
+       A4b = 415.3,\r
+       G4 = 392,\r
+       G4b = 369.99,\r
+       F4 = 349.23,\r
+       E4 = 329.63,\r
+       E4b = 311.13,\r
+       D4 = 293.66,\r
+       D4b = 277.18,\r
+       C4 = 261.63,\r
+       A0 = 27.50\r
+};*/\r
+enum SCALE{\r
+       B4  = 0x1EE,\r
+       B4b = 0x1D2,\r
+       A4  = 440,\r
+       A4b = 0x19F,\r
+       G4 = 0x188,\r
+       G4b  = 0x172,\r
+       F4  = 0x15D,\r
+       E4  = 0x14A,\r
+       E4b  = 0x137,\r
+       D4  = 0x126,\r
+       D4b = 0x115,\r
+       C4  = 0x106,\r
+       A0 = 0x7F2\r
+};
+\r
+/* function prototyping */\r
+void WriteFM(int reg, int value);\r
+int ReadFM(void);\r
+int AdlibExists(void);\r
+void FMReset(/*int percusiveMode*/);   /* Resets the card, quiets all voices, sets the percussive mode state */\r
+void FMKeyOff(int voice);\r
+void FMKeyOn(int voice, int freq, int octave);\r
+void FMVoiceVolume(int voice, int vol);\r
+void FMSetVoice(int voiceNum, FMInstrument *ins);\r
+/* Remember: percussion instruments must be assigned only to the correct voice number. */\r
+//void FMSetPercusiveMode(int state);\r
+//int  LoadSBI(char filename[], FMInstrument *ins);\r
+void fmtest(void);
+int soundtest();\r
+#endif/*_DOSLIB_SND_H_*/
\ No newline at end of file