source: roaraudio/roarclients/roarvorbis.c @ 3045:ddcabcdde0e1

Last change on this file since 3045:ddcabcdde0e1 was 3045:ddcabcdde0e1, checked in by phi, 14 years ago

create AUDIOINFO= meta data

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