]> 4ch.mooo.com Git - 16.git/blob - src/lib/vgmsnd/main.c
wwww
[16.git] / src / lib / vgmsnd / main.c
1 #ifdef _WIN32\r
2 #ifdef _DEBUG\r
3 #include <crtdbg.h>\r
4 #endif\r
5 #endif\r
6 \r
7 #include <stdlib.h>\r
8 #include <stdio.h>\r
9 #include <string.h>\r
10 #include <ctype.h>      // for toupper()\r
11 \r
12 \r
13 #ifdef _WIN32\r
14 int __cdecl _getch(void);       // from conio.h\r
15 #else\r
16 #define _getch  getchar\r
17 #endif\r
18 \r
19 #include <common.h>\r
20 #include <audio/AudioStream.h>\r
21 #include <audio/AudioStream_SpcDrvFuns.h>\r
22 #include "vgmSndDrv.h"\r
23 #include "3812intf.h"\r
24 \r
25 \r
26 int main(int argc, char* argv[]);\r
27 static UINT32 FillBuffer(void* Params, UINT32 bufSize, void* Data);\r
28 void OPL2_Write(UINT8 reg, UINT8 data);\r
29 UINT8 OPL2_ReadStatus(void);\r
30 void EngineControlCUI(void);\r
31 \r
32 \r
33 #define VGM_SLOTS       4\r
34 \r
35 static void* audDrv;\r
36 static void* audDrvLog;\r
37 INT32 CHIP_SAMPLE_RATE;\r
38 VGM_FILE vgmFiles[VGM_SLOTS];\r
39 \r
40 int main(int argc, char* argv[])\r
41 {\r
42         UINT8 retVal;\r
43         UINT32 drvCount;\r
44         UINT32 idWavOut;\r
45         UINT32 idWavOutDev;\r
46         AUDDRV_INFO* drvInfo;\r
47         AUDIO_OPTS* opts;\r
48         \r
49         Audio_Init();\r
50         drvCount = Audio_GetDriverCount();\r
51         if (! drvCount)\r
52                 goto Exit_Deinit;\r
53         \r
54         idWavOut = 0;\r
55         idWavOutDev = 0;\r
56         Audio_GetDriverInfo(idWavOut, &drvInfo);\r
57         printf("Using driver %s.\n", drvInfo->drvName);\r
58         retVal = AudioDrv_Init(idWavOut, &audDrv);\r
59         if (retVal)\r
60         {\r
61                 printf("WaveOut: Drv Init Error: %02X\n", retVal);\r
62                 goto Exit_Deinit;\r
63         }\r
64         \r
65         opts = AudioDrv_GetOptions(audDrv);\r
66         opts->numChannels = 1;\r
67         opts->numBitsPerSmpl = 16;\r
68         CHIP_SAMPLE_RATE = opts->sampleRate;\r
69         \r
70         device_start_ym3812(0, 3579545);\r
71         device_reset_ym3812(0);\r
72         InitEngine();\r
73         \r
74         AudioDrv_SetCallback(audDrv, FillBuffer);\r
75         printf("Opening Device %u ...\n", idWavOutDev);\r
76         retVal = AudioDrv_Start(audDrv, idWavOutDev);\r
77         if (retVal)\r
78         {\r
79                 printf("Dev Init Error: %02X\n", retVal);\r
80                 goto Exit_DrvDeinit;\r
81         }\r
82         \r
83         /*getchar();\r
84         printf("Current Latency: %u ms\n", AudioDrv_GetLatency(audDrv));*/\r
85         EngineControlCUI();\r
86         \r
87         retVal = AudioDrv_Stop(audDrv);\r
88         \r
89 Exit_DrvDeinit:\r
90         DeinitEngine();\r
91         device_stop_ym3812(0);\r
92         AudioDrv_Deinit(&audDrv);\r
93 Exit_Deinit:\r
94         Audio_Deinit();\r
95         printf("Done.\n");\r
96         \r
97 #if _DEBUG\r
98         if (_CrtDumpMemoryLeaks())\r
99                 _getch();\r
100 #endif\r
101         \r
102         return 0;\r
103 }\r
104 \r
105 INT32 chipSmplL[1] = {0};\r
106 INT32 chipSmplR[1] = {0};\r
107 INT32* chipSmpls[2] = {chipSmplL, chipSmplR};\r
108 static UINT32 smplLastIrq = 0;\r
109 static UINT32 FillBuffer(void* Params, UINT32 bufSize, void* data)\r
110 {\r
111         UINT32 smplCount;\r
112         INT16* SmplPtr16;\r
113         UINT32 curSmpl;\r
114         INT32 chipSmplsFin;\r
115         \r
116         smplCount = bufSize / 2;\r
117         SmplPtr16 = (INT16*)data;\r
118         for (curSmpl = 0; curSmpl < smplCount; curSmpl ++)\r
119         {\r
120                 ym3812_stream_update(0, chipSmpls, 1);\r
121                 UpdateSoundEngine();\r
122                 smplLastIrq ++;\r
123                 \r
124                 chipSmplsFin = chipSmplL[0];\r
125                 \r
126 #if 0\r
127                 if ((curSmpl / (smplCount / 16)) < 15)\r
128                         chipSmplsFin += +0x0100;\r
129                 else\r
130                         chipSmplsFin += -0x0100;\r
131 #endif\r
132                 \r
133                 if (chipSmplsFin < -0x7FFF)\r
134                         chipSmplsFin = -0x7FFF;\r
135                 else if (chipSmplsFin > 0x7FFF)\r
136                         chipSmplsFin = 0x7FFF;\r
137                 SmplPtr16[curSmpl] = (INT16)chipSmplsFin;\r
138         }\r
139         return curSmpl * 2;\r
140 }\r
141 \r
142 \r
143 void OPL2_Write(UINT8 reg, UINT8 data)\r
144 {\r
145         ym3812_w(0, 0, reg);\r
146         ym3812_w(0, 1, data);\r
147         return;\r
148 }\r
149 \r
150 UINT8 OPL2_ReadStatus(void)\r
151 {\r
152         return ym3812_r(0, 0);\r
153 }\r
154 \r
155 \r
156 \r
157 INLINE UINT8 getVgmID(char vgmIdChar)\r
158 {\r
159         vgmIdChar = toupper(vgmIdChar);\r
160         if (vgmIdChar == 'M')\r
161                 return 0x00;\r
162         else if (vgmIdChar >= '0' && vgmIdChar < '0'+VGM_SLOTS)\r
163                 return (UINT8)(vgmIdChar - '0');\r
164         else\r
165                 return 0xFF;\r
166 }\r
167 \r
168 INLINE UINT8 getVgmChn(char vgmChnChar)\r
169 {\r
170         vgmChnChar = toupper(vgmChnChar);\r
171         if (vgmChnChar == 'M')\r
172                 return 0x7F;\r
173         else if (vgmChnChar >= '0' && vgmChnChar <= '9')\r
174                 return vgmChnChar - '0';\r
175         else\r
176                 return 0xFF;\r
177 }\r
178 \r
179 void EngineControlCUI(void)\r
180 {\r
181         VGM_FILE* tempVgmFile;\r
182         UINT8 curSFX;\r
183         char inLine[0x100];\r
184         char* tempStr;\r
185         int tempPos;\r
186         UINT8 vgmId;\r
187         UINT8 vgmChn;\r
188         UINT8 retVal;\r
189         \r
190         printf("Commands:\n");\r
191         printf("Ls File.vgm - Load File.vgm into Slot s\n");\r
192         printf("Pcs - Play Slot s on Channel c\n");\r
193         printf("Sc - Stop Channel c\n");\r
194         printf("S - Stop all SFX\n");\r
195         printf("E - Pause Music\n");\r
196         printf("R - Resume Music\n");\r
197         printf("Channels: M = music, 0-5 = SFX\n");\r
198         printf("Slots: M, 0-3 (M equals slot 0)\n");\r
199         \r
200         for (curSFX = 0; curSFX < VGM_SLOTS; curSFX ++)\r
201                 memset(&vgmFiles[curSFX], 0x00, sizeof(VGM_FILE));\r
202         \r
203         while(1)\r
204         {\r
205                 tempStr = fgets(inLine, 0x100, stdin);\r
206                 if (tempStr == NULL)\r
207                         break;\r
208                 tempPos = strlen(inLine);\r
209                 if (tempPos <= 1)\r
210                         break;\r
211                 inLine[tempPos-1] = '\0';\r
212                 \r
213                 switch(toupper(inLine[0]))\r
214                 {\r
215                 case 'L':       // load\r
216                         vgmId = getVgmID(inLine[1]);\r
217                         if (vgmId == 0xFF)\r
218                         {\r
219                                 printf("Wrong File Slot!\n");\r
220                                 break;\r
221                         }\r
222                         tempVgmFile = &vgmFiles[vgmId];\r
223                         FreeVGMFile(tempVgmFile);\r
224                         retVal = OpenVGMFile(inLine + 3, tempVgmFile);\r
225                         if (retVal > 0)\r
226                                 printf("Load Error 0x%02X\n", retVal);\r
227                         else\r
228                                 printf("VGM loaded into slot %d.\n", vgmId);\r
229                         break;\r
230                 case 'P':       // play\r
231                         vgmChn = getVgmChn(inLine[1]);\r
232                         vgmId = getVgmID(inLine[2]);\r
233                         if (vgmChn == 0xFF)\r
234                         {\r
235                                 printf("Wrong Channel!\n");\r
236                                 break;\r
237                         }\r
238                         if (vgmId == 0xFF)\r
239                         {\r
240                                 printf("Wrong File Slot!\n");\r
241                                 break;\r
242                         }\r
243                         tempVgmFile = &vgmFiles[vgmId];\r
244                         if (vgmChn == 0x7F)\r
245                                 PlayMusic(tempVgmFile);\r
246                         else\r
247                                 PlaySFX(tempVgmFile, vgmChn);\r
248                         break;\r
249                 case 'S':       // stop\r
250                         vgmChn = getVgmChn(inLine[1]);\r
251                         if (vgmChn == 0x7F)\r
252                                 StopMusic();\r
253                         else\r
254                                 StopSFX(vgmChn);\r
255                         break;\r
256                 case 'E':       // pause\r
257                         PauseMusic();\r
258                         break;\r
259                 case 'R':       // resume\r
260                         ResumeMusic();\r
261                         break;\r
262                 default:\r
263                         printf("Unknown Command!\n");\r
264                         break;\r
265                 }\r
266         }\r
267         \r
268         StopMusic();\r
269         StopSFX(0xFF);\r
270         for (curSFX = 0; curSFX < VGM_SLOTS; curSFX ++)\r
271                 FreeVGMFile(&vgmFiles[curSFX]);\r
272         \r
273         printf("Quit.\n");\r
274         _getch();\r
275         \r
276         return;\r
277 }\r