# Superfm

**URL:** <https://uzu.lurk.org/t/superfm/1761>\
**Category:** TidalCycles\
**Tags:** questions\
**Created:** [28 July 2020 13:07 UTC](https://uzu.lurk.org/t/superfm/1761 "2020-07-28T13:07:36Z")\
**Posts on this page:** 20\
**Page:** 2

<div class="post-metadata">

**Author:** ![paul1](https://uzu.lurk.org/letter_avatar_proxy/v4/letter/p/3d9bf3/32.png) [@paul1](https://uzu.lurk.org/u/paul1)\
**Post date:** [8 September 2020 15:25 UTC](https://uzu.lurk.org/t/superfm/1761/21 "2020-09-08T15:25:18Z")

</div>

The array functions are much nicer than setting everything individually.

> [@ghales](#):
>
> edit: the `(gain 1)` on `fmparam` is a placeholder - I couldn't find a neutral `ControlMap` function (like `id` )

Does this work?

```haskell
-- Array functions
let fmparam function (x:xs) = foldr (#) (function 1 x) (zipWith function [2..] xs)
    lfma = fmparam fmamp
    lfmr = fmparam fmratio
    lfmd = fmparam fmdetune
    lfmer op = fmparam (fmegrate op)
    lfmel op = fmparam (fmeglevel op)

```

My haskell is rusty and was never very good to start with, so there's probably a more elegant way to do it.

---

<div class="post-metadata">

**Author:** ![earthlydelight](https://uzu.lurk.org/letter_avatar_proxy/v4/letter/e/ecc23a/32.png) [@earthlydelight](https://uzu.lurk.org/u/earthlydelight)\
**Post date:** [8 September 2020 16:31 UTC](https://uzu.lurk.org/t/superfm/1761/22 "2020-09-08T16:31:49Z")

</div>

It works very well and it's a lot more compact, thank you @paul1 !

```haskell
d1
    $ stut 2 0.7 0.125
    $ slow 3 $ s "superfm" 
    |+| note (arp "pinkyup" "[0,4,7,12] [0,5,7,9]" )
    # fmfeedback 1
    # lfma [1, 1, 1, 0, 0, 0]
    # lfmr [1, (range 0 4 (slow 4 sine)), 0.26, 0.5, 0.5, 0.5]
    # lfmd [0, 1, 0, 0, 0, 0]
    # fmmod 1 1 "<0 1.25>"
    # fmmod 1 2 (range 0 4 (slow 4 sine))
    # fmmod 1 3 (range 0 4 (slow 3 saw))
    # fmmod 3 2 (range 0 3 (slow 2 sine))
    # lfmel 1 [1, 0.5, 0, 0, 0, 0]
    # lfmer 1 [10, 0.1, 0.1, 1, 0, 0]
    # lfmel 2 [1, 0, 0, 0, 0, 0]
    # lfmer 2 [1, 0.3, 0.7, 1, 0, 0]
    # lfmel 3 [1, 0.2, 0, 1, 0, 0]
    # lfmer 3 [10, 0.5, 0.4, 1, 0, 0]
    # lpf 1000
    # room 0.3

```

---

<div class="post-metadata">

**Author:** ![loopier](https://uzu.lurk.org/user_avatar/uzu.lurk.org/loopier/32/1152_2.png) [@loopier](https://uzu.lurk.org/u/loopier)\
**Post date:** [3 November 2020 18:59 UTC](https://uzu.lurk.org/t/superfm/1761/23 "2020-11-03T18:59:30Z")

</div>

I just [posted an anouncement](https://club.tidalcycles.org/t/superfm-tutorial-live-stream/2358) for a streaming I'll be broadcasting next Thrusday to give an overview of the synth. Hoping to see you there.

---

<div class="post-metadata">

**Author:** ![specht](https://uzu.lurk.org/letter_avatar_proxy/v4/letter/s/bb73d2/32.png) [@specht](https://uzu.lurk.org/u/specht)\
**Post date:** [7 November 2020 23:22 UTC](https://uzu.lurk.org/t/superfm/1761/24 "2020-11-07T23:22:59Z")

</div>

Interesting syntax.

What does the `l` mean in `lfma`?

Isn't `env` more clear then `eg`? In SuperCollider I don't think I ever saw 'eg', but 'env' seems to be common to use in relation with envelopes. For now this seems more clear to me as a 'fm-newbie':

```haskell
fmamp
fmratio
fmmod
fmenvlevel
fmenvrate

```

Shorter is not always better 😉

Maybe even:

```haskell
fmamps
fmratios
fmdetunes
fmmod
envlevel
envrate

```

In SuperCollider you would write a envelope like

```haskell
([0, 1, 1, 0], [2, 1, 3])

```

Where the first numbers are the levels and the last two numbers are the time or rate (att, sus, rel) in this case. A syntax like that isn't possible in Tidal/Haskell?

> **[Env | SuperCollider 3.11.1 Help](http://doc.sccode.org/Classes/Env.html)**

---

<div class="post-metadata">

**Author:** ![loopier](https://uzu.lurk.org/user_avatar/uzu.lurk.org/loopier/32/1152_2.png) [@loopier](https://uzu.lurk.org/u/loopier)\
**Post date:** [8 November 2020 09:17 UTC](https://uzu.lurk.org/t/superfm/1761/25 "2020-11-08T09:17:58Z")

</div>

> [@specht](#):
>
> In SuperCollider you would write a envelope like
> 
> `([0, 1, 1, 0], [2, 1, 3])`

Although this syntax is shorter, I find myself having to think what each parameter is every time I have to change something. So, for me, is more convenient to have them separated at least between levels and rates. Just a matter of taste, I guess.

> [@specht](#):
>
> Isn't `env` more clear then `eg`? In SuperCollider I don't think I ever saw 'eg', but 'env' seems to be common to use in relation with envelopes. For now this seems more clear to me as a 'fm-newbie':
> 
> ```haskell
> fmamp
> fmratio
> fmmod
> fmenvlevel
> fmenvrate
> 
> ```

I like this one. Maybe it should be `envlevels`, `envrates`, `fmmods` and `fmratios` to denote the array, shouldn't it?  
And how about `op` instead of `fm` as prefix?  
As for the envelopes, `envr` and `envl` might be a nice short version.

Thinking about the single-value syntax I figured a more descriptive alternative would be to make a mix of ADSR and 4-stage-envelope naming. Maybe something like:

```haskell
atkl1 -- attack level for operator 1, instead of eglelvel11
atkr1 -- attack rate for operator 1, instead of egrate11
decl1 -- decay level for operator 1, instead of eglelvel12
decr1 -- decay rate for operator 1, instead of egrate12
susl1 -- sustain level for operator 1, instead of eglelvel13
susr1 -- sustain rate for operator 1, instead of egrate13
rell1 -- release level for operator 1, instead of eglelvel14
relr1 -- release rate for operator 1, instead of egrate14

```

or maybe

```haskell
latk1
ratk1
ldec1
rdec1
...
-- or
ar1
al1
dl1
dr1
sl1
sr1
rl1
rr1

```

---

<div class="post-metadata">

**Author:** ![specht](https://uzu.lurk.org/letter_avatar_proxy/v4/letter/s/bb73d2/32.png) [@specht](https://uzu.lurk.org/u/specht)\
**Post date:** [8 November 2020 10:36 UTC](https://uzu.lurk.org/t/superfm/1761/26 "2020-11-08T10:36:38Z")

</div>

Good thoughts.

> [@loopier](#):
>
> Although this syntax is shorter, I find myself having to think what each parameter is every time I have to change something. So, for me, is more convenient to have them separated at least between levels and rates. Just a matter of taste, I guess.

You have x amount of levels for the envelope, including the initial and end level. Then there are the timevalues between them, which is always levels -1 (so 4 -1 = 3 in this case).

For me it feels a bit strange to tear the envelope apart in individual arguments, which you can sort the way you want

```haskell
atkl1
decl3
rell1
relr6

```

for instance. In the Supercollider syntax, it's relation and position in the enveloppe is more clear to me at least.

Also using larger numbers for faster rates, feels a bit contractional to me. In most languages/software a smaller number would give you a faster attack. You told that you copied it from the original DX7, but I wonder if converting it to software should stick with that. That's just what my initial thoughts are, I'm not really qualified to judge this properly, just some thoughts/feedback.

Is there any relation of superfm with this DX7 implementation I found for supercollider?

> **[GitHub - everythingwillbetakenaway/DX7-Supercollider: My accurate Yamaha DX-7...](https://github.com/everythingwillbetakenaway/DX7-Supercollider)**
>
> My accurate Yamaha DX-7 clone. Programmed in Supercollider. - everythingwillbetakenaway/DX7-Supercollider

I guess it's now time to start experimenting with the superfm synth. Thanks for the synth implementation and the livestream. I'm having quite some fun with it already. 🕶

---

<div class="post-metadata">

**Author:** ![loopier](https://uzu.lurk.org/user_avatar/uzu.lurk.org/loopier/32/1152_2.png) [@loopier](https://uzu.lurk.org/u/loopier)\
**Post date:** [8 November 2020 11:42 UTC](https://uzu.lurk.org/t/superfm/1761/27 "2020-11-08T11:42:57Z")

</div>

> [@specht](#):
>
> For me it feels a bit strange to tear the envelope apart in individual arguments, which you can sort the way you want

I understand what you mean. For me, when live coding, I usually just tweak one or two envelope parameters, not the hole envelope. If I just want to change the decay time, for example, it makes more sense to me to just write the value for that parameter than the whole envelope thing because I have to consider the other parameters too, and remember their values.

> [@specht](#):
>
> Also using larger numbers for faster rates, feels a bit contractional to me. In most languages/software a smaller number would give you a faster attack. You told that you copied it from the original DX7, but I wonder if converting it to software should stick with that.

I must confess that is still confusing for me too, because I'm used to Supercolllider's syntax with times instead of rates. The advantage of keeping the DX7 scheme is that is easier to port the loads of documented patches out there, which are all set in rates.

> [@specht](#):
>
> Is there any relation of superfm with this DX7 implementation I found for supercollider?

No, there isn't. That implementation is a serious one, really cool and sounds awesome, but it's quite complex. Superfm is just using Supercollider's [FM7 Ugen](https://doc.sccode.org/Classes/FM7.html), with added envelopes and mappings to the control and mod matrices. I haven't implemented fixed operator frequencies, mod sensitivity or keyboard breakpoints, band depths and curves (yet ; P).

But having you all enjoying it as you do is motivating to do it!

---

<div class="post-metadata">

**Author:** ![specht](https://uzu.lurk.org/letter_avatar_proxy/v4/letter/s/bb73d2/32.png) [@specht](https://uzu.lurk.org/u/specht)\
**Post date:** [8 November 2020 21:11 UTC](https://uzu.lurk.org/t/superfm/1761/28 "2020-11-08T21:11:17Z")

</div>

> [@loopier](#):
>
> ```haskell
> atkl1 -- attack level for operator 1, instead of eglelvel11
> atkr1 -- attack rate for operator 1, instead of egrate11
> decl1 -- decay level for operator 1, instead of eglelvel12
> decr1 -- decay rate for operator 1, instead of egrate12
> susl1 -- sustain level for operator 1, instead of eglelvel13
> susr1 -- sustain rate for operator 1, instead of egrate13
> rell1 -- release level for operator 1, instead of eglelvel14
> relr1 -- release rate for operator 1, instead of egrate14
> 
> ```

Personally I'm more fan of a bit longer but clearer names likes these, compared to the very short ones (ar1 etc.)

But it the end it's your synth, you decide 😉 @loopier

---

<div class="post-metadata">

**Author:** ![ghales](https://uzu.lurk.org/user_avatar/uzu.lurk.org/ghales/32/2171_2.png) [@ghales](https://uzu.lurk.org/u/ghales)\
**Post date:** [15 November 2020 22:04 UTC](https://uzu.lurk.org/t/superfm/1761/29 "2020-11-15T22:04:09Z")

</div>

> [@specht](#):
>
> What does the `l` mean in `lfma`?

It's short for "list" 🤡  
I thought it would be intuitive at first, but yeah, `fmamps` is obviously way clearer!

---

<div class="post-metadata">

**Author:** ![specht](https://uzu.lurk.org/letter_avatar_proxy/v4/letter/s/bb73d2/32.png) [@specht](https://uzu.lurk.org/u/specht)\
**Post date:** [16 November 2020 12:04 UTC](https://uzu.lurk.org/t/superfm/1761/30 "2020-11-16T12:04:31Z")

</div>

> [@loopier](#):
>
> And how about `op` instead of `fm` as prefix?

Where does `op` stands for?

---

<div class="post-metadata">

**Author:** ![loopier](https://uzu.lurk.org/user_avatar/uzu.lurk.org/loopier/32/1152_2.png) [@loopier](https://uzu.lurk.org/u/loopier)\
**Post date:** [16 November 2020 12:56 UTC](https://uzu.lurk.org/t/superfm/1761/31 "2020-11-16T12:56:12Z")

</div>

> [@specht](#):
>
> Where does `op` stands for?

It stands for "operator"

---

<div class="post-metadata">

**Author:** ![specht](https://uzu.lurk.org/letter_avatar_proxy/v4/letter/s/bb73d2/32.png) [@specht](https://uzu.lurk.org/u/specht)\
**Post date:** [16 November 2020 18:00 UTC](https://uzu.lurk.org/t/superfm/1761/32 "2020-11-16T18:00:37Z")

</div>

Ok, if that's technically a more appropriate naming, it might be better indeed. It's up to you I guess.

---

<div class="post-metadata">

**Author:** ![ghales](https://uzu.lurk.org/user_avatar/uzu.lurk.org/ghales/32/2171_2.png) [@ghales](https://uzu.lurk.org/u/ghales)\
**Post date:** [20 November 2020 20:49 UTC](https://uzu.lurk.org/t/superfm/1761/33 "2020-11-20T20:49:07Z")

</div>

that's the thing though - none of this is standard library, so you can call it whatever you find more fitting 🙂

---

<div class="post-metadata">

**Author:** ![specht](https://uzu.lurk.org/letter_avatar_proxy/v4/letter/s/bb73d2/32.png) [@specht](https://uzu.lurk.org/u/specht)\
**Post date:** [20 November 2020 21:51 UTC](https://uzu.lurk.org/t/superfm/1761/34 "2020-11-20T21:51:37Z")

</div>

Sure, but it might be nice too have some nice default settings 🙂

---

<div class="post-metadata">

**Author:** ![yaxu](https://uzu.lurk.org/user_avatar/uzu.lurk.org/yaxu/32/2_2.png) [@yaxu](https://uzu.lurk.org/u/yaxu)\
**Post date:** [22 November 2020 21:06 UTC](https://uzu.lurk.org/t/superfm/1761/35 "2020-11-22T21:06:53Z")

</div>

Yep it'd be nice for it to be in the standard library I think!

---

<div class="post-metadata">

**Author:** ![yaxu](https://uzu.lurk.org/user_avatar/uzu.lurk.org/yaxu/32/2_2.png) [@yaxu](https://uzu.lurk.org/u/yaxu)\
**Post date:** [11 December 2020 20:48 UTC](https://uzu.lurk.org/t/superfm/1761/36 "2020-12-11T20:48:26Z")

</div>

It'd be good to get an improved superfm UI in the next tidal release, did we arrive at consensus?

---

<div class="post-metadata">

**Author:** ![th4](https://uzu.lurk.org/user_avatar/uzu.lurk.org/th4/32/505_2.png) [@th4](https://uzu.lurk.org/u/th4)\
**Post date:** [12 December 2020 11:04 UTC](https://uzu.lurk.org/t/superfm/1761/37 "2020-12-12T11:04:17Z")

</div>

For what my opinion is worth, I think @ghales's version is very sane. I'm currently using @paul1's version, but I find it to be very verbose, especially when you're only using a couple oscillators at a time but you still have to define the others at 0.

---

<div class="post-metadata">

**Author:** ![loopier](https://uzu.lurk.org/user_avatar/uzu.lurk.org/loopier/32/1152_2.png) [@loopier](https://uzu.lurk.org/u/loopier)\
**Post date:** [12 December 2020 11:39 UTC](https://uzu.lurk.org/t/superfm/1761/38 "2020-12-12T11:39:42Z")

</div>

If there must be a prefix, I'd go for `op` instead of `fm`.

I'm not so sure about arrayed parameters, either (as @th4 suggests if I understood well). If using patterns in them, wouldn't make it a bit confusing?

```haskell
d1 $ s "superfm*3"
# mod1 2 "0 1 0.5"
# mod1 3 "1 0 0.5"
# mod1 4 "0 1"
# mod1 5 "0 1 0"

```

might be easier to read and quicker to grab than

```haskell
d1 $ s "superfm*3"
# mod1 "0 1 0.5" "1 0 0.5" "0 1" "0 1 0" 0 0

```

For the envelope syntax, I myself have been playing with

```haskell
atkl1 -- attack level for operator 1, instead of eglelvel11
atkr1 -- attack rate for operator 1, instead of egrate11
decl1 -- decay level for operator 1, instead of eglelvel12
decr1 -- decay rate for operator 1, instead of egrate12
susl1 -- sustain level for operator 1, instead of eglelvel13
susr1 -- sustain rate for operator 1, instead of egrate13
rell1 -- release level for operator 1, instead of eglelvel14
relr1 -- release rate for operator 1, instead of egrate14

```

and seems to work pretty well. Easy to remember and shorter to write.

I also have been trying a different version of `superfm` with envelope times instead of rates, so it's more consistent with ADSR values. It's not DX7ish anymore, but I must say it makes more sense. Then the syntax would be

```haskell
-- ...
# atkt1 0.01 -- instead of # egrate11 100
# dect1 0.3 -- instead of # egrate12 30
# sust1 1 -- instead of # egrate13 1
# relt1 1 -- instead of # egrate14 1

```

Should I make a pull request to update it in time for next release? Or is it better to stick with what we already have not to confuse people?

---

<div class="post-metadata">

**Author:** ![ghales](https://uzu.lurk.org/user_avatar/uzu.lurk.org/ghales/32/2171_2.png) [@ghales](https://uzu.lurk.org/u/ghales)\
**Post date:** [12 December 2020 13:53 UTC](https://uzu.lurk.org/t/superfm/1761/39 "2020-12-12T13:53:08Z")

</div>

I'm obviously biased here but I think the array version looks cleaner. That said, why not have both?  
`fmamps` takes an array, while `fmamp` takes an extra `index` argument in the first position.

`fmamp` can be more readable while `fmamps` is more practical for large patches. They're good for different things - having both could be nice

---

<div class="post-metadata">

**Author:** ![yaxu](https://uzu.lurk.org/user_avatar/uzu.lurk.org/yaxu/32/2_2.png) [@yaxu](https://uzu.lurk.org/u/yaxu)\
**Post date:** [12 December 2020 14:31 UTC](https://uzu.lurk.org/t/superfm/1761/40 "2020-12-12T14:31:46Z")

</div>

I haven't got deep into try these out but I like the idea of adding a plural 's' for a list parameter

[Previous page](https://uzu.lurk.org/t/superfm/1761.md?page=1)

[Next page](https://uzu.lurk.org/t/superfm/1761.md?page=3)
