-
-
Notifications
You must be signed in to change notification settings - Fork 49
Expand file tree
/
Copy pathWaveform.java
More file actions
134 lines (116 loc) · 4.24 KB
/
Copy pathWaveform.java
File metadata and controls
134 lines (116 loc) · 4.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package processing.sound;
import com.jsyn.data.FloatSample;
import com.jsyn.ports.UnitOutputPort;
import com.jsyn.unitgen.FixedRateMonoWriter;
import processing.core.PApplet;
/**
* This is a Waveform analyzer. It returns the waveform of an
* audio stream the moment it is queried with the <b>analyze()</b>
* method.<br/>
* Note that by default all sound generators (including microphone capture from
* <code>AudioIn</code>) have an amplitude of 1, which means that the values of
* their waveform will be numbers in the range <code>[-0.5, 0.5]</code>.
*
* @author icalvin102
*
* @webref Analysis:Waveform
* @webBrief Inspects the underlying soundwave of an audio signal.
**/
public class Waveform extends Analyzer {
public float[] data;
private FixedRateMonoWriter writer;
private FloatSample buffer;
private int lastAnalysisOffset;
/**
* @param parent
* typically use "this"
* @param nsamples
* number of waveform samples that you want to be able to read at once (a positive integer).
*/
public Waveform(PApplet parent, int nsamples) {
super(parent);
if (nsamples <= 0) {
// TODO throw RuntimeException?
Engine.printError("number of waveform frames needs to be greater than 0");
} else {
this.data = new float[nsamples];
this.writer = new FixedRateMonoWriter();
this.buffer = new FloatSample(nsamples);
// write any connected input into the output buffer ad infinitum
this.writer.dataQueue.queueLoop(this.buffer);
}
}
protected void removeInput() {
this.writer.input.disconnectAll();
this.input = null;
}
protected void setInput(UnitOutputPort input) {
// superclass makes sure that input unit is actually playing, just connect it
Engine.getEngine().add(this.writer);
this.writer.input.connect(input);
this.writer.start();
}
/**
* Gets the content of the current audiobuffer from the input source, writes it
* into this Waveform's `data` array, and returns it.
*
* @return the current audiobuffer of the input source. The array has as
* many elements as this Waveform analyzer's number of samples
*/
public float[] analyze() {
return this.analyze(this.data);
}
/**
* Gets the content of the current audiobuffer from the input source.
*
* @param value
* an array with as many elements as this Waveform analyzer's number of
* samples
* @return the current audiobuffer of the input source. The array has as
* many elements as this Waveform analyzer's number of samples
* @webref Analysis:Waveform
* @webBrief Gets the content of the current audiobuffer from the input source.
**/
public float[] analyze(float[] value) {
if (this.input == null) {
Engine.printWarning("this Waveform has no sound source connected to it, nothing to analyze");
}
this.lastAnalysisOffset = (int) this.writer.dataQueue.getFrameCount() % this.buffer.getNumFrames();
// if initiating this read takes too long the first couple samples might actually
// already be overwritten by the next loop, so fingers crossed...
this.buffer.read(lastAnalysisOffset, value, 0, this.buffer.getNumFrames() - lastAnalysisOffset);
this.buffer.read(0, value, this.buffer.getNumFrames() - lastAnalysisOffset, lastAnalysisOffset);
// the original implementation did a *2 on all values...?
return value;
}
/*
public float[] analyzeCircular() {
return this.analyzeCircular(this.data);
}
public float[] analyzeCircular(float[] value) {
if (this.input == null) {
Engine.printWarning("this Waveform has no sound source connected to it, nothing to analyze");
}
this.lastAnalysisOffset = (int) this.writer.dataQueue.getFrameCount() % this.buffer.getNumFrames();
this.buffer.read(value);
return value;
}
public int getLastAnalysisOffset() {
return this.lastAnalysisOffset;
}
*/
// Below are just duplicated methods from superclasses which are required
// for the online reference to build the corresponding pages.
/**
* Define the audio input for the analyzer.
*
* @param input
* the input sound source. Can be an oscillator, noise generator,
* SoundFile or AudioIn.
* @webref Analysis:Waveform
* @webBrief Define the audio input for the analyzer.
**/
public void input(SoundObject input) {
super.input(input);
}
}