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
36 double **PCMd; //data structure to store PCM data PCM[channels][maxsamples]
37 int maxsamples; //size of PCM buffer
38 int start; //where to add data next
40 int *ip; //working space for FFT routines
41 double *w; //lookup table for FFT routines
42 int new; //how many new samples
45 //initPCM(int samples)
47 //Initializes the PCM buffer to
48 // number of samples specified.
50 void initPCM(int samples)
54 //Allocate memory for PCM data buffer
55 PCMd = (double **)malloc(2 * sizeof(double *));
56 PCMd[0] = (double *)malloc(samples * sizeof(double));
57 PCMd[1] = (double *)malloc(samples * sizeof(double));
62 //Initialize buffers to 0
63 for (i=0;i<samples;i++)
71 //Allocate FFT workspace
72 w= (double *)malloc(maxsamples*sizeof(double));
73 ip= (int *)malloc(maxsamples*sizeof(int));
77 //The only current addPCM function, can support more
79 //Takes in a 2x512 array of PCM samples
82 void addPCM(int16_t PCMdata[2][512])
87 for(i=0;i<samples;i++)
90 PCMd[0][j%maxsamples]=(PCMdata[0][i]/16384.0);
91 PCMd[1][j%maxsamples]=(PCMdata[1][i]/16384.0);
95 // printf("Added %d samples %d %d %f\n",samples,start,(start+samples)%maxsamples,PCM[0][start+10]);
98 start=start%maxsamples;
101 if (new>maxsamples) new=maxsamples;
105 //puts sound data requested at provided pointer
107 //samples is number of PCM samples to return
108 //freq = 0 gives PCM data
109 //freq = 1 gives FFT data
110 //smoothing is the smoothing coefficient
112 //returned values are normalized from -1 to 1
114 void getPCM(double *PCMdata, int samples, int channel, int freq, double smoothing, int derive)
120 if (index<0) index=maxsamples+index;
122 PCMdata[0]=PCMd[channel][index];
124 for(i=1;i<samples;i++)
127 if (index<0) index=maxsamples+index;
129 PCMdata[i]=(1-smoothing)*PCMd[channel][index]+smoothing*PCMdata[i-1];
132 //return derivative of PCM data
135 for(i=0;i<samples-1;i++)
137 PCMdata[i]=PCMdata[i]-PCMdata[i+1];
139 PCMdata[samples-1]=0;
142 //return frequency data instead of PCM (perform FFT)
143 if (freq) rdft(samples, 1, PCMdata, ip, w);
151 //Like getPCM except it returns all new samples in the buffer
152 //the actual return value is the number of samples, up to maxsamples.
153 //the passed pointer, PCMData, must bee able to hold up to maxsamples
155 int getPCMnew(double *PCMdata, int channel, int freq, double smoothing, int derive, int reset)
161 if (index<0) index=maxsamples+index;
163 PCMdata[0]=PCMd[channel][index];
168 if (index<0) index=maxsamples+index;
170 PCMdata[i]=(1-smoothing)*PCMd[channel][index]+smoothing*PCMdata[i-1];
173 //return derivative of PCM data
178 PCMdata[i]=PCMdata[i]-PCMdata[i+1];
183 //return frequency data instead of PCM (perform FFT)
184 // if (freq) rdft(samples, 1, PCMdata, ip, w);