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.
32 #include "os_support.h"
37 #include "kiss_fftr.h"
41 #include "quant_pitch.h"
42 #include "quant_bands.h"
46 #define MAX_PERIOD 1024
65 mdct_lookup mdct_lookup;
76 struct alloc_data alloc;
81 CELTEncoder *celt_encoder_new(const CELTMode *mode)
85 B = mode->nbMdctBlocks;
87 CELTEncoder *st = celt_alloc(sizeof(CELTEncoder));
93 st->overlap = mode->overlap;
96 N4 = (N-st->overlap)/2;
97 ec_byte_writeinit(&st->buf);
98 ec_enc_init(&st->enc,&st->buf);
100 mdct_init(&st->mdct_lookup, 2*N);
101 st->fft = kiss_fftr_alloc(MAX_PERIOD*C, 0, 0);
102 psydecay_init(&st->psy, MAX_PERIOD/2, st->Fs);
104 st->window = celt_alloc(2*N*sizeof(float));
105 st->in_mem = celt_alloc(N*C*sizeof(float));
106 st->mdct_overlap = celt_alloc(N*C*sizeof(float));
107 st->out_mem = celt_alloc(MAX_PERIOD*C*sizeof(float));
110 for (i=0;i<st->overlap;i++)
111 st->window[N4+i] = st->window[2*N-N4-i-1]
112 = sin(.5*M_PI* sin(.5*M_PI*(i+.5)/st->overlap) * sin(.5*M_PI*(i+.5)/st->overlap));
114 st->window[N-N4+i] = 1;
115 st->oldBandE = celt_alloc(C*mode->nbEBands*sizeof(float));
118 st->preemph_memE = celt_alloc(C*sizeof(float));;
119 st->preemph_memD = celt_alloc(C*sizeof(float));;
121 alloc_init(&st->alloc, st->mode);
125 void celt_encoder_destroy(CELTEncoder *st)
129 celt_warning("NULL passed to celt_encoder_destroy");
132 ec_byte_writeclear(&st->buf);
134 mdct_clear(&st->mdct_lookup);
135 kiss_fft_free(st->fft);
136 psydecay_clear(&st->psy);
138 celt_free(st->window);
139 celt_free(st->in_mem);
140 celt_free(st->mdct_overlap);
141 celt_free(st->out_mem);
143 celt_free(st->oldBandE);
145 celt_free(st->preemph_memE);
146 celt_free(st->preemph_memD);
148 alloc_clear(&st->alloc);
154 static void compute_mdcts(mdct_lookup *mdct_lookup, float *window, float *in, float *out, int N, int B, int C)
165 x[j] = window[j]*in[C*i*N+C*j+c];
166 mdct_forward(mdct_lookup, x, tmp);
167 /* Interleaving the sub-frames */
169 out[C*B*j+C*i+c] = tmp[j];
174 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)
185 /* De-interleaving the sub-frames */
187 tmp[j] = X[C*B*j+C*i+c];
188 mdct_backward(mdct_lookup, tmp, x);
190 x[j] = window[j]*x[j];
191 for (j=0;j<overlap;j++)
192 out_mem[C*(MAX_PERIOD+(i-B)*N)+C*j+c] = x[N4+j]+mdct_overlap[C*j+c];
194 out_mem[C*(MAX_PERIOD+(i-B)*N)+C*(j+overlap)+c] = x[j+N4+overlap];
195 for (j=0;j<overlap;j++)
196 mdct_overlap[C*j+c] = x[N+N4+j];
201 int celt_encode(CELTEncoder *st, celt_int16_t *pcm, unsigned char *compressed, int nbCompressedBytes)
203 int i, c, N, B, C, N4;
206 C = st->mode->nbChannels;
209 float X[B*C*N]; /**< Interleaved signal MDCTs */
210 float P[B*C*N]; /**< Interleaved pitch MDCTs*/
211 float mask[B*C*N]; /**< Masking curve */
212 float bandE[st->mode->nbEBands*C];
213 float gains[st->mode->nbPBands];
216 N4 = (N-st->overlap)/2;
222 for (i=0;i<st->overlap;i++)
223 in[C*(i+N4)+c] = st->in_mem[C*i+c];
226 float tmp = pcm[C*i+c];
227 in[C*(i+st->overlap+N4)+c] = tmp - st->preemph*st->preemph_memE[c];
228 st->preemph_memE[c] = tmp;
230 for (i=N*(B+1)-N4;i<N*(B+1);i++)
232 for (i=0;i<st->overlap;i++)
233 st->in_mem[C*i+c] = in[C*(N*(B+1)-N4-st->overlap+i)+c];
235 //for (i=0;i<(B+1)*C*N;i++) printf ("%f(%d) ", in[i], i); printf ("\n");
237 compute_mdcts(&st->mdct_lookup, st->window, in, X, N, B, C);
239 #if 0 /* Mask disabled until it can be made to do something useful */
240 compute_mdct_masking(X, mask, B*C*N, st->Fs);
242 /* Invert and stretch the mask to length of X
243 For some reason, I get better results by using the sqrt instead,
244 although there's no valid reason to. Must investigate further */
245 for (i=0;i<B*C*N;i++)
246 mask[i] = 1/(.1+mask[i]);
248 for (i=0;i<B*C*N;i++)
256 in[C*i+c] *= st->window[i];
257 in[C*(B*N+i)+c] *= st->window[N+i];
260 find_spectral_pitch(st->fft, &st->psy, in, st->out_mem, MAX_PERIOD, (B+1)*N, C, &pitch_index);
261 ec_enc_uint(&st->enc, pitch_index, MAX_PERIOD-(B+1)*N);
263 /* Compute MDCTs of the pitch part */
264 compute_mdcts(&st->mdct_lookup, st->window, st->out_mem+pitch_index*C, P, N, B, C);
268 printf ("%f ", X[j]);
270 printf ("%f ", P[j]);
273 /* Band normalisation */
274 compute_band_energies(st->mode, X, bandE);
275 normalise_bands(st->mode, X, bandE);
276 //for (i=0;i<st->mode->nbEBands;i++)printf("%f ", bandE[i]);printf("\n");
277 //for (i=0;i<N*B*C;i++)printf("%f ", X[i]);printf("\n");
279 /* Normalise the pitch vector as well (discard the energies) */
281 float bandEp[st->mode->nbEBands*st->mode->nbChannels];
282 compute_band_energies(st->mode, P, bandEp);
283 normalise_bands(st->mode, P, bandEp);
286 quant_energy(st->mode, bandE, st->oldBandE, &st->enc);
290 stereo_mix(st->mode, X, bandE, 1);
291 stereo_mix(st->mode, P, bandE, 1);
293 /* Simulates intensity stereo */
294 //for (i=30;i<N*B;i++)
295 // X[i*C+1] = P[i*C+1] = 0;
296 /* Get a tiny bit more frequency resolution and prevent unstable energy when quantising */
298 /* Pitch prediction */
299 compute_pitch_gain(st->mode, X, P, gains, bandE);
300 quant_pitch(gains, st->mode->nbPBands, &st->enc);
301 pitch_quant_bands(st->mode, X, P, gains);
303 //for (i=0;i<B*N;i++) printf("%f ",P[i]);printf("\n");
304 /* Compute residual that we're going to encode */
305 for (i=0;i<B*C*N;i++)
311 printf ("%f\n", sum);*/
312 /* Residual quantisation */
313 quant_bands(st->mode, X, P, mask, &st->alloc, nbCompressedBytes*8, &st->enc);
316 stereo_mix(st->mode, X, bandE, -1);
318 renormalise_bands(st->mode, X);
320 denormalise_bands(st->mode, X, bandE);
323 CELT_MOVE(st->out_mem, st->out_mem+C*B*N, C*(MAX_PERIOD-B*N));
325 compute_inv_mdcts(&st->mdct_lookup, st->window, X, st->out_mem, st->mdct_overlap, N, st->overlap, B, C);
326 /* De-emphasis and put everything back at the right place in the synthesis history */
334 float tmp = st->out_mem[C*(MAX_PERIOD+(i-B)*N)+C*j+c] + st->preemph*st->preemph_memD[c];
335 st->preemph_memD[c] = tmp;
336 if (tmp > 32767) tmp = 32767;
337 if (tmp < -32767) tmp = -32767;
338 pcm[C*i*N+C*j+c] = (short)floor(.5+tmp);
343 if (ec_enc_tell(&st->enc, 0) < nbCompressedBytes*8 - 8)
344 celt_warning_int ("too make unused bits", nbCompressedBytes*8-ec_enc_tell(&st->enc, 0));
345 //printf ("%d\n", ec_enc_tell(&st->enc, 0)-8*nbCompressedBytes);
346 /* Finishing the stream with a 0101... pattern so that the decoder can check is everything's right */
349 while (ec_enc_tell(&st->enc, 0) < nbCompressedBytes*8)
351 ec_enc_uint(&st->enc, val, 2);
355 ec_enc_done(&st->enc);
358 int nbBytes = ec_byte_bytes(&st->buf);
359 if (nbBytes > nbCompressedBytes)
361 celt_warning_int ("got too many bytes:", nbBytes);
362 return CELT_INTERNAL_ERROR;
364 //printf ("%d\n", *nbBytes);
365 data = ec_byte_get_buffer(&st->buf);
366 for (i=0;i<nbBytes;i++)
367 compressed[i] = data[i];
368 for (;i<nbCompressedBytes;i++)
371 /* Reset the packing for the next encoding */
372 ec_byte_reset(&st->buf);
373 ec_enc_init(&st->enc,&st->buf);
375 return nbCompressedBytes;
379 /****************************************************************************/
383 /****************************************************************************/
388 const CELTMode *mode;
400 mdct_lookup mdct_lookup;
408 int last_pitch_index;
410 struct alloc_data alloc;
413 CELTDecoder *celt_decoder_new(const CELTMode *mode)
417 B = mode->nbMdctBlocks;
418 C = mode->nbChannels;
419 CELTDecoder *st = celt_alloc(sizeof(CELTDecoder));
422 st->frame_size = B*N;
425 st->overlap = mode->overlap;
427 N4 = (N-st->overlap)/2;
429 mdct_init(&st->mdct_lookup, 2*N);
431 st->window = celt_alloc(2*N*sizeof(float));
432 st->mdct_overlap = celt_alloc(N*C*sizeof(float));
433 st->out_mem = celt_alloc(MAX_PERIOD*C*sizeof(float));
437 for (i=0;i<st->overlap;i++)
438 st->window[N4+i] = st->window[2*N-N4-i-1]
439 = sin(.5*M_PI* sin(.5*M_PI*(i+.5)/st->overlap) * sin(.5*M_PI*(i+.5)/st->overlap));
441 st->window[N-N4+i] = 1;
443 st->oldBandE = celt_alloc(C*mode->nbEBands*sizeof(float));
446 st->preemph_memD = celt_alloc(C*sizeof(float));;
448 st->last_pitch_index = 0;
449 alloc_init(&st->alloc, st->mode);
454 void celt_decoder_destroy(CELTDecoder *st)
458 celt_warning("NULL passed to celt_encoder_destroy");
462 mdct_clear(&st->mdct_lookup);
464 celt_free(st->window);
465 celt_free(st->mdct_overlap);
466 celt_free(st->out_mem);
468 celt_free(st->oldBandE);
470 celt_free(st->preemph_memD);
472 alloc_clear(&st->alloc);
477 static void celt_decode_lost(CELTDecoder *st, short *pcm)
482 C = st->mode->nbChannels;
483 float X[C*B*N]; /**< Interleaved signal MDCTs */
486 pitch_index = st->last_pitch_index;
488 /* Use the pitch MDCT as the "guessed" signal */
489 compute_mdcts(&st->mdct_lookup, st->window, st->out_mem+pitch_index*C, X, N, B, C);
491 CELT_MOVE(st->out_mem, st->out_mem+C*B*N, C*(MAX_PERIOD-B*N));
492 /* Compute inverse MDCTs */
493 compute_inv_mdcts(&st->mdct_lookup, st->window, X, st->out_mem, st->mdct_overlap, N, st->overlap, B, C);
502 float tmp = st->out_mem[C*(MAX_PERIOD+(i-B)*N)+C*j+c] + st->preemph*st->preemph_memD[c];
503 st->preemph_memD[c] = tmp;
504 if (tmp > 32767) tmp = 32767;
505 if (tmp < -32767) tmp = -32767;
506 pcm[C*i*N+C*j+c] = (short)floor(.5+tmp);
512 int celt_decode(CELTDecoder *st, char *data, int len, celt_int16_t *pcm)
517 C = st->mode->nbChannels;
519 float X[C*B*N]; /**< Interleaved signal MDCTs */
520 float P[C*B*N]; /**< Interleaved pitch MDCTs*/
521 float bandE[st->mode->nbEBands*C];
522 float gains[st->mode->nbPBands];
529 celt_decode_lost(st, pcm);
533 ec_byte_readinit(&buf,data,len);
534 ec_dec_init(&dec,&buf);
536 /* Get the pitch index */
537 pitch_index = ec_dec_uint(&dec, MAX_PERIOD-(B+1)*N);
538 st->last_pitch_index = pitch_index;
540 /* Get band energies */
541 unquant_energy(st->mode, bandE, st->oldBandE, &dec);
544 compute_mdcts(&st->mdct_lookup, st->window, st->out_mem+pitch_index*C, P, N, B, C);
547 float bandEp[st->mode->nbEBands];
548 compute_band_energies(st->mode, P, bandEp);
549 normalise_bands(st->mode, P, bandEp);
553 stereo_mix(st->mode, P, bandE, 1);
555 /* Get the pitch gains */
556 unquant_pitch(gains, st->mode->nbPBands, &dec);
558 /* Apply pitch gains */
559 pitch_quant_bands(st->mode, X, P, gains);
561 /* Decode fixed codebook and merge with pitch */
562 unquant_bands(st->mode, X, P, &st->alloc, len*8, &dec);
565 stereo_mix(st->mode, X, bandE, -1);
567 renormalise_bands(st->mode, X);
570 denormalise_bands(st->mode, X, bandE);
573 CELT_MOVE(st->out_mem, st->out_mem+C*B*N, C*(MAX_PERIOD-B*N));
574 /* Compute inverse MDCTs */
575 compute_inv_mdcts(&st->mdct_lookup, st->window, X, st->out_mem, st->mdct_overlap, N, st->overlap, B, C);
584 float tmp = st->out_mem[C*(MAX_PERIOD+(i-B)*N)+C*j+c] + st->preemph*st->preemph_memD[c];
585 st->preemph_memD[c] = tmp;
586 if (tmp > 32767) tmp = 32767;
587 if (tmp < -32767) tmp = -32767;
588 pcm[C*i*N+C*j+c] = (short)floor(.5+tmp);
595 while (ec_dec_tell(&dec, 0) < len*8)
597 if (ec_dec_uint(&dec, 2) != val)
599 celt_warning("decode error");
600 return CELT_CORRUPTED_DATA;