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.

This commit is contained in:
Gregory Maxwell 2008-09-30 18:20:14 -04:00 committed by Jean-Marc Valin
parent c18fb1d031
commit 8259531160
5 changed files with 36 additions and 31 deletions

View file

@ -371,10 +371,10 @@ static void compute_inv_mdcts(const CELTMode *mode, int shortBlocks, celt_sig_t
} }
#ifdef FIXED_POINT #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 #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 #endif
int i, c, N, N4; int i, c, N, N4;
@ -602,7 +602,7 @@ int celt_encode_float(CELTEncoder * restrict st, celt_sig_t * restrict pcm, unsi
/* Residual quantisation */ /* Residual quantisation */
quant_bands(st->mode, X, P, NULL, bandE, stereo_mode, pulses, shortBlocks, nbCompressedBytes*8, &st->enc); 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) if (C==2)
renormalise_bands(st->mode, X); renormalise_bands(st->mode, X);
@ -614,19 +614,19 @@ int celt_encode_float(CELTEncoder * restrict st, celt_sig_t * restrict pcm, unsi
compute_inv_mdcts(st->mode, shortBlocks, freq, transient_time, transient_shift, st->out_mem); 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 */ /* De-emphasis and put everything back at the right place in the synthesis history */
#ifndef SHORTCUTS if (optional_synthesis != NULL) {
for (c=0;c<C;c++) for (c=0;c<C;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], 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]); preemph,st->preemph_memD[c]);
st->preemph_memD[c] = tmp; st->preemph_memD[c] = tmp;
pcm[C*j+c] = SCALEOUT(SIG2WORD16(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));*/ /*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) /*if (ec_enc_tell(&st->enc, 0) < nbCompressedBytes*8 - 7)
@ -668,7 +668,7 @@ int celt_encode_float(CELTEncoder * restrict st, celt_sig_t * restrict pcm, unsi
#ifdef FIXED_POINT #ifdef FIXED_POINT
#ifndef DISABLE_FLOAT_API #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; int j, ret;
const int C = CHANNELS(st->mode); const int C = CHANNELS(st->mode);
@ -679,18 +679,20 @@ int celt_encode_float(CELTEncoder * restrict st, float * restrict pcm, unsigned
for (j=0;j<C*N;j++) for (j=0;j<C*N;j++)
in[j] = FLOAT2INT16(pcm[j]); in[j] = FLOAT2INT16(pcm[j]);
ret=celt_encode(st,in,compressed,nbCompressedBytes); if (optional_synthesis != NULL) {
#ifndef SHORTCUTS ret=celt_encode(st,in,in,compressed,nbCompressedBytes);
/*Converts backwards for inplace operation*/ /*Converts backwards for inplace operation*/
for (j=0;j=C*N;j++) for (j=0;j=C*N;j++)
pcm[j]=in[j]*(1/32768.); optional_synthesis[j]=in[j]*(1/32768.);
#endif } else {
ret=celt_encode(st,in,NULL,compressed,nbCompressedBytes);
}
return ret; return ret;
} }
#endif /*DISABLE_FLOAT_API*/ #endif /*DISABLE_FLOAT_API*/
#else #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; int j, ret;
VARDECL(celt_sig_t, in); VARDECL(celt_sig_t, in);
@ -701,12 +703,15 @@ int celt_encode(CELTEncoder * restrict st, celt_int16_t * restrict pcm, unsigned
for (j=0;j<C*N;j++) { for (j=0;j<C*N;j++) {
in[j] = SCALEOUT(pcm[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; return ret;
} }
#endif #endif

View file

@ -152,8 +152,8 @@ EXPORT void celt_encoder_destroy(CELTEncoder *st);
has occured (see error codes). It is IMPORTANT that the length returned has occured (see error codes). It is IMPORTANT that the length returned
be somehow transmitted to the decoder. Otherwise, no decoding is possible. 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_float(CELTEncoder *st, const float *pcm, float *optional_synthesis, unsigned char *compressed, int nbCompressedBytes);
EXPORT int celt_encode(CELTEncoder *st, celt_int16_t *pcm, 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 /** Query and set encoder parameters
@param st Encoder state @param st Encoder state
@ -161,7 +161,7 @@ EXPORT int celt_encode(CELTEncoder *st, celt_int16_t *pcm, unsigned char *compre
@param value Pointer to a 32-bit int value @param value Pointer to a 32-bit int value
@return Error code @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 */ /* Decoder stuff */

View file

@ -111,7 +111,7 @@ int main(int argc, char *argv[])
fread(in, sizeof(short), frame_size*channels, fin); fread(in, sizeof(short), frame_size*channels, fin);
if (feof(fin)) if (feof(fin))
break; break;
len = celt_encode(enc, in, data, bytes_per_packet); len = celt_encode(enc, in, in, data, bytes_per_packet);
if (len <= 0) if (len <= 0)
{ {
fprintf (stderr, "celt_encode() returned %d\n", len); fprintf (stderr, "celt_encode() returned %d\n", len);

View file

@ -116,7 +116,7 @@ int main(int argc, char *argv[])
} }
/* Setup audio device */ /* 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 */ /* Setup the encoder and decoder in wideband */
CELTEncoder *enc_state; CELTEncoder *enc_state;
@ -210,7 +210,7 @@ int main(int argc, char *argv[])
pcm[i] = pcm2[i]; pcm[i] = pcm2[i];
/* Encode */ /* 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 */ /* Pseudo header: four null bytes and a 32-bit timestamp */
((int*)outpacket)[0] = send_timestamp; ((int*)outpacket)[0] = send_timestamp;

View file

@ -598,7 +598,7 @@ int main(int argc, char **argv)
id++; id++;
/*Encode current frame*/ /*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) if (nbBytes<0)
{ {
fprintf(stderr, "Got error %d while encoding. Aborting.\n", nbBytes); fprintf(stderr, "Got error %d while encoding. Aborting.\n", nbBytes);