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, 7 months ago) by cebix
Branch: MAIN
Branch point for: cebix
Log Message:
Initial revision

File Contents

# User Rev Content
1 cebix 1.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     }