Mercurial > audlegacy-plugins
annotate src/xsf/plugin.c @ 3047:4434b4c4a715
ported EsounD plugin
author | Andrew O. Shadoura <bugzilla@tut.by> |
---|---|
date | Fri, 17 Apr 2009 16:17:10 +0300 |
parents | 3134a0987162 |
children |
rev | line source |
---|---|
2961 | 1 /* |
2 Audio Overload SDK - main driver. for demonstration only, not user friendly! | |
3 | |
4 Copyright (c) 2007-2008 R. Belmont and Richard Bannister. | |
5 | |
6 All rights reserved. | |
7 | |
8 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: | |
9 | |
10 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. | |
11 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. | |
12 * Neither the names of R. Belmont and Richard Bannister nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. | |
13 | |
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
15 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
16 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
17 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | |
18 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
19 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
20 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
21 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |
22 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
23 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
24 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
25 */ | |
26 | |
27 #include <stdio.h> | |
28 #include <stdlib.h> | |
29 #include <string.h> | |
30 | |
2971
3134a0987162
- changed include path from audacious to audlegacy.
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
2965
diff
changeset
|
31 #include <audlegacy/plugin.h> |
2961 | 32 |
33 #include "ao.h" | |
34 #include "corlett.h" | |
35 #include "vio2sf.h" | |
36 | |
37 /* xsf_get_lib: called to load secondary files */ | |
38 static gchar *path; | |
39 int xsf_get_lib(char *filename, void **buffer, unsigned int *length) | |
40 { | |
41 guchar *filebuf; | |
42 gsize size; | |
43 char buf[PATH_MAX]; | |
44 | |
45 snprintf(buf, PATH_MAX, "%s/%s", dirname(path), filename); | |
46 | |
47 aud_vfs_file_get_contents(buf, (gchar **) &filebuf, &size); | |
48 | |
49 *buffer = filebuf; | |
50 *length = (uint64)size; | |
51 | |
52 return AO_SUCCESS; | |
53 } | |
54 | |
55 static gint seek = 0; | |
56 Tuple *xsf_tuple(gchar *filename) | |
57 { | |
58 Tuple *t; | |
59 corlett_t *c; | |
60 guchar *buf; | |
61 gsize sz; | |
62 | |
63 aud_vfs_file_get_contents(filename, (gchar **) &buf, &sz); | |
64 | |
65 if (!buf) | |
66 return NULL; | |
67 | |
68 if (corlett_decode(buf, sz, NULL, NULL, &c) != AO_SUCCESS) | |
69 return NULL; | |
70 | |
71 t = aud_tuple_new_from_filename(filename); | |
72 | |
73 aud_tuple_associate_int(t, FIELD_LENGTH, NULL, c->inf_length ? psfTimeToMS(c->inf_length) + psfTimeToMS(c->inf_fade) : -1); | |
74 aud_tuple_associate_string(t, FIELD_ARTIST, NULL, c->inf_artist); | |
75 aud_tuple_associate_string(t, FIELD_ALBUM, NULL, c->inf_game); | |
76 aud_tuple_associate_string(t, -1, "game", c->inf_game); | |
77 aud_tuple_associate_string(t, FIELD_TITLE, NULL, c->inf_title); | |
78 aud_tuple_associate_string(t, FIELD_COPYRIGHT, NULL, c->inf_copy); | |
79 aud_tuple_associate_string(t, FIELD_QUALITY, NULL, "sequenced"); | |
80 aud_tuple_associate_string(t, FIELD_CODEC, NULL, "Nintendo DS Audio"); | |
81 aud_tuple_associate_string(t, -1, "console", "Nintendo DS"); | |
82 | |
83 free(c); | |
84 g_free(buf); | |
85 | |
86 return t; | |
87 } | |
88 | |
89 gchar *xsf_title(gchar *filename, gint *length) | |
90 { | |
91 gchar *title = NULL; | |
92 Tuple *tuple = xsf_tuple(filename); | |
93 | |
94 if (tuple != NULL) | |
95 { | |
96 title = aud_tuple_formatter_make_title_string(tuple, aud_get_gentitle_format()); | |
97 *length = aud_tuple_get_int(tuple, FIELD_LENGTH, NULL); | |
98 aud_tuple_free(tuple); | |
99 } | |
100 else | |
101 { | |
102 title = g_path_get_basename(filename); | |
103 *length = -1; | |
104 } | |
105 | |
106 return title; | |
107 } | |
108 | |
109 void xsf_update(unsigned char *buffer, long count, InputPlayback *playback); | |
110 | |
111 void xsf_play(InputPlayback *data) | |
112 { | |
113 guchar *buffer; | |
114 gsize size; | |
115 gint length; | |
116 gchar *title = xsf_title(data->filename, &length); | |
117 gint16 samples[44100*2]; | |
118 gint seglen = 44100 / 60; | |
2965
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
119 gfloat pos; |
2961 | 120 |
121 path = g_strdup(data->filename); | |
122 aud_vfs_file_get_contents(data->filename, (gchar **) &buffer, &size); | |
123 | |
124 if (xsf_start(buffer, size) != AO_SUCCESS) | |
125 { | |
126 free(buffer); | |
127 return; | |
128 } | |
129 | |
130 data->output->open_audio(FMT_S16_NE, 44100, 2); | |
131 | |
132 data->set_params(data, title, length, 44100*2*2*8, 44100, 2); | |
133 | |
134 data->playing = TRUE; | |
135 data->set_pb_ready(data); | |
136 | |
137 for (;;) | |
138 { | |
2964
629d5494c8f1
Ok, really fix the EOF stuff.
William Pitcock <nenolod@atheme.org>
parents:
2962
diff
changeset
|
139 while (data->playing && !seek && !data->eof) |
2961 | 140 { |
141 xsf_gen(samples, seglen); | |
142 xsf_update(samples, seglen * 4, data); | |
143 | |
2964
629d5494c8f1
Ok, really fix the EOF stuff.
William Pitcock <nenolod@atheme.org>
parents:
2962
diff
changeset
|
144 if (data->output->output_time() > length) |
2961 | 145 data->eof = TRUE; |
146 } | |
147 | |
148 if (seek) | |
149 { | |
2965
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
150 if (seek > data->output->output_time()) |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
151 { |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
152 pos = data->output->output_time(); |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
153 while (pos < seek) |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
154 { |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
155 xsf_gen(samples, seglen); |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
156 pos += 16.666; |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
157 } |
2961 | 158 |
2965
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
159 data->output->flush(seek); |
2961 | 160 seek = 0; |
2965
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
161 |
2961 | 162 continue; |
163 } | |
2965
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
164 else if (seek < data->output->output_time()) |
2961 | 165 { |
2965
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
166 data->eof = FALSE; |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
167 |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
168 g_print("xsf_term\n"); |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
169 xsf_term(); |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
170 |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
171 g_print("xsf_start... "); |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
172 if (xsf_start(buffer, size) == AO_SUCCESS) |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
173 { |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
174 g_print("ok!\n"); |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
175 pos = 0; |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
176 while (pos < seek) |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
177 { |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
178 xsf_gen(samples, seglen); |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
179 pos += 16.666; /* each segment is 16.666ms */ |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
180 } |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
181 |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
182 data->output->flush(seek); |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
183 seek = 0; |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
184 |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
185 continue; |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
186 } |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
187 else |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
188 { |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
189 g_print("fail :(\n"); |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
190 |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
191 data->output->close_audio(); |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
192 |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
193 g_free(buffer); |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
194 g_free(path); |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
195 g_free(title); |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
196 |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
197 data->playing = FALSE; |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
198 |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
199 return; |
6013ab159139
Make forward seeking work. Backwards seeking is still not working.
William Pitcock <nenolod@atheme.org>
parents:
2964
diff
changeset
|
200 } |
2961 | 201 } |
202 } | |
203 | |
204 xsf_term(); | |
205 | |
206 data->output->buffer_free(); | |
207 data->output->buffer_free(); | |
208 | |
209 while (data->eof && data->output->buffer_playing()) | |
210 g_usleep(10000); | |
211 | |
212 data->output->close_audio(); | |
213 | |
214 break; | |
215 } | |
216 | |
217 g_free(buffer); | |
218 g_free(path); | |
219 g_free(title); | |
220 | |
221 data->playing = FALSE; | |
222 } | |
223 | |
224 void xsf_update(unsigned char *buffer, long count, InputPlayback *playback) | |
225 { | |
226 const int mask = ~((((16 / 8) * 2)) - 1); | |
227 | |
228 if (buffer == NULL) | |
229 { | |
230 playback->playing = FALSE; | |
231 playback->eof = TRUE; | |
232 | |
233 return; | |
234 } | |
235 | |
236 while (count > 0) | |
237 { | |
238 int t = playback->output->buffer_free() & mask; | |
239 if (t > count) | |
240 playback->pass_audio(playback, FMT_S16_NE, 2, count, buffer, NULL); | |
241 else | |
242 { | |
243 if (t) | |
244 playback->pass_audio(playback, FMT_S16_NE, 2, t, buffer, NULL); | |
245 | |
246 g_usleep((count-t)*1000*5/441/2); | |
247 } | |
248 count -= t; | |
249 buffer += t; | |
250 } | |
251 } | |
252 | |
253 void xsf_Stop(InputPlayback *playback) | |
254 { | |
255 playback->playing = FALSE; | |
256 } | |
257 | |
258 void xsf_pause(InputPlayback *playback, short p) | |
259 { | |
260 playback->output->pause(p); | |
261 } | |
262 | |
263 int xsf_is_our_fd(gchar *filename, VFSFile *file) | |
264 { | |
265 gchar magic[4]; | |
266 aud_vfs_fread(magic, 1, 4, file); | |
267 | |
268 if (!memcmp(magic, "PSF$", 4)) | |
269 return 1; | |
270 | |
271 return 0; | |
272 } | |
273 | |
274 void xsf_Seek(InputPlayback *playback, int time) | |
275 { | |
276 seek = time * 1000; | |
277 } | |
278 | |
279 gchar *xsf_fmts[] = { "2sf", "mini2sf", NULL }; | |
280 | |
281 InputPlugin xsf_ip = | |
282 { | |
283 .description = "2SF Audio Plugin", | |
284 .play_file = xsf_play, | |
285 .stop = xsf_Stop, | |
286 .pause = xsf_pause, | |
287 .seek = xsf_Seek, | |
288 .get_song_tuple = xsf_tuple, | |
289 .is_our_file_from_vfs = xsf_is_our_fd, | |
290 .vfs_extensions = xsf_fmts, | |
291 }; | |
292 | |
293 InputPlugin *xsf_iplist[] = { &xsf_ip, NULL }; | |
294 | |
295 DECLARE_PLUGIN(psf2, NULL, NULL, xsf_iplist, NULL, NULL, NULL, NULL, NULL); | |
296 |