comparison src/xs_sidplay1.cc @ 73:2bc607888f53

Added libsidplay2 module, lots of reworking of internals, sidplay1 support now works with the new framework! Getting libsidplay2 support working shouldn't be too far now...
author Matti Hamalainen <ccr@tnsp.org>
date Sun, 14 Sep 2003 03:14:01 +0000
parents e3b205a6bc7e
children 8cb66a3f75f7
comparison
equal deleted inserted replaced
72:e3b205a6bc7e 73:2bc607888f53
17 17
18 You should have received a copy of the GNU General Public License 18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software 19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 */ 21 */
22 #include "xmms-sid.h"
23
22 #ifdef HAVE_SIDPLAY1 24 #ifdef HAVE_SIDPLAY1
25
26 extern "C" {
23 #include "xs_sidplay1.h" 27 #include "xs_sidplay1.h"
24 28 #include <stdio.h>
25 extern "C" { 29 #include <xmms/titlestring.h>
26 #include <xmms/title.h> 30 #include "xs_config.h"
31 #include "xs_support.h"
32 #include "xs_length.h"
27 } 33 }
28 34
29 #include <sidplay/player.h> 35 #include <sidplay/player.h>
30 #include <sidplay/myendian.h> 36 #include <sidplay/myendian.h>
31 #include <sidplay/fformat.h> 37 #include <sidplay/fformat.h>
32 38
33 39
34 void xs_sidplay1_close(t_xs_status *myStatus) 40 typedef struct {
35 { 41 emuEngine *currEng;
36 if (!myStatus) return; 42 emuConfig currConfig;
37 43 sidTune *currTune;
38 if (!myStatus->currEng) 44 } t_xs_sidplay1;
39 delete (emuEngine *) myStatus->currEng; 45
40 46
41 if (!myStatus->currConf) 47 /*
42 free(myStatus->currConf); 48 * We need to 'export' all this pseudo-C++ crap
43 49 */
44 free(myStatus); 50 extern "C" {
45 } 51
46 52 gboolean xs_sidplay1_isourfile(gchar *pcFileName)
47 53 {
48 gboolean xs_sidplay1_init(t_xs_status *myStatus) 54 /* Try to detect via libSIDPlay's detection routine, if required */
49 { 55 sidTune *testTune = new sidTune(pcFileName);
50 if (!myStatus) return FALSE; 56
51 57 if (!testTune) return FALSE;
52 myStatus->currEng = (void *) new emuEngine; 58 if (!testTune->getStatus())
53 if (!myStatus->currEng)
54 { 59 {
55 xs_sidplay1_close(myStatus); 60 delete testTune;
56 return FALSE; 61 return FALSE;
57 } 62 }
58 63
59 myStatus->currConf = calloc(1, sizeof(struct emuConfig)); 64 delete testTune;
60 if (!myStatus->currConf) 65 return TRUE;
66 }
67
68
69 void xs_sidplay1_close(t_xs_status *myStatus)
70 {
71 t_xs_sidplay1 *myPlayer;
72
73 /* Check pointer */
74 if (!myStatus) return;
75
76 /* Free internals */
77 xs_sidplay1_deletesid(myStatus);
78
79 myPlayer = (t_xs_sidplay1 *) myStatus->player;
80
81 if (myPlayer->currEng) delete myPlayer->currEng;
82
83 free(myPlayer);
84 myStatus->player = NULL;
85
86 /* Miscellaneous */
87 free(myStatus->currFileName);
88 myStatus->currFileName = NULL;
89 }
90
91
92 gboolean xs_sidplay1_init(t_xs_status *myStatus)
93 {
94 t_xs_sidplay1 *myPlayer;
95
96 /* Check pointer */
97 if (!myStatus) return FALSE;
98
99 /* Allocate internal structures */
100 myPlayer = (t_xs_sidplay1 *) g_malloc0(sizeof(t_xs_sidplay1));
101 if (!myPlayer) return FALSE;
102
103 /* Initialize engine */
104 myPlayer->currEng = new emuEngine();
105 if (!myPlayer->currEng)
61 { 106 {
62 xs_sidplay1_close(myStatus); 107 XSERR("Could not initialize libSIDPlay1 emulation engine\n");
108 free(myPlayer);
63 return FALSE; 109 return FALSE;
64 } 110 }
65 111
112 /* Verify endianess */
113 if (!myPlayer->currEng->verifyEndianess())
114 {
115 XSERR("Endianess verification failed\n");
116 free(myPlayer);
117 return FALSE;
118 }
119
120 myStatus->player = myPlayer;
66 return TRUE; 121 return TRUE;
67 } 122 }
68 123
69 124
70 gboolean xs_sidplay1_initsong(t_xs_status *myStatus) 125 gboolean xs_sidplay1_initsong(t_xs_status *myStatus)
71 { 126 {
72 if ((!myStatus->currTune) || (!((sidTune *)myStatus->currTune)->getStatus())) return FALSE; 127 t_xs_sidplay1 *myPlayer = (t_xs_sidplay1 *) myStatus->player;
128
129 if (!myPlayer) return FALSE;
130
131 if ((!myPlayer->currTune) || (!myPlayer->currTune->getStatus())) return FALSE;
73 132
74 return sidEmuInitializeSong( 133 return sidEmuInitializeSong(
75 (emuEngine *) myStatus->currEngine, 134 *myPlayer->currEng,
76 (sidTune *) myStatus->currTune, 135 *myPlayer->currTune,
77 myStatus->currSong); 136 myStatus->currSong);
78 } 137 }
79 138
80 139
81 void xs_sidplay1_fillbuffer(t_xs_status *myStatus, gchar *audioBuffer, gint audioBufSize) 140 gboolean xs_sidplay1_fillbuffer(t_xs_status *myStatus, gchar *audioBuffer, gint audioBufSize)
82 { 141 {
142 t_xs_sidplay1 *myPlayer = (t_xs_sidplay1 *) myStatus->player;
143
144 if (!myPlayer) return FALSE;
145
83 sidEmuFillBuffer( 146 sidEmuFillBuffer(
84 (emuEngine *) myStatus->currEngine, 147 *myPlayer->currEng,
85 (sidTune *) myStatus->currTune, 148 *myPlayer->currTune,
86 audioBuffer, 149 audioBuffer,
87 audioBufSize); 150 audioBufSize);
151
152 return TRUE;
88 } 153 }
89 154
90 155
91 gboolean xs_sidplay1_loadsid(t_xs_status *myStatus, gchar *pcFileName) 156 gboolean xs_sidplay1_loadsid(t_xs_status *myStatus, gchar *pcFileName)
92 { 157 {
158 t_xs_sidplay1 *myPlayer = (t_xs_sidplay1 *) myStatus->player;
93 sidTune *newTune; 159 sidTune *newTune;
94 sidTuneInfo tuneInfo; 160 sidTuneInfo tuneInfo;
95 161
96 /* Try to get the tune */ 162 /* Try to get the tune */
97 if (!pcFileName) return FALSE; 163 if (!pcFileName) return FALSE;
98 newTune = new sidTune(pcFileName); 164 newTune = new sidTune(pcFileName);
99 if (newTune == NULL) return FALSE; 165 if (!newTune) return FALSE;
100 166
101 /* Get current configuration */ 167 /* Get current configuration */
102 myStatus->currEngine.getConfig(myStatus->currConf); 168 myPlayer->currEng->getConfig(myPlayer->currConfig);
103 169
104 /* Configure channels and stuff */ 170 /* Configure channels and stuff */
105 switch (xs_cfg.fmtChannels) { 171 switch (xs_cfg.fmtChannels) {
106 172
107 case XS_CHN_AUTOPAN: 173 case XS_CHN_AUTOPAN:
108 myStatus->currConf.channels = SIDEMU_STEREO; 174 myPlayer->currConfig.channels = SIDEMU_STEREO;
109 myStatus->currConf.autoPanning = SIDEMU_CENTEREDAUTOPANNING; 175 myPlayer->currConfig.autoPanning = SIDEMU_CENTEREDAUTOPANNING;
110 myStatus->currConf.volumeControl = SIDEMU_FULLPANNING; 176 myPlayer->currConfig.volumeControl = SIDEMU_FULLPANNING;
111 break; 177 break;
112 178
113 case XS_CHN_STEREO: 179 case XS_CHN_STEREO:
114 myStatus->currConf.channels = SIDEMU_STEREO; 180 myPlayer->currConfig.channels = SIDEMU_STEREO;
115 myStatus->currConf.autoPanning = SIDEMU_NONE; 181 myPlayer->currConfig.autoPanning = SIDEMU_NONE;
116 myStatus->currConf.volumeControl = SIDEMU_NONE; 182 myPlayer->currConfig.volumeControl = SIDEMU_NONE;
117 break; 183 break;
118 184
119 case XS_CHN_MONO: 185 case XS_CHN_MONO:
120 default: 186 default:
121 myStatus->currConf.channels = SIDEMU_MONO; 187 myPlayer->currConfig.channels = SIDEMU_MONO;
122 myStatus->currConf.autoPanning = SIDEMU_NONE; 188 myPlayer->currConfig.autoPanning = SIDEMU_NONE;
123 myStatus->currConf.volumeControl = SIDEMU_NONE; 189 myPlayer->currConfig.volumeControl = SIDEMU_NONE;
124 break; 190 break;
125 } 191 }
126 192
127 193
128 /* Memory mode settings */ 194 /* Memory mode settings */
129 switch (xs_cfg.memoryMode) { 195 switch (xs_cfg.memoryMode) {
130 case XS_MPU_BANK_SWITCHING: 196 case XS_MPU_BANK_SWITCHING:
131 myStatus->currConf.memoryMode = MPU_BANK_SWITCHING; 197 myPlayer->currConfig.memoryMode = MPU_BANK_SWITCHING;
132 break; 198 break;
133 199
134 case XS_MPU_TRANSPARENT_ROM: 200 case XS_MPU_TRANSPARENT_ROM:
135 myStatus->currConf.memoryMode = MPU_TRANSPARENT_ROM; 201 myPlayer->currConfig.memoryMode = MPU_TRANSPARENT_ROM;
136 break; 202 break;
137 203
138 case XS_MPU_PLAYSID_ENVIRONMENT: 204 case XS_MPU_PLAYSID_ENVIRONMENT:
139 myStatus->currConf.memoryMode = MPU_PLAYSID_ENVIRONMENT; 205 myPlayer->currConfig.memoryMode = MPU_PLAYSID_ENVIRONMENT;
140 break; 206 break;
141 207
142 default: 208 default:
143 myStatus->currConf.memoryMode = MPU_BANK_SWITCHING; 209 myPlayer->currConfig.memoryMode = MPU_BANK_SWITCHING;
144 break; 210 break;
145 } 211 }
146 212
147 213
148 /* Clockspeed settings */ 214 /* Clockspeed settings */
149 switch (xs_cfg.clockSpeed) { 215 switch (xs_cfg.clockSpeed) {
150 case XS_CLOCK_NTSC: 216 case XS_CLOCK_NTSC:
151 myStatus->currConf.clockSpeed = SIDTUNE_CLOCK_NTSC; 217 myPlayer->currConfig.clockSpeed = SIDTUNE_CLOCK_NTSC;
152 break; 218 break;
153 219
154 case XS_CLOCK_PAL: 220 case XS_CLOCK_PAL:
155 default: 221 default:
156 myStatus->currConf.clockSpeed = SIDTUNE_CLOCK_PAL; 222 myPlayer->currConfig.clockSpeed = SIDTUNE_CLOCK_PAL;
157 break; 223 break;
158 } 224 }
159 225
160 226
161 /* Configure rest of the emulation */ 227 /* Configure rest of the emulation */
162 myStatus->currConf.bitsPerSample = xs_cfg.fmtBitsPerSample; 228 myPlayer->currConfig.bitsPerSample = xs_cfg.fmtBitsPerSample;
163 myStatus->currConf.frequency = xs_cfg.fmtFrequency; 229 myPlayer->currConfig.frequency = xs_cfg.fmtFrequency;
164 #ifdef HAVE_UNSIGNEDPCM 230 #ifdef HAVE_UNSIGNEDPCM
165 myStatus->currConf.sampleFormat = SIDEMU_UNSIGNED_PCM; 231 myPlayer->currConfig.sampleFormat = SIDEMU_UNSIGNED_PCM;
166 #else 232 #else
167 myStatus->currConf.sampleFormat = SIDEMU_SIGNED_PCM; 233 myPlayer->currConfig.sampleFormat = SIDEMU_SIGNED_PCM;
168 #endif 234 #endif
169 myStatus->currConf.mos8580 = xs_cfg.mos8580; 235 myPlayer->currConfig.mos8580 = xs_cfg.mos8580;
170 myStatus->currConf.emulateFilter = xs_cfg.emulateFilters; 236 myPlayer->currConfig.emulateFilter = xs_cfg.emulateFilters;
171 myStatus->currConf.filterFs = xs_cfg.filterFs; 237 myPlayer->currConfig.filterFs = xs_cfg.filterFs;
172 myStatus->currConf.filterFm = xs_cfg.filterFm; 238 myPlayer->currConfig.filterFm = xs_cfg.filterFm;
173 myStatus->currConf.filterFt = xs_cfg.filterFt; 239 myPlayer->currConfig.filterFt = xs_cfg.filterFt;
174 240
175 /* Now set the emulator configuration */ 241 /* Now set the emulator configuration */
176 myStatus->currEngine.setConfig(myStatus->currConf); 242 myPlayer->currEng->setConfig(myPlayer->currConfig);
177 243
178 /* Initialize status information */ 244 /* Initialize status information */
179 newTune->getInfo(tuneInfo); 245 newTune->getInfo(tuneInfo);
180 if (!newTune) return FALSE;
181 246
182 myStatus->isPlaying = TRUE; 247 myStatus->isPlaying = TRUE;
183 myStatus->isError = FALSE; 248 myStatus->isError = FALSE;
184 myStatus->currSong = tuneInfo.startSong; 249 myStatus->currSong = tuneInfo.startSong;
185 myStatus->nSongs = tuneInfo.songs; 250 myStatus->nSongs = tuneInfo.songs;
186 myStatus->currTune = newTune; 251 myPlayer->currTune = newTune;
187 myStatus->currFileName = g_strdup(pcFileName); 252 myStatus->currFileName = g_strdup(pcFileName);
188 253
189 return TRUE; 254 return TRUE;
190 } 255 }
191 256
192 257
258 /*
259 * Delete tune
260 */
261 void xs_sidplay1_deletesid(t_xs_status *myStatus)
262 {
263 t_xs_sidplay1 *myPlayer;
264
265 if (!myStatus) return;
266
267 myPlayer = (t_xs_sidplay1 *) myStatus->player;
268 if (!myPlayer) return;
269
270 if (myPlayer->currTune)
271 delete myPlayer->currTune;
272 }
273
274
275 gint xs_sidplay1_gettunespeed(t_xs_status *myStatus)
276 {
277 return 0;
278 }
279
280 /*
281 * Return song information
282 */
283 #include "xs_sidplay_info.h"
284
285 void xs_sidplay1_getsidinfo(gchar *songFileName, gchar **songTitle, gint *songLength)
286 {
287 sidTuneInfo tuneInfo;
288 sidTune *testTune;
289 gint tmpInt;
290
291 /* Check if the tune exists and is readable */
292 testTune = new sidTune(songFileName);
293 if (!testTune) return;
294 if (!testTune->getStatus())
295 {
296 delete testTune;
297 return;
298 }
299
300 /* Get general tune information */
301 testTune->getInfo(tuneInfo);
302 delete testTune;
303
304 /* Get titlestring */
305 *songTitle = xs_make_filetitle(songFileName, &tuneInfo, tuneInfo.startSong);
306
307 /* Get song length (in milliseconds), negative if no known length */
308 tmpInt = xs_songlen_get(songFileName, tuneInfo.startSong);
309 if (tmpInt >= 0)
310 *songLength = (tmpInt * 1000);
311 else
312 *songLength = -1;
313 }
314
315
316 } /* extern "C" */
193 #endif /* HAVE_SIDPLAY1 */ 317 #endif /* HAVE_SIDPLAY1 */