Mercurial > mplayer.hg
comparison libmpcodecs/ad_libvorbis.c @ 7172:33c38a0c20e8
renamed to match driver family name
author | arpi |
---|---|
date | Fri, 30 Aug 2002 19:49:37 +0000 |
parents | libmpcodecs/ad_vorbis.c@acc51ad47911 |
children | 7672615cc811 |
comparison
equal
deleted
inserted
replaced
7171:772f853f32a1 | 7172:33c38a0c20e8 |
---|---|
1 | |
2 #include <stdio.h> | |
3 #include <stdlib.h> | |
4 #include <unistd.h> | |
5 | |
6 #include "config.h" | |
7 #include "ad_internal.h" | |
8 | |
9 #ifdef HAVE_OGGVORBIS | |
10 | |
11 static ad_info_t info = | |
12 { | |
13 "Ogg/Vorbis audio decoder", | |
14 "libvorbis", | |
15 AFM_VORBIS, | |
16 "Felix Buenemann, A'rpi", | |
17 "libvorbis", | |
18 "buggy" | |
19 }; | |
20 | |
21 LIBAD_EXTERN(vorbis) | |
22 | |
23 #include <vorbis/codec.h> | |
24 | |
25 // This struct is also defined in demux_ogg.c => common header ? | |
26 typedef struct ov_struct_st { | |
27 vorbis_info vi; /* struct that stores all the static vorbis bitstream | |
28 settings */ | |
29 vorbis_comment vc; /* struct that stores all the bitstream user comments */ | |
30 vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */ | |
31 vorbis_block vb; /* local working space for packet->PCM decode */ | |
32 } ov_struct_t; | |
33 | |
34 static int preinit(sh_audio_t *sh) | |
35 { | |
36 sh->audio_out_minsize=1024*4; // 1024 samples/frame | |
37 return 1; | |
38 } | |
39 | |
40 static int init(sh_audio_t *sh) | |
41 { | |
42 ogg_packet op; | |
43 vorbis_comment vc; | |
44 struct ov_struct_st *ov; | |
45 #define ERROR() { \ | |
46 vorbis_comment_clear(&vc); \ | |
47 vorbis_info_clear(&ov->vi); \ | |
48 free(ov); \ | |
49 return 0; \ | |
50 } | |
51 /// Init the decoder with the 3 header packets | |
52 ov = (struct ov_struct_st*)malloc(sizeof(struct ov_struct_st)); | |
53 vorbis_info_init(&ov->vi); | |
54 vorbis_comment_init(&vc); | |
55 op.bytes = ds_get_packet(sh->ds,&op.packet); | |
56 op.b_o_s = 1; | |
57 /// Header | |
58 if(vorbis_synthesis_headerin(&ov->vi,&vc,&op) <0) { | |
59 mp_msg(MSGT_DECAUDIO,MSGL_ERR,"OggVorbis: initial (identification) header broken!\n"); | |
60 ERROR(); | |
61 } | |
62 op.bytes = ds_get_packet(sh->ds,&op.packet); | |
63 op.b_o_s = 0; | |
64 /// Comments | |
65 if(vorbis_synthesis_headerin(&ov->vi,&vc,&op) <0) { | |
66 mp_msg(MSGT_DECAUDIO,MSGL_ERR,"OggVorbis: comment header broken!\n"); | |
67 ERROR(); | |
68 } | |
69 op.bytes = ds_get_packet(sh->ds,&op.packet); | |
70 //// Codebook | |
71 if(vorbis_synthesis_headerin(&ov->vi,&vc,&op)<0) { | |
72 mp_msg(MSGT_DECAUDIO,MSGL_WARN,"OggVorbis: codebook header broken!\n"); | |
73 ERROR(); | |
74 } else { /// Print the infos | |
75 char **ptr=vc.user_comments; | |
76 while(*ptr){ | |
77 mp_msg(MSGT_DECAUDIO,MSGL_V,"OggVorbisComment: %s\n",*ptr); | |
78 ++ptr; | |
79 } | |
80 mp_msg(MSGT_DECAUDIO,MSGL_V,"OggVorbis: Bitstream is %d channel, %dHz, %dbit/s %cBR\n",(int)ov->vi.channels,(int)ov->vi.rate,(int)ov->vi.bitrate_nominal, | |
81 (ov->vi.bitrate_lower!=ov->vi.bitrate_nominal)||(ov->vi.bitrate_upper!=ov->vi.bitrate_nominal)?'V':'C'); | |
82 mp_msg(MSGT_DECAUDIO,MSGL_V,"OggVorbis: Encoded by: %s\n",vc.vendor); | |
83 } | |
84 vorbis_comment_clear(&vc); | |
85 | |
86 // printf("lower=%d upper=%d \n",(int)ov->vi.bitrate_lower,(int)ov->vi.bitrate_upper); | |
87 | |
88 // Setup the decoder | |
89 sh->channels=ov->vi.channels; | |
90 sh->samplerate=ov->vi.rate; | |
91 // assume 128kbit if bitrate not specified in the header | |
92 sh->i_bps=((ov->vi.bitrate_nominal>0) ? ov->vi.bitrate_nominal : 128000)/8; | |
93 sh->context = ov; | |
94 | |
95 /// Finish the decoder init | |
96 vorbis_synthesis_init(&ov->vd,&ov->vi); | |
97 vorbis_block_init(&ov->vd,&ov->vb); | |
98 mp_msg(MSGT_DECAUDIO,MSGL_V,"OggVorbis: Init OK!\n"); | |
99 | |
100 return 1; | |
101 } | |
102 | |
103 static void uninit(sh_audio_t *sh) | |
104 { | |
105 struct ov_struct_st *ov = sh->context; | |
106 vorbis_block_clear(&ov->vb); | |
107 vorbis_info_clear(&ov->vi); | |
108 free(ov); | |
109 } | |
110 | |
111 static int control(sh_audio_t *sh,int cmd,void* arg, ...) | |
112 { | |
113 switch(cmd) | |
114 { | |
115 #if 0 | |
116 case ADCTRL_RESYNC_STREAM: | |
117 return CONTROL_TRUE; | |
118 case ADCTRL_SKIP_FRAME: | |
119 return CONTROL_TRUE; | |
120 #endif | |
121 } | |
122 return CONTROL_UNKNOWN; | |
123 } | |
124 | |
125 static int decode_audio(sh_audio_t *sh,unsigned char *buf,int minlen,int maxlen) | |
126 { | |
127 int len = 0; | |
128 int samples; | |
129 float **pcm; | |
130 ogg_packet op; | |
131 struct ov_struct_st *ov = sh->context; | |
132 op.b_o_s = op.e_o_s = 0; | |
133 while(len < minlen) { | |
134 op.bytes = ds_get_packet(sh->ds,&op.packet); | |
135 if(!op.packet) | |
136 break; | |
137 if(vorbis_synthesis(&ov->vb,&op)==0) /* test for success! */ | |
138 vorbis_synthesis_blockin(&ov->vd,&ov->vb); | |
139 while((samples=vorbis_synthesis_pcmout(&ov->vd,&pcm))>0){ | |
140 int i,j; | |
141 int clipflag=0; | |
142 int convsize=(maxlen-len)/(2*ov->vi.channels); // max size! | |
143 int bout=(samples<convsize?samples:convsize); | |
144 | |
145 if(bout<=0) break; | |
146 | |
147 /* convert floats to 16 bit signed ints (host order) and | |
148 interleave */ | |
149 for(i=0;i<ov->vi.channels;i++){ | |
150 ogg_int16_t *convbuffer=(ogg_int16_t *)(&buf[len]); | |
151 ogg_int16_t *ptr=convbuffer+i; | |
152 float *mono=pcm[i]; | |
153 for(j=0;j<bout;j++){ | |
154 #if 1 | |
155 int val=mono[j]*32767.f; | |
156 #else /* optional dither */ | |
157 int val=mono[j]*32767.f+drand48()-0.5f; | |
158 #endif | |
159 /* might as well guard against clipping */ | |
160 if(val>32767){ | |
161 val=32767; | |
162 clipflag=1; | |
163 } | |
164 if(val<-32768){ | |
165 val=-32768; | |
166 clipflag=1; | |
167 } | |
168 *ptr=val; | |
169 ptr+=ov->vi.channels; | |
170 } | |
171 } | |
172 | |
173 if(clipflag) | |
174 mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"Clipping in frame %ld\n",(long)(ov->vd.sequence)); | |
175 len+=2*ov->vi.channels*bout; | |
176 mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"\n[decoded: %d / %d ]\n",bout,samples); | |
177 vorbis_synthesis_read(&ov->vd,bout); /* tell libvorbis how | |
178 many samples we | |
179 actually consumed */ | |
180 } | |
181 } | |
182 | |
183 | |
184 | |
185 return len; | |
186 } | |
187 | |
188 #endif /* !HAVE_OGGVORBIS */ | |
189 |