text processing utilities

Pi&More 10 - Pi Drums

Sonic Pi kann durch das Abspielen von Samples als Drum-Computer eingesetzt werden. Musiker können so eigene Tracks zum Üben erzeugen, es macht aber auch einfach Spaß eigene Rhythmen auszuknobeln. Im Vortrag wird gezeigt, wie man mit Audacity und SoX neue Samples schnell vorbereitet, Youtube als Quelle für Backing-Tracks nutzt und die Daten in Sonic Pi integriert. Ein Pi mit Hifiberry-Ergänzung sorgt für die Akustik.

Vorbereitung der Samples

Sample-Quellen: FREE DRUM SAMPLES PACK, US Saudade Kit DEMO, Matt Starrs "The Atrium Sample Pack"

Download von Audio-Daten mit youtube-dl

youtube-dl -x --audio-format wav 'https://www.youtube.com/watch?v=Jpn6P08ojnY'

Grobes Editieren mit Audacity

Audacity

Ausschnitt grob markieren und per "Datei" → "Ausgewähltes Audio exportieren" als WAV speichern.

Entfernen der Stille mit SoX

#!/bin/sh
for file in *.wav;
do
    #echo $file;
    sox $file s_$file silence 1 0 1% 1 0 0.01%
done

Dieses Skript entfernt die Stille in allen Wave-Dateien und speichert das Ergebnis mit "s_ " - Präfix. Diese Dateien werden in Sonic-Pi verwendet.

Track "Stoner"

Backing Track: https://www.youtube.com/watch?v=IoaSj8mbq5w (Wave-Datei, 24 MB)

use_bpm 130

$spath = "/home/pi/sonicpi/drum_samples"

# https://www.youtube.com/watch?v=IoaSj8mbq5w
sample "/home/pi/sonicpi/Drumless Backing Track Stoner Rock (130 BPM).wav", amp: 0.5
sleep 8

def pattern1()
  tick_reset
  32.times do
    sample  $spath, [ "12.20Inch.Crash.1", "12.20Inch.Crash.2"].choose,
      amp: 2.5,  finish: 0.1
    puts "p1"
    sleep 0.5
    sample $spath, "Snare.Top.2", amp: 1.8
    sleep 0.5
    if (tick>30) then
      sample $spath, "rude_20_ride-crash_edge", amp: 0.8,  finish: 0.3
    end
    sample $spath, "bass_drum",  decay: 0.05, amp: 1.5
  end
end

def pattern2()
  tick_reset
  
  32.times do
    sample $spath, choose(["High.Hat.Loose.1","High.Hat.Loose.2"]), amp: 2.5
    puts "p2"
    mtick = tick
    puts mtick
    
    sleep 0.5
    sample $spath, "bass_drum",  decay: 0.06, amp: 1.5
    sleep 0.25
    sample $spath, "bass_drum",  decay: 0.06, amp: 1.5
    sleep 0.25
    if mtick > 6  and (mtick % 4==0 ) then
      in_thread do
        if (mtick % 3 ==0) then
          sample $spath, "12.20Inch.Crash.2", amp: 3
        end
        
        puts mtick
        sample $spath, "bass_drum",  decay: 0.06, amp: 1.5
        sleep 0.25
        sample $spath, "bass_drum",  decay: 0.06, amp: 1.5
        sleep 0.5
        sample $spath, "bass_drum",  decay: 0.06, amp: 1.5
        
        sample $spath, choose(["Snare.Top.1", "Snare.Top.2"]), amp: 3
        sleep 0.2
        sample $spath, ["13.22Inch.Crash.1", "13.22Inch.Crash.3"].choose,
          amp: 4, pan: [-1,1].choose
      end
    end
    
    sample $spath, "Snare.Top.1",  amp: 2
    sleep 0.5
    sample $spath, "bass_drum",  decay: 0.06, amp: 1.5
    sleep 0.5
    
  end
end

