Write your own custom FoxDot function with Python.

We have already seen how to customize Foxdot with its own samples, synth and fx.

In this tutorial we will focus on creating functions using Python. We will not go back over the basics of this language but rather we will see how to use functions already defined in Foxdot to create others.


Before starting to code, we will first define what type of function we are going to do. Because depending on the type, we will use different decorators that are already predefined by foxdot.

Does the function relate to a player, a pattern, a pattern generator, a random pattern, is more global ?


A function to modify the player args. The ‘self’ reference to the player itself.

Like d1 >> play(“x.”).spread(), d1.degrade(), d1.offbeat()

Decorator: @player_method

Now let’s try to code a function that would add the duration of the player to the degree (don’t ask why we do that).

def degdur(self):
    self.degree = self.attr['degree'] + self.attr['dur']
    return self


d1 >> blip([0,2,4,2], dur=PRand([1/2,1,2])).degdur()


A function to modify an existing Pattern. The ‘self’ reference to the pattern itself.

Like P[].palindrome(), P[].rotate(), P[].stretch()

Decorator: @PatternMethod

With this simple example, we are coding a function that multiplies a pattern.

def mul(self, value):
    ''' multiply a pattern '''
    return self * value
Useless ? Not so sure, try this :
d1 >> play("x-o-").sometimes("rate.mul", -1)


A function that generates a Pattern. No ‘self’ reference.

Like PRange(), PTri(), PDur()

Decorator: @loop_pattern_func

Why not try to code a function based on PSine() but with a Saw waveform.

def PSaw(n=16):
    ''' Returns values of one cycle of Saw wave split into 'n' parts '''
    i = 1 / (n-1)
    return Pattern([i * j for j in range(0,int(n))])
b1 >> blip(0, dur=1/2, amp=PSaw(8))


A function that generates a random Pattern. No ‘self’ reference.

Like PRand(), PWhite(), PWalk()

Decorator: no decorator but a Class inheritance

Use the logarithmic distribution to create a generator.

class PLog(RandomGenerator):
    ''' Returns random floating point values using logarithmic distribution '''
    def __init__(self, mean=0, deviation=1, **kwargs):
        RandomGenerator.__init__(self, **kwargs)
        self.args = (mean, deviation)
        self.mean = mean
        self.deviation = deviation
    def func(self, index):
        if isinstance(self.mean, float):
            return lognormvariate(self.mean, self.deviation)
        elif isinstance(self.mean, int):
            return int(round(lognormvariate(self.mean, self.deviation)))
print(PLog(0,1)[:8]) --> P[1, 3, 6, 1, 1, 2, 0, 0]


Nothing special here. Just define your function.

Decorator: no decorator

Do you want a fadein function ?

def fadein(duration=16):
    return linvar([0,1],[duration,inf], start=now)
b1 >> blip(0, dur=1/2, amp=fadein(8))

>> do you remember startup.py ?

Congratulations ! You have created your first foxdot function and you want to integrate them into the software.

No problem, we recommend defining your functions in the /FoxDot/lib/Custom/startup.py

Indeed this file is launched automatically when Foxdot starts and you do not need to import all the variables and functions already defined by foxdot.

If you have any questions, suggestions or if you want to share your discoveries with us, don’t hesitate to post on the toplap forum, on the telegram group, the toplap discord or directly by email.

You can also try our FoxDot Ultimate Functions and test some useful functions.