Which sound library should I use?

I am aware of three libraries: Built-in Sound, Minim, and Beads. My main goal is sound synthesis.

While I have not studied them in-depth (I want to avoid investing time in learning about a tool I won’t use), this is what I gather:

Sound seems to be the simplest of the three and doesn’t seem to offer as many features as the others. For example, it has a low-pass filter, but can I turn it into a VCF, controlling its cutoff frequency with an oscillator?

Beads and Mimin are much more feature-rich and great for synthesis. Minim seems to be more intuitive than Beads, but lacks a crucial (IMO) feature, namely reverb.

Are they alive? According to Github, there has not been any development in Beads or Minim for years. The Beads forum on Google Groups has had no discussions in three years (though I did get a question answered in a day), and I have not found a forum dedicated to Minim.

My questions: Which library would you suggest? Can the (apparent) lack of features in Sound be compensated? Is it possible to add reverb to sounds generated by Minim? Is it worrying that Beads and Minim are not actively developed anymore?

Hi @berndbausch,

Actually, that’s a major part of a development process and the way it works … to analyse and find out which tools/libraries/etc to use and fits best regarding your project needs… :wink:
So, I guess no one can do this for you, especially when not knowing the scope and goal of your project…

Cheers
— mnse

5 Likes

Here is one more

Simply you can run examples of all libraries won’t take much time from you then you can choose what Suitable for you

2 Likes

Well, apart from the general request for advice, I do have a few specific questions:

  • Can the (apparent) lack of features in Sound be compensated? E.g. how could I implement a filter that is controlled by oscillators or other signal generators.
  • Is it possible to add reverb to sounds generated by minim? Minim is the library that I like the most, but the lack of a reverb effect is a problem.
  • Should I be worried that development on Minim and Beads seems to have ceased?

Thanks, you have whetted my appetite. I guess I could interactively build synthesizers with PureData and then translate them more or less directly to processing sketches.

The current version is 0.0.7. Development status is the opposite of the two mature libraries minim and beads.

But anyway, something to investigate.

2 Likes

Hello @berndbausch,

:)

1 Like

Hi @berndbausch. @robertesler here, developer of Pd4P3.

To my knowledge, there are two full-stack audio libraries that are currently being updated and developed for Processing 4 and those are two mentioned in other posts, Processing Sound and Pd4P3.

Minim and Beads still work, but don’t appear to be currently in development which could mean they will stop working with new updates to Processing, Java or Java Sound. They also don’t have Android support.

I would say if you wanted the ease of integrating sound into Processing, similar syntax and support for compressed audio formats then Processing Sound is a good choice. Processing Sound can also do a lot more than it advertises because it is built upon Jsyn which is a very powerful, pure Java sound library which you could utilize on top of Processing. It conforms to the Java Sound design paradigm of connecting abstract sound objects (Filters, UGens, Synthesizers, etc.) together to form DSP chains.

If you want more low-level, audio loop access, custom DSP potential, MIDI support (Both Java and Android) and access to Pure Data’s signal processing code then maybe Pd4P3 is suited for you. It is also supported by a C++ backend so if you find you need extremely low latency, then there are options for that. Pd4P3 does not support compressed audio formats. It is also designed completely different from JSyn and Processing Sound, and it may be a bit more advanced for casual users.

Both Processing Sound and Pd4P3 have Mac/Win/Linux and Android support, Reverb examples, regular development cycles and multi-channel support (Processing Sound announced multi-channel will happen in the forthcoming release.)

So choose based on your goals and comfort level and you should be in good shape for a while.
Good luck and don’t hesitate to reach out again if you need more advice.

3 Likes

Thanks much, Robert. Both for your reply and the PD4P3 project. I have already started looking into PD, and I will definitely have another look at Sound and also explore Jsyn.

Meanwhile I found there is also a library for communication with Supercollider, but it’s even older than Minim.

Thanks! The Sound library is getting closer to what I believe I need. From the Github page:

Experimental features

  • Frequency and amplitude modulation of oscillators by passing other oscillators to freq() and amp()

Still no modulation of filter cutoff frequencies, though.

However, it seems that the full feature set of Jsyn, on which Sound is based, can be used. I will check that out.

1 Like

Beads includes the JAudioLib’s audioserver libraries underneath. We also have our own ugen library called Pipes that is used in various things including PraxisLIVE. I must get around to doing a Processing sketch example with it, although that might need an update on our side due to a bug when assertions are enabled.

If you want block-based modulation of filter cutoff that’s easily accomplished with it. Default block size is 64 samples.

See GitHub - jaudiolibs/pipes: Java audio routing and unit generator library.

1 Like

@robertesler

Hi … just attempting to get Pd4P3 installed but get this error for music = new MyMusic();

