1 /* (C) 2007 Jean-Marc Valin, CSIRO
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
15 - Neither the name of the Xiph.org Foundation nor the names of its
16 contributors may be used to endorse or promote products derived from
17 this software without specific prior written permission.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
23 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 #include "os_support.h"
41 #include "kiss_fftr.h"
45 #include "quant_pitch.h"
46 #include "quant_bands.h"
50 #define MAX_PERIOD 1024
53 #define M_PI 3.14159263
60 const CELTMode *mode; /**< Mode used by the encoder */
74 mdct_lookup mdct_lookup;
88 CELTEncoder *celt_encoder_create(const CELTMode *mode)
93 if (check_mode(mode) != CELT_OK)
97 B = mode->nbMdctBlocks;
99 st = celt_alloc(sizeof(CELTEncoder));
102 st->frame_size = B*N;
105 st->overlap = mode->overlap;
107 N4 = (N-st->overlap)/2;
108 ec_byte_writeinit(&st->buf);
109 ec_enc_init(&st->enc,&st->buf);
111 mdct_init(&st->mdct_lookup, 2*N);
112 st->fft = kiss_fftr_alloc(MAX_PERIOD*C, 0, 0);
113 psydecay_init(&st->psy, MAX_PERIOD*C/2, st->mode->Fs);
115 st->window = celt_alloc(2*N*sizeof(float));
116 st->in_mem = celt_alloc(N*C*sizeof(float));
117 st->mdct_overlap = celt_alloc(N*C*sizeof(float));
118 st->out_mem = celt_alloc(MAX_PERIOD*C*sizeof(float));
121 for (i=0;i<st->overlap;i++)
122 st->window[N4+i] = st->window[2*N-N4-i-1]
123 = sin(.5*M_PI* sin(.5*M_PI*(i+.5)/st->overlap) * sin(.5*M_PI*(i+.5)/st->overlap));
125 st->window[N-N4+i] = 1;
126 st->oldBandE = celt_alloc(C*mode->nbEBands*sizeof(float));
129 st->preemph_memE = celt_alloc(C*sizeof(float));;
130 st->preemph_memD = celt_alloc(C*sizeof(float));;
135 void celt_encoder_destroy(CELTEncoder *st)
139 celt_warning("NULL passed to celt_encoder_destroy");
142 if (check_mode(st->mode) != CELT_OK)
145 ec_byte_writeclear(&st->buf);
147 mdct_clear(&st->mdct_lookup);
148 kiss_fft_free(st->fft);
149 psydecay_clear(&st->psy);
151 celt_free(st->window);
152 celt_free(st->in_mem);
153 celt_free(st->mdct_overlap);
154 celt_free(st->out_mem);
156 celt_free(st->oldBandE);
158 celt_free(st->preemph_memE);
159 celt_free(st->preemph_memD);
164 /** Apply window and compute the MDCT for all sub-frames and all channels in a frame */
165 static float compute_mdcts(mdct_lookup *mdct_lookup, float *window, float *in, float *out, int N, int B, int C)
171 ALLOC(x, 2*N, float);
172 ALLOC(tmp, N, float);
180 x[j] = window[j]*in[C*i*N+C*j+c];
183 mdct_forward(mdct_lookup, x, tmp);
184 /* Interleaving the sub-frames */
186 out[C*B*j+C*i+c] = tmp[j];
192 /** Compute the IMDCT and apply window for all sub-frames and all channels in a frame */
193 static void compute_inv_mdcts(mdct_lookup *mdct_lookup, float *window, float *X, float *out_mem, float *mdct_overlap, int N, int overlap, int B, int C)
198 ALLOC(x, 2*N, float);
199 ALLOC(tmp, N, float);
206 /* De-interleaving the sub-frames */
208 tmp[j] = X[C*B*j+C*i+c];
209 mdct_backward(mdct_lookup, tmp, x);
211 x[j] = window[j]*x[j];
212 for (j=0;j<overlap;j++)
213 out_mem[C*(MAX_PERIOD+(i-B)*N)+C*j+c] = x[N4+j]+mdct_overlap[C*j+c];
215 out_mem[C*(MAX_PERIOD+(i-B)*N)+C*(j+overlap)+c] = x[j+N4+overlap];
216 for (j=0;j<overlap;j++)
217 mdct_overlap[C*j+c] = x[N+N4+j];
222 int celt_encode(CELTEncoder *st, celt_int16_t *pcm, unsigned char *compressed, int nbCompressedBytes)
224 int i, c, N, B, C, N4;
227 float curr_power, pitch_power;
231 VARDECL(float *mask);
232 VARDECL(float *bandE);
233 VARDECL(float *gains);
235 if (check_mode(st->mode) != CELT_OK)
236 return CELT_INVALID_MODE;
240 C = st->mode->nbChannels;
241 ALLOC(in, (B+1)*C*N, float);
242 ALLOC(X, B*C*N, float); /**< Interleaved signal MDCTs */
243 ALLOC(P, B*C*N, float); /**< Interleaved pitch MDCTs*/
244 ALLOC(mask, B*C*N, float); /**< Masking curve */
245 ALLOC(bandE,st->mode->nbEBands*C, float);
246 ALLOC(gains,st->mode->nbPBands, float);
248 N4 = (N-st->overlap)/2;
254 for (i=0;i<st->overlap;i++)
255 in[C*(i+N4)+c] = st->in_mem[C*i+c];
258 float tmp = pcm[C*i+c];
259 in[C*(i+st->overlap+N4)+c] = tmp - st->preemph*st->preemph_memE[c];
260 st->preemph_memE[c] = tmp;
262 for (i=N*(B+1)-N4;i<N*(B+1);i++)
264 for (i=0;i<st->overlap;i++)
265 st->in_mem[C*i+c] = in[C*(N*(B+1)-N4-st->overlap+i)+c];
267 /*for (i=0;i<(B+1)*C*N;i++) printf ("%f(%d) ", in[i], i); printf ("\n");*/
269 curr_power = compute_mdcts(&st->mdct_lookup, st->window, in, X, N, B, C);
271 #if 0 /* Mask disabled until it can be made to do something useful */
272 compute_mdct_masking(X, mask, B*C*N, st->Fs);
274 /* Invert and stretch the mask to length of X
275 For some reason, I get better results by using the sqrt instead,
276 although there's no valid reason to. Must investigate further */
277 for (i=0;i<B*C*N;i++)
278 mask[i] = 1/(.1+mask[i]);
280 for (i=0;i<B*C*N;i++)
288 in[C*i+c] *= st->window[i];
289 in[C*(B*N+i)+c] *= st->window[N+i];
292 find_spectral_pitch(st->fft, &st->psy, in, st->out_mem, MAX_PERIOD, (B+1)*N, C, &pitch_index);
294 /* Compute MDCTs of the pitch part */
295 pitch_power = compute_mdcts(&st->mdct_lookup, st->window, st->out_mem+pitch_index*C, P, N, B, C);
297 /*printf ("%f %f\n", curr_power, pitch_power);*/
300 printf ("%f ", X[j]);
302 printf ("%f ", P[j]);
305 /* Band normalisation */
306 compute_band_energies(st->mode, X, bandE);
307 normalise_bands(st->mode, X, bandE);
308 /*for (i=0;i<st->mode->nbEBands;i++)printf("%f ", bandE[i]);printf("\n");*/
309 /*for (i=0;i<N*B*C;i++)printf("%f ", X[i]);printf("\n");*/
311 quant_energy(st->mode, bandE, st->oldBandE, nbCompressedBytes*8/3, &st->enc);
315 stereo_mix(st->mode, X, bandE, 1);
318 /* Check if we can safely use the pitch (i.e. effective gain isn't too high) */
319 if (curr_power + 1e5f < 10.f*pitch_power)
321 /* Normalise the pitch vector as well (discard the energies) */
322 VARDECL(float *bandEp);
323 ALLOC(bandEp, st->mode->nbEBands*st->mode->nbChannels, float);
324 compute_band_energies(st->mode, P, bandEp);
325 normalise_bands(st->mode, P, bandEp);
328 stereo_mix(st->mode, P, bandE, 1);
329 /* Simulates intensity stereo */
330 /*for (i=30;i<N*B;i++)
331 X[i*C+1] = P[i*C+1] = 0;*/
333 /* Pitch prediction */
334 compute_pitch_gain(st->mode, X, P, gains, bandE);
335 has_pitch = quant_pitch(gains, st->mode->nbPBands, &st->enc);
337 ec_enc_uint(&st->enc, pitch_index, MAX_PERIOD-(B+1)*N);
339 /* No pitch, so we just pretend we found a gain of zero */
340 for (i=0;i<st->mode->nbPBands;i++)
342 ec_enc_uint(&st->enc, 0, 128);
343 for (i=0;i<B*C*N;i++)
348 pitch_quant_bands(st->mode, X, P, gains);
350 /*for (i=0;i<B*N;i++) printf("%f ",P[i]);printf("\n");*/
351 /* Compute residual that we're going to encode */
352 for (i=0;i<B*C*N;i++)
358 printf ("%f\n", sum);*/
359 /* Residual quantisation */
360 quant_bands(st->mode, X, P, mask, nbCompressedBytes*8, &st->enc);
363 stereo_mix(st->mode, X, bandE, -1);
365 renormalise_bands(st->mode, X);
367 denormalise_bands(st->mode, X, bandE);
370 CELT_MOVE(st->out_mem, st->out_mem+C*B*N, C*(MAX_PERIOD-B*N));
372 compute_inv_mdcts(&st->mdct_lookup, st->window, X, st->out_mem, st->mdct_overlap, N, st->overlap, B, C);
373 /* De-emphasis and put everything back at the right place in the synthesis history */
381 float tmp = st->out_mem[C*(MAX_PERIOD+(i-B)*N)+C*j+c] + st->preemph*st->preemph_memD[c];
382 st->preemph_memD[c] = tmp;
383 if (tmp > 32767) tmp = 32767;
384 if (tmp < -32767) tmp = -32767;
385 pcm[C*i*N+C*j+c] = (short)floor(.5+tmp);
390 if (ec_enc_tell(&st->enc, 0) < nbCompressedBytes*8 - 7)
391 celt_warning_int ("many unused bits: ", nbCompressedBytes*8-ec_enc_tell(&st->enc, 0));
392 /*printf ("%d\n", ec_enc_tell(&st->enc, 0)-8*nbCompressedBytes);*/
393 /* Finishing the stream with a 0101... pattern so that the decoder can check is everything's right */
396 while (ec_enc_tell(&st->enc, 0) < nbCompressedBytes*8)
398 ec_enc_uint(&st->enc, val, 2);
402 ec_enc_done(&st->enc);
405 int nbBytes = ec_byte_bytes(&st->buf);
406 if (nbBytes > nbCompressedBytes)
408 celt_warning_int ("got too many bytes:", nbBytes);
409 return CELT_INTERNAL_ERROR;
411 /*printf ("%d\n", *nbBytes);*/
412 data = ec_byte_get_buffer(&st->buf);
413 for (i=0;i<nbBytes;i++)
414 compressed[i] = data[i];
415 for (;i<nbCompressedBytes;i++)
418 /* Reset the packing for the next encoding */
419 ec_byte_reset(&st->buf);
420 ec_enc_init(&st->enc,&st->buf);
422 return nbCompressedBytes;
426 /****************************************************************************/
430 /****************************************************************************/
437 const CELTMode *mode;
449 mdct_lookup mdct_lookup;
457 int last_pitch_index;
460 CELTDecoder *celt_decoder_create(const CELTMode *mode)
465 if (check_mode(mode) != CELT_OK)
469 B = mode->nbMdctBlocks;
470 C = mode->nbChannels;
471 st = celt_alloc(sizeof(CELTDecoder));
474 st->frame_size = B*N;
477 st->overlap = mode->overlap;
479 N4 = (N-st->overlap)/2;
481 mdct_init(&st->mdct_lookup, 2*N);
483 st->window = celt_alloc(2*N*sizeof(float));
484 st->mdct_overlap = celt_alloc(N*C*sizeof(float));
485 st->out_mem = celt_alloc(MAX_PERIOD*C*sizeof(float));
489 for (i=0;i<st->overlap;i++)
490 st->window[N4+i] = st->window[2*N-N4-i-1]
491 = sin(.5*M_PI* sin(.5*M_PI*(i+.5)/st->overlap) * sin(.5*M_PI*(i+.5)/st->overlap));
493 st->window[N-N4+i] = 1;
495 st->oldBandE = celt_alloc(C*mode->nbEBands*sizeof(float));
498 st->preemph_memD = celt_alloc(C*sizeof(float));;
500 st->last_pitch_index = 0;
504 void celt_decoder_destroy(CELTDecoder *st)
508 celt_warning("NULL passed to celt_encoder_destroy");
511 if (check_mode(st->mode) != CELT_OK)
514 mdct_clear(&st->mdct_lookup);
516 celt_free(st->window);
517 celt_free(st->mdct_overlap);
518 celt_free(st->out_mem);
520 celt_free(st->oldBandE);
522 celt_free(st->preemph_memD);
527 /** Handles lost packets by just copying past data with the same offset as the last
529 static void celt_decode_lost(CELTDecoder *st, short *pcm)
536 C = st->mode->nbChannels;
537 ALLOC(X,C*B*N, float); /**< Interleaved signal MDCTs */
539 pitch_index = st->last_pitch_index;
541 /* Use the pitch MDCT as the "guessed" signal */
542 compute_mdcts(&st->mdct_lookup, st->window, st->out_mem+pitch_index*C, X, N, B, C);
544 CELT_MOVE(st->out_mem, st->out_mem+C*B*N, C*(MAX_PERIOD-B*N));
545 /* Compute inverse MDCTs */
546 compute_inv_mdcts(&st->mdct_lookup, st->window, X, st->out_mem, st->mdct_overlap, N, st->overlap, B, C);
555 float tmp = st->out_mem[C*(MAX_PERIOD+(i-B)*N)+C*j+c] + st->preemph*st->preemph_memD[c];
556 st->preemph_memD[c] = tmp;
557 if (tmp > 32767) tmp = 32767;
558 if (tmp < -32767) tmp = -32767;
559 pcm[C*i*N+C*j+c] = (short)floor(.5+tmp);
565 int celt_decode(CELTDecoder *st, unsigned char *data, int len, celt_int16_t *pcm)
574 VARDECL(float *bandE);
575 VARDECL(float *gains);
577 if (check_mode(st->mode) != CELT_OK)
578 return CELT_INVALID_MODE;
582 C = st->mode->nbChannels;
584 ALLOC(X, C*B*N, float); /**< Interleaved signal MDCTs */
585 ALLOC(P, C*B*N, float); /**< Interleaved pitch MDCTs*/
586 ALLOC(bandE, st->mode->nbEBands*C, float);
587 ALLOC(gains, st->mode->nbPBands, float);
589 if (check_mode(st->mode) != CELT_OK)
590 return CELT_INVALID_MODE;
593 celt_decode_lost(st, pcm);
597 ec_byte_readinit(&buf,data,len);
598 ec_dec_init(&dec,&buf);
600 /* Get band energies */
601 unquant_energy(st->mode, bandE, st->oldBandE, len*8/3, &dec);
603 /* Get the pitch gains */
604 has_pitch = unquant_pitch(gains, st->mode->nbPBands, &dec);
606 /* Get the pitch index */
609 pitch_index = ec_dec_uint(&dec, MAX_PERIOD-(B+1)*N);
610 st->last_pitch_index = pitch_index;
612 /* FIXME: We could be more intelligent here and just not compute the MDCT */
617 compute_mdcts(&st->mdct_lookup, st->window, st->out_mem+pitch_index*C, P, N, B, C);
620 VARDECL(float *bandEp);
621 ALLOC(bandEp, st->mode->nbEBands*C, float);
622 compute_band_energies(st->mode, P, bandEp);
623 normalise_bands(st->mode, P, bandEp);
627 stereo_mix(st->mode, P, bandE, 1);
629 /* Apply pitch gains */
630 pitch_quant_bands(st->mode, X, P, gains);
632 /* Decode fixed codebook and merge with pitch */
633 unquant_bands(st->mode, X, P, len*8, &dec);
636 stereo_mix(st->mode, X, bandE, -1);
638 renormalise_bands(st->mode, X);
641 denormalise_bands(st->mode, X, bandE);
644 CELT_MOVE(st->out_mem, st->out_mem+C*B*N, C*(MAX_PERIOD-B*N));
645 /* Compute inverse MDCTs */
646 compute_inv_mdcts(&st->mdct_lookup, st->window, X, st->out_mem, st->mdct_overlap, N, st->overlap, B, C);
655 float tmp = st->out_mem[C*(MAX_PERIOD+(i-B)*N)+C*j+c] + st->preemph*st->preemph_memD[c];
656 st->preemph_memD[c] = tmp;
657 if (tmp > 32767) tmp = 32767;
658 if (tmp < -32767) tmp = -32767;
659 pcm[C*i*N+C*j+c] = (short)floor(.5+tmp);
666 while (ec_dec_tell(&dec, 0) < len*8)
668 if (ec_dec_uint(&dec, 2) != val)
670 celt_warning("decode error");
671 return CELT_CORRUPTED_DATA;