Mercurial > audlegacy
comparison Plugins/Input/sid/xs_sidplay1.cc @ 269:1b82a9932b60 trunk
[svn] Import sid plugin. Ported from XMMS by giacomo.
author | chainsaw |
---|---|
date | Thu, 08 Dec 2005 15:12:12 -0800 |
parents | |
children | f12d7e208b43 |
comparison
equal
deleted
inserted
replaced
268:1368faba73c9 | 269:1b82a9932b60 |
---|---|
1 /* | |
2 XMMS-SID - SIDPlay input plugin for X MultiMedia System (XMMS) | |
3 | |
4 libSIDPlay v1 support | |
5 | |
6 Programmed and designed by Matti 'ccr' Hamalainen <ccr@tnsp.org> | |
7 (C) Copyright 1999-2005 Tecnic Software productions (TNSP) | |
8 | |
9 This program is free software; you can redistribute it and/or modify | |
10 it under the terms of the GNU General Public License as published by | |
11 the Free Software Foundation; either version 2 of the License, or | |
12 (at your option) any later version. | |
13 | |
14 This program is distributed in the hope that it will be useful, | |
15 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 GNU General Public License for more details. | |
18 | |
19 You should have received a copy of the GNU General Public License | |
20 along with this program; if not, write to the Free Software | |
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
22 */ | |
23 #include "xmms-sid.h" | |
24 | |
25 #ifdef HAVE_SIDPLAY1 | |
26 | |
27 #include "xs_sidplay1.h" | |
28 #include <stdio.h> | |
29 #include "xs_config.h" | |
30 #include "xs_length.h" | |
31 #include "xs_title.h" | |
32 | |
33 #include <sidplay/player.h> | |
34 #include <sidplay/myendian.h> | |
35 #include <sidplay/fformat.h> | |
36 | |
37 | |
38 typedef struct | |
39 { | |
40 emuEngine *currEng; | |
41 emuConfig currConfig; | |
42 sidTune *currTune; | |
43 } t_xs_sidplay1; | |
44 | |
45 | |
46 /* We need to 'export' all this pseudo-C++ crap */ | |
47 extern "C" | |
48 { | |
49 | |
50 | |
51 /* Check if we can play the given file | |
52 */ | |
53 gboolean xs_sidplay1_isourfile(gchar * pcFilename) | |
54 { | |
55 sidTune *testTune = new sidTune(pcFilename); | |
56 | |
57 if (!testTune) return FALSE; | |
58 | |
59 if (!testTune->getStatus()) { | |
60 delete testTune; | |
61 return FALSE; | |
62 } | |
63 | |
64 delete testTune; | |
65 return TRUE; | |
66 } | |
67 | |
68 | |
69 /* Initialize SIDPlay1 | |
70 */ | |
71 gboolean xs_sidplay1_init(t_xs_status * myStatus) | |
72 { | |
73 gint tmpFreq; | |
74 t_xs_sidplay1 *myEngine; | |
75 assert(myStatus); | |
76 | |
77 /* Allocate internal structures */ | |
78 myEngine = (t_xs_sidplay1 *) g_malloc0(sizeof(t_xs_sidplay1)); | |
79 if (!myEngine) return FALSE; | |
80 | |
81 /* Initialize engine */ | |
82 myEngine->currEng = new emuEngine(); | |
83 if (!myEngine->currEng) { | |
84 XSERR("Could not initialize libSIDPlay1 emulation engine\n"); | |
85 g_free(myEngine); | |
86 return FALSE; | |
87 } | |
88 | |
89 /* Verify endianess */ | |
90 if (!myEngine->currEng->verifyEndianess()) { | |
91 XSERR("Endianess verification failed\n"); | |
92 delete myEngine->currEng; | |
93 g_free(myEngine); | |
94 return FALSE; | |
95 } | |
96 | |
97 myStatus->sidEngine = myEngine; | |
98 | |
99 /* Get current configuration */ | |
100 myEngine->currEng->getConfig(myEngine->currConfig); | |
101 | |
102 /* Configure channel parameters */ | |
103 switch (myStatus->audioChannels) { | |
104 | |
105 case XS_CHN_AUTOPAN: | |
106 myEngine->currConfig.channels = SIDEMU_STEREO; | |
107 myEngine->currConfig.autoPanning = SIDEMU_CENTEREDAUTOPANNING; | |
108 myEngine->currConfig.volumeControl = SIDEMU_FULLPANNING; | |
109 break; | |
110 | |
111 case XS_CHN_STEREO: | |
112 myEngine->currConfig.channels = SIDEMU_STEREO; | |
113 myEngine->currConfig.autoPanning = SIDEMU_NONE; | |
114 myEngine->currConfig.volumeControl = SIDEMU_NONE; | |
115 break; | |
116 | |
117 case XS_CHN_MONO: | |
118 default: | |
119 myEngine->currConfig.channels = SIDEMU_MONO; | |
120 myEngine->currConfig.autoPanning = SIDEMU_NONE; | |
121 myEngine->currConfig.volumeControl = SIDEMU_NONE; | |
122 myStatus->audioChannels = XS_CHN_MONO; | |
123 break; | |
124 } | |
125 | |
126 | |
127 /* Memory mode settings */ | |
128 switch (xs_cfg.memoryMode) { | |
129 case XS_MPU_TRANSPARENT_ROM: | |
130 myEngine->currConfig.memoryMode = MPU_TRANSPARENT_ROM; | |
131 break; | |
132 | |
133 case XS_MPU_PLAYSID_ENVIRONMENT: | |
134 myEngine->currConfig.memoryMode = MPU_PLAYSID_ENVIRONMENT; | |
135 break; | |
136 | |
137 case XS_MPU_BANK_SWITCHING: | |
138 default: | |
139 myEngine->currConfig.memoryMode = MPU_BANK_SWITCHING; | |
140 xs_cfg.memoryMode = XS_MPU_BANK_SWITCHING; | |
141 break; | |
142 } | |
143 | |
144 | |
145 /* Audio parameters sanity checking and setup */ | |
146 myEngine->currConfig.bitsPerSample = myStatus->audioBitsPerSample; | |
147 tmpFreq = myStatus->audioFrequency; | |
148 | |
149 if (myStatus->oversampleEnable) { | |
150 if ((tmpFreq * myStatus->oversampleFactor) > SIDPLAY1_MAX_FREQ) { | |
151 myStatus->oversampleEnable = FALSE; | |
152 } else { | |
153 tmpFreq = (tmpFreq * myStatus->oversampleFactor); | |
154 } | |
155 } else { | |
156 if (tmpFreq > SIDPLAY1_MAX_FREQ) | |
157 tmpFreq = SIDPLAY1_MAX_FREQ; | |
158 } | |
159 | |
160 myEngine->currConfig.frequency = tmpFreq; | |
161 | |
162 switch (myStatus->audioBitsPerSample) { | |
163 case XS_RES_8BIT: | |
164 switch (myStatus->audioFormat) { | |
165 case FMT_S8: | |
166 myStatus->audioFormat = FMT_S8; | |
167 myEngine->currConfig.sampleFormat = SIDEMU_SIGNED_PCM; | |
168 break; | |
169 | |
170 case FMT_U8: | |
171 default: | |
172 myStatus->audioFormat = FMT_U8; | |
173 myEngine->currConfig.sampleFormat = SIDEMU_UNSIGNED_PCM; | |
174 break; | |
175 } | |
176 break; | |
177 | |
178 case XS_RES_16BIT: | |
179 default: | |
180 switch (myStatus->audioFormat) { | |
181 case FMT_U16_NE: | |
182 case FMT_U16_LE: | |
183 case FMT_U16_BE: | |
184 myStatus->audioFormat = FMT_U16_NE; | |
185 myEngine->currConfig.sampleFormat = SIDEMU_UNSIGNED_PCM; | |
186 break; | |
187 | |
188 case FMT_S16_NE: | |
189 case FMT_S16_LE: | |
190 case FMT_S16_BE: | |
191 default: | |
192 myStatus->audioFormat = FMT_S16_NE; | |
193 myEngine->currConfig.sampleFormat = SIDEMU_SIGNED_PCM; | |
194 break; | |
195 } | |
196 break; | |
197 } | |
198 | |
199 /* Clockspeed settings */ | |
200 switch (xs_cfg.clockSpeed) { | |
201 case XS_CLOCK_NTSC: | |
202 myEngine->currConfig.clockSpeed = SIDTUNE_CLOCK_NTSC; | |
203 break; | |
204 | |
205 case XS_CLOCK_PAL: | |
206 default: | |
207 myEngine->currConfig.clockSpeed = SIDTUNE_CLOCK_PAL; | |
208 xs_cfg.clockSpeed = XS_CLOCK_PAL; | |
209 break; | |
210 } | |
211 | |
212 myEngine->currConfig.forceSongSpeed = xs_cfg.forceSpeed; | |
213 | |
214 | |
215 /* Configure rest of the emulation */ | |
216 /* if (xs_cfg.forceModel) */ | |
217 myEngine->currConfig.mos8580 = xs_cfg.mos8580; | |
218 myEngine->currConfig.emulateFilter = xs_cfg.emulateFilters; | |
219 myEngine->currConfig.filterFs = xs_cfg.filterFs; | |
220 myEngine->currConfig.filterFm = xs_cfg.filterFm; | |
221 myEngine->currConfig.filterFt = xs_cfg.filterFt; | |
222 | |
223 | |
224 /* Now set the emulator configuration */ | |
225 if (!myEngine->currEng->setConfig(myEngine->currConfig)) { | |
226 XSERR("Emulator engine configuration failed!\n"); | |
227 return FALSE; | |
228 } | |
229 | |
230 return TRUE; | |
231 } | |
232 | |
233 | |
234 /* Close SIDPlay1 engine | |
235 */ | |
236 void xs_sidplay1_close(t_xs_status * myStatus) | |
237 { | |
238 t_xs_sidplay1 *myEngine; | |
239 assert(myStatus); | |
240 | |
241 myEngine = (t_xs_sidplay1 *) myStatus->sidEngine; | |
242 | |
243 /* Free internals */ | |
244 if (myEngine->currEng) { | |
245 delete myEngine->currEng; | |
246 myEngine->currEng = NULL; | |
247 } | |
248 | |
249 g_free(myEngine); | |
250 myStatus->sidEngine = NULL; | |
251 } | |
252 | |
253 | |
254 /* Initialize current song and sub-tune | |
255 */ | |
256 gboolean xs_sidplay1_initsong(t_xs_status * myStatus) | |
257 { | |
258 t_xs_sidplay1 *myEngine; | |
259 assert(myStatus); | |
260 | |
261 myEngine = (t_xs_sidplay1 *) myStatus->sidEngine; | |
262 if (!myEngine) return FALSE; | |
263 | |
264 if (!myEngine->currTune) { | |
265 XSERR("Tune was NULL\n"); | |
266 return FALSE; | |
267 } | |
268 | |
269 if (!myEngine->currTune->getStatus()) { | |
270 XSERR("Tune status check failed\n"); | |
271 return FALSE; | |
272 } | |
273 | |
274 return sidEmuInitializeSong(*myEngine->currEng, *myEngine->currTune, myStatus->currSong); | |
275 } | |
276 | |
277 | |
278 /* Emulate and render audio data to given buffer | |
279 */ | |
280 guint xs_sidplay1_fillbuffer(t_xs_status * myStatus, gchar * audioBuffer, guint audioBufSize) | |
281 { | |
282 t_xs_sidplay1 *myEngine; | |
283 assert(myStatus); | |
284 | |
285 myEngine = (t_xs_sidplay1 *) myStatus->sidEngine; | |
286 if (!myEngine) return 0; | |
287 | |
288 sidEmuFillBuffer(*myEngine->currEng, *myEngine->currTune, audioBuffer, audioBufSize); | |
289 | |
290 return audioBufSize; | |
291 } | |
292 | |
293 | |
294 /* Load a given SID-tune file | |
295 */ | |
296 gboolean xs_sidplay1_loadsid(t_xs_status * myStatus, gchar * pcFilename) | |
297 { | |
298 t_xs_sidplay1 *myEngine; | |
299 sidTune *newTune; | |
300 assert(myStatus); | |
301 | |
302 myEngine = (t_xs_sidplay1 *) myStatus->sidEngine; | |
303 if (!myEngine) return FALSE; | |
304 | |
305 /* Try to load the file/tune */ | |
306 if (!pcFilename) return FALSE; | |
307 | |
308 newTune = new sidTune(pcFilename); | |
309 if (!newTune) return FALSE; | |
310 | |
311 myEngine->currTune = newTune; | |
312 | |
313 return TRUE; | |
314 } | |
315 | |
316 | |
317 /* Delete INTERNAL information | |
318 */ | |
319 void xs_sidplay1_deletesid(t_xs_status * myStatus) | |
320 { | |
321 t_xs_sidplay1 *myEngine; | |
322 assert(myStatus); | |
323 | |
324 myEngine = (t_xs_sidplay1 *) myStatus->sidEngine; | |
325 if (!myEngine) return; | |
326 | |
327 if (myEngine->currTune) { | |
328 delete myEngine->currTune; | |
329 myEngine->currTune = NULL; | |
330 } | |
331 } | |
332 | |
333 | |
334 /* Return song information | |
335 */ | |
336 #define TFUNCTION xs_sidplay1_getsidinfo | |
337 #define TTUNEINFO sidTuneInfo | |
338 #define TTUNE sidTune | |
339 #include "xs_sidplay.h" | |
340 | |
341 } /* extern "C" */ | |
342 #endif /* HAVE_SIDPLAY1 */ |