source: roaraudio/roarclients/roarvorbis.c @ 4725:23ef456b4382

Last change on this file since 4725:23ef456b4382 was 4708:c9d40761088a, checked in by phi, 13 years ago

updated copyright statements

File size: 8.3 KB
RevLine 
[111]1//roarvorbis.c:
2
[669]3/*
[4708]4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2011
[669]5 *
6 *  This file is part of roarclients a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  RoarAudio is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
[3517]21 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
[669]23 *
24 */
25
[111]26#include <roaraudio.h>
27
28#include <stdio.h>
29#include <stdlib.h>
30#include <math.h>
[478]31#ifdef ROAR_HAVE_LIBVORBISFILE
[111]32#include <vorbis/codec.h>
33#include <vorbis/vorbisfile.h>
[478]34#endif
[111]35
36#ifdef _WIN32
37#include <io.h>
38#include <fcntl.h>
39#endif
40
41#define BUFSIZE 1024
42
43void usage (void) {
44 printf("roarvorbis [OPTIONS]... FILE\n");
45
46 printf("\nOptions:\n\n");
47
48 printf("  --server SERVER    - Set server hostname\n"
49        "  --help             - Show this help\n"
[3043]50        "  --vclt-out FILE    - Writes VCLT file\n"
[111]51       );
52
53}
54
[124]55
[478]56#ifdef ROAR_HAVE_LIBVORBISFILE
[4656]57int _g_cf_vorbis_vfvio_return_err (void) {
58 return -1;
59}
60
61size_t cf_vorbis_vfvio_read (void *ptr, size_t size, size_t nmemb, void *datasource) {
62 ssize_t r;
[124]63
[4656]64 r = roar_vio_read(datasource, ptr, size*nmemb);
65
66 ROAR_DBG("cf_vorbis_vfvio_read(ptr=%p, size=%lu, nmemb=%lu, datasource=%p): r=%i", ptr, size, nmemb, datasource, r);
67
68 if ( r == -1 )
69  return 0;
[124]70
[4656]71 if ( r > 0 )
72  errno = 0;
73
74 r /= size;
75
76 ROAR_DBG("cf_vorbis_vfvio_read(ptr=%p, size=%lu, nmemb=%lu, datasource=%p) = %i", ptr, size, nmemb, datasource, r);
77 return r;
[124]78}
79
[4656]80
81ov_callbacks _g_cf_vorbis_vfvio = {
82  .read_func  = cf_vorbis_vfvio_read,
83  .seek_func  = (int    (*)(void *, ogg_int64_t, int      )) _g_cf_vorbis_vfvio_return_err,
84  .close_func = (int    (*)(void *                        )) _g_cf_vorbis_vfvio_return_err,
85  .tell_func  = (long   (*)(void *                        )) _g_cf_vorbis_vfvio_return_err
86};
87
88
[4659]89int update_stream (struct roar_connection *  con,
90                   roar_vs_t              ** vss,
91                   OggVorbis_File         *  vf,
92                   char                   *  file,
93                   struct roar_audio_info *  info,
94                   struct roar_vio_calls  *  vclt) {
95 struct roar_stream     * s;
[121]96 vorbis_info *vi = ov_info(vf, -1);
[111]97 int    bits     = 16;
[4659]98 int    codec    = ROAR_CODEC_PCM_S_LE;
[121]99 char **ptr = ov_comment(vf, -1)->user_comments;
[718]100 char key[ROAR_META_MAX_NAMELEN], value[LIBROAR_BUFFER_MSGDATA] = {0};
[121]101 int j, h = 0;
102 struct roar_meta   meta;
[3843]103 static int need_new_stream = 1;
104 int need_close = 0;
[715]105 int meta_ok;
[121]106
107 fprintf(stderr, "\n");
108
[3045]109 if ( vclt != NULL ) {
110  roar_vio_printf(vclt, "AUDIOINFO=rate:%iHz, channels:%i\n", vi->rate, vi->channels);
111 }
112
[3843]113 if ( !need_new_stream ) {
114  if ( info->rate != (uint16_t)vi->rate || info->channels != (uint16_t)vi->channels ) {
115   need_close      = 1;
116   need_new_stream = 1;
117  }
[122]118 }
119
120 if ( need_new_stream ) {
[4659]121  if ( need_close ) {
122   roar_vs_sync(*vss, ROAR_VS_WAIT, NULL);
123   roar_vs_close(*vss, ROAR_VS_FALSE, NULL);
124  }
[121]125
[122]126  fprintf(stderr, "Audio: %i channel, %liHz\n\n", vi->channels, vi->rate);
127
128  info->rate     = vi->rate;
129  info->channels = vi->channels;
[4659]130  info->bits     = bits;
131  info->codec    = codec;
[121]132
[4659]133  *vss = roar_vs_new_from_con(con, NULL);
134  if ( *vss == NULL ) {
[122]135   roar_disconnect(con);
136   return -1;
137  }
[4659]138
139  if ( roar_vs_stream(*vss, info, ROAR_DIR_PLAY, NULL) == -1 ) {
140   roar_vs_close(*vss, ROAR_VS_TRUE, NULL);
141   roar_disconnect(con);
142   return -1;
143  }
144
[3843]145  need_new_stream = 0;
[121]146 }
147
[4659]148 s = roar_vs_stream_obj(*vss, NULL);
[121]149
150 meta.value = value;
151 meta.key[0] = 0;
[132]152 meta.type = ROAR_META_TYPE_NONE;
[121]153
154 roar_stream_meta_set(con, s, ROAR_META_MODE_CLEAR, &meta);
155
[124]156 if ( strncmp(file, "http:", 5) == 0 )
157  meta.type = ROAR_META_TYPE_FILEURL;
158 else
159  meta.type = ROAR_META_TYPE_FILENAME;
160
[715]161
[719]162 strncpy(value, file, LIBROAR_BUFFER_MSGDATA-1);
163 value[LIBROAR_BUFFER_MSGDATA-1] = 0;
[121]164 roar_stream_meta_set(con, s, ROAR_META_MODE_SET, &meta);
165
166 while(*ptr){
[715]167  meta_ok = 1;
168
169   for (j = 0; (*ptr)[j] != 0 && (*ptr)[j] != '='; j++) {
170    if ( j == ROAR_META_MAX_NAMELEN ) {
171     ROAR_ERR("update_stream(*): invalid meta data: meta data key too long");
172     meta_ok = 0;
173     j = 0;
174     break;
175    }
[121]176    key[j] = (*ptr)[j];
[715]177   }
178   key[j] = 0;
[121]179
[715]180   if ( meta_ok ) {
181    for (j++, h = 0; (*ptr)[j] != 0 && (*ptr)[j] != '='; j++) {
[718]182     if ( h == LIBROAR_BUFFER_MSGDATA ) {
[715]183      ROAR_ERR("update_stream(*): invalid meta data: meta data value for key '%s' too long", key);
184      meta_ok = 0;
185      h = 0;
186      break;
187     }
188     value[h++] = (*ptr)[j];
189    }
[121]190    value[h]   = 0;
[715]191   }
[121]192
[715]193   if ( meta_ok ) {
194    fprintf(stderr, "Meta %-16s: %s\n", key, value);
[121]195
[3043]196    if ( vclt != NULL ) {
197     roar_vio_printf(vclt, "%s=%s\n", key, value);
198    }
199
[715]200    meta.type = roar_meta_inttype(key);
201    if ( meta.type != -1 )
202     roar_stream_meta_set(con, s, ROAR_META_MODE_SET, &meta);
203   }
204
205   ptr++;
[121]206 }
207
[4659]208 fprintf(stderr, "\n");
209
[1238]210 *value      = 0;
211 meta.key[0] = 0;
212 meta.type   = ROAR_META_TYPE_NONE;
213 roar_stream_meta_set(con, s, ROAR_META_MODE_FINALIZE, &meta);
214
[3043]215 if ( vclt != NULL ) {
216  roar_vio_printf(vclt, "==\n");
217 }
218
[121]219 return 0;
220}
221
[478]222#endif
223
[121]224int main (int argc, char * argv[]) {
[478]225#ifndef ROAR_HAVE_LIBVORBISFILE
[3787]226 (void)argc, (void)argv;
[479]227 fprintf(stderr, "Error: no Vorbis support!\n");
[478]228 return 1;
229#else
[4656]230 struct roar_vio_calls vclt, in;
[3787]231 struct roar_vio_defaults def;
[111]232 char * server   = NULL;
233 char * file     = NULL;
[3043]234 char * vcltfile = NULL;
[111]235 char * k;
236 int    i;
237 struct roar_connection con;
[4659]238 roar_vs_t * vss = NULL;
[111]239 OggVorbis_File vf;
240 int eof=0;
[132]241 int current_section = -1;
[120]242 int last_section = -1;
[122]243 struct roar_audio_info info;
[111]244 char pcmout[4096];
245
246
247 for (i = 1; i < argc; i++) {
248  k = argv[i];
249
250  if ( strcmp(k, "--server") == 0 ) {
251   server = argv[++i];
[3043]252  } else if ( strcmp(k, "--vclt-out") == 0 ) {
253   vcltfile = argv[++i];
[111]254  } else if ( strcmp(k, "--help") == 0 ) {
255   usage();
256   return 0;
257  } else if ( file == NULL ) {
258   file = k;
259  } else {
260   fprintf(stderr, "Error: unknown argument: %s\n", k);
261   usage();
262   return 1;
263  }
264 }
265
[2568]266 roar_libroar_set_server(server);
267
[1510]268 if ( file == NULL ) {
269  ROAR_ERR("No filename given.");
270  return 1;
271 }
272
[4656]273 if ( roar_vio_dstr_init_defaults(&def, ROAR_VIO_DEF_TYPE_NONE, O_RDONLY, 0644) == -1 )
274  return 1;
275
276 if ( roar_vio_open_dstr(&in, file, &def, 1) == -1 ) {
277  fprintf(stderr, "Error: can not open file: %s: %s\n", file, strerror(errno));
[1406]278  return 1;
[111]279 }
280
[4656]281 if ( roar_simple_connect(&con, server, "roarvorbis") == -1 ) {
282  ROAR_DBG("roar_simple_play(*): roar_simple_connect() faild!");
283  roar_vio_close(&in);
[1406]284  return 1;
[111]285 }
286
[4656]287 if ( ov_open_callbacks((void*)&in, &vf, NULL, 0, _g_cf_vorbis_vfvio) < 0 ) {
288// if( ov_open(in, &vf, NULL, 0) < 0 ) {
[111]289  fprintf(stderr,"Input does not appear to be an Ogg bitstream.\n");
290  roar_disconnect(&con);
[4656]291  roar_vio_close(&in);
[1406]292  return 1;
[111]293 }
294
[3043]295 if ( vcltfile != NULL ) {
296  if ( roar_vio_dstr_init_defaults(&def, ROAR_VIO_DEF_TYPE_NONE, O_WRONLY|O_CREAT|O_APPEND, 0644) == -1 )
297   return 1;
298  if ( roar_vio_open_dstr(&vclt, vcltfile, &def, 1) == -1 ) {
299   fprintf(stderr, "Error: can not open file: %s: %s\n", k, strerror(errno));
[4656]300   roar_disconnect(&con);
301   roar_vio_close(&in);
[3043]302   return 1;
303  }
304 }
305
[121]306// if ( update_stream(&con, &s, &out, &vf, file) == -1 )
[1406]307//  return 1;
[111]308
[117]309 while (!eof) {
310  long ret = ov_read(&vf, pcmout, sizeof(pcmout), 0, 2, 1, &current_section);
[120]311
[121]312  if ( last_section != current_section )
[4659]313   if ( update_stream(&con, &vss, &vf, file, &info, vcltfile == NULL ? NULL : &vclt) == -1 ) {
[4656]314    roar_vio_close(&in);
315    if ( vcltfile != NULL )
316     roar_vio_close(&vclt);
[715]317    return 1;
[4014]318   }
[121]319
[120]320  last_section = current_section;
321
[111]322  if (ret == 0) {
323   /* EOF */
[3843]324   eof = 1;
[111]325  } else if (ret < 0) {
326   /* error in the stream.  Not a problem, just reporting it in
327      case we (the app) cares.  In this case, we don't. */
328  } else {
[4659]329   roar_vs_write(vss, pcmout, ret, NULL);
[111]330  }
331 }
332
[3843]333 ov_clear(&vf);
[111]334
335// fclose(in);
[4659]336 roar_vs_close(vss, ROAR_VS_FALSE, NULL);
[120]337 roar_disconnect(&con);
[111]338
[4656]339 if ( vcltfile != NULL )
[3043]340  roar_vio_close(&vclt);
341
[4656]342 roar_vio_close(&in);
[4014]343
[111]344 return 0;
[478]345#endif
[111]346}
347
348//ll
Note: See TracBrowser for help on using the repository browser.