ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SIDPlayer/src/cl_amp.cpp
Revision: 1.1
Committed: 2000-07-28T12:42:30Z (23 years, 8 months ago) by cebix
Branch: MAIN
Branch point for: cebix
Log Message:
Initial revision

File Contents

# Content
1 /*
2 * cl_amp.cpp - SIDPlayer CL-Amp plugin
3 *
4 * SIDPlayer (C) Copyright 1996-2000 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 InitAll();
118 }
119
120 void SIDPlugin::Cleanup()
121 {
122 if (prefs_window_open && prefs_window) {
123 prefs_window->PostMessage(B_QUIT_REQUESTED);
124 while (prefs_window_open)
125 snooze(1000);
126 }
127 ExitAll();
128 }
129
130
131 /*
132 * About window
133 */
134
135 bool SIDPlugin::About(bool Question)
136 {
137 if (Question)
138 return true;
139
140 AboutWindow();
141 return true;
142 }
143
144
145 /*
146 * Prefs window
147 */
148
149 bool SIDPlugin::Prefs(bool Question)
150 {
151 if (Question)
152 return true;
153
154 if (prefs_window_open && prefs_window) {
155 prefs_window->Activate(true);
156 return false;
157 } else {
158 prefs_window = new PrefsWindow();
159 return true;
160 }
161 }
162
163
164 /*
165 * Edit window
166 */
167
168 bool SIDPlugin::Edit(const char *FileName, bool Question)
169 {
170 return false;
171 }
172
173
174 /*
175 * Get MIME type for supported audio files
176 */
177
178 bool SIDPlugin::GetMimeType(BMimeType *m, int nr)
179 {
180 if (nr == 0) {
181 m->SetTo("audio/x-psid");
182 m->SetLongDescription("C64 SID tune");
183 return true;
184 } else
185 return false;
186 }
187
188
189 /*
190 * Check if file is handled by this plugin
191 */
192
193 bool SIDPlugin::IsOur(const char *FileName)
194 {
195 if (strncasecmp(FileName, MY_URL_HEADER, MY_URL_HEADER_LEN) == 0) {
196
197 // name starts with "sid://", extract file name
198 char name[B_FILE_NAME_LENGTH];
199 char *q = strrchr(FileName, '?');
200 if (q == NULL)
201 return false;
202 int name_len = q - (FileName + MY_URL_HEADER_LEN);
203 strncpy(name, FileName + MY_URL_HEADER_LEN, name_len);
204 name[name_len] = 0;
205 return IsPSIDFile(name);
206
207 } else
208 return IsPSIDFile(FileName);
209 }
210
211
212 /*
213 * Get information about audio file
214 */
215
216 static bool get_song_info(const char *file_name, PlayerInfoStruct *Info, int &number_of_songs, int &song, bool default_song = true)
217 {
218 // Load header
219 uint8 header[PSID_MAX_HEADER_LENGTH];
220 if (!LoadPSIDHeader(file_name, header))
221 return false;
222
223 // Get number of subsongs and default song
224 number_of_songs = read_psid_16(header, PSID_NUMBER);
225 if (number_of_songs == 0)
226 number_of_songs = 1;
227 if (default_song) {
228 song = read_psid_16(header, PSID_DEFSONG);
229 if (song)
230 song--;
231 }
232 if (song >= number_of_songs)
233 song = 0;
234
235 // Set info
236 char psid_name[64];
237 int32 sl = 32, dl = 64, state = 0;
238 convert_to_utf8(B_ISO1_CONVERSION, (char *)(header + PSID_NAME), &sl, psid_name, &dl, &state);
239 if (number_of_songs > 1) {
240 sprintf(Info->Title, "%s (%d/%d)", psid_name, song + 1, number_of_songs);
241 } else
242 strcpy(Info->Title, psid_name);
243 Info->Flags = INPLUG_NO_TOTTIME | INPLUG_NO_CURRTIME | INPLUG_HANDLE_SPEED;
244 Info->Frequency = 44100;
245 Info->Stereo = true;
246 return true;
247 }
248
249 bool SIDPlugin::GetSongInfo(const char *FileName, PlayerInfoStruct *Info)
250 {
251 char name[B_FILE_NAME_LENGTH + 16];
252 if (strncasecmp(FileName, MY_URL_HEADER, MY_URL_HEADER_LEN) == 0) {
253
254 // name starts with "sid://", extract file name
255 char *q = strrchr(FileName, '?');
256 if (q == NULL)
257 return false;
258 int song = atoi(q + 1);
259 int name_len = q - (FileName + MY_URL_HEADER_LEN);
260 strncpy(name, FileName + MY_URL_HEADER_LEN, name_len);
261 name[name_len] = 0;
262
263 // Get info
264 int number_of_songs;
265 return get_song_info(name, Info, number_of_songs, song, false);
266
267 } else {
268
269 // Ordinary file name, get info and number of subsongs
270 int number_of_songs, default_song;
271 if (!get_song_info(FileName, Info, number_of_songs, default_song))
272 return false;
273
274 // Add subsongs other than default song to playlist in the correct order
275 for (int i=0; i<number_of_songs; i++) {
276 if (i != default_song) {
277 sprintf(name, "%s%s?%d", MY_URL_HEADER, FileName, i);
278 if (i < default_song)
279 SendToCLAmp_AddFile(name, Info->SongId);
280 else
281 SendToCLAmp_AddFile(name);
282 }
283 }
284 }
285 return true;
286 }
287
288
289 /*
290 * Special handling for aborting playing
291 */
292
293 void SIDPlugin::AbortPlaying()
294 {
295 }
296
297
298 /*
299 * Special handling for pause
300 */
301
302 void SIDPlugin::Pause(bool On)
303 {
304 }
305
306
307 /*
308 * Adjust playback speed
309 */
310
311 void SIDPlugin::NewSpeed(long Promille)
312 {
313 SIDAdjustSpeed(Promille / 10);
314 }
315
316
317 /*
318 * Adjust playback volume
319 */
320
321 void SIDPlugin::NewVolume(long Promille)
322 {
323 }
324
325
326 /*
327 * Prepare for playback
328 */
329
330 bool SIDPlugin::InitPlaying(const char *FileName, PlayerInfoStruct *Info)
331 {
332 char name[B_FILE_NAME_LENGTH];
333 bool subsong_given = false;
334 int song;
335
336 if (strncasecmp(FileName, MY_URL_HEADER, MY_URL_HEADER_LEN) == 0) {
337
338 // name starts with "sid://", extract file name
339 char *q = strrchr(FileName, '?');
340 if (q == NULL)
341 return false;
342 subsong_given = true;
343 song = atoi(q + 1);
344 int name_len = q - (FileName + MY_URL_HEADER_LEN);
345 strncpy(name, FileName + MY_URL_HEADER_LEN, name_len);
346 name[name_len] = 0;
347
348 } else
349 strcpy(name, FileName);
350
351 // Load PSID file
352 if (!LoadPSIDFile(name))
353 return false;
354
355 // Select subsong if subsong number given
356 if (subsong_given)
357 SelectSong(song);
358
359 // Set data
360 Info->Flags = INPLUG_NO_TOTTIME | INPLUG_NO_CURRTIME | INPLUG_HANDLE_SPEED;
361 Info->Frequency = 44100;
362 Info->Stereo = true;
363 return true;
364 }
365
366
367 /*
368 * Audio stream callback function
369 */
370
371 int SIDPlugin::GetAudio(char **Buff, int Size)
372 {
373 SIDCalcBuffer(buffer, AUDIO_BUFFER_SIZE);
374 *Buff = (char *)buffer;
375 return AUDIO_BUFFER_SIZE;
376 }
377
378
379 /*
380 * Set playback position
381 */
382
383 void SIDPlugin::JumpTo(long NewTime)
384 {
385 }
386
387
388 /*
389 * Stop playback
390 */
391
392 void SIDPlugin::CleanupPlaying()
393 {
394 }