-
-
Notifications
You must be signed in to change notification settings - Fork 49
Expand file tree
/
Copy pathSoundObject.java
More file actions
162 lines (141 loc) · 4.19 KB
/
SoundObject.java
File metadata and controls
162 lines (141 loc) · 4.19 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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
package processing.sound;
import com.jsyn.ports.UnitInputPort;
import com.jsyn.unitgen.UnitFilter;
import processing.core.PApplet;
/**
* For advanced users: common superclass of all sound sources (oscillators,
* noise, audio samples and even AudioIn).
* @webref SoundObject
*/
// Subclasses need to assign the 'amplitude' port, and also initiate a
// JSynCircuit (which effects can be plugged into) with an appropriate
// JSynProcessor if they want to support pan/add.
public abstract class SoundObject {
// subclasses need to initialise this circuit
protected JSynCircuit circuit;
// all subclasses need to set this amplitude port -- either to the amplitude
// port of the circuit, or directly to an amplitude port of their sound unit
// TODO replace this with a MixerStereo
protected UnitInputPort amplitude;
protected float amp = 1.0f;
protected boolean isPlaying = false;
protected SoundObject(PApplet parent) {
Engine.getEngine(parent);
}
private void setAmplitude() {
this.amplitude.set(this.amp);
}
/*
* Offset the output of this generator by given value
*
* @param add
* A value for offsetting the audio signal.
* @deprecated
*/
public void add(float add) {
if (this.circuit.processor == null) {
Engine.printError("stereo sound sources do not support adding");
} else {
this.circuit.processor.add(add);
}
}
/**
* Change the amplitude/volume of this sound.
*
* @param amp
* A float value between 0.0 (complete silence) and 1.0 (full volume)
* controlling the amplitude/volume of this sound.
* @webref SoundObject
**/
public void amp(float amp) {
this.amp = amp;
this.setAmplitude();
}
/**
* Check if this sound object is currently playing.
*
* @return `true` if this sound object is currently playing, `false` if it is
* not.
*/
public boolean isPlaying() {
return this.isPlaying;
}
/**
* Move the sound in a stereo panorama.
*
* @param pos
* The panoramic position of this sound unit as a float from -1.0
* (left) to 1.0 (right).
* @webref SoundObject
**/
public void pan(float pos) {
if (this.circuit.processor == null) {
Engine.printError("stereo sound sources do not support panning");
} else if (Engine.checkPan(pos)) {
this.circuit.processor.pan(pos);
}
}
/**
* Starts the generator
**/
public void play() {
// TODO print info message if it's already playing?
if (!this.isPlaying) {
Engine.getEngine().play(this.circuit);
this.setAmplitude();
this.isPlaying = true;
// TODO rewire effect if one was set previously (before stopping)?
}
}
/**
* Stops this sound from playing back.
*
* @webref SoundObject:SoundObject
**/
public void stop() {
this.isPlaying = false;
this.amplitude.set(0);
if (this.circuit.effect != null) {
this.removeEffect(this.circuit.effect);
}
// also removes the unit implicitly
Engine.getEngine().stop(this.circuit);
}
/**
* The 'true' number of underlying channels of this sound. All SoundObjects are put into
* a stereo-pannable wrapper, but for multi-channel purposes, anything that's not a true
* stereo sample should be considered to be mono.
* @see MultiChannel
*/
public int channels() {
return 1;
}
protected void setEffect(Effect<? extends UnitFilter> effect) {
if (this.circuit.effect == effect) {
Engine.printWarning("this effect is already processing the given sound source");
} else {
if (this.circuit.effect != null) {
this.removeEffect(this.circuit.effect);
}
Engine.getEngine().add(effect.left);
Engine.getEngine().add(effect.right);
this.circuit.setEffect(effect);
}
}
protected void removeEffect(Effect<? extends UnitFilter> effect) {
if (this.circuit.effect != effect) {
// possibly a previous effect that's being stopped here, ignore call
Engine.printError("this effect is not currently processing any signals.");
} else {
this.circuit.removeEffect();
}
}
/**
* Gets the <code>JSynCircuit</code> object which encapsulates all the JSyn
* units (basic sound generator, pan and amplitude) which control the sound
* synthesis of this SoundObject.
*/
public JSynCircuit getUnitGenerator() {
return this.circuit;
}
}