UnsatisfiedLinkError: no pdplusplus in java.library.path: :/Applications/Processing.app/Contents/Java/core/library/macos-aarch64:/Users/markhudson/Documents/Processing/libraries/Pd4P3/library:/Applications/Processing.app/Contents/MacOS
A library used by this sketch relies on native code that is not available.
UnsatisfiedLinkError: no pdplusplus in java.library.path: :/Applications/Processing.app/Contents/Java/core/library/macos-aarch64:/Users/markhudson/Documents/Processing/libraries/Pd4P3/library:/Applications/Processing.app/Contents/MacOS
UnsatisfiedLinkError: no pdplusplus in java.library.path: :/Applications/Processing.app/Contents/Java/core/library/macos-aarch64:/Users/markhudson/Documents/Processing/libraries/Pd4P3/library:/Applications/Processing.app/Contents/MacOS

Any ideas as how to fix?

Best regards
Mark

Hi @berndbausch, Sound library maintainer here :wave:

I’m currently on a sprint to add new features to the library, and adding modulation of filter cutoff frequencies is definitely on the table! I might be able to squeeze in a new method by the end of the day, please watch the Github release preview link for updates. The Javadoc documentation gets generated automatically, so as soon as you see a .freq(Modulator) and .res(Modulator) methods on the Javadocs, it should also be included in the v2.4.0 preview download. We also very much appreciate any testing and feedback, either here or on Github!

As Robert already mentioned, you can in theory also just use Processing Sound to initialise the JSyn engine, use some of the basic library features, but then also go wild with it by getting direct access to and playing with the underlying synthesis engine, through Sound.getSynthesisEngine() and MultiChannel.outputs().

1 Like

Hi @shedMusic. Are you on an M1 or M2 processor? It should be built for ARM but I didnt have an M1/2 Mac at the time to test on.
I will try today and see if I get the same error.
Sorry about that, hopefully I can fix that later today.

@robertesler
Hi , thanks for getting back to me :slight_smile:
It’s a MacBook Air (M2, 2022)

No mad rush as I’m just watching some of your videos on YouTube … I like the one that shows me how to get setup up in JUCE !

Very much in practice, actually. The first thing I did after reading Robert’s reply was running two Jsyn example programs in a Processing sketch. And it worked immediately.

I guess getSynthesisEngine() will allow me to combine Sound and Jsyn calls in the same sketch? So much to explore! Thanks for helping. I am blown away by the support in this forum.

Hi

Can you share processing sketch

Yes, I suppose if you never import or call any processing.sound.* classes all that happens is that the library provides the JSyn jar in the classpath, but any JSyn code that you run is completely independent of the engine and wrappers offered by the Sound library.

Yes exactly, if you configure the Synthesizer/SynthesisEngine (same thing, one is the interface the other one the actual class) through processing.sound.Sound and processing.sound.MultiChannel, it just makes listing+selecting audio devices a bit easier, creates LineOuts for all output channels automatically, and you can avoid having lots of verbose .getUnitOutputPort(), .getUnitGenerator(), .connect(),… calls in your code. (But you can still throw those in by getting the pre-initialised JSyn objects and fiddling with them yourself.) The library includes a LowLevelEngine example that gives an idea of the most important methods.

I just pushed a new v.2.4.0-preview release to Github, updated documentation with the filter modulation methods is here, all feedback welcome: Filter (Javadocs: Processing Sound)

1 Like

It should be fixed now. You can delete and reinstall if you like. When I tested it the MacOS made me approve the libpdplusplus.dylib in the System Preferences Security Panel, similar to when you download and execute software from the internet. Not sure if that will happen for everyone, but it’s just the first time.
Apparently there was no ARM build in the bundle anymore.

In case others are interested, here is my very unsophisticated Jsyn experimentation. I am sure I am violating plenty of best practices, but it works. Note that I am not versed in Java at all.

I used the sample programs PlayTone.java and HearSinePM.java with some minor modifications:

  • Remove the package clause
  • Replace the public class by a simple class
  • Add a constructor to the class. In the case of the PlayTone example, I turned the test() method into the constructor, in the case of HearSinePM, the init() method.
  • Remove the @Override from the HearSinePM constructor
  • Turn the main() into setup()

To interact with the sketches, I also added an empty draw() and a keyPressed(), but found that key presses were ignored while the sound was playing. When the playing stops, they are recognized. Same for mouse clicks. Perhaps Jsyn blocks the interrupt that Processing uses for keyboard and mouse interaction.

PlayTone


import com.jsyn.JSyn;
import com.jsyn.Synthesizer;
import com.jsyn.unitgen.LineOut;
import com.jsyn.unitgen.SineOscillator;

/**
 * Play a tone using a JSyn oscillator.
 *
 * @author Phil Burk (C) 2010 Mobileer Inc
 */
class PlayTone {

