Muzyka algorytmiczna

Zajęcia 10 (2025-04-30)

Zadanie

Na kolejne zajęcia (2025-05-07)

Przygotowanie krótkiego utworu (~1min) w środowisku Sonic Pi, spełniającego następujące wymagania:

MIDI

Za tworzenie i wysyłanie komunikatów MIDI odpowiada rodzina funkcji midi*. Każda z nich akceptuje parametr port:, który pozwala na wybranie docelowego portu. Domyślną wartością jest * wysyłająca na wszystkie porty.

10.times do |i|
  midi :c4, vel: i * 10, sustain: 1
  sleep 1
end
use_real_time

in_thread do
  use_midi_defaults port: "timidity_timidity_port_0_136_0"
  midi_pc 24 # AcousticGuitarNylon

  loop do
    midi scale(:c4, :major).tick
    sleep 1
  end
end

in_thread do
  use_midi_defaults port: "timidity_timidity_port_1_136_1"
  midi_pc 19 # Church Organ
  loop do
    midi scale(:c2, :major).tick
    sleep 4
  end
end

Przykładowy program rozbijający kanały MIDI na osobne porty

midi_all_notes_off

input = "midi_through_midi_through_port-0_14_0"
out1 = "midi_through_midi_through_port-1_14_1"
out2 = "midi_through_midi_through_port-2_14_2"
out3 = "midi_through_midi_through_port-3_14_3"

live_loop :chan1 do
  use_real_time
  n, vel = sync "/midi:#{input}:1/note_on"
  midi_note_on n, vel, port: out1
end

live_loop :chan2 do
  use_real_time
  n, vel = sync "/midi:#{input}:2/note_on"
  midi_note_on n, vel, port: out2
end

live_loop :chan3 do
  use_real_time
  n, vel = sync "/midi:#{input}:3/note_on"
  midi_note_on n, vel, port: out3
end

Przykładowy program odbierający komunikaty MIDI

port = "midi_through_midi_through_port-0_14_0"

synths = Hash.new

define :release do |s|
  in_thread do
    control s, amp: 0, amp_slide: 0.1
    sleep 0.2
    s.kill
  end
end


live_loop :receive do
  use_real_time
  n, v = sync "/midi:#{port}:*/note_on"
  if v == 0 then
    if synths[n]
      release synths[n]
      synths[n] = nil
    end
  else
    if synths[n]
      release synths[n]
      synths[n] = nil
    end
    synths[n] = synth :tech_saws, note: n, sustain: 99999, amp: 0.3
  end
end

OSC (Open Sound Control)

W trakcie zajęć 2024-10-30 znaleziono kilka problematycznych zachowań Sonic Pi w ramach komunikacji OSC. Komunikaty nie były zawsze przesyłane pomiędzy komputerami, na niektórych udawało się wyłącznie nadawać, na innych wyłącznie odbierać. Wykorzystywanie OSC uznawane jest przez to jako eksperymentalne.

Podstawowa komunikacja

Komunikaty OSC odbierane są poprzez funkcję sync; wysyłane poprzez funkcje osc, osc_send.

Lokalna komunikacja MIDI

use_real_time

live_loop :receiver do
  n = sync "/osc:*:4560/note"
  play n
end

live_loop :sender do
  osc_send "localhost", 4560, "/note", :c4
  print "send"
  sleep 1
end