def pattern4()
  tick_reset
  
  32.times do
    
    sample :drum_cymbal_pedal,  amp: 0.8
    puts "p4"
    puts look
    
    if (look>20 ) then
      sample $spath, ["12.20Inch.Crash.1","12.20Inch.Crash.2" ].choose,
        amp: 3, pan: [-1,1].choose, amp: 3, finish: 0.6
    end
    
    if ( look % 2==0 ) then
      sample $spath, "Snare.Top.2", amp: 2
    end
    sample $spath, "bass_drum",  decay: 0.06, amp: 1.5
    sleep 0.5
    sample $spath, "bass_drum",  decay: 0.06, amp: 1.5
    sleep 0.5
  end
end

pattern2()

pattern1()

pattern2()

pattern4()

pattern2()

def pattern5()
  tick_reset
  
  16.times do
    sample $spath, choose(["High.Hat.Loose.1","High.Hat.Loose.2"]), amp: 2.5
    puts "p5"
    puts tick
    
    sample $spath, "bass_drum",  decay: 0.06, amp: 1.5
    if (look>0 and look%2==0) then
      sleep 0.25
      2.times do
        sample $spath, "bass_drum",  decay: 0.06, amp: 1.5
        sleep 0.25
      end
    else
      sleep 0.75
    end
    
    sample $spath, "bass_drum",  decay: 0.06, amp: 1.5
    sleep 0.25
    
    sample $spath, "Snare.Top.1",  amp: 3
    sleep 0.5
    if (look>12 and look%2==0) then
      sample $spath, ["12.20Inch.Crash.1","12.20Inch.Crash.2" ].choose,
        amp: 3, pan: [-1,1].choose
    end
    sample $spath, "bass_drum",  decay: 0.06, amp: 1.5
    sleep 0.5
  end
end

pattern5()

So hört es sich an:

Track "Thrash"

Backing Track: https://www.youtube.com/watch?v=nCYEX7SMAY0 (Wave-Datei, 42 MB)

use_bpm 190

$spath = "/home/pi/sonicpi/drum_samples"

# https://www.youtube.com/watch?v=nCYEX7SMAY0
sample "/home/pi/sonicpi/190_Thrash_Metal_Drumless_Backing_Track.wav", amp: 0.7
sleep 4

def pattern0()
  tick_reset
  
  16.times do
    puts "p0"
    sample $spath, "High.Hat.Closed.1", amp: 3
    if tick>8 then
      sleep 0.5
      sample $spath, "High.Hat.Loose.1", amp: 3, finish: 0.2
      sleep 1.0
      sample $spath, "High.Hat.Loose.2", amp: 3, finish: 0.2
      sleep 0.5
    else
      sleep 2
    end
  end
end

pattern0()

def pattern1()
  tick_reset
  32.times do
    sample  $spath, [ "12.20Inch.Crash.1", "12.20Inch.Crash.2"].choose,
      amp: 2.5, finish: 0.07
    
    puts "p1"
    if (tick>30) then
      sleep 0.5
      sample $spath, "Snare.Top.2", amp: 1.8
      sleep 0.2
      sample $spath, "Snare_Center_v15_01", amp: 1.8
      sleep 0.2
      sample $spath, "rude_20_ride-crash_edge", amp: 0.8,  finish: 0.3
      sample $spath, "Snare_Rimshot_v01_01", amp: 1.8
      sleep 0.1
    else
      sleep 0.5
      sample $spath, "Snare.Top.2", amp: 1.8
      sleep 0.5
    end
    sample $spath, "bass_drum",  decay: 0.05, amp: 1.5
  end
end

pattern1()