    PlayTone() {

        // Create a context for the synthesizer.
        Synthesizer synth = JSyn.createSynthesizer();

        // Start synthesizer using default stereo output at 44100 Hz.
        synth.start();

        // Add a tone generator.
        SineOscillator oscillator = new SineOscillator();
        synth.add(oscillator);
        // Add a stereo audio output unit.
        LineOut lineOut = new LineOut();
        synth.add(lineOut);

        // Connect the oscillator to both channels of the output.
        oscillator.output.connect(0, lineOut.input, 0);
        oscillator.output.connect(0, lineOut.input, 1);

        // Set the frequency and amplitude for the sine wave.
        oscillator.frequency.set(345.0);
        oscillator.amplitude.set(0.6);

        // We only need to start the LineOut. It will pull data from the
        // oscillator.
        lineOut.start();

        // Sleep while the sound is generated in the background.
        try {
            double time = synth.getCurrentTime();
            // Sleep for a few seconds.
            synth.sleepUntil(time + 4.0);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // Stop everything.
        synth.stop();
    }
}

void setup() {
        PlayTone p = new PlayTone();
}

HearSinePM


import java.awt.BorderLayout;
import java.awt.GridLayout;

import javax.swing.BorderFactory;
import javax.swing.JApplet;
import javax.swing.JLabel;
import javax.swing.JPanel;

import com.jsyn.JSyn;
import com.jsyn.Synthesizer;
import com.jsyn.ports.UnitInputPort;
import com.jsyn.scope.AudioScope;
import com.jsyn.swing.DoubleBoundedRangeModel;
import com.jsyn.swing.JAppletFrame;
import com.jsyn.swing.PortModelFactory;
import com.jsyn.swing.RotaryTextController;
import com.jsyn.unitgen.LineOut;
import com.jsyn.unitgen.SineOscillator;
import com.jsyn.unitgen.SineOscillatorPhaseModulated;

/**
 * Play a tone using a phase modulated sinewave oscillator. Phase modulation (PM) is very similar to
 * frequency modulation (FM) but is easier to control.
 *
 * @author Phil Burk (C) 2010 Mobileer Inc
 */
class HearSinePM extends JApplet {
    private Synthesizer synth;
    SineOscillatorPhaseModulated carrier;
    SineOscillator modulator;
    LineOut lineOut;
    AudioScope scope;

    HearSinePM() {
        synth = JSyn.createSynthesizer();
        // Add a tone generator.
        synth.add(modulator = new SineOscillator());
        // Add a trigger.
        synth.add(carrier = new SineOscillatorPhaseModulated());
        // Add an output mixer.
        synth.add(lineOut = new LineOut());

        modulator.output.connect(carrier.modulation);
        carrier.output.connect(0, lineOut.input, 0);
        carrier.output.connect(0, lineOut.input, 1);
        modulator.amplitude.setup(0.0, 1.0, 10.0);
        carrier.amplitude.setup(0.0, 0.25, 1.0);
        setupGUI();
    }

    private void setupGUI() {
        setLayout(new BorderLayout());

        add(new JLabel("Show Phase Modulation in an AudioScope"), BorderLayout.NORTH);

        // Arrange the knob in a row.
        JPanel knobPanel = new JPanel();
        knobPanel.setLayout(new GridLayout(1, 0));

        knobPanel.add(setupPortKnob(modulator.frequency, "MFreq"));
        knobPanel.add(setupPortKnob(modulator.amplitude, "MAmp"));
        knobPanel.add(setupPortKnob(carrier.frequency, "CFreq"));
        knobPanel.add(setupPortKnob(carrier.amplitude, "CAmp"));
        add(knobPanel, BorderLayout.SOUTH);

        scope = new AudioScope(synth);
        scope.addProbe(carrier.output);
        scope.addProbe(modulator.output);
        scope.setTriggerMode(AudioScope.TriggerMode.NORMAL);
        scope.getView().setControlsVisible(true);
        add(scope.getView(), BorderLayout.CENTER);
        scope.start();
        validate();
    }

    private RotaryTextController setupPortKnob(UnitInputPort port, String label) {
        DoubleBoundedRangeModel model = PortModelFactory.createExponentialModel(port);
        RotaryTextController knob = new RotaryTextController(model, 10);
        knob.setBorder(BorderFactory.createTitledBorder(label));
        knob.setTitle(label);
        return knob;
    }

    @Override
    public void start() {
        // Start synthesizer using default stereo output at 44100 Hz.
        synth.start();
        scope.start();
        // We only need to start the LineOut. It will pull data from the
        // oscillator.
        lineOut.start();
    }

    @Override
    public void stop() {
        scope.stop();
        synth.stop();
    }
}

void setup() {
    /* Can be run as either an application or as an applet. */
        HearSinePM applet = new HearSinePM();
        JAppletFrame frame = new JAppletFrame("Hear Phase Modulation", applet);
        frame.setSize(640, 400);
        frame.setVisible(true);
        frame.test();
}
2 Likes

@kevinstadler

Hi Sir

Can you provide processing example measure sound frequency