Home | History | Annotate | Download | only in test
      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