Basic random pattern generator for Play: simple graph and wave file of reference

Hello I started developing a random pattern generator for the Play.

I want to share it here just to let someone more skilled than me with Python to eventually enrich/fix it or see it just to have some great ideas about the Play.
The purpose is to create some app that could boost even more our enjoyinment of this great machine.
I spend many hours using it and sometimes I need a distraction to add a little extravagance to its use.

The code:
It is in its basic state: just random patterns and a final graph to make the output nicer.

I also added the possibility to use a drum hit (for example a ClosedHat or one you prefer, just name it drum_hit.wav) to generate a final .WAV file that gives the idea of the random generated patterns.

Notes: the code is in Python, please grab it here :).
Problems: on my computer the FFMPEG doesn’t work, any help appreciated. The output at this state is too much random.

Ideal code: a library of genres with the first 3 track fixed and last fives generated randomly. So the output has a minimum of musical touch. I started this code too but got stumbled in some errors and abandoned it…May send it if you want…

Please note I’m not a developer nor a musician.
Just a falied normal person doing random things.

Have a look if you want…

import random
import matplotlib.pyplot as plt
from pydub import AudioSegment

def generate_pattern(genre):
    pattern = [[0 for i in range(16)] for j in range(8)]
    for i in range(8):
        for j in range(16):
            pattern[i][j] = random.randint(0, 1)
    return pattern

def plot_pattern(pattern):
    fig, ax = plt.subplots()
    ax.imshow(pattern, cmap='binary')
    ax.set_xticks(range(16))
    ax.set_yticks(range(8))
    plt.show()

def generate_audio_from_pattern(pattern, filename):
    sound = AudioSegment.silent(duration=0)
    for i in range(8):
        track = pattern[i]
        track_sound = AudioSegment.silent(duration=0)
        for j in range(16):
            if track[j] == 1:
                track_sound += AudioSegment.from_wav("drum_hit.wav")
            else:
                track_sound += AudioSegment.silent(duration=250)
        sound = sound.overlay(track_sound)
    sound.export(filename, format="wav")

if __name__ == '__main__':
    num_patterns = int(input("Quanti pattern vuoi creare? "))
    genres = ['techno', 'house', 'drum_and_bass', 'hip_hop', 'jazz']
    for i in range(num_patterns):
        genre = random.choice(genres)
        pattern = generate_pattern(genre)
        print('Generated pattern for genre:', genre)
        for i in range(8):
            print('Track', i+1, ':', pattern[i])
        plot_pattern(pattern)
        generate_audio_from_pattern(pattern, f"{genre}_pattern_{i}.wav")

More intelligent version with genres library, I did abandon after some attemptes…

import random

# Numero di tracce
num_tracks = 8

# Numero di step in un pattern
num_steps = 16

# Generi musicali disponibili
genres = ['dance', 'hip-hop', 'jazz', 'rock']

# Matrice di pattern vuoti
pattern = [[0 for j in range(num_steps)] for i in range(num_tracks)]

def generate_pattern(genre):
    if genre == 'dance':
        # Genere dance
        pattern[0][::4] = [1, 0, 0, 0]  # Kick ogni 4 step
        pattern[1][1::2] = [1, 0]  # Snare ogni 2 step a partire dal secondo
        pattern[2][::2] = [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0]  # Hi-hat ogni 2 step
    elif genre == 'hip-hop':
        # Genere hip-hop
        pattern[0][::4] = [1, 0, 0, 0, 1, 0, 0, 0]  # Kick ogni 4 step
        pattern[1][2::4] = [1, 0, 0, 0]  # Snare ogni 4 step a partire dal terzo
        pattern[2][::2] = [1, 0, 1, 0, 1, 0, 1, 0]  # Hi-hat ogni 2 step
    elif genre == 'jazz':
        # Genere jazz
        pattern[0][::4] = [1, 0, 0, 0]  # Kick ogni 4 step
        pattern[1][3::4] = [1, 0, 0, 0]  # Snare ogni 4 step a partire dal quarto
        pattern[2][1::2] = [1, 0, 0, 0, 1, 0, 0, 0]  # Hi-hat ogni 2 step
    elif genre == 'rock':
        # Genere rock
        pattern[0][::4] = [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0]  # Kick ogni 4 step
        pattern[1][1::4] = [1, 0, 0, 0]  # Snare ogni 4 step a partire dal secondo
        pattern[2][::2] = [1, 0, 1, 0, 1, 0, 1, 0]  # Hi-hat ogni 2 step

    # Genera valori casuali per le restanti tracce
    for i in range(3, num_tracks):
        pattern[i] = [random.randint(0, 1) for j in range(num_steps)]
    
    return pattern

# Genera un pattern casuale per un genere musicale casuale
genre = random.choice(genres)
print(f'Genere: {genre}')
pattern = generate_pattern(genre)
for i in range(num_tracks):
     print(f'Traccia {i+1}: {" ".join(map(str, pattern[i]))}')

Wave files: drum_hit.wav created by the user.
The other one is the output, not working on my pc but will likely work. it gives an audio synthesis of the pattern…

wave files

6 Likes

Anyone still interested?

Yes, keep the good work

1 Like