ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SIDPlayer/src/cl_amp.cpp
Revision: 1.4
Committed: 2003-04-11T20:23:02Z (21 years, 6 months ago) by cebix
Branch: MAIN
Changes since 1.3: +1 -1 lines
Log Message:
- added support for Catweasel SID
- replay timing is now based on CIA timer value, removed replayfreq

File Contents

# Content
1 /*
2 * cl_amp.cpp - SIDPlayer CL-Amp plugin
3 *
4 * SIDPlayer (C) Copyright 1996-2003 Christian Bauer
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #include "sys.h"
22
23 #include <AppKit.h>
24 #include <support/UTF8.h>
25 #include <stdio.h>
26
27 #include "prefs.h"
28 #include "main.h"
29 #include "psid.h"
30 #include "sid.h"
31 #include "prefs_window.h"
32
33 #include "InputPlugin.h"
34
35 class SIDPlugin;
36
37
38 // Size of audio buffer
39 const int AUDIO_BUFFER_SIZE = 4096;
40
41 // URL header for subsong recognition
42 static const char MY_URL_HEADER[] = "sid://";
43 const int MY_URL_HEADER_LEN = 6;
44
45
46 // Plugin class definition
47 class SIDPlugin : public InputPlugin {
48 public:
49 SIDPlugin();
50 virtual ~SIDPlugin();
51
52 void Init();
53 void Cleanup();
54
55 // Thread A
56 bool About(bool Question);
57 bool Prefs(bool Question);
58 bool Edit(const char *FileName, bool Question);
59 bool GetMimeType(BMimeType *m, int nr);
60 bool IsOur(const char *FileName);
61 bool GetSongInfo(const char *FName, PlayerInfoStruct *Info);
62 void AbortPlaying();
63 void Pause(bool On);
64 void NewSpeed(long Promille);
65 void NewVolume(long Promille);
66
67 // Thread B
68 bool InitPlaying(const char *FileName, PlayerInfoStruct *Info);
69 int GetAudio(char **Buff, int Size);
70 void JumpTo(long NewTime);
71 void CleanupPlaying();
72
73 private:
74 uint8 buffer[AUDIO_BUFFER_SIZE]; // Audio data buffer
75 PrefsWindow *prefs_window; // Pointer to prefs window
76 };
77
78
79 /*
80 * CL-Amp plugin interface
81 */
82
83 extern "C" _EXPORT InputPlugin *NewPlugin(int *version);
84
85 InputPlugin *NewPlugin(int *version)
86 {
87 *version = CURRENT_INPUT_PLUGIN_VERSION;
88 return new SIDPlugin();
89 }
90
91
92 /*
93 * Constructor
94 */
95
96 SIDPlugin::SIDPlugin() : InputPlugin("PSID", "SIDPlayer C64 SID tune player by Christian Bauer")
97 {
98 prefs_window = NULL;
99 }
100
101
102 /*
103 * Destructor
104 */
105
106 SIDPlugin::~SIDPlugin()
107 {
108 }
109
110
111 /*
112 * Init/cleanup
113 */
114
115 void SIDPlugin::Init()
116 {
117 int argc = 0;
118 char **argv = NULL;
119 InitAll(argc, argv);
120 }
121
122 void SIDPlugin::Cleanup()
123 {
124 if (prefs_window_open && prefs_window) {
125 prefs_window->PostMessage(B_QUIT_REQUESTED);
126 while (prefs_window_open)
127 snooze(1000);
128 }
129 ExitAll();
130 }
131
132
133 /*
134 * About window
135 */
136
137 bool SIDPlugin::About(bool Question)
138 {
139 if (Question)
140 return true;
141
142 AboutWindow();
143 return true;
144 }
145
146
147 /*
148 * Prefs window
149 */
150
151 bool SIDPlugin::Prefs(bool Question)
152 {
153 if (Question)
154 return true;
155
156 if (prefs_window_open && prefs_window) {
157 prefs_window->Activate(true);
158 return false;
159 } else {
160 prefs_window = new PrefsWindow();
161 return true;
162 }
163 }
164
165
166 /*
167 * Edit window
168 */
169
170 bool SIDPlugin::Edit(const char *FileName, bool Question)
171 {
172 return false;
173 }
174
175
176 /*
177 * Get MIME type for supported audio files
178 */
179
180 bool SIDPlugin::GetMimeType(BMimeType *m, int nr)
181 {
182 if (nr == 0) {
183 m->SetTo("audio/x-psid");
184 m->SetLongDescription("C64 SID tune");
185 return true;
186 } else
187 return false;
188 }
189
190
191 /*
192 * Check if file is handled by this plugin
193 */
194
195 bool SIDPlugin::IsOur(const char *FileName)
196 {
197 if (strncasecmp(FileName, MY_URL_HEADER, MY_URL_HEADER_LEN) == 0) {
198
199 // name starts with "sid://", extract file name
200 char name[B_FILE_NAME_LENGTH];
201 char *q = strrchr(FileName, '?');
202 if (q == NULL)
203 return false;
204 int name_len = q - (FileName + MY_URL_HEADER_LEN);
205 strncpy(name, FileName + MY_URL_HEADER_LEN, name_len);
206 name[name_len] = 0;
207 return IsPSIDFile(name);
208
209 } else
210 return IsPSIDFile(FileName);
211 }
212
213
214 /*
215 * Get information about audio file
216 */
217
218 static bool get_song_info(const char *file_name, PlayerInfoStruct *Info, int &number_of_songs, int &song, bool default_song = true)
219 {
220 // Load header
221 uint8 header[PSID_MAX_HEADER_LENGTH];
222 if (!LoadPSIDHeader(file_name, header))
223 return false;
224
225 // Get number of subsongs and default song
226 number_of_songs = read_psid_16(header, PSID_NUMBER);
227 if (number_of_songs == 0)
228 number_of_songs = 1;
229 if (default_song) {
230 song = read_psid_16(header, PSID_DEFSONG);
231 if (song)
232 song--;
233 }
234 if (song >= number_of_songs)
235 song = 0;
236
237 // Set info
238 char psid_name[64];
239 int32 sl = 32, dl = 64, state = 0;
240 convert_to_utf8(B_ISO1_CONVERSION, (char *)(header + PSID_NAME), &sl, psid_name, &dl, &state);
241 if (number_of_songs > 1) {
242 sprintf(Info->Title, "%s (%d/%d)", psid_name, song + 1, number_of_songs);
243 } else
244 strcpy(Info->Title, psid_name);
245 Info->Flags = INPLUG_NO_TOTTIME | INPLUG_NO_CURRTIME | INPLUG_HANDLE_SPEED;
246 Info->Frequency = 44100;
247 Info->Stereo = true;
248 return true;
249 }
250
251 bool SIDPlugin::GetSongInfo(const char *FileName, PlayerInfoStruct *Info)
252 {
253 char name[B_FILE_NAME_LENGTH + 16];
254 if (strncasecmp(FileName, MY_URL_HEADER, MY_URL_HEADER_LEN) == 0) {
255
256 // name starts with "sid://", extract file name
257 char *q = strrchr(FileName, '?');
258 if (q == NULL)
259 return false;
260 int song = atoi(q + 1);
261 int name_len = q - (FileName + MY_URL_HEADER_LEN);
262 strncpy(name, FileName + MY_URL_HEADER_LEN, name_len);
263 name[name_len] = 0;
264
265 // Get info
266 int number_of_songs;
267 return get_song_info(name, Info, number_of_songs, song, false);
268
269 } else {
270
271 // Ordinary file name, get info and number of subsongs
272 int number_of_songs, default_song;
273 if (!get_song_info(FileName, Info, number_of_songs, default_song))
274 return false;
275
276 // Add subsongs other than default song to playlist in the correct order
277 for (int i=0; i<number_of_songs; i++) {
278 if (i != default_song) {
279 sprintf(name, "%s%s?%d", MY_URL_HEADER, FileName, i);
280 if (i < default_song)
281 SendToCLAmp_AddFile(name, Info->SongId);
282 else
283 SendToCLAmp_AddFile(name);
284 }
285 }
286 }
287 return true;
288 }
289
290
291 /*
292 * Special handling for aborting playing
293 */
294
295 void SIDPlugin::AbortPlaying()
296 {
297 }
298
299
300 /*
301 * Special handling for pause
302 */
303
304 void SIDPlugin::Pause(bool On)
305 {
306 }
307
308
309 /*
310 * Adjust playback speed
311 */
312
313 void SIDPlugin::NewSpeed(long Promille)
314 {
315 SIDAdjustSpeed(Promille / 10);
316 }
317
318
319 /*
320 * Adjust playback volume
321 */
322
323 void SIDPlugin::NewVolume(long Promille)
324 {
325 }
326
327
328 /*
329 * Prepare for playback
330 */
331
332 bool SIDPlugin::InitPlaying(const char *FileName, PlayerInfoStruct *Info)
333 {
334 char name[B_FILE_NAME_LENGTH];
335 bool subsong_given = false;
336 int song;
337
338 if (strncasecmp(FileName, MY_URL_HEADER, MY_URL_HEADER_LEN) == 0) {
339
340 // name starts with "sid://", extract file name
341 char *q = strrchr(FileName, '?');
342 if (q == NULL)
343 return false;
344 subsong_given = true;
345 song = atoi(q + 1);
346 int name_len = q - (FileName + MY_URL_HEADER_LEN);
347 strncpy(name, FileName + MY_URL_HEADER_LEN, name_len);
348 name[name_len] = 0;
349
350 } else
351 strcpy(name, FileName);
352
353 // Load PSID file
354 if (!LoadPSIDFile(name))
355 return false;
356
357 // Select subsong if subsong number given
358 if (subsong_given)
359 SelectSong(song);
360
361 // Set data
362 Info->Flags = INPLUG_NO_TOTTIME | INPLUG_NO_CURRTIME | INPLUG_HANDLE_SPEED;
363 Info->Frequency = 44100;
364 Info->Stereo = true;
365 return true;
366 }
367
368
369 /*
370 * Audio stream callback function
371 */
372
373 int SIDPlugin::GetAudio(char **Buff, int Size)
374 {
375 SIDCalcBuffer(buffer, AUDIO_BUFFER_SIZE);
376 *Buff = (char *)buffer;
377 return AUDIO_BUFFER_SIZE;
378 }
379
380
381 /*
382 * Set playback position
383 */
384
385 void SIDPlugin::JumpTo(long NewTime)
386 {
387 }
388
389
390 /*
391 * Stop playback
392 */
393
394 void SIDPlugin::CleanupPlaying()
395 {
396 }