]> git.sesse.net Git - vlc/blob - modules/visualization/galaktos/PCM.c
Removes trailing spaces. Removes tabs.
[vlc] / modules / visualization / galaktos / PCM.c
1 /*****************************************************************************
2  * PCM.c:
3  *****************************************************************************
4  * Copyright (C) 2004 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Cyril Deguet <asmax@videolan.org>
8  *          code from projectM http://xmms-projectm.sourceforge.net
9  *
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.
14  *
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.
19  *
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  *****************************************************************************/
24
25
26 //PCM.c - Sound data handler
27 //
28 //by Peter Sperl
29 //
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
32
33 #include <inttypes.h>
34
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
38
39 int *ip;          //working space for FFT routines
40 double *w;        //lookup table for FFT routines
41 int new;          //how many new samples
42
43
44 //initPCM(int samples)
45 //
46 //Initializes the PCM buffer to
47 // number of samples specified.
48
49 void initPCM(int samples)
50 {
51   int i;
52
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));
57  
58   maxsamples=samples;
59   new=0;
60
61   //Initialize buffers to 0
62   for (i=0;i<samples;i++)
63     {
64       PCMd[0][i]=0;
65       PCMd[1][i]=0;
66     }
67
68   start=0;
69
70   //Allocate FFT workspace
71   w=  (double *)malloc(maxsamples*sizeof(double));
72   ip= (int *)malloc(maxsamples*sizeof(int));
73   ip[0]=0;
74 }
75
76 //The only current addPCM function, can support more
77 //
78 //Takes in a 2x512 array of PCM samples
79 //and stores them
80
81 void addPCM(int16_t PCMdata[2][512])
82 {
83   int i,j;
84   int samples=512;
85
86      for(i=0;i<samples;i++)
87        {
88          j=i+start;
89          PCMd[0][j%maxsamples]=(PCMdata[0][i]/16384.0);
90          PCMd[1][j%maxsamples]=(PCMdata[1][i]/16384.0);
91        }
92  
93  
94      // printf("Added %d samples %d %d %f\n",samples,start,(start+samples)%maxsamples,PCM[0][start+10]);
95
96  start+=samples;
97  start=start%maxsamples;
98
99  new+=samples;
100  if (new>maxsamples) new=maxsamples;
101 }
102
103
104 //puts sound data requested at provided pointer
105 //
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
110
111 //returned values are normalized from -1 to 1
112
113 void getPCM(double *PCMdata, int samples, int channel, int freq, double smoothing, int derive)
114 {
115    int i,index;
116  
117    index=start-1;
118
119    if (index<0) index=maxsamples+index;
120
121    PCMdata[0]=PCMd[channel][index];
122  
123    for(i=1;i<samples;i++)
124      {
125        index=start-1-i;
126        if (index<0) index=maxsamples+index;
127  
128        PCMdata[i]=(1-smoothing)*PCMd[channel][index]+smoothing*PCMdata[i-1];
129      }
130  
131    //return derivative of PCM data
132    if(derive)
133      {
134        for(i=0;i<samples-1;i++)
135      {    
136        PCMdata[i]=PCMdata[i]-PCMdata[i+1];
137      }
138        PCMdata[samples-1]=0;
139      }
140
141    //return frequency data instead of PCM (perform FFT)
142    if (freq) rdft(samples, 1, PCMdata, ip, w);
143
144
145  
146 }
147
148 //getPCMnew
149 //
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
153
154 int getPCMnew(double *PCMdata, int channel, int freq, double smoothing, int derive, int reset)
155 {
156    int i,index;
157  
158    index=start-1;
159
160    if (index<0) index=maxsamples+index;
161
162    PCMdata[0]=PCMd[channel][index];
163  
164    for(i=1;i<new;i++)
165      {
166        index=start-1-i;
167        if (index<0) index=maxsamples+index;
168  
169        PCMdata[i]=(1-smoothing)*PCMd[channel][index]+smoothing*PCMdata[i-1];
170      }
171  
172    //return derivative of PCM data
173    if(derive)
174      {
175        for(i=0;i<new-1;i++)
176      {    
177        PCMdata[i]=PCMdata[i]-PCMdata[i+1];
178      }
179        PCMdata[new-1]=0;
180      }
181
182    //return frequency data instead of PCM (perform FFT)
183    //   if (freq) rdft(samples, 1, PCMdata, ip, w);
184    i=new;
185    if (reset)  new=0;
186
187    return i;
188 }
189
190 //Free stuff
191 void freePCM()
192 {
193   free(PCMd[0]);
194   free(PCMd[1]);
195   free(PCMd);
196   free(ip);
197   free(w);
198 }