envelope.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /********************************************************************
  2. * *
  3. * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
  4. * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
  5. * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
  6. * PLEASE READ THESE TERMS DISTRIBUTING. *
  7. * *
  8. * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
  9. * by Monty <monty@xiph.org> and The XIPHOPHORUS Company *
  10. * http://www.xiph.org/ *
  11. * *
  12. ********************************************************************
  13. function: PCM data envelope analysis and manipulation
  14. last mod: $Id: envelope.c,v 1.17.2.1 2000/06/12 00:31:15 xiphmont Exp $
  15. Preecho calculation.
  16. ********************************************************************/
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <stdio.h>
  20. #include <math.h>
  21. #include "vorbis/codec.h"
  22. #include "os.h"
  23. #include "mdct.h"
  24. #include "envelope.h"
  25. #include "bitwise.h"
  26. #include "window.h"
  27. #include "misc.h"
  28. void _ve_envelope_init(envelope_lookup *e,int samples_per){
  29. int i;
  30. e->winlen=samples_per;
  31. e->window=malloc(e->winlen*sizeof(double));
  32. mdct_init(&e->mdct,e->winlen);
  33. /* We just use a straight sin^2(x) window for this */
  34. for(i=0;i<e->winlen;i++){
  35. e->window[i]=sin((i+.5)/e->winlen*M_PI);
  36. e->window[i]*=e->window[i];
  37. }
  38. }
  39. void _ve_envelope_clear(envelope_lookup *e){
  40. if(e->window)free(e->window);
  41. mdct_clear(&e->mdct);
  42. memset(e,0,sizeof(envelope_lookup));
  43. }
  44. /* use MDCT for spectral power estimation */
  45. static void _ve_deltas(double *deltas,double *pcm,int n,double *window,
  46. int winsize,mdct_lookup *m){
  47. int i,j;
  48. double *out=alloca(sizeof(double)*winsize);
  49. for(j=0;j<n;j++){
  50. double acc=0.;
  51. memcpy(out,pcm+j*winsize,winsize*sizeof(double));
  52. for(i=0;i<winsize;i++)
  53. out[i]*=window[i];
  54. mdct_forward(m,out,out);
  55. for(i=winsize/10;i<winsize/2;i++)
  56. acc+=fabs(out[i]);
  57. if(deltas[j]<acc)deltas[j]=acc;
  58. }
  59. }
  60. void _ve_envelope_deltas(vorbis_dsp_state *v){
  61. vorbis_info *vi=v->vi;
  62. int step=vi->envelopesa;
  63. int dtotal=v->pcm_current/vi->envelopesa;
  64. int dcurr=v->envelope_current;
  65. int pch;
  66. if(dtotal>dcurr){
  67. double *mult=v->multipliers+dcurr;
  68. memset(mult,0,sizeof(double)*(dtotal-dcurr));
  69. for(pch=0;pch<vi->channels;pch++){
  70. double *pcm=v->pcm[pch]+dcurr*step;
  71. _ve_deltas(mult,pcm,dtotal-dcurr,v->ve.window,v->ve.winlen,&v->ve.mdct);
  72. }
  73. v->envelope_current=dtotal;
  74. }
  75. }