home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2001 September / PC-WELT 9-2001.ISO / software / hw / brennen / flask_src.exe / Audio / Utils / AudioCompressor.cpp next >
Encoding:
C/C++ Source or Header  |  2000-06-08  |  3.4 KB  |  155 lines

  1. /* 
  2.  *  AudioCompressor.cpp 
  3.  *
  4.  *    Copyright (C) Alberto Vigata - January 2000 - ultraflask@yahoo.com
  5.  *
  6.  *  This file is part of FlasKMPEG, a free MPEG to MPEG/AVI converter
  7.  *    
  8.  *  FlasKMPEG is free software; you can redistribute it and/or modify
  9.  *  it under the terms of the GNU General Public License as published by
  10.  *  the Free Software Foundation; either version 2, or (at your option)
  11.  *  any later version.
  12.  *   
  13.  *  FlasKMPEG is distributed in the hope that it will be useful,
  14.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  *  GNU General Public License for more details.
  17.  *   
  18.  *  You should have received a copy of the GNU General Public License
  19.  *  along with GNU Make; see the file COPYING.  If not, write to
  20.  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  21.  *
  22.  */
  23.  
  24. #include <windows.h>
  25. #include <mmsystem.h>
  26. #include <malloc.h>
  27. #include <winbase.h>
  28. #include <math.h>
  29.  
  30. #include "AudioCompressor.h"
  31.  
  32.  
  33. CAudioCompressor::CAudioCompressor()
  34. {
  35.     this->comp_lut= NULL;
  36. }
  37.  
  38. CAudioCompressor::~CAudioCompressor()
  39. {
  40.     if(comp_lut)
  41.         free(comp_lut);
  42. }
  43.  
  44. int CAudioCompressor::CreateCompressor()
  45. {
  46.     TKnot myKnot;
  47.     int i;
  48.     //Initialize knots
  49.     for(i=DEFAULT_KNOTS-1; i>=0; i--)
  50.     {
  51.         myKnot.in_dBLevel  = -(float)(i+1)*((float)DB_RANGE/(float)(DEFAULT_KNOTS+1));
  52.         myKnot.out_dBLevel = myKnot.in_dBLevel;
  53.         knots.AddItem( &myKnot );
  54.     }
  55.     AdjustKnots(3);
  56.     RenderCompressor();
  57.  
  58.     return 1;
  59. }
  60.  
  61. int CAudioCompressor::AdjustKnots(int step)
  62. {
  63.     int i;
  64.     // Adjust out_DBLevels of every knot
  65.     float free_range;
  66.     float knot_step;
  67.  
  68.     if(step<0)
  69.         step=0;
  70.     if(step>=COMPRESSOR_STEPS)
  71.         step=COMPRESSOR_STEPS-1;
  72.  
  73.     for(i=0; i<knots.GetCount(); i++)
  74.     {
  75.         // workout free dynamic range up to FS
  76.         free_range = 0 - knots[i].in_dBLevel;
  77.         // workout knot_step
  78.         knot_step  = free_range/(float)COMPRESSOR_STEPS;
  79.  
  80.         knots[i].out_dBLevel = knots[i].in_dBLevel + knot_step*step;
  81.     }
  82.     return 1;
  83. }
  84.  
  85. int CAudioCompressor::RenderCompressor()
  86. {
  87.     int x;
  88.     if(comp_lut)
  89.     {
  90.         free(comp_lut);
  91.         comp_lut=NULL;
  92.     }
  93.     comp_lut = (short *)malloc(INTEGER_COMPRESSOR_SIZE*sizeof(short));
  94.     if(!comp_lut)
  95.         return 0;
  96.  
  97. #define DB_TO_LINEAR(x) (  32767.0f *(float)pow(10, (float)x/20.0f ) )
  98.     short in_start, in_end;
  99.  
  100.     // Render individual knots
  101.     float end_dBLevel, start_dBLevel, stepLevel;
  102.     TKnot this_knot, prev_knot;
  103.     int   steps, i;
  104.  
  105.     prev_knot.in_dBLevel = -DB_RANGE;
  106.     prev_knot.out_dBLevel = -DB_RANGE;
  107.  
  108.     for(i=0; i<=knots.GetCount(); i++)
  109.     {    
  110.         if(i<knots.GetCount())
  111.         {
  112.             this_knot = knots[i];
  113.         }
  114.         else{
  115.             this_knot.in_dBLevel = 0;
  116.             this_knot.out_dBLevel = 0;
  117.         }
  118.  
  119.  
  120.         start_dBLevel = prev_knot.out_dBLevel;
  121.         end_dBLevel   =   this_knot.out_dBLevel;
  122.  
  123.         in_start =(short)DB_TO_LINEAR( prev_knot.in_dBLevel );
  124.         in_end   =(short)DB_TO_LINEAR( this_knot.in_dBLevel );
  125.  
  126.         steps = in_end - in_start;
  127.         stepLevel = (end_dBLevel - start_dBLevel) / (float)steps;
  128.  
  129.         for(x=in_start; x<in_end; x++)
  130.         {
  131.             comp_lut[ x+32768]=  (short)DB_TO_LINEAR( start_dBLevel );
  132.             comp_lut[-x+32768]= -(short)DB_TO_LINEAR( start_dBLevel );
  133.             start_dBLevel += stepLevel;
  134.         }
  135.  
  136.         prev_knot = this_knot;
  137.     }
  138.     return 1;
  139. }
  140.  
  141. int CAudioCompressor::Compress(short *data, int samples_count)
  142. {
  143.     int i;
  144.  
  145.     short *lut=&comp_lut[32768];
  146.  
  147.     if(!data)
  148.         return 0;
  149.  
  150.     for(i=0; i<samples_count; i++)
  151.         data[i] = lut[ data[i] ];
  152.     return 1;
  153.  
  154. }
  155.