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 (20 years, 10 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

# User Rev Content
1 cebix 1.1 /*
2     * cl_amp.cpp - SIDPlayer CL-Amp plugin
3     *
4 cebix 1.4 * SIDPlayer (C) Copyright 1996-2003 Christian Bauer
5 cebix 1.1 *
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 cebix 1.3 int argc = 0;
118     char **argv = NULL;
119     InitAll(argc, argv);
120 cebix 1.1 }
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     }