source: roaraudio/roarclients/roarvorbis.c @ 4655:7d9e6e2b384c

roaraudio_0_4beta2
Last change on this file since 4655:7d9e6e2b384c was 4014:2fee6bf2dc0c, checked in by phi, 14 years ago

fixed some resurce leaks

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