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
39 double **PCMd; //data structure to store PCM data PCM[channels][maxsamples]
40 int maxsamples; //size of PCM buffer
41 int start; //where to add data next
43 int *ip; //working space for FFT routines
44 double *w; //lookup table for FFT routines
45 int new; //how many new samples
48 //initPCM(int samples)
50 //Initializes the PCM buffer to
51 // number of samples specified.
53 void initPCM(int samples)
57 //Allocate memory for PCM data buffer
58 PCMd = (double **)malloc(2 * sizeof(double *));
59 PCMd[0] = (double *)malloc(samples * sizeof(double));
60 PCMd[1] = (double *)malloc(samples * sizeof(double));
65 //Initialize buffers to 0
66 for (i=0;i<samples;i++)
74 //Allocate FFT workspace
75 w= (double *)malloc(maxsamples*sizeof(double));
76 ip= (int *)malloc(maxsamples*sizeof(int));
80 //The only current addPCM function, can support more
82 //Takes in a 2x512 array of PCM samples
85 void addPCM(int16_t PCMdata[2][512])
90 for(i=0;i<samples;i++)
93 PCMd[0][j%maxsamples]=(PCMdata[0][i]/16384.0);
94 PCMd[1][j%maxsamples]=(PCMdata[1][i]/16384.0);
98 // printf("Added %d samples %d %d %f\n",samples,start,(start+samples)%maxsamples,PCM[0][start+10]);
101 start=start%maxsamples;
104 if (new>maxsamples) new=maxsamples;
108 //puts sound data requested at provided pointer
110 //samples is number of PCM samples to return
111 //freq = 0 gives PCM data
112 //freq = 1 gives FFT data
113 //smoothing is the smoothing coefficient
115 //returned values are normalized from -1 to 1
117 void getPCM(double *PCMdata, int samples, int channel, int freq, double smoothing, int derive)
123 if (index<0) index=maxsamples+index;
125 PCMdata[0]=PCMd[channel][index];
127 for(i=1;i<samples;i++)
130 if (index<0) index=maxsamples+index;
132 PCMdata[i]=(1-smoothing)*PCMd[channel][index]+smoothing*PCMdata[i-1];
135 //return derivative of PCM data
138 for(i=0;i<samples-1;i++)
140 PCMdata[i]=PCMdata[i]-PCMdata[i+1];
142 PCMdata[samples-1]=0;
145 //return frequency data instead of PCM (perform FFT)
146 if (freq) rdft(samples, 1, PCMdata, ip, w);
154 //Like getPCM except it returns all new samples in the buffer
155 //the actual return value is the number of samples, up to maxsamples.
156 //the passed pointer, PCMData, must bee able to hold up to maxsamples
158 int getPCMnew(double *PCMdata, int channel, int freq, double smoothing, int derive, int reset)
164 if (index<0) index=maxsamples+index;
166 PCMdata[0]=PCMd[channel][index];
171 if (index<0) index=maxsamples+index;
173 PCMdata[i]=(1-smoothing)*PCMd[channel][index]+smoothing*PCMdata[i-1];
176 //return derivative of PCM data
181 PCMdata[i]=PCMdata[i]-PCMdata[i+1];
186 //return frequency data instead of PCM (perform FFT)
187 // if (freq) rdft(samples, 1, PCMdata, ip, w);