Mercurial > audlegacy-plugins
comparison src/sexypsf/xmms.c @ 1201:2ae8155baef1
First cleanups
author | michi@tux.homenetwork |
---|---|
date | Mon, 02 Jul 2007 15:53:49 +0200 |
parents | 3bcb772fa1b5 |
children | 82ef51e8934a |
comparison
equal
deleted
inserted
replaced
1200:0ae013f630fa | 1201:2ae8155baef1 |
---|---|
12 * Lesser General Public License for more details. | 12 * Lesser General Public License for more details. |
13 * | 13 * |
14 * You should have received a copy of the GNU Lesser General Public | 14 * You should have received a copy of the GNU Lesser General Public |
15 * License along with this library; if not, write to the Free Software | 15 * License along with this library; if not, write to the Free Software |
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
17 */ | 17 */ |
18 | 18 |
19 #include "audacious/output.h" | 19 #include "audacious/output.h" |
20 #include "audacious/plugin.h" | 20 #include "audacious/plugin.h" |
21 #include "audacious/titlestring.h" | 21 #include "audacious/titlestring.h" |
22 #include "audacious/util.h" | 22 #include "audacious/util.h" |
25 #include <stdlib.h> | 25 #include <stdlib.h> |
26 #include <string.h> | 26 #include <string.h> |
27 #include <unistd.h> | 27 #include <unistd.h> |
28 #include "driver.h" | 28 #include "driver.h" |
29 | 29 |
30 #define CMD_SEEK 0x80000000 | 30 #define CMD_SEEK 0x80000000 |
31 #define CMD_STOP 0x40000000 | 31 #define CMD_STOP 0x40000000 |
32 | 32 |
33 #define uint32 u32 | 33 static volatile int seek_time = 0; |
34 #define int16 short | 34 static volatile int stop = 0; |
35 | |
36 static volatile uint32 command; | |
37 static volatile int playing=0; | 35 static volatile int playing=0; |
38 static volatile int nextsong=0; | 36 static volatile int nextsong=0; |
39 | 37 |
40 extern InputPlugin sexypsf_ip; | 38 extern InputPlugin sexypsf_ip; |
41 static char *fnsave=NULL; | 39 static char *fnsave = NULL; |
42 | 40 |
43 static gchar *get_title_psf(gchar *fn); | 41 static gchar *get_title_psf(gchar *fn); |
44 static int paused; | 42 static short paused; |
45 static GThread *dethread; | 43 static GThread *dethread; |
46 static PSFINFO *PSFInfo=NULL; | 44 static PSFINFO *PSFInfo = NULL; |
45 static InputPlayback *playback; | |
47 | 46 |
48 static int is_our_fd(gchar *filename, VFSFile *file) { | 47 static int is_our_fd(gchar *filename, VFSFile *file) { |
49 gchar magic[4], *tmps; | 48 gchar magic[4]; |
50 // Filter out psflib [we use them, but we can't play them] | 49 vfs_fread(magic, 1, 4, file); |
51 static const gchar *teststr = "psflib"; | 50 |
52 if (strlen(teststr) < strlen(filename)) { | 51 // only allow PSF1 for now |
53 tmps = filename + strlen(filename); | 52 if (!memcmp(magic, "PSF\x01", 4)) |
54 tmps -= strlen(teststr); | 53 return 1; |
55 if (!strcasecmp(tmps, teststr)) | 54 return 0; |
56 return 0; | 55 } |
57 } | 56 |
58 vfs_fread(magic,1,4,file); | 57 |
59 //Only allow PSF1 for now. | 58 void sexypsf_update(unsigned char *buffer, long count) |
60 if (!memcmp(magic,"PSF\x01",4)) | 59 { |
61 return 1; | 60 const int mask = ~((((16 / 8) * 2)) - 1); |
62 return 0; | 61 |
63 } | 62 while (count > 0) |
64 | 63 { |
65 static void SI(gchar *filename) | 64 int t = playback->output->buffer_free() & mask; |
66 { | 65 if (t > count) |
67 gchar *name = get_title_psf(filename); | 66 produce_audio(playback->output->written_time(), FMT_S16_NE, 2, count, buffer, NULL); |
68 sexypsf_ip.set_info(name,PSFInfo->length,44100*2*2*8,44100,2); | 67 else |
69 g_free(name); | 68 { |
70 } | 69 if (t) |
71 | 70 produce_audio(playback->output->written_time(), FMT_S16_NE, 2, t, buffer, NULL); |
72 static InputPlayback *playback; | 71 g_usleep((count-t)*1000*5/441/2); |
73 | 72 } |
74 void sexypsf_update(unsigned char *Buffer, long count) | 73 count -= t; |
75 { | 74 buffer += t; |
76 int mask = ~((((16 / 8) * 2)) - 1); | 75 } |
77 | 76 if (seek_time) |
78 while(count>0) | 77 { |
79 { | 78 if(sexypsf_seek(seek_time)) |
80 int t=playback->output->buffer_free() & mask; | 79 playback->output->flush(seek_time); |
81 if(t>count) | 80 // negative time - must make a C time machine |
82 produce_audio(playback->output->written_time(), FMT_S16_NE, 2, count, Buffer, NULL); | 81 else |
83 else | 82 { |
84 { | 83 sexypsf_stop(); |
85 if(t) | 84 return; |
86 produce_audio(playback->output->written_time(), FMT_S16_NE, 2, t, Buffer, NULL); | 85 } |
87 g_usleep((count-t)*1000*5/441/2); | 86 seek_time = 0; |
88 } | 87 } |
89 count-=t; | 88 if (stop) |
90 Buffer+=t; | 89 sexypsf_stop(); |
91 } | 90 } |
92 if(command&CMD_SEEK) | 91 |
93 { | 92 static gpointer sexypsf_playloop(gpointer arg) |
94 int t=(command&~(CMD_SEEK|CMD_STOP))*1000; | |
95 | |
96 if(sexypsf_seek(t)) | |
97 playback->output->flush(t); | |
98 else // Negative time! Must make a C time machine. | |
99 { | |
100 sexypsf_stop(); | |
101 return; | |
102 } | |
103 command&=~CMD_SEEK; | |
104 } | |
105 if(command&CMD_STOP) | |
106 sexypsf_stop(); | |
107 } | |
108 | |
109 static void *sexypsf_playloop(void *arg) | |
110 { | 93 { |
111 dofunky: | 94 dofunky: |
112 | 95 |
113 sexypsf_execute(); | 96 sexypsf_execute(); |
114 | 97 |
115 /* We have reached the end of the song. Now what... */ | 98 /* we have reached the end of the song */ |
116 playback->output->buffer_free(); | 99 |
117 playback->output->buffer_free(); | 100 playback->output->buffer_free(); |
118 | 101 playback->output->buffer_free(); |
119 while(!(command&CMD_STOP)) | 102 |
120 { | 103 while (!(stop)) |
121 if(command&CMD_SEEK) | 104 { |
122 { | 105 if (seek_time) |
123 int t=(command&~(CMD_SEEK|CMD_STOP))*1000; | 106 { |
124 playback->output->flush(t); | 107 playback->output->flush(seek_time); |
125 if(!(PSFInfo=sexypsf_load(fnsave))) | 108 if(!(PSFInfo=sexypsf_load(fnsave))) |
126 break; | 109 break; |
127 sexypsf_seek(t); | 110 sexypsf_seek(seek_time); |
128 command&=~CMD_SEEK; | 111 seek_time = 0; |
129 goto dofunky; | 112 goto dofunky; |
130 } | 113 } |
131 if(!playback->output->buffer_playing()) break; | 114 if (!playback->output->buffer_playing()) break; |
132 usleep(2000); | 115 usleep(2000); |
133 } | 116 } |
134 playback->output->close_audio(); | 117 playback->output->close_audio(); |
135 if(!(command&CMD_STOP)) nextsong=1; | 118 if(!(stop)) nextsong=1; |
136 g_thread_exit(NULL); | 119 g_thread_exit(NULL); |
137 return(NULL); | 120 return NULL; |
138 } | 121 } |
139 | 122 |
140 static void sexypsf_xmms_play(InputPlayback *data) | 123 static void sexypsf_xmms_play(InputPlayback *data) |
141 { | 124 { |
142 char *fn = data->filename; | 125 char *fn = data->filename; |
143 if(playing) | 126 if(playing) |
144 return; | 127 return; |
145 playback = data; | 128 playback = data; |
146 nextsong=0; | 129 nextsong=0; |
147 paused = 0; | 130 paused = 0; |
148 if(!playback->output->open_audio(FMT_S16_NE, 44100, 2)) | 131 if(!playback->output->open_audio(FMT_S16_NE, 44100, 2)) |
149 { | 132 { |
150 puts("Error opening audio."); | 133 puts("Error opening audio."); |
151 return; | 134 return; |
152 } | 135 } |
153 fnsave=malloc(strlen(fn)+1); | 136 fnsave=malloc(strlen(fn)+1); |
154 strcpy(fnsave,fn); | 137 strcpy(fnsave,fn); |
155 if(!(PSFInfo=sexypsf_load(fn))) | 138 if(!(PSFInfo=sexypsf_load(fn))) |
156 { | 139 { |
157 playback->output->close_audio(); | 140 playback->output->close_audio(); |
158 nextsong=1; | 141 nextsong=1; |
159 } | 142 } |
160 else | 143 else |
161 { | 144 { |
162 command=0; | 145 stop = seek_time = 0; |
163 SI(fn); | 146 |
164 playing=1; | 147 gchar *name = get_title_psf(fn); |
165 dethread = g_thread_create((GThreadFunc)sexypsf_playloop,NULL,TRUE,NULL); | 148 sexypsf_ip.set_info(name,PSFInfo->length,44100*2*2*8,44100,2); |
166 } | 149 g_free(name); |
150 | |
151 playing=1; | |
152 dethread = g_thread_create((GThreadFunc)sexypsf_playloop,NULL,TRUE,NULL); | |
153 } | |
167 } | 154 } |
168 | 155 |
169 static void sexypsf_xmms_stop(InputPlayback * playback) | 156 static void sexypsf_xmms_stop(InputPlayback * playback) |
170 { | 157 { |
171 if(!playing) return; | 158 if(!playing) return; |
172 | 159 |
173 if(paused) | 160 if(paused) |
174 playback->output->pause(0); | 161 playback->output->pause(0); |
175 paused = 0; | 162 paused = 0; |
176 | 163 |
177 command=CMD_STOP; | 164 stop = TRUE; |
178 g_thread_join(dethread); | 165 g_thread_join(dethread); |
179 playing = 0; | 166 playing = 0; |
180 | 167 |
181 if(fnsave) | 168 if(fnsave) |
182 { | 169 { |
183 free(fnsave); | 170 free(fnsave); |
184 fnsave=NULL; | 171 fnsave=NULL; |
185 } | 172 } |
186 sexypsf_freepsfinfo(PSFInfo); | 173 sexypsf_freepsfinfo(PSFInfo); |
187 PSFInfo=NULL; | 174 PSFInfo=NULL; |
188 } | 175 } |
189 | 176 |
190 static void sexypsf_xmms_pause(InputPlayback * playback, short p) | 177 static void sexypsf_xmms_pause(InputPlayback * playback, short p) |
191 { | 178 { |
192 if(!playing) return; | 179 if(!playing) return; |
193 playback->output->pause(p); | 180 playback->output->pause(p); |
194 paused = p; | 181 paused = p; |
195 } | 182 } |
196 | 183 |
197 static void sexypsf_xmms_seek(InputPlayback * data, int time) | 184 static void sexypsf_xmms_seek(InputPlayback * data, int time) |
198 { | 185 { |
199 if(!playing) return; | 186 if(!playing) return; |
200 command=CMD_SEEK|time; | 187 seek_time = time * 1000; |
201 } | 188 } |
202 | 189 |
203 static int sexypsf_xmms_gettime(InputPlayback *playback) | 190 static int sexypsf_xmms_gettime(InputPlayback *playback) |
204 { | 191 { |
205 if(nextsong) | 192 if(nextsong) |
206 return(-1); | 193 return(-1); |
207 if(!playing) return(0); | 194 if(!playing) return(0); |
208 return playback->output->output_time(); | 195 return playback->output->output_time(); |
209 } | 196 } |
210 | 197 |
211 static void sexypsf_xmms_getsonginfo(char *fn, char **title, int *length) | 198 static void sexypsf_xmms_getsonginfo(char *fn, char **title, int *length) |
212 { | 199 { |
213 PSFINFO *tmp; | 200 PSFINFO *tmp; |
214 | 201 |
215 if((tmp=sexypsf_getpsfinfo(fn))) { | 202 if((tmp=sexypsf_getpsfinfo(fn))) { |
216 *length = tmp->length; | 203 *length = tmp->length; |
217 *title = get_title_psf(fn); | 204 *title = get_title_psf(fn); |
218 sexypsf_freepsfinfo(tmp); | 205 sexypsf_freepsfinfo(tmp); |
219 } | 206 } |
220 } | 207 } |
221 | 208 |
222 static TitleInput *get_tuple_psf(gchar *fn) { | 209 static TitleInput *get_tuple_psf(gchar *fn) { |
223 TitleInput *tuple = NULL; | 210 TitleInput *tuple = NULL; |
224 PSFINFO *tmp = sexypsf_getpsfinfo(fn); | 211 PSFINFO *tmp = sexypsf_getpsfinfo(fn); |
225 | 212 |
226 if (tmp->length) { | 213 if (tmp->length) { |
227 tuple = bmp_title_input_new(); | 214 tuple = bmp_title_input_new(); |
228 tuple->length = tmp->length; | 215 tuple->length = tmp->length; |
229 tuple->performer = g_strdup(tmp->artist); | 216 tuple->performer = g_strdup(tmp->artist); |
230 tuple->album_name = g_strdup(tmp->game); | 217 tuple->album_name = g_strdup(tmp->game); |
231 tuple->track_name = g_strdup(tmp->title); | 218 tuple->track_name = g_strdup(tmp->title); |
232 tuple->file_name = g_path_get_basename(fn); | 219 tuple->file_name = g_path_get_basename(fn); |
233 tuple->file_path = g_path_get_dirname(fn); | 220 tuple->file_path = g_path_get_dirname(fn); |
234 } | 221 sexypsf_freepsfinfo(tmp); |
235 | 222 } |
236 return tuple; | 223 |
237 } | 224 return tuple; |
225 } | |
238 | 226 |
239 static gchar *get_title_psf(gchar *fn) { | 227 static gchar *get_title_psf(gchar *fn) { |
240 gchar *title; | 228 gchar *title; |
241 TitleInput *tinput = get_tuple_psf(fn); | 229 TitleInput *tinput = get_tuple_psf(fn); |
242 | 230 |
243 if (tinput != NULL) { | 231 if (tinput != NULL) { |
244 title = xmms_get_titlestring(xmms_get_gentitle_format(), | 232 title = xmms_get_titlestring(xmms_get_gentitle_format(), |
245 tinput); | 233 tinput); |
246 bmp_title_input_free(tinput); | 234 bmp_title_input_free(tinput); |
247 } | 235 } |
248 else | 236 else |
249 title = g_path_get_basename(fn); | 237 title = g_path_get_basename(fn); |
250 | 238 |
251 return title; | 239 return title; |
252 } | 240 } |
253 | 241 |
254 gchar *sexypsf_fmts[] = { "psf", "minipsf", NULL }; | 242 gchar *sexypsf_fmts[] = { "psf", "minipsf", NULL }; |
255 | 243 |
256 InputPlugin sexypsf_ip = | 244 InputPlugin sexypsf_ip = |
257 { | 245 { |
258 NULL, | 246 NULL, |
259 NULL, | 247 NULL, |
260 "PSF Audio Plugin", | 248 "PSF Audio Plugin", |
261 NULL, | 249 NULL, |
262 NULL, | 250 NULL, |
263 NULL, | 251 NULL, |
264 NULL, | 252 NULL, |
265 NULL, | 253 NULL, |
266 sexypsf_xmms_play, | 254 sexypsf_xmms_play, |
267 sexypsf_xmms_stop, | 255 sexypsf_xmms_stop, |
268 sexypsf_xmms_pause, | 256 sexypsf_xmms_pause, |
269 sexypsf_xmms_seek, | 257 sexypsf_xmms_seek, |
270 NULL, | 258 NULL, |
271 sexypsf_xmms_gettime, | 259 sexypsf_xmms_gettime, |
272 NULL, | 260 NULL, |
273 NULL, | 261 NULL, |
274 NULL, | 262 NULL, |
275 NULL, | 263 NULL, |
276 NULL, | 264 NULL, |
277 NULL, | 265 NULL, |
278 NULL, | 266 NULL, |
279 sexypsf_xmms_getsonginfo, | 267 sexypsf_xmms_getsonginfo, |
280 NULL, | 268 NULL, |
281 NULL, | 269 NULL, |
282 get_tuple_psf, | 270 get_tuple_psf, |
283 NULL, | 271 NULL, |
284 NULL, | 272 NULL, |
285 is_our_fd, | 273 is_our_fd, |
286 sexypsf_fmts, | 274 sexypsf_fmts, |
287 }; | 275 }; |
288 | 276 |
289 InputPlugin *sexypsf_iplist[] = { &sexypsf_ip, NULL }; | 277 InputPlugin *sexypsf_iplist[] = { &sexypsf_ip, NULL }; |
290 | 278 |
291 DECLARE_PLUGIN(sexypsf, NULL, NULL, sexypsf_iplist, NULL, NULL, NULL, NULL); | 279 DECLARE_PLUGIN(sexypsf, NULL, NULL, sexypsf_iplist, NULL, NULL, NULL, NULL); |