1 /******************************************************************** 2 * * 3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * 4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * 5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * 6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * 7 * * 8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 * 9 * by the Xiph.Org Foundation http://www.xiph.org/ * 10 * * 11 ******************************************************************** 12 13 function: utility functions for vorbis codec test suite. 14 last mod: $Id: util.c 13293 2007-07-24 00:09:47Z erikd $ 15 16 ********************************************************************/ 17 18 #include <stdio.h> 19 #include <stdlib.h> 20 #include <math.h> 21 #include <string.h> 22 #include <errno.h> 23 24 #include <vorbis/codec.h> 25 #include <vorbis/vorbisenc.h> 26 27 #include "write_read.h" 28 29 /* The following function is basically a hacked version of the code in 30 * examples/encoder_example.c */ 31 void 32 write_vorbis_data_or_die (const char *filename, int srate, float q, const float * data, int count, int ch) 33 { 34 FILE * file ; 35 ogg_stream_state os; 36 ogg_page og; 37 ogg_packet op; 38 vorbis_info vi; 39 vorbis_comment vc; 40 vorbis_dsp_state vd; 41 vorbis_block vb; 42 43 int eos = 0, ret; 44 45 if ((file = fopen (filename, "wb")) == NULL) { 46 printf("\n\nError : fopen failed : %s\n", strerror (errno)) ; 47 exit (1) ; 48 } 49 50 /********** Encode setup ************/ 51 52 vorbis_info_init (&vi); 53 54 ret = vorbis_encode_init_vbr (&vi,ch,srate,q); 55 if (ret) { 56 printf ("vorbis_encode_init_vbr return %d\n", ret) ; 57 exit (1) ; 58 } 59 60 vorbis_comment_init (&vc); 61 vorbis_comment_add_tag (&vc,"ENCODER","test/util.c"); 62 vorbis_analysis_init (&vd,&vi); 63 vorbis_block_init (&vd,&vb); 64 65 ogg_stream_init (&os,12345678); 66 67 { 68 ogg_packet header; 69 ogg_packet header_comm; 70 ogg_packet header_code; 71 72 vorbis_analysis_headerout (&vd,&vc,&header,&header_comm,&header_code); 73 ogg_stream_packetin (&os,&header); 74 ogg_stream_packetin (&os,&header_comm); 75 ogg_stream_packetin (&os,&header_code); 76 77 /* Ensures the audio data will start on a new page. */ 78 while (!eos){ 79 int result = ogg_stream_flush (&os,&og); 80 if (result == 0) 81 break; 82 fwrite (og.header,1,og.header_len,file); 83 fwrite (og.body,1,og.body_len,file); 84 } 85 86 } 87 88 { 89 /* expose the buffer to submit data */ 90 float **buffer = vorbis_analysis_buffer (&vd,count); 91 int i; 92 93 for(i=0;i<ch;i++) 94 memcpy (buffer [i], data, count * sizeof (float)) ; 95 96 /* tell the library how much we actually submitted */ 97 vorbis_analysis_wrote (&vd,count); 98 vorbis_analysis_wrote (&vd,0); 99 } 100 101 while (vorbis_analysis_blockout (&vd,&vb) == 1) { 102 vorbis_analysis (&vb,NULL); 103 vorbis_bitrate_addblock (&vb); 104 105 while (vorbis_bitrate_flushpacket (&vd,&op)) { 106 ogg_stream_packetin (&os,&op); 107 108 while (!eos) { 109 int result = ogg_stream_pageout (&os,&og); 110 if (result == 0) 111 break; 112 fwrite (og.header,1,og.header_len,file); 113 fwrite (og.body,1,og.body_len,file); 114 115 if (ogg_page_eos (&og)) 116 eos = 1; 117 } 118 } 119 } 120 121 ogg_stream_clear (&os); 122 vorbis_block_clear (&vb); 123 vorbis_dsp_clear (&vd); 124 vorbis_comment_clear (&vc); 125 vorbis_info_clear (&vi); 126 127 fclose (file) ; 128 } 129 130 /* The following function is basically a hacked version of the code in 131 * examples/decoder_example.c */ 132 void 133 read_vorbis_data_or_die (const char *filename, int srate, float * data, int count) 134 { 135 ogg_sync_state oy; 136 ogg_stream_state os; 137 ogg_page og; 138 ogg_packet op; 139 140 vorbis_info vi; 141 vorbis_comment vc; 142 vorbis_dsp_state vd; 143 vorbis_block vb; 144 145 FILE *file; 146 char *buffer; 147 int bytes; 148 int eos = 0; 149 int i; 150 int read_total = 0 ; 151 152 if ((file = fopen (filename, "rb")) == NULL) { 153 printf("\n\nError : fopen failed : %s\n", strerror (errno)) ; 154 exit (1) ; 155 } 156 157 ogg_sync_init (&oy); 158 159 { 160 /* fragile! Assumes all of our headers will fit in the first 8kB, 161 which currently they will */ 162 buffer = ogg_sync_buffer (&oy,8192); 163 bytes = fread (buffer,1,8192,file); 164 ogg_sync_wrote (&oy,bytes); 165 166 if(ogg_sync_pageout (&oy,&og) != 1) { 167 if(bytes < 8192) { 168 printf ("Out of data.\n") ; 169 goto done_decode ; 170 } 171 172 fprintf (stderr,"Input does not appear to be an Ogg bitstream.\n"); 173 exit (1); 174 } 175 176 ogg_stream_init (&os,ogg_page_serialno(&og)); 177 178 vorbis_info_init (&vi); 179 vorbis_comment_init (&vc); 180 if (ogg_stream_pagein (&os,&og) < 0) { 181 fprintf (stderr,"Error reading first page of Ogg bitstream data.\n"); 182 exit (1); 183 } 184 185 if (ogg_stream_packetout(&os,&op) != 1) { 186 fprintf (stderr,"Error reading initial header packet.\n"); 187 exit (1); 188 } 189 190 if (vorbis_synthesis_headerin (&vi,&vc,&op) < 0) { 191 fprintf (stderr,"This Ogg bitstream does not contain Vorbis " 192 "audio data.\n"); 193 exit (1); 194 } 195 196 i = 0; 197 while ( i < 2) { 198 while (i < 2) { 199 200 int result = ogg_sync_pageout (&oy,&og); 201 if(result == 0) 202 break; 203 if(result==1) { 204 ogg_stream_pagein(&os,&og); 205 206 while (i < 2) { 207 result = ogg_stream_packetout (&os,&op); 208 if (result == 0) break; 209 if (result < 0) { 210 fprintf (stderr,"Corrupt secondary header. Exiting.\n"); 211 exit(1); 212 } 213 vorbis_synthesis_headerin (&vi,&vc,&op); 214 i++; 215 } 216 } 217 } 218 219 buffer = ogg_sync_buffer (&oy,4096); 220 bytes = fread (buffer,1,4096,file); 221 if (bytes == 0 && i < 2) { 222 fprintf (stderr,"End of file before finding all Vorbis headers!\n"); 223 exit (1); 224 } 225 226 ogg_sync_wrote (&oy,bytes); 227 } 228 229 if (vi.rate != srate) { 230 printf ("\n\nError : File '%s' has sample rate of %ld when it should be %d.\n\n", filename, vi.rate, srate); 231 exit (1) ; 232 } 233 234 vorbis_synthesis_init (&vd,&vi); 235 vorbis_block_init (&vd,&vb); 236 237 while(!eos) { 238 while (!eos) { 239 int result = ogg_sync_pageout (&oy,&og); 240 if (result == 0) 241 break; 242 if (result < 0) { 243 fprintf (stderr,"Corrupt or missing data in bitstream; " 244 "continuing...\n"); 245 } else { 246 ogg_stream_pagein (&os,&og); 247 while (1) { 248 result = ogg_stream_packetout (&os,&op); 249 250 if (result == 0) 251 break; 252 if (result < 0) { 253 /* no reason to complain; already complained above */ 254 } else { 255 float **pcm; 256 int samples; 257 258 if (vorbis_synthesis (&vb,&op) == 0) 259 vorbis_synthesis_blockin(&vd,&vb); 260 while ((samples = vorbis_synthesis_pcmout (&vd,&pcm)) > 0 && read_total < count) { 261 int bout = samples < count ? samples : count; 262 bout = read_total + bout > count ? count - read_total : bout; 263 264 memcpy (data + read_total, pcm[0], bout * sizeof (float)) ; 265 266 vorbis_synthesis_read (&vd,bout); 267 read_total += bout ; 268 } 269 } 270 } 271 272 if (ogg_page_eos (&og)) eos = 1; 273 } 274 } 275 276 if (!eos) { 277 buffer = ogg_sync_buffer (&oy,4096); 278 bytes = fread (buffer,1,4096,file); 279 ogg_sync_wrote (&oy,bytes); 280 if (bytes == 0) eos = 1; 281 } 282 } 283 284 ogg_stream_clear (&os); 285 286 vorbis_block_clear (&vb); 287 vorbis_dsp_clear (&vd); 288 vorbis_comment_clear (&vc); 289 vorbis_info_clear (&vi); 290 } 291 done_decode: 292 293 /* OK, clean up the framer */ 294 ogg_sync_clear (&oy); 295 296 fclose (file) ; 297 } 298 299