Pular para conteúdo

Ritmo — Duration, Tempo, Sequence

O modulo de ritmo permite construir composicoes com tempo, compasso e duracoes musicais reais. Cada evento (nota, acorde, pausa) tem sua propria duracao, e a Sequence toca tudo na ordem correta.


Duration — duracoes musicais

Uma Duration representa o valor ritmico de uma nota ou pausa. Pode ser construida de varias formas:

from gingo import Duration

# Por nome completo
q = Duration("quarter")       # seminima (1/4)
h = Duration("half")          # minima (1/2)
w = Duration("whole")         # semibreve (1/1)
e = Duration("eighth")        # colcheia (1/8)
s = Duration("sixteenth")     # semicolcheia (1/16)

# Por abreviacao
q = Duration("q")             # quarter
h = Duration("h")             # half
w = Duration("w")             # whole
e = Duration("e")             # eighth
s = Duration("s")             # sixteenth

# Por notacao LilyPond
q = Duration("4")             # quarter (1/4)
e = Duration("8")             # eighth (1/8)
s = Duration("16")            # sixteenth (1/16)

# Por fracao (string ou numerica)
d = Duration("1/4")           # seminima
d = Duration("3/8")           # seminima pontuada
d = Duration(3, 8)            # 3/8 (numerico)

Nomes disponiveis

print(Duration.standard_names())
# ['whole', 'half', 'quarter', 'eighth', 'sixteenth', 'thirty_second']
Nome Fracao Nome em portugues
whole 1/1 Semibreve
half 1/2 Minima
quarter 1/4 Seminima
eighth 1/8 Colcheia
sixteenth 1/16 Semicolcheia
thirty_second 1/32 Fusa

Pontuacao e quialteras

# Ponto de aumento (1.5x a duracao)
dq = Duration("quarter", dots=1)   # 3/8
dq = Duration("q.")               # abreviacao com ponto
dq = Duration("4.")               # LilyPond com ponto
dq.beats()                         # 1.5

# Duplo ponto (1.75x a duracao)
dd = Duration("h..")              # minima duplamente pontuada
dd = Duration("half", dots=2)     # equivalente

# Tercina (3 notas no espaco de 2)
t = Duration("quarter", tuplet=3)
t.beats()                          # ~0.667

Operacoes

a = Duration("quarter")
b = Duration("eighth")

c = a + b           # 3/8
d = a * 2           # 1/2 (= half)

a.rational()         # (1, 4)
a.numerator()        # 1
a.denominator()      # 4
a.beats()            # 1.0 (em seminimas)

MIDI ticks

Conversao entre Duration e ticks MIDI. O parametro ppqn (pulses per quarter note) define a resolucao — o padrao e 480:

# Duration -> ticks
Duration("quarter").midi_ticks()        # 480
Duration("eighth").midi_ticks()         # 240
Duration("half").midi_ticks()           # 960
Duration("quarter", dots=1).midi_ticks()  # 720 (seminima pontuada)

# Custom ppqn
Duration("quarter").midi_ticks(96)      # 96

# Ticks -> Duration
Duration.from_ticks(480)                # Duration("quarter")
Duration.from_ticks(240)                # Duration("eighth")
Duration.from_ticks(720)                # 3/8 (seminima pontuada)

Tempo — velocidade da musica

O Tempo define a velocidade em BPM (batidas por minuto) e converte duracoes em segundos reais:

from gingo import Tempo, Duration

# Por BPM
t = Tempo(120)
t.bpm()              # 120.0
t.marking()          # "Allegro"
t.ms_per_beat()      # 500.0 (ms por seminima)

# Por nome (marking)
t = Tempo("Adagio")
t.bpm()              # 70.0

# Converter duracao em segundos
t = Tempo(120)
t.seconds(Duration("quarter"))   # 0.5
t.seconds(Duration("half"))      # 1.0
t.seconds(Duration("eighth"))    # 0.25

Markings padrao

Marking BPM Carater
Largo ~45 Muito lento, solene
Adagio ~70 Lento, expressivo
Andante ~90 Caminhando
Moderato ~110 Moderado
Allegro ~130 Rapido, alegre
Vivace ~155 Vivo
Presto ~185 Muito rapido
# Converter entre BPM e marking
Tempo.bpm_to_marking(120.0)   # "Allegro"
Tempo.marking_to_bpm("Adagio") # 70.0

MIDI

Conversoes para o formato MIDI:

# Microsegundos por batida (meta-event MIDI 0xFF 0x51)
Tempo(120).microseconds_per_beat()    # 500000
Tempo(60).microseconds_per_beat()     # 1000000

# Criar Tempo a partir de microsegundos
Tempo.from_microseconds(500000)       # Tempo(120)
Tempo.from_microseconds(1000000)      # Tempo(60)

TimeSignature — compasso

O TimeSignature define quantas batidas por compasso e qual nota vale uma batida:

from gingo import TimeSignature

ts = TimeSignature(4, 4)     # 4/4 (compasso quaternario)
ts.beats_per_bar()           # 4
ts.beat_unit()               # 4 (seminima)
ts.signature()               # (4, 4)
ts.classification()          # "simple quadruple"
ts.common_name()             # "Common time"

# Outros compassos
ts34 = TimeSignature(3, 4)   # 3/4 (valsa)
ts68 = TimeSignature(6, 8)   # 6/8 (composto binario)

NoteEvent, ChordEvent, Rest — eventos

Eventos sao as unidades de uma Sequence. Cada evento tem uma duracao e (para notas e acordes) uma oitava:

