source: roaraudio/plugins/xmms/roar.c @ 460:bd4644ea0cf7

Last change on this file since 460:bd4644ea0cf7 was 460:bd4644ea0cf7, checked in by phi, 16 years ago

copied some more code from esdout, now seeking works (why???, why not before?)

File size: 6.6 KB
Line 
1//roar.c:
2
3#include <roaraudio.h>
4
5//#include "xmms/i18n.h"
6#include <gtk/gtk.h>
7#include <stdio.h>
8#include <string.h>
9
10#include "xmms/plugin.h"
11#include "xmms/xmmsctrl.h"
12#include "xmms/dirbrowser.h"
13#include "xmms/configfile.h"
14#include "xmms/util.h"
15
16#define _(x) (x)
17
18gint ctrlsocket_get_session_id(void);
19
20void roar_init(void);
21void roar_about(void);
22void roar_configure(void);
23
24void roar_get_volume(int *l, int *r);
25void roar_set_volume(int l, int r);
26void roar_mixer_init(void);
27void roar_mixer_init_vol(int l, int r);
28
29int roar_playing(void);
30int roar_free(void);
31void roar_write(void *ptr, int length);
32void roar_close(void);
33void roar_flush(int time);
34void roar_pause(short p);
35int roar_open(AFormat fmt, int rate, int nch);
36int roar_get_output_time(void);
37int roar_get_written_time(void);
38
39int roar_update_metadata(void);
40int roar_chk_metadata(void);
41
42OutputPlugin roar_op = {
43        NULL,
44        NULL,
45        "RoarAudio XMMS Plugin", /* Description */
46        roar_init,
47        roar_about,
48        NULL, //roar_configure,
49        roar_get_volume,
50        roar_set_volume,
51        roar_open,
52        roar_write,
53        roar_close,
54        roar_flush,
55        roar_pause,
56        roar_free,
57        roar_playing,
58        roar_get_output_time,
59        roar_get_written_time,
60};
61
62#define STATE_CONNECTED 1
63#define STATE_PLAYING   2
64
65struct xmms_roar_out {
66 int state;
67 char * server;
68 struct roar_connection con;
69 struct roar_stream     stream;
70 int data_fh;
71 long unsigned int written;
72 long unsigned int bps;
73 int session;
74 int pause;
75} g_inst;
76
77OutputPlugin *get_oplugin_info(void) {
78 return &roar_op;
79}
80
81void roar_init(void) {
82 g_inst.state = 0;
83 g_inst.server = NULL;
84 g_inst.session = ctrlsocket_get_session_id();
85 ROAR_DBG("roar_init(*) = (void)");
86}
87
88int roar_playing(void) {
89 return g_inst.state & STATE_PLAYING ? TRUE : FALSE;
90}
91
92void roar_write(void *ptr, int length) {
93 int r;
94
95 if ( g_inst.pause )
96  return;
97
98 while (length) {
99  if ( (r = write(g_inst.data_fh, ptr, length >= 17640 ? 17640 : length)) != -1 ) {
100   g_inst.written   += r;
101   ptr              += r;
102   length           -= r;
103  } else {
104   return;
105  }
106 }
107}
108
109int roar_open(AFormat fmt, int rate, int nch) {
110 int codec = ROAR_CODEC_DEFAULT;
111 int bits;
112
113 if ( !(g_inst.state & STATE_CONNECTED) ) {
114  if ( roar_simple_connect(&(g_inst.con), g_inst.server, "XMMS") == -1 ) {
115   return FALSE;
116  }
117  g_inst.state |= STATE_CONNECTED;
118 }
119
120  bits = 16;
121  switch (fmt) {
122   case FMT_S8:
123     bits = 8;
124     codec = ROAR_CODEC_DEFAULT;
125    break;
126   case FMT_U8:
127     bits = 8;
128     codec = ROAR_CODEC_PCM_S_LE; // _LE, _BE, _PDP,... all the same for 8 bit output
129    break;
130   case FMT_U16_LE:
131     codec = ROAR_CODEC_PCM_U_LE;
132    break;
133   case FMT_U16_BE:
134     codec = ROAR_CODEC_PCM_U_BE;
135    break;
136   case FMT_U16_NE:
137#if BYTE_ORDER == BIG_ENDIAN
138     codec = ROAR_CODEC_PCM_U_BE;
139#elif BYTE_ORDER == LITTLE_ENDIAN
140     codec = ROAR_CODEC_PCM_U_LE;
141#else
142     codec = ROAR_CODEC_PCM_U_PDP;
143#endif
144    break;
145   case FMT_S16_LE:
146     codec = ROAR_CODEC_PCM_S_LE;
147    break;
148   case FMT_S16_BE:
149     codec = ROAR_CODEC_PCM_S_BE;
150    break;
151   case FMT_S16_NE:
152     codec = ROAR_CODEC_DEFAULT;
153    break;
154 }
155
156 g_inst.bps       = nch * rate * bits / 8;
157
158 if ( (g_inst.data_fh = roar_simple_new_stream_obj(&(g_inst.con), &(g_inst.stream),
159                              rate, nch, bits, codec, ROAR_DIR_PLAY)) == -1) {
160  return FALSE;
161 }
162 g_inst.state |= STATE_PLAYING;
163
164 g_inst.written = 0;
165 g_inst.pause   = 0;
166
167 roar_update_metadata();
168
169 return TRUE;
170}
171
172void roar_close(void) {
173 close(g_inst.data_fh);
174 g_inst.state |= STATE_PLAYING;
175 g_inst.state -= STATE_PLAYING;
176 g_inst.written = 0;
177}
178
179void roar_pause(short p) {
180 g_inst.pause = p;
181}
182
183int roar_free(void) {
184 if ( g_inst.pause )
185  return 0;
186 else
187  return 1000000; // ???
188}
189
190void roar_flush(int time) {
191 gint64 r = time;
192
193 r *= g_inst.bps;
194 r /= 1000;
195
196 g_inst.written = r;
197}
198
199int roar_get_output_time(void) {
200 return roar_get_written_time();
201}
202
203int roar_get_written_time(void) {
204 gint64 r;
205
206 if ( !g_inst.bps ) {
207  ROAR_DBG("roar_get_written_time(void) = 0");
208  return 0;
209 }
210
211 r  = g_inst.written;
212 r *= 1000; // sec -> msec
213 r /= g_inst.bps;
214 ROAR_DBG("roar_get_written_time(void) = %lu", r);
215
216 return r;
217}
218
219
220// ABOUT:
221
222void roar_about(void) {
223 static GtkWidget *dialog;
224
225 if (dialog != NULL)
226  return;
227
228 dialog = xmms_show_message(
229                _("About RoarAudio Plugin"),
230                _("RoarAudio XMMS Plugin..."
231                 ), _("OK"), FALSE, NULL, NULL);
232 gtk_signal_connect(GTK_OBJECT(dialog), "destroy",
233                    GTK_SIGNAL_FUNC(gtk_widget_destroyed),
234                    &dialog);
235}
236
237// CONFIG:
238
239// META DATA:
240
241int roar_update_metadata(void) {
242 struct roar_meta   meta;
243 char empty = 0;
244 char * info;
245 int pos;
246
247 pos     = xmms_remote_get_playlist_pos(g_inst.session);
248
249 meta.value = &empty;
250 meta.key[0] = 0;
251 meta.type = ROAR_META_TYPE_NONE;
252
253 roar_stream_meta_set(&(g_inst.con), &(g_inst.stream), ROAR_META_MODE_CLEAR, &meta);
254
255 info = xmms_remote_get_playlist_file(g_inst.session, pos);
256
257 if ( info ) {
258  if ( strncmp(info, "http:", 5) == 0 )
259   meta.type = ROAR_META_TYPE_FILEURL;
260  else
261   meta.type = ROAR_META_TYPE_FILENAME;
262
263  meta.value = info;
264  roar_stream_meta_set(&(g_inst.con), &(g_inst.stream), ROAR_META_MODE_SET, &meta);
265
266  free(info);
267 }
268
269 info = xmms_remote_get_playlist_title(g_inst.session, pos);
270
271 if ( info ) {
272  meta.type = ROAR_META_TYPE_TITLE;
273
274  meta.value = info;
275  roar_stream_meta_set(&(g_inst.con), &(g_inst.stream), ROAR_META_MODE_SET, &meta);
276
277  free(info);
278 }
279
280 return 0;
281}
282
283int roar_chk_metadata(void) {
284 static int    old_pos = -1;
285 static char * old_title = "NEW TITLE";
286 int pos;
287 char * title;
288 int need_update = 0;
289
290 pos     = xmms_remote_get_playlist_pos(g_inst.session);
291
292 if ( pos != old_pos ) {
293  old_pos = pos;
294  need_update = 1;
295 } else {
296  title = xmms_remote_get_playlist_title(g_inst.session, pos);
297
298  if ( strcmp(title, old_title) ) {
299   free(old_title);
300   old_title = title;
301   need_update = 1;
302  } else {
303   free(title);
304  }
305 }
306
307 if ( need_update ) {
308  roar_update_metadata();
309 }
310
311 return 0;
312}
313
314// MIXER:
315
316void roar_get_volume(int *l, int *r) {
317 int channels;
318 struct roar_mixer_settings mixer;
319
320 if ( !(g_inst.state & STATE_CONNECTED) )
321  return;
322
323 if ( roar_get_vol(&(g_inst.con), g_inst.stream.id, &mixer, &channels) == -1 ) {
324  *l = *r = 100;
325  return;
326 }
327
328 if ( channels == 1 ) {
329  *l = *r = mixer.mixer[0]/655.35;
330 } else {
331  *l = mixer.mixer[0]/655.35;
332  *r = mixer.mixer[1]/655.35;
333 }
334}
335
336void roar_set_volume(int l, int r) {
337 struct roar_mixer_settings mixer;
338
339 if ( !(g_inst.state & STATE_CONNECTED) )
340  return;
341
342 mixer.mixer[0] = l * 655.35;
343 mixer.mixer[1] = r * 655.35;
344
345 roar_set_vol(&(g_inst.con), g_inst.stream.id, &mixer, 2);
346}
347
348//ll
Note: See TracBrowser for help on using the repository browser.