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