from gingo import (
    Note, Chord, Duration,
    NoteEvent, ChordEvent, Rest,
)

# NoteEvent: nota + duracao + oitava
ne = NoteEvent(Note("C"), Duration("quarter"), 4)
ne.note()         # Note("C")
ne.octave()       # 4
ne.duration()     # Duration("quarter")
ne.frequency()    # 261.63 Hz
ne.midi_number()  # 60

# ChordEvent: acorde + duracao + oitava
ce = ChordEvent(Chord("Am"), Duration("half"), 4)
ce.chord()        # Chord("Am")
ce.octave()       # 4
ce.duration()     # Duration("half")
ce.note_events()  # lista de NoteEvents

# Rest: pausa
r = Rest(Duration("quarter"))
r.duration()      # Duration("quarter")

Ouvir eventos individuais

ne = NoteEvent(Note("E"), Duration("quarter"), 5)
ne.play()                    # toca na oitava e duracao do evento

ce = ChordEvent(Chord("Dm7"), Duration("half"), 4)
ce.play(waveform="triangle")

Sequence — composicoes

Uma Sequence organiza eventos em ordem, com tempo e compasso:

from gingo import (
    Note, Chord, Sequence, Tempo, TimeSignature,
    NoteEvent, ChordEvent, Rest, Duration,
)

# Criar sequencia
seq = Sequence(Tempo(120), TimeSignature(4, 4))

# Adicionar eventos
seq.add(NoteEvent(Note("C"), Duration("quarter"), 4))
seq.add(NoteEvent(Note("E"), Duration("quarter"), 4))
seq.add(NoteEvent(Note("G"), Duration("quarter"), 4))
seq.add(Rest(Duration("quarter")))
seq.add(ChordEvent(Chord("CM"), Duration("half"), 4))

# Informacoes
len(seq)              # 5 eventos
seq.total_seconds()   # duracao total em segundos
seq.bar_count()       # quantos compassos

# Acessar eventos
seq[0]                # NoteEvent (C)
seq[-1]               # ChordEvent (CM)

# Tocar e exportar
seq.play()
seq.to_wav("melodia.wav")

Exemplo: melodia com acordes

seq = Sequence(Tempo(100), TimeSignature(4, 4))

# Compasso 1: melodia
for note_name in ["C", "D", "E", "F"]:
    seq.add(NoteEvent(Note(note_name), Duration("quarter"), 4))

# Compasso 2: acorde + pausa
seq.add(ChordEvent(Chord("CM"), Duration("half"), 4))
seq.add(Rest(Duration("half")))

seq.play(waveform="triangle")

Exemplo: II-V-I em semininimas

seq = Sequence(Tempo(120), TimeSignature(4, 4))

seq.add(ChordEvent(Chord("Dm7"), Duration("quarter"), 4))
seq.add(ChordEvent(Chord("G7"), Duration("quarter"), 4))
seq.add(ChordEvent(Chord("C7M"), Duration("half"), 4))

seq.play(strum=0.04)

Transposicao

# Transpor toda a sequencia (notas e acordes)
seq_up = seq.transpose(5)    # sobe 5 semitons
seq_up.play()

Manipulacao

seq.remove(2)     # remove evento no indice 2
seq.clear()       # remove todos
seq.set_tempo(Tempo(140))
seq.set_time_signature(TimeSignature(3, 4))

MIDI — import e export

A Sequence pode ser exportada e importada como Standard MIDI File (SMF):

from gingo import (
    Sequence, Tempo, TimeSignature,
    NoteEvent, ChordEvent, Rest,
    Note, Chord, Duration,
)

# Criar sequencia
seq = Sequence(Tempo(120), TimeSignature(4, 4))
seq.add(NoteEvent(Note("C"), Duration("q"), 4))
seq.add(NoteEvent(Note("E"), Duration("q"), 4))
seq.add(NoteEvent(Note("G"), Duration("q"), 4))
seq.add(Rest(Duration("q")))
seq.add(ChordEvent(Chord("CM"), Duration("h"), 4))

# Exportar para MIDI (formato 0)
seq.to_midi("melodia.mid")

# Custom ppqn (resolucao)
seq.to_midi("melodia_96.mid", ppqn=96)

# Importar de MIDI (formato 0 ou 1)
seq2 = Sequence.from_midi("melodia.mid")
len(seq2)              # 5 eventos
seq2.tempo().bpm()     # 120

O que e preservado no roundtrip

  • NoteEvent: nota, oitava, duracao
  • ChordEvent: acorde (reconstruido via Chord.identify()), oitava, duracao
  • Rest: duracao (gaps entre notas viram pausas)
  • Tempo: meta-event de tempo MIDI
  • TimeSignature: meta-event de compasso MIDI

Formato

O export gera um Standard MIDI File formato 0 (single track) com:

  • Header chunk (MThd): formato, tracks, ppqn
  • Track chunk (MTrk): meta-events (tempo, time signature) + Note On/Off
  • Codificacao VLQ (Variable-Length Quantity) para delta times

CLI

O modulo de ritmo tem subcomandos para consulta rapida:

gingo duration quarter              # mostra fracao, beats, MIDI ticks
gingo duration quarter --tempo 120  # mostra duracao em segundos
gingo tempo 120                     # mostra marking, ms/beat, us/beat MIDI
gingo tempo Allegro --all           # mostra todos os markings
gingo timesig 6 8 --tempo 120      # mostra classificacao, duracao do compasso

Para ouvir objetos musicais pelo terminal, use --play:

gingo note C --play
gingo chord Am7 --play
gingo scale "C major" --play
gingo field "C major" --play