def pattern2()
  tick_reset
  
  32.times do
    sample $spath, choose(["High.Hat.Loose.1","High.Hat.Loose.2"]), amp: 2.5
    puts "p2"
    mtick = tick
    puts mtick
    
    sleep 0.5
    sample $spath, "bass_drum",  decay: 0.06, amp: 1.5
    sleep 0.25
    sample $spath, "bass_drum",  decay: 0.06, amp: 1.5
    sleep 0.25
    
    if mtick > 12  and (mtick % 4==0 ) then
      in_thread do
        if (mtick % 3 ==0) then
          sample $spath, "12.20Inch.Crash.2", amp: 3
        end
        
        sample $spath, "bass_drum",  decay: 0.06, amp: 1.5
        sleep 0.25
        sample $spath, "bass_drum",  decay: 0.06, amp: 1.5
        sleep 0.5
        sample $spath, "bass_drum",  decay: 0.06, amp: 1.5
        sample $spath, choose(["Snare.Top.1", "Snare.Top.2"]), amp: 3
        sleep 0.2
        sample $spath, ["13.22Inch.Crash.1", "13.22Inch.Crash.3"].choose,
          amp: 4, pan: [-1,1].choose
      end
    end
    
    sample $spath, "Snare.Top.1",  amp: 2
    sleep 0.5
    sample $spath, "bass_drum",  decay: 0.06, amp: 1.5
    sleep 0.5
  end
end

def pattern4(lastrun=0)
  tick_reset
  
  (64-(lastrun*48)).times do
    
    sample :drum_cymbal_pedal,  amp: 0.8
    puts "p4"
    puts tick
    
    if (look>6 or lastrun==1 and look%5==0) then
      sample $spath, ["12.20Inch.Crash.1","12.20Inch.Crash.2" ].choose,
        amp: 3, pan: [-1,1].choose, amp: 3.5, finish: 0.4
    end
    if (lastrun==1 or look>24) then
      sample $spath, ["High.Hat.Loose.1","High.Hat.Loose.2" ].choose,
        amp: 2.5, finish: 0.4
    end
    
    if ( look % 2==0 or lastrun==1) then
      sample $spath, "Snare.Top.2", amp: 2
    end
    sample $spath, "bass_drum",  decay: 0.06, amp: 1.5
    sleep 0.5
    if (look<63 or (lastrun==1 and look<15)) then
      sample $spath, "bass_drum",  decay: 0.06, amp: 1.5
    end
    sleep 0.5
  end
end

def pattern3()
  tick_reset
  incamp=0.2
  32.times do
    sample :drum_cymbal_pedal,  amp: 0.8
    puts "p3"
    puts tick
    if (look>16) then
      incamp+=0.2
      if (look>23) then
        sample $spath, "rude_18_thin_crash_edge", amp: 0.4
      else
        sample $spath, "High.Hat.Loose.1",  amp: incamp, finish: 1
      end
    end
    if (look>0 && look%2==0) then
      sample $spath, "Snare.Top.1", amp: 3
    end
    
    sleep 0.5
    sample $spath, "bass_drum",  decay: 0.06, amp: 1.5
    sample $spath, "Snare.Top.With.Butt.End.Of.Stick.2", amp: 2
    sleep 0.5
    sample $spath, "bass_drum",  decay: 0.06, amp: 1.5
    
  end
end

pattern2()

pattern1()

pattern2()

pattern4()

pattern3()

pattern1()

pattern2()

pattern1()

pattern2()

pattern1()

pattern4()

def pattern5()
  tick_reset
  
  24.times do
    sample $spath, choose(["High.Hat.Loose.1","High.Hat.Loose.2"]), amp: 2.5
    puts "p5"
    puts tick
    
    sample $spath, "bass_drum",  decay: 0.06, amp: 1.5
    if (look>12 and look%2==0) then
      sleep 0.25
      2.times do
        sample $spath, "bass_drum",  decay: 0.06, amp: 1.5
        sleep 0.25
      end
    else
      sleep 0.75
    end
    
    sample $spath, "bass_drum",  decay: 0.06, amp: 1.5
    sleep 0.25
    
    sample $spath, "Snare.Top.1",  amp: 3
    sleep 0.5
    if (look>12 and look%2==0) then
      sample $spath, ["12.20Inch.Crash.1","12.20Inch.Crash.2" ].choose,
        amp: 3, pan: [-1,1].choose
    end
    sample $spath, "bass_drum",  decay: 0.06, amp: 1.5
    sleep 0.5
  end
end

pattern5()

pattern4(1)

So hört es sich an:

pi and more logoPi&more 10 Workshop

Samples + Skripte

pi_drums.zip (8 MB)

More information:

Pi & more
Tupel7