/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 }