/Users/lyon/j4p/src/sound/Oscillator.java

1    package sound; 
2     
3    import gui.ClosableJFrame; 
4    import gui.In; 
5    import gui.run.RunJob; 
6    import math.transforms.DFT; 
7     
8    import java.awt.BorderLayout; 
9    import java.awt.Container; 
10    
11   public class Oscillator { 
12       private double audioData[]; 
13       private double waveTable[]; 
14       private int sampleRate = 8000; 
15       private double frequency; 
16       private double lambda; 
17       private double samplesPerCycle; 
18    
19       // private double delta_freq; 
20    
21       private final static double twopi = Math.PI * 2; 
22       private double frequencyOfModulation; 
23       private double modulationIndex; 
24    
25       public Oscillator(double frequency_, int length) { 
26           frequency = frequency_; 
27           audioData = new double[length]; 
28    
29           //the period of the wave form is 
30           lambda = 1 / frequency; 
31    
32           //The number of samples per period is 
33           samplesPerCycle = sampleRate * lambda; 
34    
35           //delta_freq = 1 / samplesPerCycle; 
36           waveTable = 
37                   new double[(int) Math.round(samplesPerCycle)]; 
38           System.out.println("Wavetable size=" + waveTable.length); 
39       } 
40    
41       public static void main(String arg[]) { 
42           while (true) 
43               playTone(220,In.getInt("enter duration")); 
44    
45    
46    
47           //testAudioDft(); 
48       } 
49    
50       private static void playTone(int f, int dur) { 
51           Oscillator osc = new Oscillator(f, dur); 
52           UlawCodec ulc = new UlawCodec(osc.getSineWave()); 
53           ulc.play(); 
54       } 
55    
56       private static void asynchronousToneTest() { 
57           RunJob rj1 = new RunJob(.25, true, 8) { 
58               public void run() { 
59                   playTone(440); 
60               } 
61           }; 
62           RunJob rj2 = new RunJob(2, true, 2) { 
63               public void run() { 
64                   playTone(230); 
65               } 
66           }; 
67           rj1.start(); 
68           rj2.start(); 
69       } 
70    
71       public static void testPlayAndDisplayTone() { 
72           playAndDisplayTone(440); 
73           playAndDisplayTone(220); 
74       } 
75    
76       public static void playAndDisplayTone(int frequency) { 
77           Oscillator osc = new Oscillator(frequency, 8000); 
78           double d [] = osc.getSineWave(); 
79           UlawCodec ulc = new UlawCodec(d); 
80           ulc.displayInternalData(); 
81           System.out.println("freq="+ulc.getFrequency()); 
82       } 
83    
84       public static void playTone(int frequency) { 
85           Oscillator osc = new Oscillator(frequency, 8000); 
86           double d [] = osc.getSineWave(); 
87           UlawCodec ulc = new UlawCodec(d); 
88           ulc.play(); 
89       } 
90    
91       public double actualFrequency() { 
92           return (double) sampleRate / (double) waveTable.length; 
93       } 
94    
95       private double[] AudioDataFromTable() { 
96           int k = 0; 
97           for (int i = 0; i < audioData.length; i++) { 
98               audioData[i] = waveTable[k]; 
99               k++; 
100              if (k >= waveTable.length) 
101                  k = 0; 
102          } 
103          System.out.println("\nlambda=" + lambda + 
104                  "\nfrequency = " + frequency + 
105                  "\nwaveTable.length = " + waveTable.length + 
106                  "\nsampleRate = " + sampleRate + 
107                  "\naudioData.length = " + audioData.length + 
108                  "\nactual frequency = " + actualFrequency()); 
109          return audioData; 
110      } 
111   
112      public double[] getSineWave() { 
113          for (int i = 0; i < waveTable.length; i++) 
114              waveTable[i] = 
115                      0.98 * Math.sin(twopi * i / waveTable.length); 
116          return AudioDataFromTable(); 
117      } 
118   
119      public double[] getSquareWave() { 
120          getSawWave(); 
121          for (int i = 0; i < waveTable.length; i++) 
122              if (waveTable[i] > 0) 
123                  waveTable[i] = .98; 
124              else 
125                  waveTable[i] = -.98; 
126          return AudioDataFromTable(); 
127      } 
128   
129      public double[] getSawWave() { 
130          double v = -0.99; 
131          double dv = 2.0 / (double) waveTable.length; 
132          for (int i = 0; i < waveTable.length; i++) { 
133              waveTable[i] = v; 
134              v += dv; 
135          } 
136          System.out.println("Sawwave ends at:" + (v - dv)); 
137          return AudioDataFromTable(); 
138      } 
139   
140      public double[] getTriangleWave() { 
141          int sign; 
142          double v = 0; 
143          double dv = 3.d / (double) waveTable.length; 
144          for (int i = 0; i < waveTable.length; i++) { 
145              waveTable[i] = v; 
146              sign = 
147                      sign(Math.cos(twopi * i / waveTable.length)); 
148              v = v + sign * dv; 
149          } 
150          return AudioDataFromTable(); 
151      } 
152   
153      public int sign(double d) { 
154          if (d < 0) return -1; 
155          return 1; 
156      } 
157   
158      public double getDuration() { 
159          return 
160                  ((double) audioData.length / 
161                  (double) sampleRate); 
162      } 
163   
164      public int getSampleRate() { 
165          return sampleRate; 
166      } 
167   
168      public double getFrequency() { 
169          return frequency; 
170      } 
171   
172      public void setModulationIndex(double I) { 
173          modulationIndex = I; 
174      } 
175   
176      public void setModulationFrequency(double fm) { 
177          frequencyOfModulation = fm; 
178      } 
179   
180      public double[] getFM() { 
181          double r1 = twopi * frequency / sampleRate; 
182          double r2 = twopi * frequencyOfModulation / sampleRate; 
183          for (int n = 0; n < audioData.length; n++) 
184              audioData[n] = 
185                      Math.sin(r1 * n + 
186                      +modulationIndex * Math.sin(r2 * n)); 
187          return audioData; 
188      } 
189   
190      public double[] getAM() { 
191          double r1 = twopi * frequency / sampleRate; 
192          double r2 = twopi * frequencyOfModulation / sampleRate; 
193          for (int n = 0; n < audioData.length; n++) 
194              audioData[n] = 
195                      Math.cos(r1 * n) * Math.cos(r2 * n); 
196          return audioData; 
197      } 
198   
199      public static void testAudioDft() { 
200          Oscillator o = new Oscillator(440, 1024); 
201          double d[] = o.getSineWave(); 
202          DFT f = new DFT(d.length); 
203          f.dft(d); 
204          double psd[] = f.getPowerSpectralDensity(); 
205          OscopePanel op = new OscopePanel(psd); 
206          ClosableJFrame cjf = new ClosableJFrame("psd"); 
207          Container c = cjf.getContentPane(); 
208          c.setLayout(new BorderLayout()); 
209          c.add(op, BorderLayout.CENTER); 
210          cjf.setSize(400, 400); 
211          cjf.show(); 
212      } 
213  }