# スレッド

それでは、強烈なベースラインとかっこいいビートを作った場合、どのようにしてそれらを同時に鳴らしたらいいでしょう？ 1つの回答としては、手動でそれらを同時に鳴らす事です ― まず、いくつかのベースを演奏し、その後にいくつかのドラム、またその後にベースというように…しかしながら、すぐに沢山の楽器を処理することが難しいことに気づくでしょう。

もし、Sonic Piが自動的にそれらを作り出せるとしたらどうでしょう？ thread（スレッド）と呼ばれる特別な命令によってそれが可能になります。

## 無限の繰り返し

例を単純にするために、以下のコードを強烈なベースラインとかっこいいビートだと思ってください。

    loop do
      sample :drum_heavy_kick
      sleep 1
    end
    loop do
      use_synth :fm
      play 40, release: 0.2
      sleep 0.5
    end

ループはプログラムのブラックホールのようだと以前にお話しました。一度ループを入れると、stopボタンを押さない限り、そこから抜け出せなくなります。では、どうしたら同時にふたつの繰り返しを演奏することが出来るでしょう？ 私たちは、同時にそれらのコードをタイミングを合わせスタートさせるようにSonic Piに伝えなくてはいけません。これがスレッドを使った解決方法なのです。

## スレッドを使った解決方法

    in_thread do
      loop do
        sample :drum_heavy_kick
        sleep 1
      end
    end
    loop do
      use_synth :fm
      play 40, release: 0.2
      sleep 0.5
    end

はじめのdo/endブロックを`in_thread`で囲むことで、次にくるdo/endブロックをぴったりと同時にループさせるようにSonic Piに命令することができます。それではドラムとベースラインを同時に鳴らすことに挑戦してみましょう！

そして、もう1つの音を追加したいので、先ほどのように繰り返しを入れてみましょう。

    in_thread do
      loop do
        sample :drum_heavy_kick
        sleep 1
      end
    end
    loop do
      use_synth :fm
      play 40, release: 0.2
      sleep 0.5
    end
    loop do
      use_synth :zawa
      play 52, release: 2.5, phase: 2, amp: 0.5
      sleep 2
    end

前と同じ問題が出てきましたね。`in_thread`によって最初の繰り返しと2つ目の繰り返しが同時に演奏されています。しかし3番目の繰り返しが演奏されません。ですので以下のように、もう1つのスレッドが必要となります。

    in_thread do
      loop do
        sample :drum_heavy_kick
        sleep 1
      end
    end
    in_thread do
      loop do
        use_synth :fm
        play 40, release: 0.2
        sleep 0.5
      end
    end
    loop do
      use_synth :zawa
      play 52, release: 2.5, phase: 2, amp: 0.5
      sleep 2
    end

## スレッドとして実行する

驚くべきことに`Run`ボタンを押すということは、実際にはコードを実行するための新しいスレッドを作っていることになります。そのために複数回`Run`ボタンを押すことは、互いの上に音を階層化することになります。`Run`それ自体がスレッドであるために、音を自動的に紡ぎ合わせることになるのです。

## スコープ

Sonic Piをマスターしようとするとき、スレッドが、音楽のために最も重要な構成要素であることに気がつくでしょう。スレッドの重要な役割の1つとして、他のスレッドから現在の設定を分離することがあります。どういうことかというと、例えば`use_synth`を使ってシンセの種類を変更する時、現在のスレッド中にあるシンセだけを変更します。他のどのスレッドも変更しません。そのことを確認してみましょう。

    play 50
    sleep 1
    in_thread do
      use_synth :tb303
      play 50
    end
    sleep 1
    play 50

真ん中の音だけがほかのものと違うことに注目してみましょう。`use_synth`の宣言はスレッドの中だけに影響し、スレッドの外にあるものには影響しません。

## インヘリタンス（継承機能）

`in_thread`を使って新しいスレッドを作ると、新しいスレッドには現在のスレッドの全ての設定が自動的に継承されます。ではその機能を見てみましょう。

    use_synth :tb303
    play 50
    sleep 1
    in_thread do
      play 55
    end

2番目の音符は、それが別のスレッドから再生されたにもかかわらず`:tb303`シンセで演奏されることに注目してください。`use_*`関数を使ったいかなる設定も同様に作用するでしょう。

スレッドが新規に作成されると、元のスレッドからすべての設定を継承しますが、スレッド作成以降の変更を共有することはありません。

## スレッドの命名

最後に、スレッドに名前つける機能を覚えましょう。

    in_thread(name: :bass) do
      loop do
        use_synth :prophet
        play chord(:e2, :m7).choose, release: 0.6
        sleep 0.5
      end
    end
    in_thread(name: :drums) do
      loop do
        sample :elec_snare
        sleep 1
      end
    end

このコードを実行した際、ログ画面を見てみましょう。ログの中にスレッドの名前が表示されることを確認できましたか？

    [Run 36, Time 4.0, Thread :bass]
     |- synth :prophet, {release: 0.6, note: 47}

## 1つの名前につき1つのスレッド

名前付きのスレッドについて知っておくべき最後のひとつは、ある名前の付いたスレッドは同時に1つだけ実行されることです。では以下を見てみましょう。次のコードを考えてみてください。

    in_thread do
      loop do
        sample :loop_amen
        sleep sample_duration :loop_amen
      end
    end

Bufferに上のコードを貼り付けて、`Run`ボタンを押します。数回押してみましょう。複数のアーメン・ブレイクが不協和音として反復されるでしょう。もういいですよね。`Stop`ボタンを押しましょう。

この動作はこれまで何度も見てきました。Runボタンを押すと、既に鳴っているサウンドのレイヤーの一番上にサウンドを追加します。このためループが含まれている場合、Runボタンを3回押すと、3つのレイヤーが一斉に再生されます。

ただし、名前付きのスレッドでそれは異なります。

    in_thread(name: :amen) do
      loop do
        sample :loop_amen
        sleep sample_duration :loop_amen
      end
    end

このコードでRunボタン複数回、押してみてください。ひとつのアーメン・ブレイクのループのみが聞こえるでしょう。そして下記のテキストがログ画面に表示されます。

    ==> Skipping thread creation: thread with name :amen already exists.

Sonic Pi は、`:amen`という名前があるスレッドが既に存在するため、別のものを作成しませんと伝えています。

この動作はすぐに使う必要性はないように思えますが、ライブコーディングを始めると、非常に便利なものになるでしょう。