shithub: opus

Download patch

ref: 82595311602a327dc52aef96e0ed151b4ae5046b
parent: c18fb1d0314e386ee07e80048c2dd1de625c017d
author: Gregory Maxwell <[email protected]>
date: Tue Sep 30 14:20:14 EDT 2008

API: Change celt_encode and celt_encode_float so that they take an optional synthesis parameter after the PCM input. If optional_synthesis is null the encoder will be able to save some computation. If optional_synthesis is non-null if will be used to write the encoder's expectation of the decoder's output. Synthesis may alias the input pcm, so calling the encoder with the same buffer twice will achieve the old behavior. Remove 'restrict' from the CTL prototype.

--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -371,10 +371,10 @@
 }
 
 #ifdef FIXED_POINT
-int celt_encode(CELTEncoder * restrict st, celt_int16_t * restrict pcm, unsigned char *compressed, int nbCompressedBytes)
+int celt_encode(CELTEncoder * restrict st, const celt_int16_t * pcm, celt_int16_t * optional_synthesis, unsigned char *compressed, int nbCompressedBytes)
 {
 #else
-int celt_encode_float(CELTEncoder * restrict st, celt_sig_t * restrict pcm, unsigned char *compressed, int nbCompressedBytes)
+int celt_encode_float(CELTEncoder * restrict st, const celt_sig_t * pcm, celt_sig_t * optional_synthesis, unsigned char *compressed, int nbCompressedBytes)
 {
 #endif
    int i, c, N, N4;
@@ -602,7 +602,7 @@
    /* Residual quantisation */
    quant_bands(st->mode, X, P, NULL, bandE, stereo_mode, pulses, shortBlocks, nbCompressedBytes*8, &st->enc);
    
-   if (st->pitch_enabled)
+   if (st->pitch_enabled || optional_synthesis!=NULL)
    {
       if (C==2)
          renormalise_bands(st->mode, X);
@@ -614,19 +614,19 @@
       
       compute_inv_mdcts(st->mode, shortBlocks, freq, transient_time, transient_shift, st->out_mem);
       /* De-emphasis and put everything back at the right place in the synthesis history */
-#ifndef SHORTCUTS
-      for (c=0;c<C;c++)
-      {
-         int j;
-         for (j=0;j<N;j++)
+      if (optional_synthesis != NULL) {
+         for (c=0;c<C;c++)
          {
-            celt_sig_t tmp = MAC16_32_Q15(st->out_mem[C*(MAX_PERIOD-N)+C*j+c],
+            int j;
+            for (j=0;j<N;j++)
+            {
+               celt_sig_t tmp = MAC16_32_Q15(st->out_mem[C*(MAX_PERIOD-N)+C*j+c],
                                    preemph,st->preemph_memD[c]);
-            st->preemph_memD[c] = tmp;
-            pcm[C*j+c] = SCALEOUT(SIG2WORD16(tmp));
+               st->preemph_memD[c] = tmp;
+               optional_synthesis[C*j+c] = SCALEOUT(SIG2WORD16(tmp));
+            }
          }
       }
-#endif
    }
    /*fprintf (stderr, "remaining bits after encode = %d\n", nbCompressedBytes*8-ec_enc_tell(&st->enc, 0));*/
    /*if (ec_enc_tell(&st->enc, 0) < nbCompressedBytes*8 - 7)
@@ -668,7 +668,7 @@
 
 #ifdef FIXED_POINT
 #ifndef DISABLE_FLOAT_API
-int celt_encode_float(CELTEncoder * restrict st, float * restrict pcm, unsigned char *compressed, int nbCompressedBytes)
+int celt_encode_float(CELTEncoder * restrict st, const float * pcm, float * optional_synthesis, unsigned char *compressed, int nbCompressedBytes)
 {
    int j, ret;
    const int C = CHANNELS(st->mode);
@@ -679,18 +679,20 @@
    for (j=0;j<C*N;j++)
      in[j] = FLOAT2INT16(pcm[j]);
 
-   ret=celt_encode(st,in,compressed,nbCompressedBytes);
-#ifndef SHORTCUTS
+   if (optional_synthesis != NULL) {
+     ret=celt_encode(st,in,in,compressed,nbCompressedBytes);
    /*Converts backwards for inplace operation*/
-   for (j=0;j=C*N;j++)
-     pcm[j]=in[j]*(1/32768.);
-#endif
+      for (j=0;j=C*N;j++)
+         optional_synthesis[j]=in[j]*(1/32768.);
+   } else {
+     ret=celt_encode(st,in,NULL,compressed,nbCompressedBytes);
+   }
    return ret;
 
 }
 #endif /*DISABLE_FLOAT_API*/
 #else
-int celt_encode(CELTEncoder * restrict st, celt_int16_t * restrict pcm, unsigned char *compressed, int nbCompressedBytes)
+int celt_encode(CELTEncoder * restrict st, const celt_int16_t * pcm, celt_int16_t * optional_synthesis, unsigned char *compressed, int nbCompressedBytes)
 {
    int j, ret;
    VARDECL(celt_sig_t, in);
@@ -701,12 +703,15 @@
    for (j=0;j<C*N;j++) {
      in[j] = SCALEOUT(pcm[j]);
    }
-   ret = celt_encode_float(st,in,compressed,nbCompressedBytes);
-#ifndef SHORTCUTS
-   for (j=0;j<C*N;j++)
-     pcm[j] = FLOAT2INT16(in[j]);
 
-#endif
+   if (optional_synthesis != NULL) {
+      ret = celt_encode_float(st,in,in,compressed,nbCompressedBytes);
+      for (j=0;j<C*N;j++)
+         optional_synthesis[j] = FLOAT2INT16(in[j]);
+   } else {
+      ret = celt_encode_float(st,in,NULL,compressed,nbCompressedBytes);
+   }
+
    return ret;
 }
 #endif
--- a/libcelt/celt.h
+++ b/libcelt/celt.h
@@ -152,8 +152,8 @@
          has occured (see error codes). It is IMPORTANT that the length returned
          be somehow transmitted to the decoder. Otherwise, no decoding is possible.
 */
-EXPORT int celt_encode_float(CELTEncoder *st, float *pcm, unsigned char *compressed, int nbCompressedBytes);
-EXPORT int celt_encode(CELTEncoder *st, celt_int16_t *pcm, unsigned char *compressed, int nbCompressedBytes);
+EXPORT int celt_encode_float(CELTEncoder *st, const float *pcm, float *optional_synthesis, unsigned char *compressed, int nbCompressedBytes);
+EXPORT int celt_encode(CELTEncoder *st, const celt_int16_t *pcm, celt_int16_t *optional_synthesis, unsigned char *compressed, int nbCompressedBytes);
 
 /** Query and set encoder parameters 
  @param st Encoder state
@@ -161,7 +161,7 @@
  @param value Pointer to a 32-bit int value
  @return Error code
 */
-EXPORT int celt_encoder_ctl(CELTEncoder * restrict st, int request, celt_int32_t *value);
+EXPORT int celt_encoder_ctl(CELTEncoder * st, int request, celt_int32_t *value);
 
 /* Decoder stuff */
 
--- a/libcelt/testcelt.c
+++ b/libcelt/testcelt.c
@@ -111,7 +111,7 @@
       fread(in, sizeof(short), frame_size*channels, fin);
       if (feof(fin))
          break;
-      len = celt_encode(enc, in, data, bytes_per_packet);
+      len = celt_encode(enc, in, in, data, bytes_per_packet);
       if (len <= 0)
       {
          fprintf (stderr, "celt_encode() returned %d\n", len);
--- a/tools/celtclient.c
+++ b/tools/celtclient.c
@@ -116,7 +116,7 @@
    }
 
    /* Setup audio device */
-   audio_dev = alsa_device_open(argv[1], SAMPLING_RATE, 1, FRAME_SIZE);
+   audio_dev = alsa_device_open(argv[1], SAMPLING_RATE, 2, FRAME_SIZE);
    
    /* Setup the encoder and decoder in wideband */
    CELTEncoder *enc_state;
@@ -210,7 +210,7 @@
             pcm[i] = pcm2[i];
          
          /* Encode */
-         celt_encode(enc_state, pcm, outpacket+4, packetSize);
+         celt_encode(enc_state, pcm, NULL, outpacket+4, packetSize);
          
          /* Pseudo header: four null bytes and a 32-bit timestamp */
          ((int*)outpacket)[0] = send_timestamp;
--- a/tools/celtenc.c
+++ b/tools/celtenc.c
@@ -598,7 +598,7 @@
       id++;
       /*Encode current frame*/
 
-      nbBytes = celt_encode(st, input, bits, bytes_per_packet);
+      nbBytes = celt_encode(st, input, NULL, bits, bytes_per_packet);
       if (nbBytes<0)
       {
          fprintf(stderr, "Got error %d while encoding. Aborting.\n", nbBytes);