Skip to content

Commit 70d7627

Browse files
committed
Add Sound.verbose() setting for toggling native library output
1 parent 27ecb91 commit 70d7627

File tree

3 files changed

+46
-12
lines changed

3 files changed

+46
-12
lines changed

examples/IO/LowLevelEngine/LowLevelEngine.pde

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ void setup() {
88
Sound.list();
99

1010
// to improve support for USB audio interfaces on Windows, it is possible to
11-
// use the PortAudio library, which is however not enabled by default. The
11+
// use the PortAudio bindings, which are however not enabled by default. The
1212
// listing above might therefore not have given accurate input/output channel
13-
// numbers. The library automatically loads PortAudio drivers when
14-
// Sound.outputDevice() is called on a device that it is unable to use
15-
// correctly with the default drivers, OR you can always load them explicitly
16-
// using MultiChannel.usePortAudio().
13+
// numbers. The Sound library automatically loads PortAudio drivers when it
14+
// determines that it is unable to use a device correctly with the default
15+
// drivers, but you can always force loading PortAudio (on both Windows and
16+
// Mac) using MultiChannel.usePortAudio():
1717
if (MultiChannel.usePortAudio()) {
18-
// if PortAudio was loaded successfully, the ids and names of the sound
18+
// if PortAudio was loaded successfully, the id's and names of the sound
1919
// devices (and possibly their number of input/output channels) will have
2020
// changed!
2121
Sound.list();
@@ -30,5 +30,25 @@ void setup() {
3030
SynthesisEngine s = Sound.getSynthesisEngine();
3131
println("Current CPU usage: " + s.getUsage());
3232

33+
// with direct access to the SynthesisEngine, you can always create and add
34+
// your own JSyn unit generator chains. if you want to connect them to audio
35+
// output, you can connect them to the ChannelOut units automatically
36+
// generated by the library:
37+
ChannelOut[] outputs = MultiChannel.outputs();
38+
39+
// if you want to mess
40+
SinOsc sin = new SinOsc(this);
41+
JSynCircuit circuit = sin.getUnitGenerator();
42+
}
43+
44+
45+
// sketches without a draw() method won't get updated in the loop, and synthesis
46+
// won't continue
47+
void draw() {
3348
}
3449

50+
51+
// a useful callback method when you are debugging a sound sketch
52+
void mouseClicked() {
53+
Sound.Status();
54+
}

src/processing/sound/Engine.java

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
*/
3737
class Engine {
3838

39+
static boolean verbose = false;
40+
3941
private static AudioDeviceManager createDefaultAudioDeviceManager() {
4042
try {
4143
Class.forName("javax.sound.sampled.AudioSystem");
@@ -58,9 +60,15 @@ private static AudioDeviceManager createAudioDeviceManager(boolean portAudio) {
5860
}
5961
// hide JPortAudio init messages from console
6062
PrintStream originalStream = System.out;
61-
System.setOut(new PrintStream(new OutputStream(){
62-
public void write(int b) { }
63-
}));
63+
PrintStream originalErr = System.err;
64+
if (!Engine.verbose) {
65+
System.setOut(new PrintStream(new OutputStream(){
66+
public void write(int b) { }
67+
}));
68+
System.setErr(new PrintStream(new OutputStream(){
69+
public void write(int b) { }
70+
}));
71+
}
6472
// JPortAudio takes care of loading all native libraries -- except the
6573
// dependent portaudio dll on Windows for some reason. try loading it no
6674
// matter what platform we're on and ignore any errors, if it's really not
@@ -85,10 +93,13 @@ public void write(int b) { }
8593
// java.base/jdk.internal.loader.NativeLibraries.load(Native Method)
8694
if (e.getMessage().contains("disallowed")) {
8795
throw new RuntimeException("in order to use the PortAudio drivers, you need to give Processing permission to open the PortAudio library file.\n\n============================== ENABLING PORTAUDIO ON MAC OS X ==============================\n\nPlease follow these steps to enable PortAudio (dont worry, you only need to do this once):\n\n - if you pressed 'Move to Bin' in the previous popup, you will need first need to restore the\n library file: please find libjportaudio.jnilib in your Bin, right click and select 'Put Back'\n\n - go to System Preferences > Security & Privacy> General. At the bottom you will see\na message saying that 'libjportaudio.jnilib was blocked'. Press 'Allow Anyway'. When you\nrun this sketch again you should get another popup, just select 'Open' and you're done!\n\n============================================================================================");
96+
} else if (Engine.verbose) {
97+
e.printStackTrace();
8898
}
8999
throw new RuntimeException("PortAudio is not supported on this operating system/architecture");
90100
} finally {
91101
System.setOut(originalStream);
102+
System.setErr(originalErr);
92103
}
93104
}
94105

@@ -390,13 +401,12 @@ protected int selectOutputDevice(int deviceId) {
390401
// try portaudio access to the same device -- need get the name of the
391402
// old output device and re-select it on the new device manager
392403
String targetDeviceName = this.getDeviceName(deviceId);
404+
Engine.printMessage("Output device '" + targetDeviceName + "' did not work with the default audio driver, trying again with PortAudio...");
393405
try {
394406
this.usePortAudio(true);
395407
} catch (RuntimeException ee) {
396408
throw new RuntimeException(e);
397409
}
398-
// this might replace this.synth
399-
Engine.printMessage("Output device '" + targetDeviceName + "' did not work with the default driver, switching to PortAudio...");
400410
int newDeviceIdForOldDevice = this.synth.getAudioDeviceManager().getDefaultOutputDeviceID();
401411
try {
402412
// TODO also loop through candidates

src/processing/sound/Sound.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ public static String[] list(boolean printAll) {
100100
String[] deviceNames = Sound.deviceNames();
101101
AudioDeviceManager audioManager = Engine.getAudioDeviceManager();
102102
System.out.println();
103-
Engine.printMessage(audioManager.getName() + " audio device listing\n");
103+
Engine.printMessage(audioManager.getName() + " device listing\n");
104104
if (printAll) {
105105
Sound.printDeviceTable(IntStream.range(0, deviceNames.length).toArray());
106106
} else {
@@ -274,6 +274,10 @@ public static void status() {
274274
Engine.println();
275275
}
276276

277+
public static void verbose(boolean verbose) {
278+
Engine.verbose = verbose;
279+
}
280+
277281
public static void printConnections() {
278282
Sound.getSynthesisEngine().printConnections();
279283
}

0 commit comments

Comments
 (0)