Primeira vez aqui? Seja bem vindo e cheque o FAQ!
x

Como gerar música a partir de um algoritmo?

+3 votos
75 visitas
perguntada Abr 17 em Programação Computacional por Douglas Sad Silveira (121 pontos)  

Considere o seguinte modelo probabilístico:

a) Escolha o compasso;

b) A música pode alternar entre diferentes tipos de ritmos dentro do compasso. Sorteie ritmos para cada compasso [você pode usar uma cadeia de markov];

c) Sorteie a possível sequência de notas. [ Você pode usar uma cadeia de Markov]. Para não ficar tão livre (e aleatório), considere apenas as notas da escala de C maior natural.

Use a linguagem de sua escolha para gerar a música

Compartilhe

2 Respostas

+3 votos
respondida Abr 24 por Stuart Mill (1,084 pontos)  
selecionada Abr 24 por Douglas Sad Silveira
 
Melhor resposta

[Vou fazer meu comentário na forma de resposta para poder usar o ambiente de código]

Explorando as ideias da biblioteca e livro indicados pelo Douglas, fiz um código para criar uma música a partir da sequência de Fibonacci (convertendo cada cada número a uma das 12 notas da oitava escolhida) [Note que serão sequências de notas que se repetem].

Além disso, pegando os primeiros dígitos de \(\pi\) e \( e\), fiz as músicas também para brincar um pouco com a biblioteca. Nos últimos casos, simplesmente peguei as constantes da biblioteca math e criei uma lista com os dígitos.

Segue o código:

from __future__ import division
import collections
import itertools
from random import choice
from pyknon.genmidi import Midi
from pyknon.music import Note, NoteSeq, Rest
import math
def choice_if_list(item):
    if isinstance(item, collections.Iterable):
        return choice(item)
    else:
        return item


def playlist(pitchlist, octave,duration, volume=120):
    result = NoteSeq()
    for pitch in pitchlist:
        note = pitch % 12
        octave = choice_if_list(octave)
        dur = choice_if_list(duration)
        vol = choice_if_list(volume)

        result.append(Note(note,octave,dur,vol))
    return result

def fib_it(n):
    listafib=[]
    a = 0
    b=1
    if(n==1):
        listafib.append(0)

    if(n==2):
        listafib.append(1)

    else:
        listafib.append(0)
        listafib.append(1)
        for i in range(2,n):
            f = a+b
            listafib.append(f)
            a,b = b,f
    return listafib
def fib_music(lista):
    listafibmusic=[]
    for i in range(len(lista)):
        listafibmusic.append(lista[i] % 12)
    return listafibmusic
x = fib_it(100)
fibmusic = fib_music(x)
octave = range(3,7)
n1 = playlist(fibmusic, octave,1/8)

def gen_midi(filename, note_list):
    midi = Midi(tempo=100)
    midi.seq_notes(note_list)
    midi.write(filename)

# Primeiro dígitos de pi
pi_lista = []
for i in str((math.pi)):
    pi_lista.append(i)
pi_lista.remove(".")
pi_lista = [int(n) for n in pi_lista]
#print(pi_lista)
n2 = playlist(pi_lista, octave, 1/8)
# Primeiros dígitos do número de Euler
e_lista = []   
for i in str((math.e)):
    e_lista.append((i))
e_lista.remove(".")
e_lista = [int(n) for n in e_lista]
#print(e_lista)
n3 = playlist(e_lista, octave, 1/8)

gen_midi("fibmusic.mid", n1)
gen_midi("pimusic.mid", n2)
gen_midi("eulermusic.mid", n3)
+3 votos
respondida Abr 17 por Douglas Sad Silveira (121 pontos)  
editado Abr 17 por Douglas Sad Silveira

O código implementado se baseia nos capítulos 4 e 5 do livro de Pedro Kroger, "Music for Geeks & Nerds. Learn more about music with Python and a little bit of math", cujo download está disponível aqui

Foi utilizado o Python 2.7 para executar o código apresentado abaixo:

# -*- coding: utf-8 -*-
"""
Created on Tue Apr 16 22:16:08 2019

@author: Douglas
"""

import random 
from pyknon.genmidi import Midi
from pyknon.music import NoteSeq


Duracao_da_Nota  = { "2", "4", "8", "16"}
#  2 corresponde a 1/2 tempo, 4 a 1/4 tempo, 8 a 1/8 tempo e 16 a 1/16 tempo

#  Criando as diferentes escalas com tonalidade em C maior natural para cada 
#  estilo musical

C_major = {'C', 'D', 'E', 'F', 'G', 'A', 'B'}

C_major_Blues = {'C', 'D', 'D#', 'E', 'G', 'A'}

C_major_Jazz = {'C', 'C#', 'D#', 'F', 'F#', 'G#', 'A#', 'C'}

def seq_nota_aleatoria(numnotas, escalas, Duracao_da_Nota, pausas=True):
    # Adicionar uma pausa as notas da escala.
    if pausas:
        escalas.add('r')

    essa_seq = ''
    for i in range(numnotas):
        escala = (random.sample(escalas, 1))
        Duracao_da_Nota = (random.sample(Duracao_da_Nota, 1))
        essa_seq += escala[0] + Duracao_da_Nota[0] + ' '

    return NoteSeq(essa_seq)

notas_C_major = seq_nota_aleatoria(100, C_major, Duracao_da_Nota)
midi = Midi(1, tempo=140)
midi.seq_notes(notas_C_major, track=0)
midi.write("C_major.mid")


notas_C_major_Blues = seq_nota_aleatoria(100, C_major_Blues, Duracao_da_Nota)
midi = Midi(1, tempo=180)
midi.seq_notes(notas_C_major_Blues, track=0)
midi.write("C_major_Blues.mid")

notas_C_major_Jazz = seq_nota_aleatoria(100, C_major_Jazz, Duracao_da_Nota)
midi = Midi(1, tempo=190)
midi.seq_notes(notas_C_major_Jazz, track=0)
midi.write("C_major_Jazz.mid")


### Abaixo, eu consigo criar um arquivo midi contendo todas as variações 
### aleatórias de estilo, ritmo, escalas enunciadas acima. 
### O nome dado foi "fusion".


## classic se refere a escala de C maior natural:
classic = NoteSeq(seq_nota_aleatoria(100, C_major, Duracao_da_Nota))
## blues se refere a escala de C maior para o ritmo blues:
blues   = NoteSeq(seq_nota_aleatoria(100, C_major_Blues, Duracao_da_Nota))
## jazz se refere a escala de C maior (modo dórico) para o ritmo jazz:
jazz    = NoteSeq(seq_nota_aleatoria(100, C_major_Jazz, Duracao_da_Nota))

### juntando as três variações de ritmo num único arquivo midi:
midi = Midi(number_tracks=3, tempo = 120)
midi.seq_notes(classic, track=0,)
midi.seq_notes(blues, track=1)
midi.seq_notes(jazz, track=2)
midi.write("fusion.midi")

links do youtube para se ouvir as músicas aleatórias geradas a partir da implementação acima:

Música aleatória no Python - C maior natural
Música aleatória no Python - C maior Blues
Música aleatória no Python - C maior Jazz
Música aleatória no Python - C maior Fusion

comentou Jun 5 por Pablo Castro (286 pontos)  
[Interlúdio] Nesse vídeo tem uma bela melodia com a sequência de Fibonacci
https://www.youtube.com/watch?v=IGJeGOw8TzQ&feature=youtu.be
...