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);
146 static void haar1(float *X, int N, int stride)
149 for (k=0;k<stride;k++)
151 for (i=k;i<N*stride;i+=2*stride)
156 X[i] = .707107f*(a+b);
157 X[i+stride] = .707107f*(a-b);
162 static void time_dct(float *X, int N, int B, int stride)
169 haar1(X, B*N, stride);
172 celt_warning("time_dct not defined for B > 2");
176 static void time_idct(float *X, int N, int B, int stride)
183 haar1(X, B*N, stride);
186 celt_warning("time_dct not defined for B > 2");
190 static void compute_mdcts(mdct_lookup *mdct_lookup, float *window, float *in, float *out, int N, int B, int C)
201 x[j] = window[j]*in[C*i*N+C*j+c];
202 mdct_forward(mdct_lookup, x, tmp);
203 /* Interleaving the sub-frames */
205 out[C*B*j+C*i+c] = tmp[j];
210 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)
221 /* De-interleaving the sub-frames */
223 tmp[j] = X[C*B*j+C*i+c];
224 mdct_backward(mdct_lookup, tmp, x);
226 x[j] = window[j]*x[j];
227 for (j=0;j<overlap;j++)
228 out_mem[C*(MAX_PERIOD+(i-B)*N)+C*j+c] = x[N4+j]+mdct_overlap[C*j+c];
230 out_mem[C*(MAX_PERIOD+(i-B)*N)+C*(j+overlap)+c] = x[j+N4+overlap];
231 for (j=0;j<overlap;j++)
232 mdct_overlap[C*j+c] = x[N+N4+j];
237 int celt_encode(CELTEncoder *st, short *pcm)
239 int i, c, N, B, C, N4;
242 C = st->mode->nbChannels;
245 float X[B*C*N]; /**< Interleaved signal MDCTs */
246 float P[B*C*N]; /**< Interleaved pitch MDCTs*/
247 float mask[B*C*N]; /**< Masking curve */
248 float bandE[st->mode->nbEBands*C];
249 float gains[st->mode->nbPBands];
252 N4 = (N-st->overlap)/2;
258 for (i=0;i<st->overlap;i++)
259 in[C*(i+N4)+c] = st->in_mem[C*i+c];
262 float tmp = pcm[C*i+c];
263 in[C*(i+st->overlap+N4)+c] = tmp - st->preemph*st->preemph_memE[c];
264 st->preemph_memE[c] = tmp;
266 for (i=N*(B+1)-N4;i<N*(B+1);i++)
268 for (i=0;i<st->overlap;i++)
269 st->in_mem[C*i+c] = in[C*(N*(B+1)-N4-st->overlap+i)+c];
271 //for (i=0;i<(B+1)*C*N;i++) printf ("%f(%d) ", in[i], i); printf ("\n");
273 compute_mdcts(&st->mdct_lookup, st->window, in, X, N, B, C);
275 compute_mdct_masking(X, mask, B*C*N, st->Fs);
277 /* Invert and stretch the mask to length of X
278 For some reason, I get better results by using the sqrt instead,
279 although there's no valid reason to. Must investigate further */
280 for (i=0;i<B*C*N;i++)
281 mask[i] = 1/(.1+mask[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, in, st->out_mem, MAX_PERIOD, (B+1)*N, C, &pitch_index);
293 ec_enc_uint(&st->enc, pitch_index, MAX_PERIOD-(B+1)*N);
295 /* Compute MDCTs of the pitch part */
296 compute_mdcts(&st->mdct_lookup, st->window, st->out_mem+pitch_index*C, P, N, B, C);
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 /* Normalise the pitch vector as well (discard the energies) */
313 float bandEp[st->mode->nbEBands*st->mode->nbChannels];
314 compute_band_energies(st->mode, P, bandEp);
315 normalise_bands(st->mode, P, bandEp);
318 quant_energy(st->mode, bandE, st->oldBandE, &st->enc);
322 stereo_mix(st->mode, X, bandE, 1);
323 stereo_mix(st->mode, P, bandE, 1);
324 //haar1(X, B*N*C, 1);
325 //haar1(P, B*N*C, 1);
327 /* Simulates intensity stereo */
328 //for (i=30;i<N*B;i++)
329 // X[i*C+1] = P[i*C+1] = 0;
330 /* Get a tiny bit more frequency resolution and prevent unstable energy when quantising */
331 time_dct(X, N, B, C);
332 time_dct(P, N, B, C);
335 /* Pitch prediction */
336 compute_pitch_gain(st->mode, X, P, gains, bandE);
337 quant_pitch(gains, st->mode->nbPBands, &st->enc);
338 pitch_quant_bands(st->mode, X, P, gains);
340 //for (i=0;i<B*N;i++) printf("%f ",P[i]);printf("\n");
341 /* Compute residual that we're going to encode */
342 for (i=0;i<B*C*N;i++)
348 printf ("%f\n", sum);*/
349 /* Residual quantisation */
350 quant_bands(st->mode, X, P, mask, &st->alloc, 770, &st->enc);
352 time_idct(X, N, B, C);
354 //haar1(X, B*N*C, 1);
355 stereo_mix(st->mode, X, bandE, -1);
357 renormalise_bands(st->mode, X);
359 denormalise_bands(st->mode, X, bandE);
362 CELT_MOVE(st->out_mem, st->out_mem+C*B*N, C*(MAX_PERIOD-B*N));
364 compute_inv_mdcts(&st->mdct_lookup, st->window, X, st->out_mem, st->mdct_overlap, N, st->overlap, B, C);
365 /* De-emphasis and put everything back at the right place in the synthesis history */
373 float tmp = st->out_mem[C*(MAX_PERIOD+(i-B)*N)+C*j+c] + st->preemph*st->preemph_memD[c];
374 st->preemph_memD[c] = tmp;
375 if (tmp > 32767) tmp = 32767;
376 if (tmp < -32767) tmp = -32767;
377 pcm[C*i*N+C*j+c] = (short)floor(.5+tmp);
384 char *celt_encoder_get_bytes(CELTEncoder *st, int *nbBytes)
387 ec_enc_done(&st->enc);
388 *nbBytes = ec_byte_bytes(&st->buf);
389 data = ec_byte_get_buffer(&st->buf);
390 //printf ("%d\n", *nbBytes);
392 /* Reset the packing for the next encoding */
393 ec_byte_reset(&st->buf);
394 ec_enc_init(&st->enc,&st->buf);
400 /****************************************************************************/
404 /****************************************************************************/
409 const CELTMode *mode;
421 mdct_lookup mdct_lookup;
429 int last_pitch_index;
431 struct alloc_data alloc;
434 CELTDecoder *celt_decoder_new(const CELTMode *mode)
438 B = mode->nbMdctBlocks;
439 C = mode->nbChannels;
440 CELTDecoder *st = celt_alloc(sizeof(CELTDecoder));
443 st->frame_size = B*N;
446 st->overlap = mode->overlap;
448 N4 = (N-st->overlap)/2;
450 mdct_init(&st->mdct_lookup, 2*N);
452 st->window = celt_alloc(2*N*sizeof(float));
453 st->mdct_overlap = celt_alloc(N*C*sizeof(float));
454 st->out_mem = celt_alloc(MAX_PERIOD*C*sizeof(float));
458 for (i=0;i<st->overlap;i++)
459 st->window[N4+i] = st->window[2*N-N4-i-1]
460 = sin(.5*M_PI* sin(.5*M_PI*(i+.5)/st->overlap) * sin(.5*M_PI*(i+.5)/st->overlap));
462 st->window[N-N4+i] = 1;
464 st->oldBandE = celt_alloc(C*mode->nbEBands*sizeof(float));
467 st->preemph_memD = celt_alloc(C*sizeof(float));;
469 st->last_pitch_index = 0;
470 alloc_init(&st->alloc, st->mode);
475 void celt_decoder_destroy(CELTDecoder *st)
479 celt_warning("NULL passed to celt_encoder_destroy");
483 mdct_clear(&st->mdct_lookup);
485 celt_free(st->window);
486 celt_free(st->mdct_overlap);
487 celt_free(st->out_mem);
489 celt_free(st->oldBandE);
490 alloc_clear(&st->alloc);
495 static void celt_decode_lost(CELTDecoder *st, short *pcm)
500 C = st->mode->nbChannels;
501 float X[C*B*N]; /**< Interleaved signal MDCTs */
504 pitch_index = st->last_pitch_index;
506 /* Use the pitch MDCT as the "guessed" signal */
507 compute_mdcts(&st->mdct_lookup, st->window, st->out_mem+pitch_index*C, X, N, B, C);
509 CELT_MOVE(st->out_mem, st->out_mem+C*B*N, C*(MAX_PERIOD-B*N));
510 /* Compute inverse MDCTs */
511 compute_inv_mdcts(&st->mdct_lookup, st->window, X, st->out_mem, st->mdct_overlap, N, st->overlap, B, C);
520 float tmp = st->out_mem[C*(MAX_PERIOD+(i-B)*N)+C*j+c] + st->preemph*st->preemph_memD[c];
521 st->preemph_memD[c] = tmp;
522 if (tmp > 32767) tmp = 32767;
523 if (tmp < -32767) tmp = -32767;
524 pcm[C*i*N+C*j+c] = (short)floor(.5+tmp);
530 int celt_decode(CELTDecoder *st, char *data, int len, short *pcm)
535 C = st->mode->nbChannels;
537 float X[C*B*N]; /**< Interleaved signal MDCTs */
538 float P[C*B*N]; /**< Interleaved pitch MDCTs*/
539 float bandE[st->mode->nbEBands*C];
540 float gains[st->mode->nbPBands];
547 celt_decode_lost(st, pcm);
551 ec_byte_readinit(&buf,data,len);
552 ec_dec_init(&dec,&buf);
554 /* Get the pitch index */
555 pitch_index = ec_dec_uint(&dec, MAX_PERIOD-(B+1)*N);
556 st->last_pitch_index = pitch_index;
558 /* Get band energies */
559 unquant_energy(st->mode, bandE, st->oldBandE, &dec);
562 compute_mdcts(&st->mdct_lookup, st->window, st->out_mem+pitch_index*C, P, N, B, C);
565 float bandEp[st->mode->nbEBands];
566 compute_band_energies(st->mode, P, bandEp);
567 normalise_bands(st->mode, P, bandEp);
571 //haar1(P, B*N*C, 1);
572 stereo_mix(st->mode, P, bandE, 1);
573 time_dct(P, N, B, C);
575 /* Get the pitch gains */
576 unquant_pitch(gains, st->mode->nbPBands, &dec);
578 /* Apply pitch gains */
579 pitch_quant_bands(st->mode, X, P, gains);
581 /* Decode fixed codebook and merge with pitch */
582 unquant_bands(st->mode, X, P, &st->alloc, 770, &dec);
584 time_idct(X, N, B, C);
586 //haar1(X, B*N*C, 1);
587 stereo_mix(st->mode, X, bandE, -1);
589 renormalise_bands(st->mode, X);
592 denormalise_bands(st->mode, X, bandE);
595 CELT_MOVE(st->out_mem, st->out_mem+C*B*N, C*(MAX_PERIOD-B*N));
596 /* Compute inverse MDCTs */
597 compute_inv_mdcts(&st->mdct_lookup, st->window, X, st->out_mem, st->mdct_overlap, N, st->overlap, B, C);
606 float tmp = st->out_mem[C*(MAX_PERIOD+(i-B)*N)+C*j+c] + st->preemph*st->preemph_memD[c];
607 st->preemph_memD[c] = tmp;
608 if (tmp > 32767) tmp = 32767;
609 if (tmp < -32767) tmp = -32767;
610 pcm[C*i*N+C*j+c] = (short)floor(.5+tmp);