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