source: roaraudio/roarclients/roarvorbis.c @ 3517:1a3218a3fc5b

Last change on this file since 3517:1a3218a3fc5b was 3517:1a3218a3fc5b, checked in by phi, 14 years ago

updated license headers, FSF moved office

File size: 6.9 KB
RevLine 
[111]1//roarvorbis.c:
2
[669]3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008
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
[124]57FILE * open_http (char * file) {
[861]58#ifdef ROAR_HAVE_BIN_WGET
[124]59 char cmd[1024];
60
[861]61 snprintf(cmd, 1023, ROAR_HAVE_BIN_WGET " -qO - '%s'", file);
[124]62
63 return popen(cmd, "r");
[861]64#else
65 return NULL;
66#endif
[124]67}
68
[3043]69int update_stream (struct roar_connection * con, struct roar_stream * s, int * out, OggVorbis_File * vf, char * file, struct roar_audio_info * info, struct roar_vio_calls * vclt) {
[121]70 vorbis_info *vi = ov_info(vf, -1);
[111]71 int    bits     = 16;
72 int    codec    = ROAR_CODEC_DEFAULT;
[121]73 char **ptr = ov_comment(vf, -1)->user_comments;
[718]74 char key[ROAR_META_MAX_NAMELEN], value[LIBROAR_BUFFER_MSGDATA] = {0};
[121]75 int j, h = 0;
76 struct roar_meta   meta;
[122]77 int need_new_stream = 0;
[715]78 int meta_ok;
[121]79
80 fprintf(stderr, "\n");
81
[3045]82 if ( vclt != NULL ) {
83  roar_vio_printf(vclt, "AUDIOINFO=rate:%iHz, channels:%i\n", vi->rate, vi->channels);
84 }
85
[122]86 if ( *out == -1 ) {
87  need_new_stream = 1;
88 } else if ( info->rate != vi->rate || info->channels != vi->channels ) {
89  need_new_stream = 1;
90 }
91
92 if ( need_new_stream ) {
93  if ( *out != -1 )
[121]94  close(*out);
95
[122]96  fprintf(stderr, "Audio: %i channel, %liHz\n\n", vi->channels, vi->rate);
97
98  info->rate     = vi->rate;
99  info->channels = vi->channels;
[121]100
[122]101  if ( (*out = roar_simple_new_stream_obj(con, s, vi->rate, vi->channels, bits, codec, ROAR_DIR_PLAY)) == -1 ) {
102   roar_disconnect(con);
103   return -1;
104  }
[121]105 }
106
107
108 meta.value = value;
109 meta.key[0] = 0;
[132]110 meta.type = ROAR_META_TYPE_NONE;
[121]111
112 roar_stream_meta_set(con, s, ROAR_META_MODE_CLEAR, &meta);
113
[124]114 if ( strncmp(file, "http:", 5) == 0 )
115  meta.type = ROAR_META_TYPE_FILEURL;
116 else
117  meta.type = ROAR_META_TYPE_FILENAME;
118
[715]119
[719]120 strncpy(value, file, LIBROAR_BUFFER_MSGDATA-1);
121 value[LIBROAR_BUFFER_MSGDATA-1] = 0;
[121]122 roar_stream_meta_set(con, s, ROAR_META_MODE_SET, &meta);
123
124 while(*ptr){
[715]125  meta_ok = 1;
126
127   for (j = 0; (*ptr)[j] != 0 && (*ptr)[j] != '='; j++) {
128    if ( j == ROAR_META_MAX_NAMELEN ) {
129     ROAR_ERR("update_stream(*): invalid meta data: meta data key too long");
130     meta_ok = 0;
131     j = 0;
132     break;
133    }
[121]134    key[j] = (*ptr)[j];
[715]135   }
136   key[j] = 0;
[121]137
[715]138   if ( meta_ok ) {
139    for (j++, h = 0; (*ptr)[j] != 0 && (*ptr)[j] != '='; j++) {
[718]140     if ( h == LIBROAR_BUFFER_MSGDATA ) {
[715]141      ROAR_ERR("update_stream(*): invalid meta data: meta data value for key '%s' too long", key);
142      meta_ok = 0;
143      h = 0;
144      break;
145     }
146     value[h++] = (*ptr)[j];
147    }
[121]148    value[h]   = 0;
[715]149   }
[121]150
[715]151   if ( meta_ok ) {
152    fprintf(stderr, "Meta %-16s: %s\n", key, value);
[121]153
[3043]154    if ( vclt != NULL ) {
155     roar_vio_printf(vclt, "%s=%s\n", key, value);
156    }
157
[715]158    meta.type = roar_meta_inttype(key);
159    if ( meta.type != -1 )
160     roar_stream_meta_set(con, s, ROAR_META_MODE_SET, &meta);
161   }
162
163   ptr++;
[121]164 }
165
[1238]166 *value      = 0;
167 meta.key[0] = 0;
168 meta.type   = ROAR_META_TYPE_NONE;
169 roar_stream_meta_set(con, s, ROAR_META_MODE_FINALIZE, &meta);
170
[3043]171 if ( vclt != NULL ) {
172  roar_vio_printf(vclt, "==\n");
173 }
174
[121]175 return 0;
176}
177
[478]178#endif
179
[121]180int main (int argc, char * argv[]) {
[3043]181 struct roar_vio_calls vclt;
182 struct roar_vio_defaults def;
[478]183#ifndef ROAR_HAVE_LIBVORBISFILE
[479]184 fprintf(stderr, "Error: no Vorbis support!\n");
[478]185 return 1;
186#else
[111]187 char * server   = NULL;
188 char * file     = NULL;
[3043]189 char * vcltfile = NULL;
[111]190 char * k;
191 int    i;
192 FILE * in;
[120]193 int    out = -1;
[111]194 struct roar_connection con;
195 struct roar_stream     s;
196 OggVorbis_File vf;
197 int eof=0;
[132]198 int current_section = -1;
[120]199 int last_section = -1;
[122]200 struct roar_audio_info info;
[111]201 char pcmout[4096];
202
203
204 for (i = 1; i < argc; i++) {
205  k = argv[i];
206
207  if ( strcmp(k, "--server") == 0 ) {
208   server = argv[++i];
[3043]209  } else if ( strcmp(k, "--vclt-out") == 0 ) {
210   vcltfile = argv[++i];
[111]211  } else if ( strcmp(k, "--help") == 0 ) {
212   usage();
213   return 0;
214  } else if ( file == NULL ) {
215   file = k;
216  } else {
217   fprintf(stderr, "Error: unknown argument: %s\n", k);
218   usage();
219   return 1;
220  }
221 }
222
[2568]223 roar_libroar_set_server(server);
224
[1510]225 if ( file == NULL ) {
226  ROAR_ERR("No filename given.");
227  return 1;
228 }
229
[115]230 if ( roar_simple_connect(&con, server, "roarvorbis") == -1 ) {
[111]231  ROAR_DBG("roar_simple_play(*): roar_simple_connect() faild!");
[1406]232  return 1;
[111]233 }
234
[124]235 if ( strncmp(file, "http:", 5) == 0 ) {
236  in = open_http(file);
237 } else {
238  in = fopen(file, "rb");
239 }
240
241 if ( in == NULL ) {
[111]242  roar_disconnect(&con);
[1406]243  return 1;
[111]244 }
245
246#ifdef _WIN32
247  _setmode(_fileno(in), _O_BINARY);
248#endif
249
250 if(ov_open(in, &vf, NULL, 0) < 0) {
251  fprintf(stderr,"Input does not appear to be an Ogg bitstream.\n");
252  roar_disconnect(&con);
[1406]253  return 1;
[111]254 }
255
[3043]256 if ( vcltfile != NULL ) {
257  if ( roar_vio_dstr_init_defaults(&def, ROAR_VIO_DEF_TYPE_NONE, O_WRONLY|O_CREAT|O_APPEND, 0644) == -1 )
258   return 1;
259  if ( roar_vio_open_dstr(&vclt, vcltfile, &def, 1) == -1 ) {
260   fprintf(stderr, "Error: can not open file: %s: %s\n", k, strerror(errno));
261   return 1;
262  }
263 }
264
[121]265// if ( update_stream(&con, &s, &out, &vf, file) == -1 )
[1406]266//  return 1;
[111]267
[117]268 while (!eof) {
269  long ret = ov_read(&vf, pcmout, sizeof(pcmout), 0, 2, 1, &current_section);
[120]270
[121]271  if ( last_section != current_section )
[3043]272   if ( update_stream(&con, &s, &out, &vf, file, &info, vcltfile == NULL ? NULL : &vclt) == -1 )
[715]273    return 1;
[121]274
[120]275  last_section = current_section;
276
[111]277  if (ret == 0) {
278   /* EOF */
279   eof=1;
280  } else if (ret < 0) {
281   /* error in the stream.  Not a problem, just reporting it in
282      case we (the app) cares.  In this case, we don't. */
283  } else {
284     /* we don't bother dealing with sample rate changes, etc, but
285        you'll have to */
[507]286//    write(out, pcmout, ret);
287   roar_stream_send_data(&con, &s, pcmout, ret);
[111]288  }
289 }
290
291  ov_clear(&vf);
292
293// fclose(in);
[120]294 close(out);
295 roar_disconnect(&con);
[111]296
[3043]297 if ( vcltfile != NULL ) {
298  roar_vio_close(&vclt);
299 }
300
[111]301 return 0;
[478]302#endif
[111]303}
304
305//ll
Note: See TracBrowser for help on using the repository browser.