source: roaraudio/roard/codecfilter_vorbis.c @ 486:5f7954982f5a

Last change on this file since 486:5f7954982f5a was 486:5f7954982f5a, checked in by phi, 16 years ago

added some bugfixed because of roar_stream_m2s() change

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