source: roaraudio/plugins/xmms/roar.c @ 461:a2704faf66d0

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

get song change to work

File size: 6.7 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 FALSE;
90}
91
92void roar_write(void *ptr, int length) {
93 int r;
94
95 if ( g_inst.pause )
96  return;
97
98 ROAR_DBG("roar_write(ptr=%p, length=%i) = (void)", ptr, length);
99
100 while (length) {
101  if ( (r = write(g_inst.data_fh, ptr, length >= 17640 ? 17640 : length)) != -1 ) {
102   g_inst.written   += r;
103   ptr              += r;
104   length           -= r;
105  } else {
106   return;
107  }
108 }
109}
110
111int roar_open(AFormat fmt, int rate, int nch) {
112 int codec = ROAR_CODEC_DEFAULT;
113 int bits;
114
115 if ( !(g_inst.state & STATE_CONNECTED) ) {
116  if ( roar_simple_connect(&(g_inst.con), g_inst.server, "XMMS") == -1 ) {
117   return FALSE;
118  }
119  g_inst.state |= STATE_CONNECTED;
120 }
121
122  bits = 16;
123  switch (fmt) {
124   case FMT_S8:
125     bits = 8;
126     codec = ROAR_CODEC_DEFAULT;
127    break;
128   case FMT_U8:
129     bits = 8;
130     codec = ROAR_CODEC_PCM_S_LE; // _LE, _BE, _PDP,... all the same for 8 bit output
131    break;
132   case FMT_U16_LE:
133     codec = ROAR_CODEC_PCM_U_LE;
134    break;
135   case FMT_U16_BE:
136     codec = ROAR_CODEC_PCM_U_BE;
137    break;
138   case FMT_U16_NE:
139#if BYTE_ORDER == BIG_ENDIAN
140     codec = ROAR_CODEC_PCM_U_BE;
141#elif BYTE_ORDER == LITTLE_ENDIAN
142     codec = ROAR_CODEC_PCM_U_LE;
143#else
144     codec = ROAR_CODEC_PCM_U_PDP;
145#endif
146    break;
147   case FMT_S16_LE:
148     codec = ROAR_CODEC_PCM_S_LE;
149    break;
150   case FMT_S16_BE:
151     codec = ROAR_CODEC_PCM_S_BE;
152    break;
153   case FMT_S16_NE:
154     codec = ROAR_CODEC_DEFAULT;
155    break;
156 }
157
158 g_inst.bps       = nch * rate * bits / 8;
159
160 if ( (g_inst.data_fh = roar_simple_new_stream_obj(&(g_inst.con), &(g_inst.stream),
161                              rate, nch, bits, codec, ROAR_DIR_PLAY)) == -1) {
162  return FALSE;
163 }
164 g_inst.state |= STATE_PLAYING;
165
166 g_inst.written = 0;
167 g_inst.pause   = 0;
168
169 roar_update_metadata();
170
171 return TRUE;
172}
173
174void roar_close(void) {
175 close(g_inst.data_fh);
176 g_inst.data_fh = -1;
177 g_inst.state |= STATE_PLAYING;
178 g_inst.state -= STATE_PLAYING;
179 g_inst.written = 0;
180 ROAR_DBG("roar_close(void) = (void)");
181}
182
183void roar_pause(short p) {
184 g_inst.pause = p;
185}
186
187int roar_free(void) {
188 if ( g_inst.pause )
189  return 0;
190 else
191  return 1000000; // ???
192}
193
194void roar_flush(int time) {
195 gint64 r = time;
196
197 r *= g_inst.bps;
198 r /= 1000;
199
200 g_inst.written = r;
201}
202
203int roar_get_output_time(void) {
204 return roar_get_written_time();
205}
206
207int roar_get_written_time(void) {
208 gint64 r;
209
210 if ( !g_inst.bps ) {
211  ROAR_DBG("roar_get_written_time(void) = 0");
212  return 0;
213 }
214
215 r  = g_inst.written;
216 r *= 1000; // sec -> msec
217 r /= g_inst.bps;
218 ROAR_DBG("roar_get_written_time(void) = %lu", r);
219
220 return r;
221}
222
223
224// ABOUT:
225
226void roar_about(void) {
227 static GtkWidget *dialog;
228
229 if (dialog != NULL)
230  return;
231
232 dialog = xmms_show_message(
233                _("About RoarAudio Plugin"),
234                _("RoarAudio XMMS Plugin..."
235                 ), _("OK"), FALSE, NULL, NULL);
236 gtk_signal_connect(GTK_OBJECT(dialog), "destroy",
237                    GTK_SIGNAL_FUNC(gtk_widget_destroyed),
238                    &dialog);
239}
240
241// CONFIG:
242
243// META DATA:
244
245int roar_update_metadata(void) {
246 struct roar_meta   meta;
247 char empty = 0;
248 char * info;
249 int pos;
250
251 pos     = xmms_remote_get_playlist_pos(g_inst.session);
252
253 meta.value = &empty;
254 meta.key[0] = 0;
255 meta.type = ROAR_META_TYPE_NONE;
256
257 roar_stream_meta_set(&(g_inst.con), &(g_inst.stream), ROAR_META_MODE_CLEAR, &meta);
258
259 info = xmms_remote_get_playlist_file(g_inst.session, pos);
260
261 if ( info ) {
262  if ( strncmp(info, "http:", 5) == 0 )
263   meta.type = ROAR_META_TYPE_FILEURL;
264  else
265   meta.type = ROAR_META_TYPE_FILENAME;
266
267  meta.value = info;
268  roar_stream_meta_set(&(g_inst.con), &(g_inst.stream), ROAR_META_MODE_SET, &meta);
269
270  free(info);
271 }
272
273 info = xmms_remote_get_playlist_title(g_inst.session, pos);
274
275 if ( info ) {
276  meta.type = ROAR_META_TYPE_TITLE;
277
278  meta.value = info;
279  roar_stream_meta_set(&(g_inst.con), &(g_inst.stream), ROAR_META_MODE_SET, &meta);
280
281  free(info);
282 }
283
284 return 0;
285}
286
287int roar_chk_metadata(void) {
288 static int    old_pos = -1;
289 static char * old_title = "NEW TITLE";
290 int pos;
291 char * title;
292 int need_update = 0;
293
294 pos     = xmms_remote_get_playlist_pos(g_inst.session);
295
296 if ( pos != old_pos ) {
297  old_pos = pos;
298  need_update = 1;
299 } else {
300  title = xmms_remote_get_playlist_title(g_inst.session, pos);
301
302  if ( strcmp(title, old_title) ) {
303   free(old_title);
304   old_title = title;
305   need_update = 1;
306  } else {
307   free(title);
308  }
309 }
310
311 if ( need_update ) {
312  roar_update_metadata();
313 }
314
315 return 0;
316}
317
318// MIXER:
319
320void roar_get_volume(int *l, int *r) {
321 int channels;
322 struct roar_mixer_settings mixer;
323
324 if ( !(g_inst.state & STATE_CONNECTED) )
325  return;
326
327 if ( roar_get_vol(&(g_inst.con), g_inst.stream.id, &mixer, &channels) == -1 ) {
328  *l = *r = 100;
329  return;
330 }
331
332 if ( channels == 1 ) {
333  *l = *r = mixer.mixer[0]/655.35;
334 } else {
335  *l = mixer.mixer[0]/655.35;
336  *r = mixer.mixer[1]/655.35;
337 }
338}
339
340void roar_set_volume(int l, int r) {
341 struct roar_mixer_settings mixer;
342
343 if ( !(g_inst.state & STATE_CONNECTED) )
344  return;
345
346 mixer.mixer[0] = l * 655.35;
347 mixer.mixer[1] = r * 655.35;
348
349 roar_set_vol(&(g_inst.con), g_inst.stream.id, &mixer, 2);
350}
351
352//ll
Note: See TracBrowser for help on using the repository browser.