# Beads audio library in Python mode

**URL:** <https://discourse.processing.org/t/beads-audio-library-in-python-mode/3077>\
**Category:** Processing.py\
**Created:** [August 28, 2018, 3:08pm UTC](https://discourse.processing.org/t/beads-audio-library-in-python-mode/3077 "2018-08-28T15:08:11Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![wissme](https://avatars.discourse-cdn.com/v4/letter/w/d2c977/32.png) [@wissme](https://discourse.processing.org/u/wissme)\
**Post date:** [August 28, 2018, 3:08pm UTC](https://discourse.processing.org/t/beads-audio-library-in-python-mode/3077/1 "2018-08-28T15:08:11Z")

</div>

Hi ! I am starting to learn Beads audio library, wonderful book by Evan Merz but in Java.  
The beads library works fine in Processing.py up to some points where the Java does not seem obvious to be translated in Python.  
------\> Has anybody tried to translate in Python the Merz book, or better the 11 Lessons ?  
I am stuck with FM synthesis, having to translate a CUSTOM FUNCTION (much used in the book) :

```auto
modulator = new WavePlayer(ac, 5, Buffer.SINE);
// this is a custom function
// custom functions are a bit like custom Unit Generators (custom Beads)
// but they only override the calculate function
Function frequencyModulation = new Function(modulator)
{
  public float calculate() {
    // return x[0], which is the original value of the modulator signal (a sine wave)
    // multiplied by 50 to make the sine vary between -50 and 50
    // then add 200, so that it varies from 150 to 250
    return (x[0] * 50.0) + 200.0; // <---- works fine !
  }
};

carrier = new WavePlayer(ac, frequencyModulation, Buffer.SINE);

----------- I tried this but without luck :

class My_Function(Function) :
    def calculate(self) :
        return x[0]*50+200 # <---- x is not defined !!!

modulator = WavePlayer(ac,5,Buffer.SINE)
frequencyModulation = My_Function(modulator)
carrier = WavePlayer(ac,frequencyModulation,Buffer.SINE)

Any help ?
```

---

<div class="post-metadata">

**Author:** ![kfrajer](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kfrajer/32/196_2.png) [@kfrajer](https://discourse.processing.org/u/kfrajer)\
**Post date:** [August 29, 2018, 1:30pm UTC](https://discourse.processing.org/t/beads-audio-library-in-python-mode/3077/2 "2018-08-29T13:30:41Z")

</div>

### _Please format your code_ 😊

It consist on these two steps:

1. In your code editor (PDE, VS code, Eclipse, etc) ensure you execute the beautifier function. This function automatically indents your code. Auto-indenting makes your code easier to read and helps catching bugs due to mismatch parenthesis, for instance. In the PDE, you use the key combination: `ctrl+t`
2. You copy and paste your code in the forum. Then you select the code and you hit the formatting button aka. the button with this symbol: `</>`

That’s it! Please notice you do not create a new post in case you need to format something you already posted. You can edit your post, copy the code to the PDE, indent the code properly there and then past it back here, format the code and \>\> **save** \<\< the edits.

## Extra info:

Formatting your code makes everybody’s life easier, your code looks much better plus it ensures your code integrity is not affected by the forum’s formatting (Do you know the forum processes markup code?) Please visit the sticky posts or the FAQ section/post to learn about this, other advantages and super powers you can get in this brand new forum.

Kf

---

<div class="post-metadata">

**Author:** ![wissme](https://avatars.discourse-cdn.com/v4/letter/w/d2c977/32.png) [@wissme](https://discourse.processing.org/u/wissme)\
**Post date:** [August 29, 2018, 4:58pm UTC](https://discourse.processing.org/t/beads-audio-library-in-python-mode/3077/3 "2018-08-29T16:58:29Z")

</div>

OK Thanks. I thought your editor was verbatim-like…

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [September 4, 2018, 4:54am UTC](https://discourse.processing.org/t/beads-audio-library-in-python-mode/3077/4 "2018-09-04T04:54:40Z")

</div>

> [@wissme](#):
>
> return (x[0] \* 50.0) + 200.0; // \<---- works fine !

That is pretty mysterious (to me, at least).

You don’t include headers, so I’m not sure – is `Function` imported from a standard Java library, or is it a custom method of Beads? To make a Python equivalent, first need to track down what exactly x is in the original Java and where it is coming from…

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [September 4, 2018, 4:57am UTC](https://discourse.processing.org/t/beads-audio-library-in-python-mode/3077/5 "2018-09-04T04:57:39Z")

</div>

…ah, I should have just looked it up.

`Function` is a custom class in Beads – specifically, it extends UGen, and it holds `x[]`.

Here is the source:

- [https://github.com/orsjb/beads/blob/master/src/beads\_main/net/beadsproject/beads/ugens/Function.java](https://github.com/orsjb/beads/blob/master/src/beads_main/net/beadsproject/beads/ugens/Function.java)

…and the documentation:

- [http://www.beadsproject.net/doc/net/beadsproject/beads/ugens/Function.html](http://www.beadsproject.net/doc/net/beadsproject/beads/ugens/Function.html)

* * *

(…so, it is NOT: [https://docs.oracle.com/javase/8/docs/api/java/util/function/Function.html](https://docs.oracle.com/javase/8/docs/api/java/util/function/Function.html) )

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [September 4, 2018, 9:51am UTC](https://discourse.processing.org/t/beads-audio-library-in-python-mode/3077/6 "2018-09-04T09:51:47Z")

</div>

> [@jeremydouglass](#):
>
> … and it holds _x[]_.

However, that `float[]` field is `protected`! 🤯  
[BeadsProject.net/doc/net/beadsproject/beads/ugens/Function.html#x](http://BeadsProject.net/doc/net/beadsproject/beads/ugens/Function.html#x)

And Jython can’t access non-`public` members from Java classes! 🥶

I’ve had to use reflection in order to access that Function::_x[]_ `protected` field. 🔭  
And then stored it as an alias field named _xx[]_ right after! 🤪

```auto
"""
 Lesson03_FMSynthesis (v1.1)
 Py Mode: GoToLoop (2018-Sep-04)
 Discourse.Processing.org/t/beads-audio-library-in-python-mode/3077/6
"""

add_library('beads')

from java.util import Arrays

FG, BG = 0xffFF66CC, 0xff000000
FREQ = 5.0

def setup():
    size(512, 512)
    noSmooth()
    loadPixels()

    global ac
    ac = AudioContext()

    modulator = WavePlayer(ac, FREQ, Buffer.SINE)
    carrier = WavePlayer(ac, FreqControl(modulator), Buffer.SINE)

    gain = Gain(ac, 1, .1)
    gain.addInput(carrier)

    ac.out.addInput(gain)
    ac.start()

def draw():
    Arrays.fill(pixels, BG)

    siz = ac.bufferSize
    gain = ac.out

    w = width
    h = height

    cy = h >> 1
    res = len(pixels) - 1

    for i in range(w):
        vOff = int(cy * (1 + gain.getValue(0, i * siz / w)))
        pixels[min(res, vOff * h + i)] = FG

    updatePixels()

def keyPressed(): key == ESC and ac.stop()

class FreqControl(Function):
    MULT, AUGMENT = 50.0, 200.0

    def __init__ (f, *args, **kw):
        super(FreqControl, f). __init__ (*args, **kw)

        f.mul = kw.get('mul', f.MULT)
        f.aug = kw.get('aug', f.AUGMENT)

        fieldX = Function.getDeclaredField('x')
        fieldX.accessible = True
        f.xx = fieldX.get(f)

    def calculate(f): return f.xx[0] * f.mul + f.aug

```

---

<div class="post-metadata">

**Author:** ![neilcsmith](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/neilcsmith/32/144_2.png) [@neilcsmith](https://discourse.processing.org/u/neilcsmith)\
**Post date:** [September 4, 2018, 9:59am UTC](https://discourse.processing.org/t/beads-audio-library-in-python-mode/3077/7 "2018-09-04T09:59:51Z")

</div>

> [@GoToLoop](#):
>
> And Jython can’t access non- `public` members from Java classes!

Are you saying Jython can’t extend Java classes? This is meant to be extended, hence why it’s protected.

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [September 4, 2018, 10:06am UTC](https://discourse.processing.org/t/beads-audio-library-in-python-mode/3077/8 "2018-09-04T10:06:07Z")

</div>

> [@neilcsmith](#):
>
> Are you saying Jython can’t extend Java classes?

Not at all. You can see in my solution that I extend the `abstract class` Function as `class` Funct. 🧐

> [@GoToLoop](#):
>
> `class Funct(Function):`

---

<div class="post-metadata">

**Author:** ![neilcsmith](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/neilcsmith/32/144_2.png) [@neilcsmith](https://discourse.processing.org/u/neilcsmith)\
**Post date:** [September 4, 2018, 10:18am UTC](https://discourse.processing.org/t/beads-audio-library-in-python-mode/3077/9 "2018-09-04T10:18:35Z")

</div>

> [@GoToLoop](#):
>
> Not at all. You can see in my solution that I extend the `abstract class` Function as `class` Funct.

Can I?! Never used Python / Jython - have contributed to Beads! 😄 But if Jython can’t extend a Java class and access its protected members, it can’t really extend a Java class!

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [September 4, 2018, 6:55pm UTC](https://discourse.processing.org/t/beads-audio-library-in-python-mode/3077/10 "2018-09-04T18:55:27Z")

</div>

> [@neilcsmith](#):
>
> This is meant to be extended, hence why it’s `protected`.

Class Function is already `abstract`. Thus it already needs to be extended. 🧐

Therefore, there’s no need at all for its field _x[]_ to be non-`public` there. 🤐

> [@neilcsmith](#):
>
> But if Jython can’t extend a Java class and access its `protected` members, it can’t really extend a Java class!

The Java non-`public` members are inherited, of course. ☕

Only they can’t be accessed directly. Need reflection hacks! 🤖

Your inheritance definition is too strict methinks. 😳

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [September 4, 2018, 7:10pm UTC](https://discourse.processing.org/t/beads-audio-library-in-python-mode/3077/11 "2018-09-04T19:10:02Z")

</div>

As a fix to make Python Mode users happy, the `abstract class` Function should add a `public` getter for its `protected` field _x[]_: 🤩

```auto
public float getX(final int idx) {
  return x[idx];
}

```

---

<div class="post-metadata">

**Author:** ![neilcsmith](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/neilcsmith/32/144_2.png) [@neilcsmith](https://discourse.processing.org/u/neilcsmith)\
**Post date:** [September 4, 2018, 7:14pm UTC](https://discourse.processing.org/t/beads-audio-library-in-python-mode/3077/12 "2018-09-04T19:14:44Z")

</div>

> [@GoToLoop](#):
>
> Therefore, there’s no need at all for its field _x[]_ to be non- `public` there.

Er, definitely not! This is the entire reason that protected exists. The fault here is in Jython not Beads.

---

<div class="post-metadata">

**Author:** ![wissme](https://avatars.discourse-cdn.com/v4/letter/w/d2c977/32.png) [@wissme](https://discourse.processing.org/u/wissme)\
**Post date:** [September 6, 2018, 6:07am UTC](https://discourse.processing.org/t/beads-audio-library-in-python-mode/3077/13 "2018-09-06T06:07:57Z")

</div>

Hi ! Any of you is in charge of Beads ? Who and when this getter will be available for Python mode users ?  
Thanks.

---

<div class="post-metadata">

**Author:** ![wissme](https://avatars.discourse-cdn.com/v4/letter/w/d2c977/32.png) [@wissme](https://discourse.processing.org/u/wissme)\
**Post date:** [September 6, 2018, 6:16am UTC](https://discourse.processing.org/t/beads-audio-library-in-python-mode/3077/14 "2018-09-06T06:16:35Z")

</div>

> [@GoToLoop](#):
>
> Lesson03\_FMSynthesis (v1.1) Py Mode: GoToLoop (2018-Sep-04)

I can’t find the Lesson 03 Python file in the standard distribution which contains only Lesson 01 and 04 ???

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [September 6, 2018, 6:31am UTC](https://discourse.processing.org/t/beads-audio-library-in-python-mode/3077/15 "2018-09-06T06:31:22Z")

</div>

> [@wissme](#):
>
> I can’t find the “Lesson 03” Python file in the standard distribution…

Only “Java Mode” got the complete set of 11 examples. ☕  
My version was converted to “Python Mode” from the “Java Mode” version: 🐍  
[https://github.com/orsjb/beads/blob/master/packages/Processing/tutorial/Lesson03\_FMSynthesis/Lesson03\_FMSynthesis.pde](https://github.com/orsjb/beads/blob/master/packages/Processing/tutorial/Lesson03_FMSynthesis/Lesson03_FMSynthesis.pde)

---

<div class="post-metadata">

**Author:** ![neilcsmith](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/neilcsmith/32/144_2.png) [@neilcsmith](https://discourse.processing.org/u/neilcsmith)\
**Post date:** [September 6, 2018, 7:17am UTC](https://discourse.processing.org/t/beads-audio-library-in-python-mode/3077/16 "2018-09-06T07:17:45Z")

</div>

> [@wissme](#):
>
> Any of you is in charge of Beads ? Who and when this getter will be available for Python mode users ?

Why should it be up to Beads to work around issues with Jython?!

You’d be better following up on the Beads mailing list - [Redirecting to Google Groups](https://groups.google.com/forum/m/#!forum/beadsproject)

---

<div class="post-metadata">

**Author:** ![wissme](https://avatars.discourse-cdn.com/v4/letter/w/d2c977/32.png) [@wissme](https://discourse.processing.org/u/wissme)\
**Post date:** [September 6, 2018, 8:56am UTC](https://discourse.processing.org/t/beads-audio-library-in-python-mode/3077/17 "2018-09-06T08:56:46Z")

</div>

That would be kind to have a **complete set of Beads Lessons in Python mode** for those who do not program in Java (and your trick is a bit too clever as it requires Java knowledge of protected variables).  
**Python Beads** deserves more than the present number of users, notably for teaching, it’s a good job.  
Thanks for the rest of us.

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [September 6, 2018, 6:26pm UTC](https://discourse.processing.org/t/beads-audio-library-in-python-mode/3077/18 "2018-09-06T18:26:03Z")

</div>

> [@wissme](#):
>
> (and your trick is a bit too clever as it requires Java knowledge of protected variables)

Jython treats any Java’s non-`public` members as if they were full-force `private`, regardless whether they have `protected` or “Package” more liberal access levels. 🕵️‍♂️

Although reflection techniques are “clever”, these 3 statements aren’t that hard to grasp IMO: 🥌

```auto
fieldX = Function.getDeclaredField('x')
fieldX.accessible = True
self.xx = fieldX.get(self)

```

Believe me, if that field _x[]_ were `private` instead of the less restrictive `protected`, the Java version would have a much bigger boilerplate for us to code: 🛡

```auto
import beads.*;
import java.lang.reflect.Field;

class FreqControl extends Function {
  static final float MULT = 50.0, AUGMENT = 200.0;
  final float[] xx;

  @SafeVarargs FreqControl(final UGen... inputs) {
    super(inputs);

    try {
      final Field fieldX = Function.class.getDeclaredField("x");
      fieldX.setAccessible(true);
      xx = (float[]) fieldX.get(this);
    }

    catch (final ReflectiveOperationException cause) {
      throw new RuntimeException(cause);
    }
  }

  @Override float calculate() {
    return xx[0] * MULT + AUGMENT;
  }
}

```

> [@wissme](#):
>
> **Python Beads** deserves more than the present number of users, notably for teaching, …

You should try convincing them to either change the field Function::_x[]_ 's access level to `public` or include a `public` getter method for it: 😣

> **[Issues · orsjb/beads](https://github.com/orsjb/beads/issues)**
>
> The Beads project. Contribute to orsjb/beads development by creating an account on GitHub.

> [@wissme](#):
>
> … to have a **complete set of Beads Lessons in Python mode** for those who do not program in Java.

Never used Beads library before; but you can always post your Java to Python Mode conversion attempts here in the forum. 🕶

---

<div class="post-metadata">

**Author:** ![neilcsmith](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/neilcsmith/32/144_2.png) [@neilcsmith](https://discourse.processing.org/u/neilcsmith)\
**Post date:** [September 6, 2018, 6:43pm UTC](https://discourse.processing.org/t/beads-audio-library-in-python-mode/3077/19 "2018-09-06T18:43:49Z")

</div>

> [@GoToLoop](#):
>
> You should try convincing them to either change the field Function:: _x[]_ 's access level to `public` or include a `public` getter method for it:

It’s not meant to be public! It’s meant to be private to subclasses, aka. protected.

Beads hasn’t seen much development in a while, but the mailing list I linked earlier is probably the best place to discuss this.

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [September 6, 2018, 6:46pm UTC](https://discourse.processing.org/t/beads-audio-library-in-python-mode/3077/20 "2018-09-06T18:46:50Z")

</div>

I’ve merely listed the 2 possible easiest options to “fix” the issue for Processing’s Python Mode, regardless of their technical merit. 🐍 Which 1 to pick is another matter! 😛

[Next page](https://discourse.processing.org/t/beads-audio-library-in-python-mode/3077.md?page=2)
