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"
41 #include "quant_pitch.h"
42 #include "quant_bands.h"
46 #define MAX_PERIOD 1024
65 mdct_lookup mdct_lookup;
75 struct alloc_data alloc;
80 CELTEncoder *celt_encoder_new(const CELTMode *mode)
84 B = mode->nbMdctBlocks;
86 CELTEncoder *st = celt_alloc(sizeof(CELTEncoder));
92 st->overlap = mode->overlap;
95 N4 = (N-st->overlap)/2;
96 ec_byte_writeinit(&st->buf);
97 ec_enc_init(&st->enc,&st->buf);
99 mdct_init(&st->mdct_lookup, 2*N);
100 st->fft = spx_fft_init(MAX_PERIOD*C);
102 st->window = celt_alloc(2*N*sizeof(float));
103 st->in_mem = celt_alloc(N*C*sizeof(float));
104 st->mdct_overlap = celt_alloc(N*C*sizeof(float));
105 st->out_mem = celt_alloc(MAX_PERIOD*C*sizeof(float));
108 for (i=0;i<st->overlap;i++)
109 st->window[N4+i] = st->window[2*N-N4-i-1]
110 = sin(.5*M_PI* sin(.5*M_PI*(i+.5)/st->overlap) * sin(.5*M_PI*(i+.5)/st->overlap));
112 st->window[N-N4+i] = 1;
113 st->oldBandE = celt_alloc(C*mode->nbEBands*sizeof(float));
116 st->preemph_memE = celt_alloc(C*sizeof(float));;
117 st->preemph_memD = celt_alloc(C*sizeof(float));;
119 alloc_init(&st->alloc, st->mode);
123 void celt_encoder_destroy(CELTEncoder *st)
127 celt_warning("NULL passed to celt_encoder_destroy");
130 ec_byte_writeclear(&st->buf);
132 mdct_clear(&st->mdct_lookup);
133 spx_fft_destroy(st->fft);
135 celt_free(st->window);
136 celt_free(st->in_mem);
137 celt_free(st->mdct_overlap);
138 celt_free(st->out_mem);
140 celt_free(st->oldBandE);
141 alloc_clear(&st->alloc);
147 static void compute_mdcts(mdct_lookup *mdct_lookup, float *window, float *in, float *out, int N, int B, int C)
158 x[j] = window[j]*in[C*i*N+C*j+c];
159 mdct_forward(mdct_lookup, x, tmp);
160 /* Interleaving the sub-frames */
162 out[C*B*j+C*i+c] = tmp[j];
167 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)
178 /* De-interleaving the sub-frames */
180 tmp[j] = X[C*B*j+C*i+c];
181 mdct_backward(mdct_lookup, tmp, x);
183 x[j] = window[j]*x[j];
184 for (j=0;j<overlap;j++)
185 out_mem[C*(MAX_PERIOD+(i-B)*N)+C*j+c] = x[N4+j]+mdct_overlap[C*j+c];
187 out_mem[C*(MAX_PERIOD+(i-B)*N)+C*(j+overlap)+c] = x[j+N4+overlap];
188 for (j=0;j<overlap;j++)
189 mdct_overlap[C*j+c] = x[N+N4+j];
194 int celt_encode(CELTEncoder *st, celt_int16_t *pcm, unsigned char *compressed, int nbCompressedBytes)
196 int i, c, N, B, C, N4;
199 C = st->mode->nbChannels;
202 float X[B*C*N]; /**< Interleaved signal MDCTs */
203 float P[B*C*N]; /**< Interleaved pitch MDCTs*/
204 float mask[B*C*N]; /**< Masking curve */
205 float bandE[st->mode->nbEBands*C];
206 float gains[st->mode->nbPBands];
209 N4 = (N-st->overlap)/2;
215 for (i=0;i<st->overlap;i++)
216 in[C*(i+N4)+c] = st->in_mem[C*i+c];
219 float tmp = pcm[C*i+c];
220 in[C*(i+st->overlap+N4)+c] = tmp - st->preemph*st->preemph_memE[c];
221 st->preemph_memE[c] = tmp;
223 for (i=N*(B+1)-N4;i<N*(B+1);i++)
225 for (i=0;i<st->overlap;i++)
226 st->in_mem[C*i+c] = in[C*(N*(B+1)-N4-st->overlap+i)+c];
228 //for (i=0;i<(B+1)*C*N;i++) printf ("%f(%d) ", in[i], i); printf ("\n");
230 compute_mdcts(&st->mdct_lookup, st->window, in, X, N, B, C);
232 compute_mdct_masking(X, mask, B*C*N, st->Fs);
234 /* Invert and stretch the mask to length of X
235 For some reason, I get better results by using the sqrt instead,
236 although there's no valid reason to. Must investigate further */
237 for (i=0;i<B*C*N;i++)
238 mask[i] = 1/(.1+mask[i]);
245 in[C*i+c] *= st->window[i];
246 in[C*(B*N+i)+c] *= st->window[N+i];
249 find_spectral_pitch(st->fft, in, st->out_mem, MAX_PERIOD, (B+1)*N, C, &pitch_index);
250 ec_enc_uint(&st->enc, pitch_index, MAX_PERIOD-(B+1)*N);
252 /* Compute MDCTs of the pitch part */
253 compute_mdcts(&st->mdct_lookup, st->window, st->out_mem+pitch_index*C, P, N, B, C);
257 printf ("%f ", X[j]);
259 printf ("%f ", P[j]);
262 /* Band normalisation */
263 compute_band_energies(st->mode, X, bandE);
264 normalise_bands(st->mode, X, bandE);
265 //for (i=0;i<st->mode->nbEBands;i++)printf("%f ", bandE[i]);printf("\n");
266 //for (i=0;i<N*B*C;i++)printf("%f ", X[i]);printf("\n");
268 /* Normalise the pitch vector as well (discard the energies) */
270 float bandEp[st->mode->nbEBands*st->mode->nbChannels];
271 compute_band_energies(st->mode, P, bandEp);
272 normalise_bands(st->mode, P, bandEp);
275 quant_energy(st->mode, bandE, st->oldBandE, &st->enc);
279 stereo_mix(st->mode, X, bandE, 1);
280 stereo_mix(st->mode, P, bandE, 1);
282 /* Simulates intensity stereo */
283 //for (i=30;i<N*B;i++)
284 // X[i*C+1] = P[i*C+1] = 0;
285 /* Get a tiny bit more frequency resolution and prevent unstable energy when quantising */
287 /* Pitch prediction */
288 compute_pitch_gain(st->mode, X, P, gains, bandE);
289 quant_pitch(gains, st->mode->nbPBands, &st->enc);
290 pitch_quant_bands(st->mode, X, P, gains);
292 //for (i=0;i<B*N;i++) printf("%f ",P[i]);printf("\n");
293 /* Compute residual that we're going to encode */
294 for (i=0;i<B*C*N;i++)
300 printf ("%f\n", sum);*/
301 /* Residual quantisation */
302 quant_bands(st->mode, X, P, mask, &st->alloc, nbCompressedBytes*8, &st->enc);
305 stereo_mix(st->mode, X, bandE, -1);
307 renormalise_bands(st->mode, X);
309 denormalise_bands(st->mode, X, bandE);
312 CELT_MOVE(st->out_mem, st->out_mem+C*B*N, C*(MAX_PERIOD-B*N));
314 compute_inv_mdcts(&st->mdct_lookup, st->window, X, st->out_mem, st->mdct_overlap, N, st->overlap, B, C);
315 /* De-emphasis and put everything back at the right place in the synthesis history */
323 float tmp = st->out_mem[C*(MAX_PERIOD+(i-B)*N)+C*j+c] + st->preemph*st->preemph_memD[c];
324 st->preemph_memD[c] = tmp;
325 if (tmp > 32767) tmp = 32767;
326 if (tmp < -32767) tmp = -32767;
327 pcm[C*i*N+C*j+c] = (short)floor(.5+tmp);
332 //printf ("%d\n", ec_enc_tell(&st->enc, 0)-8*nbCompressedBytes);
333 /* Finishing the stream with a 0101... pattern so that the decoder can check is everything's right */
336 while (ec_enc_tell(&st->enc, 0) < nbCompressedBytes*8)
338 ec_enc_uint(&st->enc, val, 2);
342 ec_enc_done(&st->enc);
345 int nbBytes = ec_byte_bytes(&st->buf);
346 if (nbBytes != nbCompressedBytes)
348 if (nbBytes > nbCompressedBytes)
349 celt_warning("got too many bytes");
351 celt_warning("not enough bytes");
352 celt_warning_int ("output bytes:", nbBytes);
353 return CELT_INTERNAL_ERROR;
355 //printf ("%d\n", *nbBytes);
356 data = ec_byte_get_buffer(&st->buf);
357 for (i=0;i<nbBytes;i++)
358 compressed[i] = data[i];
360 /* Reset the packing for the next encoding */
361 ec_byte_reset(&st->buf);
362 ec_enc_init(&st->enc,&st->buf);
364 return nbCompressedBytes;
368 /****************************************************************************/
372 /****************************************************************************/
377 const CELTMode *mode;
389 mdct_lookup mdct_lookup;
397 int last_pitch_index;
399 struct alloc_data alloc;
402 CELTDecoder *celt_decoder_new(const CELTMode *mode)
406 B = mode->nbMdctBlocks;
407 C = mode->nbChannels;
408 CELTDecoder *st = celt_alloc(sizeof(CELTDecoder));
411 st->frame_size = B*N;
414 st->overlap = mode->overlap;
416 N4 = (N-st->overlap)/2;
418 mdct_init(&st->mdct_lookup, 2*N);
420 st->window = celt_alloc(2*N*sizeof(float));
421 st->mdct_overlap = celt_alloc(N*C*sizeof(float));
422 st->out_mem = celt_alloc(MAX_PERIOD*C*sizeof(float));
426 for (i=0;i<st->overlap;i++)
427 st->window[N4+i] = st->window[2*N-N4-i-1]
428 = sin(.5*M_PI* sin(.5*M_PI*(i+.5)/st->overlap) * sin(.5*M_PI*(i+.5)/st->overlap));
430 st->window[N-N4+i] = 1;
432 st->oldBandE = celt_alloc(C*mode->nbEBands*sizeof(float));
435 st->preemph_memD = celt_alloc(C*sizeof(float));;
437 st->last_pitch_index = 0;
438 alloc_init(&st->alloc, st->mode);
443 void celt_decoder_destroy(CELTDecoder *st)
447 celt_warning("NULL passed to celt_encoder_destroy");
451 mdct_clear(&st->mdct_lookup);
453 celt_free(st->window);
454 celt_free(st->mdct_overlap);
455 celt_free(st->out_mem);
457 celt_free(st->oldBandE);
458 alloc_clear(&st->alloc);
463 static void celt_decode_lost(CELTDecoder *st, short *pcm)
468 C = st->mode->nbChannels;
469 float X[C*B*N]; /**< Interleaved signal MDCTs */
472 pitch_index = st->last_pitch_index;
474 /* Use the pitch MDCT as the "guessed" signal */
475 compute_mdcts(&st->mdct_lookup, st->window, st->out_mem+pitch_index*C, X, N, B, C);
477 CELT_MOVE(st->out_mem, st->out_mem+C*B*N, C*(MAX_PERIOD-B*N));
478 /* Compute inverse MDCTs */
479 compute_inv_mdcts(&st->mdct_lookup, st->window, X, st->out_mem, st->mdct_overlap, N, st->overlap, B, C);
488 float tmp = st->out_mem[C*(MAX_PERIOD+(i-B)*N)+C*j+c] + st->preemph*st->preemph_memD[c];
489 st->preemph_memD[c] = tmp;
490 if (tmp > 32767) tmp = 32767;
491 if (tmp < -32767) tmp = -32767;
492 pcm[C*i*N+C*j+c] = (short)floor(.5+tmp);
498 int celt_decode(CELTDecoder *st, char *data, int len, celt_int16_t *pcm)
503 C = st->mode->nbChannels;
505 float X[C*B*N]; /**< Interleaved signal MDCTs */
506 float P[C*B*N]; /**< Interleaved pitch MDCTs*/
507 float bandE[st->mode->nbEBands*C];
508 float gains[st->mode->nbPBands];
515 celt_decode_lost(st, pcm);
519 ec_byte_readinit(&buf,data,len);
520 ec_dec_init(&dec,&buf);
522 /* Get the pitch index */
523 pitch_index = ec_dec_uint(&dec, MAX_PERIOD-(B+1)*N);
524 st->last_pitch_index = pitch_index;
526 /* Get band energies */
527 unquant_energy(st->mode, bandE, st->oldBandE, &dec);
530 compute_mdcts(&st->mdct_lookup, st->window, st->out_mem+pitch_index*C, P, N, B, C);
533 float bandEp[st->mode->nbEBands];
534 compute_band_energies(st->mode, P, bandEp);
535 normalise_bands(st->mode, P, bandEp);
539 stereo_mix(st->mode, P, bandE, 1);
541 /* Get the pitch gains */
542 unquant_pitch(gains, st->mode->nbPBands, &dec);
544 /* Apply pitch gains */
545 pitch_quant_bands(st->mode, X, P, gains);
547 /* Decode fixed codebook and merge with pitch */
548 unquant_bands(st->mode, X, P, &st->alloc, len*8, &dec);
551 stereo_mix(st->mode, X, bandE, -1);
553 renormalise_bands(st->mode, X);
556 denormalise_bands(st->mode, X, bandE);
559 CELT_MOVE(st->out_mem, st->out_mem+C*B*N, C*(MAX_PERIOD-B*N));
560 /* Compute inverse MDCTs */
561 compute_inv_mdcts(&st->mdct_lookup, st->window, X, st->out_mem, st->mdct_overlap, N, st->overlap, B, C);
570 float tmp = st->out_mem[C*(MAX_PERIOD+(i-B)*N)+C*j+c] + st->preemph*st->preemph_memD[c];
571 st->preemph_memD[c] = tmp;
572 if (tmp > 32767) tmp = 32767;
573 if (tmp < -32767) tmp = -32767;
574 pcm[C*i*N+C*j+c] = (short)floor(.5+tmp);
581 while (ec_dec_tell(&dec, 0) < len*8)
583 if (ec_dec_uint(&dec, 2) != val)
585 celt_warning("decode error");
586 return CELT_CORRUPTED_DATA;