[vorbis] Vorbisgain in ogg123

Paul Martin pm at nowster.zetnet.co.uk
Sat Dec 28 02:43:21 PST 2002



On Sat, Dec 28, 2002 at 03:41:43PM +1300, John Morton wrote:
> I'm considering patching my copy of ogg123 to support vorbisgain tags. Is 
> there any interest in folding this sort of patch into the main line ogg123? 
> Has anyone done this already (or to another command line ogg player)?

Very simple decoder (stdin to stdout). Only argument is the decibel
gain (0 dB is unity gain). I had to write this as libvorbisfile doesn't
have any useful function for doing this.

I use it like this
  cat oggfile.ogg | decode -5.5 | bplay -S -s 44100 -b 16

<p>#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "vorbis/codec.h"
#include "vorbis/vorbisfile.h"
#include "os.h"

#ifdef _WIN32
#include <io.h>
#include <fcntl.h>
#endif

int main (int argc, char **argv)
{
   OggVorbis_File vf;
   int eof = 0;
   int current_section;
   float **pcm;
   char *pcmout = NULL;
   vorbis_fpu_control fpu;
   float scale = 32768.0f;
   int channels;
   int val;
   int currtenths = 0;
   int totaltenths;
   int off = 0;

   if (argc>1) {
      float decibel = 0.0f;
      sscanf(argv[1],"%f",&decibel);
      scale = scale * pow(10.0,decibel/20.0);
   }
   
#ifdef _WIN32
   _setmode (_fileno (stdin), _O_BINARY);
   _setmode (_fileno (stdout), _O_BINARY);
#endif

   if (ov_open (stdin, &vf, NULL, 0) < 0) {
      fprintf (stderr, "Input does not appear to be an Ogg bitstream.\n");
      exit (1);
   }

   {
      char **ptr = ov_comment (&vf, -1)->user_comments;
      vorbis_info *vi = ov_info (&vf, -1);
      while (*ptr) {
         fprintf (stderr, "%s\n", *ptr);
         ++ptr;
      }
      channels = vi->channels;
      fprintf (stderr, "\nBitstream is %d channel, %ldHz\n", channels,
               vi->rate);
      fprintf (stderr, "Encoded by: %s\n\n", ov_comment (&vf, -1)->vendor);
      totaltenths = (int) floor(ov_time_total(&vf,-1)*10.0);
      fprintf (stderr, "Scaling by %.2f\n",scale);
   }

   while (!eof) {
      long ret = ov_read_float (&vf, &pcm, &current_section);
      if (ret == 0) {
         /* EOF */
         eof = 1;
      }
      else if (ret < 0) {
         /* error in the stream.  Not a problem, just reporting it in
            case we (the app) cares.  In this case, we don't. */
      }
      else {
         /* we don't bother dealing with sample rate changes, etc, but
            you'll have to */
         int i, j;
         int samples = ret;

         pcmout = realloc (pcmout, 2 * samples * 2);

         vorbis_fpu_setround (&fpu);
         for (i = 0; i < channels; i++) {
            float *src = pcm[i];
            short *dest = ((short *) pcmout) + i;
            for (j = 0; j < samples; j++) {
               val = vorbis_ftoi (src[j] * scale);
               if (val > 32767) {
                  val = 32767;
                  fprintf(stderr,"+clip\n");
               }
               else if (val < -32768) {
                  val = -32768;
                  fprintf(stderr,"-clip\n");
               }
               *dest = val + off;
               dest += channels;
               if (channels == 1) {
                  *dest = val + off;
                  dest++;
               }
            }
         }
         vorbis_fpu_restore (fpu);

         fwrite (pcmout, 4, ret, stdout);
         
      }
      
      {
         int tenths;
         
         tenths = (int) floor(10.f * ov_time_tell(&vf));
         if (currtenths != tenths) {
            currtenths=tenths;
            fprintf (stderr,"\r %5.1f/%-5.1f  ",currtenths/10.0,
                     totaltenths/10.0);
         }
      }
   }
   ov_clear (&vf);
   fprintf (stderr, "Done.\n");
   return (0);
}

<p>
-- 
Paul Martin <pm at zetnet.net> (work)
  <pm at nowster.zetnet.co.uk> (home)
--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'vorbis-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.




More information about the Vorbis mailing list