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 */ 31void 32write_vorbis_data_or_die (const char *filename, int srate, const float * data, int count) 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,1,srate,0.8); 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 92 memcpy (buffer [0], data, count * sizeof (float)) ; 93 94 /* tell the library how much we actually submitted */ 95 vorbis_analysis_wrote (&vd,count); 96 vorbis_analysis_wrote (&vd,0); 97 } 98 99 while (vorbis_analysis_blockout (&vd,&vb) == 1) { 100 vorbis_analysis (&vb,NULL); 101 vorbis_bitrate_addblock (&vb); 102 103 while (vorbis_bitrate_flushpacket (&vd,&op)) { 104 ogg_stream_packetin (&os,&op); 105 106 while (!eos) { 107 int result = ogg_stream_pageout (&os,&og); 108 if (result == 0) 109 break; 110 fwrite (og.header,1,og.header_len,file); 111 fwrite (og.body,1,og.body_len,file); 112 113 if (ogg_page_eos (&og)) 114 eos = 1; 115 } 116 } 117 } 118 119 ogg_stream_clear (&os); 120 vorbis_block_clear (&vb); 121 vorbis_dsp_clear (&vd); 122 vorbis_comment_clear (&vc); 123 vorbis_info_clear (&vi); 124 125 fclose (file) ; 126} 127 128/* The following function is basically a hacked version of the code in 129 * examples/decoder_example.c */ 130void 131read_vorbis_data_or_die (const char *filename, int srate, float * data, int count) 132{ 133 ogg_sync_state oy; 134 ogg_stream_state os; 135 ogg_page og; 136 ogg_packet op; 137 138 vorbis_info vi; 139 vorbis_comment vc; 140 vorbis_dsp_state vd; 141 vorbis_block vb; 142 143 FILE *file; 144 char *buffer; 145 int bytes; 146 int eos = 0; 147 int i; 148 int read_total = 0 ; 149 150 if ((file = fopen (filename, "rb")) == NULL) { 151 printf("\n\nError : fopen failed : %s\n", strerror (errno)) ; 152 exit (1) ; 153 } 154 155 ogg_sync_init (&oy); 156 157 { 158 buffer = ogg_sync_buffer (&oy,4096); 159 bytes = fread (buffer,1,4096,file); 160 ogg_sync_wrote (&oy,bytes); 161 162 if(ogg_sync_pageout (&oy,&og) != 1) { 163 if(bytes < 4096) { 164 printf ("Out of data.\n") ; 165 goto done_decode ; 166 } 167 168 fprintf (stderr,"Input does not appear to be an Ogg bitstream.\n"); 169 exit (1); 170 } 171 172 ogg_stream_init (&os,ogg_page_serialno(&og)); 173 174 vorbis_info_init (&vi); 175 vorbis_comment_init (&vc); 176 if (ogg_stream_pagein (&os,&og) < 0) { 177 fprintf (stderr,"Error reading first page of Ogg bitstream data.\n"); 178 exit (1); 179 } 180 181 if (ogg_stream_packetout(&os,&op) != 1) { 182 fprintf (stderr,"Error reading initial header packet.\n"); 183 exit (1); 184 } 185 186 if (vorbis_synthesis_headerin (&vi,&vc,&op) < 0) { 187 fprintf (stderr,"This Ogg bitstream does not contain Vorbis " 188 "audio data.\n"); 189 exit (1); 190 } 191 192 i = 0; 193 while ( i < 2) { 194 while (i < 2) { 195 int result = ogg_sync_pageout (&oy,&og); 196 if(result == 0) 197 break; 198 if(result==1) { 199 ogg_stream_pagein(&os,&og); 200 201 while (i < 2) { 202 result = ogg_stream_packetout (&os,&op); 203 if (result == 0) 204 goto done_decode; 205 if (result < 0) { 206 fprintf (stderr,"Corrupt secondary header. Exiting.\n"); 207 exit(1); 208 } 209 vorbis_synthesis_headerin (&vi,&vc,&op); 210 i++; 211 } 212 } 213 } 214 215 buffer = ogg_sync_buffer (&oy,4096); 216 bytes = fread (buffer,1,4096,file); 217 if (bytes == 0 && i < 2) { 218 fprintf (stderr,"End of file before finding all Vorbis headers!\n"); 219 exit (1); 220 } 221 222 ogg_sync_wrote (&oy,bytes); 223 } 224 225 if (vi.rate != srate) { 226 printf ("\n\nError : File '%s' has sample rate of %ld when it should be %d.\n\n", filename, vi.rate, srate); 227 exit (1) ; 228 } 229 if (vi.channels != 1) { 230 printf ("\n\nError : File '%s' has %d channels, but should be mono.\n\n", filename, vi.channels); 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 } 292done_decode: 293 294 /* OK, clean up the framer */ 295 ogg_sync_clear (&oy); 296 297 fclose (file) ; 298} 299 300