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
35 double **PCMd; //data structure to store PCM data PCM[channels][maxsamples]
36 int maxsamples; //size of PCM buffer
37 int start; //where to add data next
39 int *ip; //working space for FFT routines
40 double *w; //lookup table for FFT routines
41 int new; //how many new samples
44 //initPCM(int samples)
46 //Initializes the PCM buffer to
47 // number of samples specified.
49 void initPCM(int samples)
53 //Allocate memory for PCM data buffer
54 PCMd = (double **)malloc(2 * sizeof(double *));
55 PCMd[0] = (double *)malloc(samples * sizeof(double));
56 PCMd[1] = (double *)malloc(samples * sizeof(double));
61 //Initialize buffers to 0
62 for (i=0;i<samples;i++)
70 //Allocate FFT workspace
71 w= (double *)malloc(maxsamples*sizeof(double));
72 ip= (int *)malloc(maxsamples*sizeof(int));
76 //The only current addPCM function, can support more
78 //Takes in a 2x512 array of PCM samples
81 void addPCM(int16_t PCMdata[2][512])
86 for(i=0;i<samples;i++)
89 PCMd[0][j%maxsamples]=(PCMdata[0][i]/16384.0);
90 PCMd[1][j%maxsamples]=(PCMdata[1][i]/16384.0);
94 // printf("Added %d samples %d %d %f\n",samples,start,(start+samples)%maxsamples,PCM[0][start+10]);
97 start=start%maxsamples;
100 if (new>maxsamples) new=maxsamples;
104 //puts sound data requested at provided pointer
106 //samples is number of PCM samples to return
107 //freq = 0 gives PCM data
108 //freq = 1 gives FFT data
109 //smoothing is the smoothing coefficient
111 //returned values are normalized from -1 to 1
113 void getPCM(double *PCMdata, int samples, int channel, int freq, double smoothing, int derive)
119 if (index<0) index=maxsamples+index;
121 PCMdata[0]=PCMd[channel][index];
123 for(i=1;i<samples;i++)
126 if (index<0) index=maxsamples+index;
128 PCMdata[i]=(1-smoothing)*PCMd[channel][index]+smoothing*PCMdata[i-1];
131 //return derivative of PCM data
134 for(i=0;i<samples-1;i++)
136 PCMdata[i]=PCMdata[i]-PCMdata[i+1];
138 PCMdata[samples-1]=0;
141 //return frequency data instead of PCM (perform FFT)
142 if (freq) rdft(samples, 1, PCMdata, ip, w);
150 //Like getPCM except it returns all new samples in the buffer
151 //the actual return value is the number of samples, up to maxsamples.
152 //the passed pointer, PCMData, must bee able to hold up to maxsamples
154 int getPCMnew(double *PCMdata, int channel, int freq, double smoothing, int derive, int reset)
160 if (index<0) index=maxsamples+index;
162 PCMdata[0]=PCMd[channel][index];
167 if (index<0) index=maxsamples+index;
169 PCMdata[i]=(1-smoothing)*PCMd[channel][index]+smoothing*PCMdata[i-1];
172 //return derivative of PCM data
177 PCMdata[i]=PCMdata[i]-PCMdata[i+1];
182 //return frequency data instead of PCM (perform FFT)
183 // if (freq) rdft(samples, 1, PCMdata, ip, w);