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