OPENRNDR and sound (Minim library)

It won’t be a question, at least not asked by me. My friend asked me during the OPENRNDR workshop how to use sound with OPENRNDR. and then she immediately googled it. There was no answer over the Internet. So I will write how I do it in my projects with Minim library.

Despite what you might think Minim is not bound directly to Processing. It can be integrated with any java derived code. In case of OPENRNDR you need to add this dependency to build.gradle.kts:

dependencies {
    // ...
    compile("net.compartmental.code:minim:2.2.2") {
        exclude(group = "org.apache.maven.plugins", module = "maven-javadoc-plugin")
    }
}

And then something like this will do the trick:

  program {
    val minim = Minim(object : Object() {
      fun sketchPath(fileName: String): String {
        return fileName
      }
      fun createInput(fileName: String): InputStream {
        return FileInputStream(File(fileName))
      }
    })
    val lineIn = minim.lineIn
    val fft = FFT(lineIn.bufferSize(), lineIn.sampleRate())
    //...

The sketchPath and createInput functions should reflect structure of music resources in your project.

1 Like

Thanks for the example :slight_smile:

The beads audio library is also not Processing dependent, and they seem to be migrating to gradle:

I haven’t tried it recently, but I used it in the past.

Thanks for sharing @kazik, Beads doesn’t have so many examples out there (not that I’ve found). Minim seems like an easier to use alternative.

For anyone wanting to use beads just add the following to build.gradle.kts:

repositories {
   maven( url = "https://jitpack.io")
}

dependencies {
  compile("com.github.orsjb","beads","migrate_to_gradle-SNAPSHOT")
}

If you want to pair it with Open-AL:

class OpenALIO : AudioIO() {
    private var aqs: AudioSource? = null
    val source: AudioSource
        get() {
            return aqs?: error("not started")
        }
    override fun start(): Boolean {
        println("starting OpenALIO")
        aqs = AudioSystem.createQueueSource(queueSize = 2) {
            this.update()
            val bs = context.bufferSize
            val buffer1 = context.out.getOutBuffer(0)
            val bb = ByteBuffer.allocateDirect(bs * 2)
            bb.order(ByteOrder.nativeOrder())
            for (i in 0 until bs) {
                bb.putShort((buffer1[i].coerceIn(-1.0f, 1.0f) * 32767).toShort())
            }
            bb.rewind()
            AudioData(AudioFormat.MONO_16, 48000, bb)
        }
        (aqs as AudioQueueSource).play()
        return true
    }
    override fun getAudioInput(p0: IntArray?): UGen {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }
}

and use it with:

val context: AudioContext = AudioContext(
        OpenALIO(),
        48000/60,
        IOAudioFormat(48000.0f, 16, 0, 2)
    )

PS: This is courtesy of @edwin… just sharing the solution.

I didn’t realize Minim has a synthesis framework too. That was mostly my reason for going with Beads, plus that it was easy to drop-in an audio back-end. I used OpenAL to achieve positional audio with a 4 speaker setup.