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"
44 #define MAX_PERIOD 1024
60 mdct_lookup mdct_lookup;
73 CELTEncoder *celt_encoder_new(const CELTMode *mode)
77 B = mode->nbMdctBlocks;
78 CELTEncoder *st = celt_alloc(sizeof(CELTEncoder));
85 ec_byte_writeinit(&st->buf);
86 ec_enc_init(&st->enc,&st->buf);
88 mdct_init(&st->mdct_lookup, 2*N);
89 st->fft = spx_fft_init(MAX_PERIOD);
91 st->window = celt_alloc(2*N*sizeof(float));
92 st->in_mem = celt_alloc(N*sizeof(float));
93 st->mdct_overlap = celt_alloc(N*sizeof(float));
94 st->out_mem = celt_alloc(MAX_PERIOD*sizeof(float));
96 st->window[i] = st->window[2*N-i-1] = sin(.5*M_PI* sin(.5*M_PI*(i+.5)/N) * sin(.5*M_PI*(i+.5)/N));
98 st->oldBandE = celt_alloc(mode->nbEBands*sizeof(float));
104 void celt_encoder_destroy(CELTEncoder *st)
108 celt_warning("NULL passed to celt_encoder_destroy");
111 ec_byte_writeclear(&st->buf);
113 mdct_clear(&st->mdct_lookup);
114 spx_fft_destroy(st->fft);
116 celt_free(st->window);
117 celt_free(st->in_mem);
118 celt_free(st->mdct_overlap);
119 celt_free(st->out_mem);
121 celt_free(st->oldBandE);
125 static void haar1(float *X, int N)
133 X[i] = .707107f*(a+b);
134 X[i+1] = .707107f*(a-b);
138 static void inv_haar1(float *X, int N)
146 X[i] = .707107f*(a+b);
147 X[i+1] = .707107f*(a-b);
151 static void compute_mdcts(mdct_lookup *mdct_lookup, float *window, float *in, float *out, int N, int B)
160 x[j] = window[j]*in[i*N+j];
161 mdct_forward(mdct_lookup, x, tmp);
162 /* Interleaving the sub-frames */
169 int celt_encode(CELTEncoder *st, short *pcm)
176 float X[B*N]; /**< Interleaved signal MDCTs */
177 float P[B*N]; /**< Interleaved pitch MDCTs*/
178 float bandE[st->mode->nbEBands];
179 float gains[st->mode->nbPBands];
183 in[i] = st->in_mem[i];
186 float tmp = pcm[i-N];
187 in[i] = tmp - st->preemph*st->preemph_memE;
188 st->preemph_memE = tmp;
191 st->in_mem[i] = in[B*N+i];
194 compute_mdcts(&st->mdct_lookup, st->window, in, X, N, B);
199 in[i] *= st->window[i];
200 in[B*N+i] *= st->window[N+i];
202 find_spectral_pitch(st->fft, in, st->out_mem, MAX_PERIOD, (B+1)*N, &pitch_index);
203 ec_enc_uint(&st->enc, pitch_index, MAX_PERIOD-(B+1)*N);
205 /* Compute MDCTs of the pitch part */
206 compute_mdcts(&st->mdct_lookup, st->window, st->out_mem+pitch_index, P, N, B);
210 printf ("%f ", X[j]);
212 printf ("%f ", P[j]);
217 /* Band normalisation */
218 compute_band_energies(st->mode, X, bandE);
219 normalise_bands(st->mode, X, bandE);
220 //for (i=0;i<st->mode->nbEBands;i++)printf("%f ", bandE[i]);printf("\n");
223 float bandEp[st->mode->nbEBands];
224 compute_band_energies(st->mode, P, bandEp);
225 normalise_bands(st->mode, P, bandEp);
228 quant_energy(st->mode, bandE, st->oldBandE, &st->enc);
230 /* Pitch prediction */
231 compute_pitch_gain(st->mode, X, P, gains, bandE);
232 quant_pitch(gains, st->mode->nbPBands, &st->enc);
233 pitch_quant_bands(st->mode, X, P, gains);
235 //for (i=0;i<B*N;i++) printf("%f ",P[i]);printf("\n");
236 /* Subtract the pitch prediction from the signal to encode */
243 printf ("%f\n", sum);*/
244 /* Residual quantisation */
245 quant_bands(st->mode, X, P, &st->enc);
247 if (0) {//This is just for debugging
248 ec_enc_done(&st->enc);
250 ec_byte_readinit(&st->buf,ec_byte_get_buffer(&st->buf),ec_byte_bytes(&st->buf));
251 ec_dec_init(&dec,&st->buf);
253 unquant_bands(st->mode, X, P, &dec);
258 denormalise_bands(st->mode, X, bandE);
262 CELT_MOVE(st->out_mem, st->out_mem+B*N, MAX_PERIOD-B*N);
263 /* Compute inverse MDCTs */
269 /* De-interleaving the sub-frames */
272 mdct_backward(&st->mdct_lookup, tmp, x);
274 x[j] = st->window[j]*x[j];
276 st->out_mem[MAX_PERIOD+(i-B)*N+j] = x[j]+st->mdct_overlap[j];
278 st->mdct_overlap[j] = x[N+j];
282 float tmp = st->out_mem[MAX_PERIOD+(i-B)*N+j] + st->preemph*st->preemph_memD;
283 st->preemph_memD = tmp;
284 pcm[i*N+j] = (short)floor(.5+tmp);
290 char *celt_encoder_get_bytes(CELTEncoder *st, int *nbBytes)
293 ec_enc_done(&st->enc);
294 *nbBytes = ec_byte_bytes(&st->buf);
295 data = ec_byte_get_buffer(&st->buf);
296 //printf ("%d\n", *nbBytes);
298 /* Reset the packing for the next encoding */
299 ec_byte_reset(&st->buf);
300 ec_enc_init(&st->enc,&st->buf);
306 /****************************************************************************/
310 /****************************************************************************/
315 const CELTMode *mode;
326 mdct_lookup mdct_lookup;
335 CELTDecoder *celt_decoder_new(const CELTMode *mode)
339 B = mode->nbMdctBlocks;
340 CELTDecoder *st = celt_alloc(sizeof(CELTDecoder));
343 st->frame_size = B*N;
347 mdct_init(&st->mdct_lookup, 2*N);
349 st->window = celt_alloc(2*N*sizeof(float));
350 st->mdct_overlap = celt_alloc(N*sizeof(float));
351 st->out_mem = celt_alloc(MAX_PERIOD*sizeof(float));
353 st->window[i] = st->window[2*N-i-1] = sin(.5*M_PI* sin(.5*M_PI*(i+.5)/N) * sin(.5*M_PI*(i+.5)/N));
355 st->oldBandE = celt_alloc(mode->nbEBands*sizeof(float));
361 void celt_decoder_destroy(CELTDecoder *st)
365 celt_warning("NULL passed to celt_encoder_destroy");
369 mdct_clear(&st->mdct_lookup);
371 celt_free(st->window);
372 celt_free(st->mdct_overlap);
373 celt_free(st->out_mem);
375 celt_free(st->oldBandE);
379 int celt_decode(CELTDecoder *st, char *data, int len, short *pcm)
385 float X[B*N]; /**< Interleaved signal MDCTs */
386 float P[B*N]; /**< Interleaved pitch MDCTs*/
387 float bandE[st->mode->nbEBands];
388 float gains[st->mode->nbPBands];
393 ec_byte_readinit(&buf,data,len);
394 ec_dec_init(&dec,&buf);
396 /* Get the pitch index */
397 pitch_index = ec_dec_uint(&dec, MAX_PERIOD-(B+1)*N);;
399 /* Get band energies */
400 unquant_energy(st->mode, bandE, st->oldBandE, &dec);
403 compute_mdcts(&st->mdct_lookup, st->window, st->out_mem+pitch_index, P, N, B);
408 float bandEp[st->mode->nbEBands];
409 compute_band_energies(st->mode, P, bandEp);
410 normalise_bands(st->mode, P, bandEp);
413 /* Get the pitch gains */
414 unquant_pitch(gains, st->mode->nbPBands, &dec);
416 /* Apply pitch gains */
417 pitch_quant_bands(st->mode, X, P, gains);
419 /* Decode fixed codebook and merge with pitch */
420 unquant_bands(st->mode, X, P, &dec);
423 denormalise_bands(st->mode, X, bandE);
427 CELT_MOVE(st->out_mem, st->out_mem+B*N, MAX_PERIOD-B*N);
428 /* Compute inverse MDCTs */
434 /* De-interleaving the sub-frames */
437 mdct_backward(&st->mdct_lookup, tmp, x);
439 x[j] = st->window[j]*x[j];
441 st->out_mem[MAX_PERIOD+(i-B)*N+j] = x[j]+st->mdct_overlap[j];
443 st->mdct_overlap[j] = x[N+j];
447 float tmp = st->out_mem[MAX_PERIOD+(i-B)*N+j] + st->preemph*st->preemph_memD;
448 st->preemph_memD = tmp;
449 pcm[i*N+j] = (short)floor(.5+tmp);