comparison src/wav/wav-sndfile.c @ 12:3da1b8942b8b trunk

[svn] - remove src/Input src/Output src/Effect src/General src/Visualization src/Container
author nenolod
date Mon, 18 Sep 2006 03:14:20 -0700
parents src/Input/wav/wav-sndfile.c@0ad4849f6219
children d124034ebea3
comparison
equal deleted inserted replaced
11:cff1d04026ae 12:3da1b8942b8b
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 <audacious/util.h>
29 #include <audacious/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