source: roaraudio/plugins/xmms/roar.c @ 457:60f64b109d75

Last change on this file since 457:60f64b109d75 was 457:60f64b109d75, checked in by phi, 16 years ago

some non working pthread based meta data update code

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