source: roaraudio/plugins/audacious/roar.c @ 3105:eb48aea36705

Last change on this file since 3105:eb48aea36705 was 1700:8bdc09219ddb, checked in by phi, 15 years ago

interface has been changed

File size: 9.1 KB
Line 
1//roar.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft    - 2008,
5 *                    Daniel Duntemann <dauxx@dauxx.org> - 2009
6 *
7 *  This file is part of the Audacious RoarAudio output plugin a part of RoarAudio,
8 *  a cross-platform sound system for both, home and professional use.
9 *  See README for details.
10 *
11 *  This file is free software; you can redistribute it and/or modify
12 *  it under the terms of the GNU General Public License version 3
13 *  as published by the Free Software Foundation.
14 *
15 *  RoarAudio is distributed in the hope that it will be useful,
16 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 *  GNU General Public License for more details.
19 *
20 *  You should have received a copy of the GNU General Public License
21 *  along with this software; see the file COPYING.  If not, write to
22 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 */
25
26#include "all.h"
27
28// FIXME: This interface has been changed
29gint ctrlsocket_get_session_id(void) {
30 return -1;
31}
32
33OutputPlugin roar_op = {
34    .description = "RoarAudio Output Plugin",         
35    .init = roar_init,
36    .cleanup = NULL,
37    .about = roar_about,
38    .configure = roar_configure, 
39    .get_volume = roar_get_volume,
40    .set_volume = roar_set_volume,
41    .open_audio = roar_open, 
42    .write_audio = roar_write,
43    .close_audio = roar_close,
44    .flush = roar_flush,
45    .pause = roar_pause,
46    .buffer_free = roar_free,
47    .buffer_playing = roar_playing,
48    .output_time = roar_get_output_time, 
49    .written_time = roar_get_written_time,
50    .tell_audio = NULL
51};
52
53OutputPlugin *roar_oplist[] = { &roar_op, NULL };
54
55
56SIMPLE_OUTPUT_PLUGIN("RoarAudio Audacious Plugin",roar_oplist);
57
58OutputPlugin *get_oplugin_info(void) {
59 return &roar_op;
60}
61
62void roar_init(void) {
63 mcs_handle_t * cfgfile;
64
65 cfgfile = aud_cfg_db_open();
66
67 g_inst.state = 0;
68 g_inst.server = NULL;
69 g_inst.session = ctrlsocket_get_session_id();
70
71 aud_cfg_db_get_string(cfgfile, "ROAR", "server", &g_inst.server);
72
73 aud_cfg_db_get_string(cfgfile, "ROAR", "player_name", &g_inst.cfg.player_name);
74
75 aud_cfg_db_close(cfgfile);
76
77 if ( g_inst.cfg.player_name == NULL )
78  g_inst.cfg.player_name = "Audacious";
79
80 ROAR_DBG("roar_init(*) = (void)");
81}
82
83int roar_playing(void) {
84 return FALSE;
85}
86
87void roar_write(void *ptr, int length) {
88 int r;
89
90 if ( g_inst.pause )
91  return;
92
93 ROAR_DBG("roar_write(ptr=%p, length=%i) = (void)", ptr, length);
94
95 while (length) {
96  if ( (r = write(g_inst.data_fh, ptr, length >= 17640 ? 17640 : length)) != -1 ) {
97   g_inst.written   += r;
98   ptr              += r;
99   length           -= r;
100  } else {
101   return;
102  }
103 }
104}
105
106int roar_open(AFormat fmt, int rate, int nch) {
107 int codec = ROAR_CODEC_DEFAULT;
108 int bits;
109
110 if ( !(g_inst.state & STATE_CONNECTED) ) {
111  if ( roar_simple_connect(&(g_inst.con), g_inst.server, g_inst.cfg.player_name) == -1 ) {
112   return FALSE;
113  }
114  g_inst.state |= STATE_CONNECTED;
115 }
116
117  bits = 16;
118  switch (fmt) {
119   case FMT_S8:
120     bits = 8;
121     codec = ROAR_CODEC_DEFAULT;
122    break;
123   case FMT_U8:
124     bits = 8;
125     codec = ROAR_CODEC_PCM_U_LE; // _LE, _BE, _PDP,... all the same for 8 bit output
126    break;
127   case FMT_U16_LE:
128     codec = ROAR_CODEC_PCM_U_LE;
129    break;
130   case FMT_U16_BE:
131     codec = ROAR_CODEC_PCM_U_BE;
132    break;
133   case FMT_U16_NE:
134#if BYTE_ORDER == BIG_ENDIAN
135     codec = ROAR_CODEC_PCM_U_BE;
136#elif BYTE_ORDER == LITTLE_ENDIAN
137     codec = ROAR_CODEC_PCM_U_LE;
138#else
139     codec = ROAR_CODEC_PCM_U_PDP;
140#endif
141    break;
142   case FMT_S16_LE:
143     codec = ROAR_CODEC_PCM_S_LE;
144    break;
145   case FMT_S16_BE:
146     codec = ROAR_CODEC_PCM_S_BE;
147    break;
148   case FMT_S16_NE:
149     codec = ROAR_CODEC_DEFAULT;
150    break;
151    case FMT_U24_LE: /* stored in lower 3 bytes of 32-bit value, highest byte must be 0 */
152     codec = ROAR_CODEC_PCM_U_LE;
153     bits = 24;
154     break;
155    case FMT_U24_BE:
156     codec = ROAR_CODEC_PCM_U_BE;
157     bits = 24;
158     break;
159    case FMT_U24_NE:
160     bits = 24;
161#if BYTE_ORDER == BIG_ENDIAN
162     codec = ROAR_CODEC_PCM_U_BE;
163#elif BYTE_ORDER == LITTLE_ENDIAN
164     codec = ROAR_CODEC_PCM_U_LE;
165#else
166     codec = ROAR_CODEC_PCM_U_PDP;
167#endif     
168     break;
169    case FMT_S24_LE:
170     bits = 24;
171     codec = ROAR_CODEC_PCM_S_LE;
172     break;
173    case FMT_S24_BE:
174     bits = 24;
175     codec = ROAR_CODEC_PCM_S_BE;
176     break;
177    case FMT_S24_NE:
178     codec = ROAR_CODEC_DEFAULT;
179     bits= 24;
180     break;
181    case FMT_U32_LE: /* highest byte must be 0 */
182     codec = ROAR_CODEC_PCM_U_LE;
183     bits = 32;
184     break;
185    case FMT_U32_BE:
186     codec = ROAR_CODEC_PCM_U_BE;
187     bits = 32;
188     break;
189    case FMT_U32_NE:
190     bits = 32;
191#if BYTE_ORDER == BIG_ENDIAN
192     codec = ROAR_CODEC_PCM_U_BE;
193#elif BYTE_ORDER == LITTLE_ENDIAN
194     codec = ROAR_CODEC_PCM_U_LE;
195#else
196     codec = ROAR_CODEC_PCM_U_PDP;
197#endif     
198     break;
199    case FMT_S32_LE:
200     bits = 32;
201     codec = ROAR_CODEC_PCM_S_LE;
202     break;
203    case FMT_S32_BE:
204     bits = 32;
205     codec = ROAR_CODEC_PCM_S_BE;
206     break;
207    case FMT_S32_NE:
208     codec = ROAR_CODEC_DEFAULT;
209     bits= 32;
210     break;
211    case FMT_FLOAT:
212    ROAR_DBG("roar_open(*): FMT_FLOAT");
213    break;
214    case FMT_FIXED32:
215     ROAR_DBG("roar_open(*): FMT_FIXED32");
216     break;
217     
218 }
219
220 ROAR_DBG("roar_open(*): fmt %i", fmt);
221
222 g_inst.bps       = nch * rate * bits / 8;
223
224 roar_close();
225
226 if ( (g_inst.data_fh = roar_simple_new_stream_obj(&(g_inst.con), &(g_inst.stream),
227                              rate, nch, bits, codec, ROAR_DIR_PLAY)) == -1) {
228  roar_disconnect(&(g_inst.con));
229  g_inst.state |= STATE_CONNECTED;
230  g_inst.state -= STATE_CONNECTED;
231  if ( !(g_inst.state & STATE_NORECONNECT) ) {
232   g_inst.state |= STATE_NORECONNECT;
233   usleep(100000);
234   return roar_open(fmt, rate, nch);
235  } else {
236   g_inst.state -= STATE_NORECONNECT;
237   return FALSE;
238  }
239 }
240 g_inst.state |= STATE_PLAYING;
241
242 g_inst.written = 0;
243 g_inst.pause   = 0;
244
245#ifdef _WITH_BROKEN_CODE
246 roar_update_metadata();
247#endif
248
249 return TRUE;
250}
251
252void roar_close(void) {
253 if ( g_inst.data_fh != -1 )
254  close(g_inst.data_fh);
255 g_inst.data_fh = -1;
256 g_inst.state |= STATE_PLAYING;
257 g_inst.state -= STATE_PLAYING;
258 g_inst.written = 0;
259 ROAR_DBG("roar_close(void) = (void)");
260}
261
262void roar_pause(short p) {
263 g_inst.pause = p;
264}
265
266int roar_free(void) {
267 if ( g_inst.pause )
268  return 0;
269 else
270  return 1000000; // ???
271}
272
273void roar_flush(int time) {
274 gint64 r = time;
275
276 r *= g_inst.bps;
277 r /= 1000;
278
279 g_inst.written = r;
280}
281
282int roar_get_output_time(void) {
283 return roar_get_written_time();
284}
285
286int roar_get_written_time(void) {
287 gint64 r;
288
289 if ( !g_inst.bps ) {
290  ROAR_DBG("roar_get_written_time(void) = 0");
291  return 0;
292 }
293
294 r  = g_inst.written;
295 r *= 1000; // sec -> msec
296 r /= g_inst.bps;
297 ROAR_DBG("roar_get_written_time(void) = %lu", r);
298
299 return r;
300}
301
302
303// META DATA:
304
305int roar_update_metadata(void) {
306#ifdef _WITH_BROKEN_CODE
307 struct roar_meta   meta;
308 char empty = 0;
309 char * info = NULL;
310 int pos;
311
312 pos     = audacious_remote_get_playlist_pos(g_inst.session);
313
314 meta.value = &empty;
315 meta.key[0] = 0;
316 meta.type = ROAR_META_TYPE_NONE;
317
318 roar_stream_meta_set(&(g_inst.con), &(g_inst.stream), ROAR_META_MODE_CLEAR, &meta);
319
320 info = audacious_remote_get_playlist_file(g_inst.session, pos);
321
322 if ( info ) {
323  if ( strncmp(info, "http:", 5) == 0 )
324   meta.type = ROAR_META_TYPE_FILEURL;
325  else
326   meta.type = ROAR_META_TYPE_FILENAME;
327
328  meta.value = info;
329  ROAR_DBG("roar_update_metadata(*): setting meta data: type=%i, strlen(value)=%i", meta.type, strlen(info));
330  roar_stream_meta_set(&(g_inst.con), &(g_inst.stream), ROAR_META_MODE_SET, &meta);
331
332  free(info);
333 }
334
335 info = audacious_remote_get_playlist_title(g_inst.session, pos);
336 if ( info ) {
337  meta.type = ROAR_META_TYPE_TITLE;
338
339  meta.value = info;
340  roar_stream_meta_set(&(g_inst.con), &(g_inst.stream), ROAR_META_MODE_SET, &meta);
341
342  free(info);
343 }
344
345 meta.value = &empty;
346 meta.type = ROAR_META_TYPE_NONE;
347 roar_stream_meta_set(&(g_inst.con), &(g_inst.stream), ROAR_META_MODE_FINALIZE, &meta);
348
349#endif
350 return 0;
351}
352
353int roar_chk_metadata(void) {
354#ifdef _WITH_BROKEN_CODE
355 static int    old_pos = -1;
356 static char * old_title = "NEW TITLE";
357 int pos;
358 char * title;
359 int need_update = 0;
360
361 pos     = audacious_remote_get_playlist_pos(g_inst.session);
362
363 if ( pos != old_pos ) {
364  old_pos = pos;
365  need_update = 1;
366 } else {
367  title = audacious_remote_get_playlist_title(g_inst.session, pos);
368
369  if ( strcmp(title, old_title) ) {
370   free(old_title);
371   old_title = title;
372   need_update = 1;
373  } else {
374   free(title);
375  }
376 }
377
378 if ( need_update ) {
379  roar_update_metadata();
380 }
381
382#endif
383 return 0;
384}
385
386// MIXER:
387
388
389void roar_get_volume(int *l, int *r) {
390 int channels;
391 struct roar_mixer_settings mixer;
392
393 if ( !(g_inst.state & STATE_CONNECTED) )
394  return;
395
396 if ( roar_get_vol(&(g_inst.con), g_inst.stream.id, &mixer, &channels) == -1 ) {
397  *l = *r = 100;
398  return;
399 }
400
401 if ( channels == 1 ) {
402  *l = *r = mixer.mixer[0]/655.35;
403 } else {
404  *l = mixer.mixer[0]/655.35;
405  *r = mixer.mixer[1]/655.35;
406 }
407}
408
409void roar_set_volume(int l, int r) {
410 struct roar_mixer_settings mixer;
411
412 if ( !(g_inst.state & STATE_CONNECTED) )
413  return;
414
415 mixer.mixer[0] = l * 655.35;
416 mixer.mixer[1] = r * 655.35;
417
418 roar_set_vol(&(g_inst.con), g_inst.stream.id, &mixer, 2);
419}
420
421//ll
Note: See TracBrowser for help on using the repository browser.