shithub: opus-tools

Download patch

ref: c8ea3edb24db14c9a4386d458b0823c297cae5fc
parent: 5db3932b157d501a27dbbf82975384a605a5907a
author: Gregory Maxwell <[email protected]>
date: Fri Aug 19 08:18:16 EDT 2011

Switch the encode and decode tools to use the float API and update for the VBR API change.

--- a/src/opusdec.c
+++ b/src/opusdec.c
@@ -339,39 +339,47 @@
    return st;
 }
 
-void audio_write(opus_int16 *pcm, int channels, int frame_size, FILE *fout, SpeexResamplerState *resampler, int *skip)
+void audio_write(float *pcm, int channels, int frame_size, FILE *fout, SpeexResamplerState *resampler, int *skip, int file)
 {
-   if (resampler)
-   {
-      opus_int16 buf[2048];
-      do {
-         int tmp_skip;
-         unsigned in_len, out_len;
-         in_len = frame_size;
-         out_len = 1024;
-         speex_resampler_process_interleaved_int(resampler, pcm, &in_len, buf, &out_len);
-         if (skip)
-         {
-            tmp_skip = (*skip>out_len) ? out_len : *skip;
-            *skip -= tmp_skip;
-         } else {
-            tmp_skip = 0;
-         }
-         fwrite(buf+tmp_skip*channels, 2, (out_len-tmp_skip)*channels, fout);
-         pcm += channels*in_len;
-         frame_size -= in_len;
-      } while (frame_size != 0);
-   } else {
-      int tmp_skip;
-      if (skip)
-      {
-         tmp_skip = (*skip>frame_size) ? frame_size : *skip;
-         *skip -= tmp_skip;
-      } else {
-         tmp_skip = 0;
-      }
-      fwrite(pcm+tmp_skip*channels, 2, (frame_size-tmp_skip)*channels, fout);
-   }
+   int i,tmp_skip;
+   unsigned out_len;
+   short out[2048];
+   float buf[2048];
+   float *output;
+
+   do {
+     if (resampler){
+       output=buf;
+       unsigned in_len;
+       in_len = frame_size;
+       out_len = 1024;
+       speex_resampler_process_interleaved_float(resampler, pcm, &in_len, buf, &out_len);
+       pcm += channels*in_len;
+       frame_size -= in_len;
+     } else {
+       output=pcm;
+       out_len=frame_size;
+       frame_size=0;
+     }
+
+     if (skip){
+       tmp_skip = (*skip>out_len) ? out_len : *skip;
+       *skip -= tmp_skip;
+     } else {
+       tmp_skip = 0;
+     }
+
+     /*Convert to short and save to output file*/
+     /*FIXME: This should dither for integer output*/
+     if (file){
+       for (i=0;i<out_len*channels;i++)
+         out[i]=le_short((short)lrintf(fmax(fmin(output[i]*32768.f+0.5f,32767),-32768)));
+     } else {
+       for (i=0;i<out_len*channels;i++)
+         out[i]=(short)lrintf(fmax(fmin(output[i]*32768.f+0.5f,32767),-32768));
+     }
+     fwrite(out+tmp_skip*channels, 2, (out_len-tmp_skip)*channels, fout);
+   } while (frame_size != 0);
 }
 
 int main(int argc, char **argv)
@@ -380,8 +388,7 @@
    int option_index = 0;
    char *inFile, *outFile;
    FILE *fin, *fout=NULL;
-   opus_int16 out[MAX_FRAME_SIZE];
-   opus_int16 output[MAX_FRAME_SIZE];
+   float output[MAX_FRAME_SIZE];
    int frame_size=0;
    void *st=NULL;
    int packet_count=0;
@@ -585,9 +592,9 @@
                   int ret;
                   /*Decode frame*/
                   if (!lost)
-                     ret = opus_decode(st, (unsigned char*)op.packet, op.bytes, output, MAX_FRAME_SIZE, 0);
+                     ret = opus_decode_float(st, (unsigned char*)op.packet, op.bytes, output, MAX_FRAME_SIZE, 0);
                   else
-                     ret = opus_decode(st, NULL, 0, output, MAX_FRAME_SIZE, 0);
+                     ret = opus_decode_float(st, NULL, 0, output, MAX_FRAME_SIZE, 0);
 
                   /*for (i=0;i<frame_size*channels;i++)
                     printf ("%d\n", (int)output[i]);*/
@@ -598,13 +605,11 @@
                      break;
                   }
                   frame_size = ret;
+
                   /* Apply header gain */
                   for (i=0;i<frame_size*channels;i++)
