1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2004 the VideoLAN team
7 * Authors: Cyril Deguet <asmax@videolan.org>
8 * code from projectM http://xmms-projectm.sourceforge.net
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
26 //PCM.c - Sound data handler
30 //Takes sound data from wherever and hands it back out.
31 //Returns PCM Data or spectrum data, or the derivative of the PCM data
37 double **PCMd; //data structure to store PCM data PCM[channels][maxsamples]
38 int maxsamples; //size of PCM buffer
39 int start; //where to add data next
41 int *ip; //working space for FFT routines
42 double *w; //lookup table for FFT routines
43 int new; //how many new samples
46 //initPCM(int samples)
48 //Initializes the PCM buffer to
49 // number of samples specified.
51 void initPCM(int samples)
55 //Allocate memory for PCM data buffer
56 PCMd = (double **)malloc(2 * sizeof(double *));
57 PCMd[0] = (double *)malloc(samples * sizeof(double));
58 PCMd[1] = (double *)malloc(samples * sizeof(double));
63 //Initialize buffers to 0
64 for (i=0;i<samples;i++)
72 //Allocate FFT workspace
73 w= (double *)malloc(maxsamples*sizeof(double));
74 ip= (int *)malloc(maxsamples*sizeof(int));
78 //The only current addPCM function, can support more
80 //Takes in a 2x512 array of PCM samples
83 void addPCM(int16_t PCMdata[2][512])
88 for(i=0;i<samples;i++)
91 PCMd[0][j%maxsamples]=(PCMdata[0][i]/16384.0);
92 PCMd[1][j%maxsamples]=(PCMdata[1][i]/16384.0);
96 // printf("Added %d samples %d %d %f\n",samples,start,(start+samples)%maxsamples,PCM[0][start+10]);
99 start=start%maxsamples;
102 if (new>maxsamples) new=maxsamples;
106 //puts sound data requested at provided pointer
108 //samples is number of PCM samples to return
109 //freq = 0 gives PCM data
110 //freq = 1 gives FFT data
111 //smoothing is the smoothing coefficient
113 //returned values are normalized from -1 to 1
115 void getPCM(double *PCMdata, int samples, int channel, int freq, double smoothing, int derive)
121 if (index<0) index=maxsamples+index;
123 PCMdata[0]=PCMd[channel][index];
125 for(i=1;i<samples;i++)
128 if (index<0) index=maxsamples+index;
130 PCMdata[i]=(1-smoothing)*PCMd[channel][index]+smoothing*PCMdata[i-1];
133 //return derivative of PCM data
136 for(i=0;i<samples-1;i++)
138 PCMdata[i]=PCMdata[i]-PCMdata[i+1];
140 PCMdata[samples-1]=0;
143 //return frequency data instead of PCM (perform FFT)
144 if (freq) rdft(samples, 1, PCMdata, ip, w);
152 //Like getPCM except it returns all new samples in the buffer
153 //the actual return value is the number of samples, up to maxsamples.
154 //the passed pointer, PCMData, must bee able to hold up to maxsamples
156 int getPCMnew(double *PCMdata, int channel, int freq, double smoothing, int derive, int reset)
162 if (index<0) index=maxsamples+index;
164 PCMdata[0]=PCMd[channel][index];
169 if (index<0) index=maxsamples+index;
171 PCMdata[i]=(1-smoothing)*PCMd[channel][index]+smoothing*PCMdata[i-1];
174 //return derivative of PCM data
179 PCMdata[i]=PCMdata[i]-PCMdata[i+1];
184 //return frequency data instead of PCM (perform FFT)
185 // if (freq) rdft(samples, 1, PCMdata, ip, w);