Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

PCM.c

00001 /*****************************************************************************
00002  * PCM.c:
00003  *****************************************************************************
00004  * Copyright (C) 2004 the VideoLAN team
00005  * $Id: PCM.c 11664 2005-07-09 06:17:09Z courmisch $
00006  *
00007  * Authors: Cyril Deguet <[email protected]>
00008  *          code from projectM http://xmms-projectm.sourceforge.net
00009  *
00010  * This program is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00023  *****************************************************************************/
00024 
00025 
00026 //PCM.c - Sound data handler
00027 //
00028 //by Peter Sperl
00029 //
00030 //Takes sound data from wherever and hands it back out.
00031 //Returns PCM Data or spectrum data, or the derivative of the PCM data
00032 
00033 #include <stdlib.h>
00034 #include <stdio.h>
00035 
00036 double **PCMd;    //data structure to store PCM data  PCM[channels][maxsamples]
00037 int maxsamples;   //size of PCM buffer
00038 int start;        //where to add data next
00039 
00040 int *ip;          //working space for FFT routines
00041 double *w;        //lookup table for FFT routines
00042 int new;          //how many new samples
00043 
00044 
00045 //initPCM(int samples)
00046 //
00047 //Initializes the PCM buffer to
00048 // number of samples specified.
00049 
00050 void initPCM(int samples)
00051 {
00052   int i; 
00053 
00054   //Allocate memory for PCM data buffer
00055   PCMd = (double **)malloc(2 * sizeof(double *));
00056   PCMd[0] = (double *)malloc(samples * sizeof(double));
00057   PCMd[1] = (double *)malloc(samples * sizeof(double));
00058   
00059   maxsamples=samples;
00060   new=0;
00061 
00062   //Initialize buffers to 0
00063   for (i=0;i<samples;i++)
00064     {
00065       PCMd[0][i]=0;
00066       PCMd[1][i]=0;
00067     }
00068 
00069   start=0;
00070 
00071   //Allocate FFT workspace
00072   w=  (double *)malloc(maxsamples*sizeof(double));
00073   ip= (int *)malloc(maxsamples*sizeof(int));
00074   ip[0]=0;
00075 }
00076 
00077 //The only current addPCM function, can support more
00078 //
00079 //Takes in a 2x512 array of PCM samples
00080 //and stores them
00081 
00082 void addPCM(int16_t PCMdata[2][512])
00083 {
00084   int i,j;
00085   int samples=512;
00086 
00087          for(i=0;i<samples;i++)
00088            {
00089              j=i+start;
00090              PCMd[0][j%maxsamples]=(PCMdata[0][i]/16384.0);
00091              PCMd[1][j%maxsamples]=(PCMdata[1][i]/16384.0);  
00092            }
00093        
00094  
00095          // printf("Added %d samples %d %d %f\n",samples,start,(start+samples)%maxsamples,PCM[0][start+10]); 
00096 
00097  start+=samples;
00098  start=start%maxsamples;
00099 
00100  new+=samples;
00101  if (new>maxsamples) new=maxsamples;
00102 }
00103 
00104 
00105 //puts sound data requested at provided pointer
00106 //
00107 //samples is number of PCM samples to return
00108 //freq = 0 gives PCM data
00109 //freq = 1 gives FFT data
00110 //smoothing is the smoothing coefficient
00111 
00112 //returned values are normalized from -1 to 1
00113 
00114 void getPCM(double *PCMdata, int samples, int channel, int freq, double smoothing, int derive)
00115 {
00116    int i,index;
00117    
00118    index=start-1;
00119 
00120    if (index<0) index=maxsamples+index;
00121 
00122    PCMdata[0]=PCMd[channel][index];
00123    
00124    for(i=1;i<samples;i++)
00125      {
00126        index=start-1-i;
00127        if (index<0) index=maxsamples+index;
00128        
00129        PCMdata[i]=(1-smoothing)*PCMd[channel][index]+smoothing*PCMdata[i-1];
00130      }
00131    
00132    //return derivative of PCM data
00133    if(derive)
00134      {
00135        for(i=0;i<samples-1;i++)
00136          {         
00137            PCMdata[i]=PCMdata[i]-PCMdata[i+1];
00138          }
00139        PCMdata[samples-1]=0;
00140      }
00141 
00142    //return frequency data instead of PCM (perform FFT)
00143    if (freq) rdft(samples, 1, PCMdata, ip, w);
00144 
00145 
00146      
00147 }
00148 
00149 //getPCMnew
00150 //
00151 //Like getPCM except it returns all new samples in the buffer
00152 //the actual return value is the number of samples, up to maxsamples.
00153 //the passed pointer, PCMData, must bee able to hold up to maxsamples
00154 
00155 int getPCMnew(double *PCMdata, int channel, int freq, double smoothing, int derive, int reset)
00156 {
00157    int i,index;
00158    
00159    index=start-1;
00160 
00161    if (index<0) index=maxsamples+index;
00162 
00163    PCMdata[0]=PCMd[channel][index];
00164    
00165    for(i=1;i<new;i++)
00166      {
00167        index=start-1-i;
00168        if (index<0) index=maxsamples+index;
00169        
00170        PCMdata[i]=(1-smoothing)*PCMd[channel][index]+smoothing*PCMdata[i-1];
00171      }
00172    
00173    //return derivative of PCM data
00174    if(derive)
00175      {
00176        for(i=0;i<new-1;i++)
00177          {         
00178            PCMdata[i]=PCMdata[i]-PCMdata[i+1];
00179          }
00180        PCMdata[new-1]=0;
00181      }
00182 
00183    //return frequency data instead of PCM (perform FFT)
00184    //   if (freq) rdft(samples, 1, PCMdata, ip, w);
00185    i=new;
00186    if (reset)  new=0;
00187 
00188    return i;
00189 }
00190 
00191 //Free stuff
00192 void freePCM()
00193 {
00194   free(PCMd[0]);
00195   free(PCMd[1]);
00196   free(PCMd);
00197   free(ip);
00198   free(w);
00199 }

Generated on Tue Dec 20 10:14:58 2005 for vlc-0.8.4a by  doxygen 1.4.2