source: roaraudio/roard/codecfilter_vorbis.c @ 439:452cf038155c

Last change on this file since 439:452cf038155c was 382:46b315ef4767, checked in by phi, 16 years ago

CF Vorbis: fixed a read() on closed() and a close() before read() bug

File size: 3.8 KB
RevLine 
[204]1//codecfilter_vorbis.c:
2
3#include "roard.h"
4
[362]5#ifdef ROAR_HAVE_LIBVORBISFILE
6
[205]7int cf_vorbis_open(CODECFILTER_USERDATA_T * inst, int codec,
8                                            struct roar_stream_server * info,
9                                            struct roar_codecfilter   * filter) {
10 struct codecfilter_vorbis_inst * self = malloc(sizeof(struct codecfilter_vorbis_inst));
11
12 if ( !self )
13  return -1;
14
15 self->current_section      = -1;
16 self->last_section         = -1;
[382]17 self->opened               =  0;
18 self->got_it_running       =  0;
[205]19 self->stream               = info;
20// self->outlen               = ROAR_OUTPUT_BUFFER_SAMPLES * s->info.channels * s->info.bits / 8; // optimal size
21
22 if ( (self->in = fdopen(((struct roar_stream*)info)->fh, "r")) == NULL ) {
23  free((void*)self);
24  return -1;
25 }
26
27 *inst = (CODECFILTER_USERDATA_T) self;
28
[206]29 ((struct roar_stream*)info)->info.codec = ROAR_CODEC_DEFAULT;
30
31 return 0;
[205]32}
33
34int cf_vorbis_close(CODECFILTER_USERDATA_T   inst) {
35 struct codecfilter_vorbis_inst * self = (struct codecfilter_vorbis_inst *) inst;
36
37 if ( !inst )
38  return -1;
39
[382]40 if ( self->got_it_running )
41  ov_clear(&(self->vf));
[205]42
43 free(inst);
[206]44 return 0;
[205]45}
46
47int cf_vorbis_read(CODECFILTER_USERDATA_T   inst, char * buf, int len) {
48 struct codecfilter_vorbis_inst * self = (struct codecfilter_vorbis_inst *) inst;
49 long r;
[206]50 long todo = len;
51 long done = 0;
[205]52
[206]53// printf("cf_vorbis_read(inst=%p, buf=%p, len=%i) = ?\n", inst, buf, len);
54
55 self->opened++;
56 if ( self->opened == 16 ) {
57  //printf("cf_vorbis_read(*): opening...\n");
[205]58  if ( ov_open(self->in, &(self->vf), NULL, 0) < 0 ) {
[382]59//   free((void*)self);
[206]60   return 0;
[205]61  }
62 }
[206]63
64 if ( self->opened < 16 ) {
65  return -1;
66 }
[205]67
[382]68
69 self->got_it_running = 1;
70
[206]71 while (todo) {
72  r = ov_read(&(self->vf), buf+done, todo, 0, 2, 1, &(self->current_section));
73  if ( r < 1 ) {
74   break;
75  } else {
[207]76   if ( self->last_section != self->current_section )
77    if ( cf_vorbis_update_stream(self) == -1 )
78     return 0;
79
80   self->last_section = self->current_section;
[206]81   todo -= r;
82   done += r;
83  }
84 }
[205]85
[206]86 //printf("ov_read(*) = %i\n", done);
87
88 if ( done == 0 ) {
[205]89  // do some EOF handling...
[206]90  return 0;
[205]91 } else {
[206]92  return len;
[205]93 }
94}
95
[207]96int cf_vorbis_update_stream (struct codecfilter_vorbis_inst * self) {
97 vorbis_info *vi = ov_info(&(self->vf), -1);
98 char **ptr = ov_comment(&(self->vf), -1)->user_comments;
99 char key[80] = {0}, value[80] = {0};
100 struct roar_stream * s = (struct roar_stream *) self->stream;
101 int type;
102 int j, h = 0;
[222]103 float rpg_track = 0, rpg_album = 0;
[207]104
105 s->info.channels = vi->channels;
106 s->info.rate     = vi->rate;
107 s->info.bits     = 16;
108 s->info.codec    = ROAR_CODEC_DEFAULT;
109
110 stream_meta_clear(s->id);
111
112 while(*ptr){
113   for (j = 0; (*ptr)[j] != 0 && (*ptr)[j] != '='; j++)
114    key[j] = (*ptr)[j];
115    key[j] = 0;
116
117   for (j++, h = 0; (*ptr)[j] != 0 && (*ptr)[j] != '='; j++)
118    value[h++] = (*ptr)[j];
119    value[h]   = 0;
120
121   type = roar_meta_inttype(key);
122   if ( type != -1 )
123    stream_meta_set(s->id, type, "", value);
124
125   ROAR_DBG("cf_vorbis_update_stream(*): Meta %-16s: %s", key, value);
[222]126
127   if ( strcmp(key, "REPLAYGAIN_TRACK_PEAK") == 0 ) {
128    rpg_track = 1/atof(value);
129/*
130   } else if ( strcmp(key, "REPLAYGAIN_TRACK_GAIN") == 0 ) {
131    rpg_track = powf(10, atof(value)/20);
132*/
133   } else if ( strcmp(key, "REPLAYGAIN_ALBUM_PEAK") == 0 ) {
134    rpg_album = 1/atof(value);
135/*
136   } else if ( strcmp(key, "REPLAYGAIN_ALBUM_GAIN") == 0 ) {
137    rpg_album = powf(10, atof(value)/20);
138*/
139   }
140
[207]141   ++ptr;
142 }
143
[222]144 if ( rpg_album ) {
145  self->stream->mixer.rpg_div = 2718;  // = int(exp(1)*1000)
146  self->stream->mixer.rpg_mul = (float)rpg_album*2718;
147 } else if ( rpg_track ) {
148  self->stream->mixer.rpg_div = 2718;
149  self->stream->mixer.rpg_mul = (float)rpg_track*2718;
150 }
151
[223]152 //printf("RPG: mul=%i, div=%i\n", self->stream->mixer.rpg_mul, self->stream->mixer.rpg_div);
[207]153 return 0;
154}
155
[362]156#endif
157
[204]158//ll
Note: See TracBrowser for help on using the repository browser.