Mercurial > audlegacy-plugins
comparison src/Input/wav/wav-sndfile.c @ 0:13389e613d67 trunk
[svn] - initial import of audacious-plugins tree (lots to do)
author | nenolod |
---|---|
date | Mon, 18 Sep 2006 01:11:49 -0700 |
parents | |
children | 0ad4849f6219 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:13389e613d67 |
---|---|
1 /* Audacious - Cross-platform multimedia player | |
2 * Copyright (C) 2005 Audacious development team. | |
3 * | |
4 * Based on the xmms_sndfile input plugin: | |
5 * Copyright (C) 2000, 2002 Erik de Castro Lopo | |
6 * | |
7 * This program is free software; you can redistribute it and/or modify | |
8 * it under the terms of the GNU General Public License as published by | |
9 * the Free Software Foundation; either version 2 of the License, or | |
10 * (at your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, | |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 * GNU General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU General Public License | |
18 * along with this program; if not, write to the Free Software | |
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
20 */ | |
21 | |
22 #include <glib.h> | |
23 #include <glib/gi18n.h> | |
24 #include <string.h> | |
25 #include <math.h> | |
26 #include <stdio.h> | |
27 | |
28 #include <libaudacious/util.h> | |
29 #include <libaudacious/titlestring.h> | |
30 #include "audacious/output.h" | |
31 #include "wav-sndfile.h" | |
32 | |
33 #include <sndfile.h> | |
34 | |
35 static SNDFILE *sndfile = NULL; | |
36 static SF_INFO sfinfo; | |
37 | |
38 static int song_length; | |
39 static int bit_rate = 0; | |
40 static int decoding; | |
41 static int seek_time = -1; | |
42 | |
43 static GThread *decode_thread; | |
44 GStaticMutex decode_mutex = G_STATIC_MUTEX_INIT; | |
45 | |
46 InputPlugin wav_ip = { | |
47 NULL, | |
48 NULL, | |
49 NULL, | |
50 plugin_init, | |
51 wav_about, | |
52 NULL, | |
53 is_our_file, | |
54 NULL, | |
55 play_start, | |
56 play_stop, | |
57 NULL, /* Could call do_pause here, but it will cause auto-stop anyway */ | |
58 file_seek, | |
59 NULL, | |
60 get_time, | |
61 NULL, | |
62 NULL, | |
63 NULL, | |
64 NULL, | |
65 NULL, | |
66 NULL, | |
67 NULL, | |
68 get_song_info, | |
69 NULL, | |
70 NULL | |
71 }; | |
72 | |
73 int | |
74 get_song_length (char *filename) | |
75 { SNDFILE *tmp_sndfile; | |
76 SF_INFO tmp_sfinfo; | |
77 | |
78 if (! (tmp_sndfile = sf_open (filename, SFM_READ, &tmp_sfinfo))) | |
79 return 0; | |
80 | |
81 sf_close (tmp_sndfile); | |
82 tmp_sndfile = NULL; | |
83 | |
84 if (tmp_sfinfo.samplerate <= 0) | |
85 return 0; | |
86 | |
87 return (int) ceil (1000.0 * tmp_sfinfo.frames / tmp_sfinfo.samplerate); | |
88 } /* get_song_length */ | |
89 | |
90 static gchar *get_title(char *filename) | |
91 { | |
92 gchar *title; | |
93 title = g_path_get_basename(filename); | |
94 return title; | |
95 } | |
96 | |
97 static void | |
98 plugin_init (void) | |
99 { | |
100 decoding = FALSE; | |
101 seek_time = -1; | |
102 } /* plugin_int */ | |
103 | |
104 static int | |
105 is_our_file (char *filename) | |
106 { SNDFILE *tmp_sndfile; | |
107 SF_INFO tmp_sfinfo; | |
108 | |
109 /* Have to open the file to see if libsndfile can handle it. */ | |
110 if (! (tmp_sndfile = sf_open (filename, SFM_READ, &tmp_sfinfo))) | |
111 return FALSE; | |
112 | |
113 /* It can so close file and return TRUE. */ | |
114 sf_close (tmp_sndfile); | |
115 tmp_sndfile = NULL; | |
116 | |
117 return TRUE; | |
118 } /* is_our_file */ | |
119 | |
120 static void* | |
121 play_loop (void *arg) | |
122 { static short buffer [BUFFER_SIZE]; | |
123 int samples; | |
124 | |
125 g_static_mutex_lock(&decode_mutex); | |
126 | |
127 decoding = TRUE; | |
128 while (decoding) | |
129 { | |
130 /* sf_read_short will return 0 for all reads at EOF. */ | |
131 samples = sf_read_short (sndfile, buffer, BUFFER_SIZE); | |
132 | |
133 if (samples > 0 && decoding) | |
134 { while ((wav_ip.output->buffer_free () < (samples * sizeof (short))) && decoding) | |
135 xmms_usleep (10000); | |
136 | |
137 produce_audio (wav_ip.output->written_time (), FMT_S16_NE, sfinfo.channels, | |
138 samples * sizeof (short), buffer, &decoding); | |
139 } | |
140 else | |
141 xmms_usleep (10000); | |
142 | |
143 /* Do seek if seek_time is valid. */ | |
144 if (seek_time > 0) | |
145 { sf_seek (sndfile, seek_time * sfinfo.samplerate, SEEK_SET); | |
146 wav_ip.output->flush (seek_time * 1000); | |
147 seek_time = -1; | |
148 }; | |
149 | |
150 }; /* while (decoding) */ | |
151 | |
152 g_static_mutex_unlock(&decode_mutex); | |
153 g_thread_exit (NULL); | |
154 return NULL; | |
155 } /* play_loop */ | |
156 | |
157 static void | |
158 play_start (char *filename) | |
159 { | |
160 int pcmbitwidth; | |
161 gchar *song_title; | |
162 | |
163 if (sndfile) | |
164 return; | |
165 | |
166 pcmbitwidth = 32; | |
167 | |
168 song_title = get_title(filename); | |
169 | |
170 if (! (sndfile = sf_open (filename, SFM_READ, &sfinfo))) | |
171 return; | |
172 | |
173 bit_rate = sfinfo.samplerate * pcmbitwidth * sfinfo.channels; | |
174 | |
175 if (sfinfo.samplerate > 0) | |
176 song_length = (int) ceil (1000.0 * sfinfo.frames / sfinfo.samplerate); | |
177 else | |
178 song_length = 0; | |
179 | |
180 if (! wav_ip.output->open_audio (FMT_S16_NE, sfinfo.samplerate, sfinfo.channels)) | |
181 { sf_close (sndfile); | |
182 sndfile = NULL; | |
183 return; | |
184 }; | |
185 | |
186 wav_ip.set_info (song_title, song_length, bit_rate, sfinfo.samplerate, sfinfo.channels); | |
187 g_free (song_title); | |
188 | |
189 decode_thread = g_thread_create ((GThreadFunc)play_loop, NULL, TRUE, NULL); | |
190 | |
191 xmms_usleep (40000); | |
192 } /* play_start */ | |
193 | |
194 static void | |
195 play_stop (void) | |
196 { | |
197 if (decode_thread == NULL) | |
198 return; | |
199 | |
200 decoding = FALSE; | |
201 | |
202 g_thread_join (decode_thread); | |
203 wav_ip.output->close_audio (); | |
204 | |
205 sf_close (sndfile); | |
206 sndfile = NULL; | |
207 decode_thread = NULL; | |
208 | |
209 seek_time = -1; | |
210 } /* play_stop */ | |
211 | |
212 static void | |
213 file_seek (int time) | |
214 { | |
215 if (! sfinfo.seekable) | |
216 return; | |
217 | |
218 seek_time = time; | |
219 | |
220 while (seek_time != -1) | |
221 xmms_usleep (80000); | |
222 } /* file_seek */ | |
223 | |
224 static int | |
225 get_time (void) | |
226 { | |
227 if ( ! (wav_ip.output->buffer_playing () && decoding)) | |
228 return -1; | |
229 | |
230 return wav_ip.output->output_time (); | |
231 } /* get_time */ | |
232 | |
233 static void | |
234 get_song_info (char *filename, char **title, int *length) | |
235 { | |
236 (*length) = get_song_length(filename); | |
237 (*title) = get_title(filename); | |
238 } /* get_song_info */ | |
239 | |
240 static void wav_about(void) | |
241 { | |
242 static GtkWidget *box; | |
243 if (!box) | |
244 { | |
245 box = xmms_show_message( | |
246 _("About sndfile WAV support"), | |
247 _("Adapted for Audacious usage by Tony Vroon <chainsaw@gentoo.org>\n" | |
248 "from the xmms_sndfile plugin which is:\n" | |
249 "Copyright (C) 2000, 2002 Erik de Castro Lopo\n\n" | |
250 "This program is free software ; you can redistribute it and/or modify \n" | |
251 "it under the terms of the GNU General Public License as published by \n" | |
252 "the Free Software Foundation ; either version 2 of the License, or \n" | |
253 "(at your option) any later version. \n \n" | |
254 "This program is distributed in the hope that it will be useful, \n" | |
255 "but WITHOUT ANY WARRANTY ; without even the implied warranty of \n" | |
256 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. \n" | |
257 "See the GNU General Public License for more details. \n\n" | |
258 "You should have received a copy of the GNU General Public \n" | |
259 "License along with this program ; if not, write to \n" | |
260 "the Free Software Foundation, Inc., \n" | |
261 "51 Franklin Street, Fifth Floor, \n" | |
262 "Boston, MA 02110-1301 USA"), | |
263 _("Ok"), FALSE, NULL, NULL); | |
264 g_signal_connect(G_OBJECT(box), "destroy", | |
265 (GCallback)gtk_widget_destroyed, &box); | |
266 } | |
267 } | |
268 | |
269 | |
270 InputPlugin *get_iplugin_info(void) | |
271 { | |
272 wav_ip.description = g_strdup_printf(_("sndfile WAV plugin")); | |
273 return &wav_ip; | |
274 } | |
275 |