-                  {
-                     float tmp = gain*output[i];
-                     tmp = (tmp < -32767) ? -32767 : ((tmp > 32767) ? 32767 : tmp);
-                     output[i] = floor(.5+tmp);
-                  }
+                     output[i] *= gain;
+
                   if (print_bitrate) {
                      opus_int32 tmp=op.bytes;
                      char ch=13;
@@ -616,21 +621,12 @@
                      truncate = decoded-page_granule;
                   else
                      truncate = 0;
-                  /*Convert to short and save to output file*/
-                  if (strlen(outFile)!=0)
                   {
-                     for (i=0;i<frame_size*channels;i++)
-                        out[i]=le_short(output[i]);
-                  } else {
-                     for (i=0;i<frame_size*channels;i++)
-                        out[i]=output[i];
-                  }
-                  {
                      int new_frame_size;
                      if (truncate > frame_size)
                         truncate = frame_size;
                      new_frame_size = frame_size - truncate;
-                     audio_write(out, channels, new_frame_size, fout, resampler, &preskip);
+                     audio_write(output, channels, new_frame_size, fout, resampler, &preskip, strlen(outFile)==0);
                      audio_size+=sizeof(short)*new_frame_size*channels;
                   }
                }
@@ -647,7 +643,7 @@
    if (resampler)
    {
       int i;
-      opus_int16 zeros[200];
+      float zeros[200];
       int drain;
       
       for (i=0;i<200;i++)
@@ -657,7 +653,7 @@
          int tmp = drain;
          if (tmp > 100)
             tmp = 100;
-         audio_write(zeros, channels, tmp, fout, resampler, NULL);
+         audio_write(zeros, channels, tmp, fout, resampler, NULL, strlen(outFile)==0);
          drain -= tmp;
       } while (drain>0);
    }
--- a/src/opusenc.c
+++ b/src/opusenc.c
@@ -77,7 +77,7 @@
 
 /* Convert input audio bits, endians and channels */
 static int read_samples_pcm(FILE *fin,int frame_size, int bits, int channels, 
-                            int lsb, short * input, char *buff, opus_int32 *size,
+                            int lsb, float * input, char *buff, opus_int32 *size,
                             int *extra_samples)
 {
    short s[MAX_FRAME_SIZE];
@@ -133,11 +133,10 @@
       }
    }
 
-   /* FIXME: This is probably redundent now */
    /* copy to float input buffer */
    for (i=0;i<frame_size*channels;i++)
    {
-      input[i]=s[i];
+      input[i]=s[i]*(1/32768.f);
    }
 
    for (i=nb_read*channels;i<frame_size*channels;i++)
@@ -158,13 +157,13 @@
 }
 
 static int read_samples(FILE *fin,int frame_size, int bits, int channels, 
-                        int lsb, short * input, char *buff, opus_int32 *size,
+                        int lsb, float * input, char *buff, opus_int32 *size,
                         SpeexResamplerState *resampler, int *extra_samples)
 {
    if (resampler)
    {
       /* FIXME: This is a hack, get rid of these static variables */
-      static opus_int16 pcmbuf[2048];
+      static float pcmbuf[2048];
       static int inbuf=0;
       int out_samples=0;
       while (out_samples<frame_size)
@@ -177,7 +176,7 @@
          inbuf += ret;
          in_len = inbuf;
          out_len = frame_size-out_samples;
-         speex_resampler_process_interleaved_int(resampler, pcmbuf, &in_len, input+out_samples*channels, &out_len);
+         speex_resampler_process_interleaved_float(resampler, pcmbuf, &in_len, input+out_samples*channels, &out_len);
          if (ret==0 && in_len==0)
          {
             for (i=out_samples*channels;i<frame_size*channels;i++)
@@ -257,7 +256,7 @@
    int option_index = 0;
    char *inFile, *outFile;
    FILE *fin, *fout;
-   short input[MAX_FRAME_SIZE];
+   float input[MAX_FRAME_SIZE];
    opus_int32 frame_size = 960;
    int quiet=0;
    int nbBytes;
@@ -540,7 +539,7 @@
    }
    if (!with_cbr)
    {
-     if (opus_encoder_ctl(st, OPUS_SET_VBR_FLAG(1)) != OPUS_OK)
+     if (opus_encoder_ctl(st, OPUS_SET_VBR(1)) != OPUS_OK)
      {
         fprintf (stderr, "VBR request failed\n");
         return 1;
@@ -647,7 +646,7 @@
       id++;
       /*Encode current frame*/
 
-      nbBytes = opus_encode(st, input, frame_size, bits, bytes_per_packet);
+      nbBytes = opus_encode_float(st, input, frame_size, bits, bytes_per_packet);
       if (nbBytes<0)
       {
          fprintf(stderr, "Got error %d while encoding. Aborting.\n", nbBytes);