TidalCycles × vim-tidal Tutorial

概要

今回はライブコーディング環境であるTidalCyclesの仕組みや基本パターンを図解し、vim-tidalを有効に活かすためのTipsをチュートリアル形式でまとめていきます。

大まかな流れは以下の通りです。

  1. TidalCyclesの仕組みを図解する
  2. 基本パターンごとに図解&実践する
  3. ライブコーディングにオススメな.vimrc設定を紹介する

3番以外はvim-tidalの使用に依存した内容ではないため、TidalCyclesの基本的な仕組みをただ理解したい方にとっても参考になるかと思います。

TidalCycles × Vim

TidalCyclesを動作させるエディタとして、AtomやVisual Studio Code等がある中、なぜあえてVimを選ぶかというと、実践Vimと出会ったからです。

この本では、キャッチフレーズにあるように、思考のスピードで編集するためのTipsを数多く紹介してくれます。実際に数個のTipsを試してみるだけでも、かなり編集のスピードが上がりました。

このように”思考のスピードで編集することを可能にしているVim”ですが、かなりライブコーディングと相性がいいのではないかと考えています。

なぜならライブコーディングでは、リアルタイムにコードを書いて音楽を生成し、変化を加え続けます。そのため、まさに思考のスピードでコードを編集することが求められるからです。

このようなVimの力をライブコーディングで発揮できれば、より素晴らしいパフォーマンスができるようになるのではないかと考えているため、私はVimを選びます。

前提条件

当記事では、以下の前提条件を満たしている必要があります。

  • TidalCycles環境の構築
  • vim-tidalのインストール

TidalCycles環境の構築は、Installation – TidalCycles userbaseが参考にしてください。

vim-tidalのインストール手順は、tidalcycles/vim-tidal: Vim plugin for TidalCycles – GitHubのREADMEを参考にしてください。

また、Linux(Ubuntu)の場合、TidalCycles × vim-tidal環境を構築した記事を書いたことがあるので、もしよかったら参考にしてみてください。

UbuntuにTidalCycles + vim-tidalを導入し、Vim練習環境にする

環境

  • macOS Big Sur 11.1
  • TidalCycles 1.6.1
  • SuperCollider 3.10.3
  • vim-tidal 1.4.8
  • Vim 8.2.2375

TidalCyclesの基本構造

まずはTidalCyclesが音を扱う仕組みを図解していきます。

TidalCyclesは単体で音を生成することはできず、音響合成用プログラミング環境であるSuperCollider内のSuperDirtというサンプラーで音を生成します。

ではTidalcyclesは何をしているかというと、記述されたパターンに基づいて、生成される音を変幻自在に操っています。

SuperDirt & vim-tidalの起動

説明に入る前に、いつでもパターンを試せるように音を生成する準備だけしておきます。

sclangというSuperColliderのクライアントコマンドで、SuperColliderを起動します。

% sclang

するとsc3というプロンプトが表示されるので、SuperDirt.startと入力してEnterを押します。

*** Welcome to SuperCollider 3.10.3. *** For help type cmd-d.
sc3> SuperDirt.start

無事に起動できていれば、最後の行に以下のメッセージが表示されます。

SuperDirt: listening to Tidal on port 57120

つまり57120番ポートでSuperDirtがTidalCyclesの接続を待ち受けるということを意味しています。

そして最後に別のタブを開き、以下のコマンドを実行して、vim-tidalを起動させます。

% tidalvim

このようにtmuxによって画面分割され、上画面にVim、下画面にtidalプロンプトが表示されていれば起動成功です。

TidalCyles × SuperCollider

先ほどTidalCyclesは単体で音を生成することができず、SuperCollider内のSuperDirtと連携していると説明しました。これを図に表すと以下のようになります。

d1やd2で始まっている文字列は、TidalCyclesにおける実際のコードの記述です。図のようにSuperCollider内のSuperDirtとコネクションを確立して、相互に連携しています。

また、SuperDirtの中にはDirt-Samplesという様々な音のサンプルを集めたものがあります。ではTidalCyclesは具体的にどうやってDirt-Samples内の特定のサンプルを操るのでしょうか。

これを理解するために、Dirt-Samplesの実体を直接確認します。私の環境では以下のパスにDirt-Samplesが存在します。

% ll ~/Library/Application\ Support/SuperCollider/downloaded-quarks/Dirt-Samples
drwxr-xr-x   9 kengosuzuki  staff   288 10 27 00:23 808
drwxr-xr-x  27 kengosuzuki  staff   864 10 27 00:23 808bd
drwxr-xr-x  27 kengosuzuki  staff   864 10 27 00:23 808cy
drwxr-xr-x   7 kengosuzuki  staff   224 10 27 00:23 808hc
drwxr-xr-x   7 kengosuzuki  staff   224 10 27 00:23 808ht
drwxr-xr-x   7 kengosuzuki  staff   224 10 27 00:23 808lc
drwxr-xr-x   7 kengosuzuki  staff   224 10 27 00:23 808lt
drwxr-xr-x   7 kengosuzuki  staff   224 10 27 00:23 808mc
drwxr-xr-x   7 kengosuzuki  staff   224 10 27 00:23 808mt
drwxr-xr-x   7 kengosuzuki  staff   224 10 27 00:23 808oh
drwxr-xr-x  27 kengosuzuki  staff   864 10 27 00:23 808sd
...

このDirt-Samplesディレクトリ内にあるディレクトリには、それぞれ多種多様なサンプルファイルが格納されています。

これらの中から特定のサンプルを使用したい場合は、TidalCyclesで以下のように記述します。音を鳴らしてみたい場合は、記述した行でCtrl + eを行ってください(止めるときはCtrl + h)。

d1 $ sound "bd bd:2 bd:3 bd:4"

実際に鳴らしてみるとわかると思いますが、一つずつ異なる音色のサンプルが鳴って繰り返されます。このパターンが意味するのは、bdというサンプルディレクトリ内の上から1個目、2個目、3個目、4個目のサンプルファイルを使用するということです。bdディレクトリの中身は以下の通りです(一部省略)。

% ll Library/Application\ Support/SuperCollider/downloaded-quarks/Dirt-Samples/bd
-rw-r--r--  1 kengosuzuki  staff  25108 10 27 00:23 BT0A0A7.wav   <=== bd:0(bd)
-rw-r--r--  1 kengosuzuki  staff   8978 10 27 00:23 BT0A0D0.wav   <=== bd:1
-rw-r--r--  1 kengosuzuki  staff  15138 10 27 00:23 BT0A0D3.wav   <=== bd:2
-rw-r--r--  1 kengosuzuki  staff  44028 10 27 00:23 BT0A0DA.wav   <=== bd:3
-rw-r--r--  1 kengosuzuki  staff   9628 10 27 00:23 BT0AAD0.wav   <=== bd:4
-rw-r--r--  1 kengosuzuki  staff  44020 10 27 00:23 BT0AADA.wav   <=== bd:5
-rw-r--r--  1 kengosuzuki  staff   8740 10 27 00:23 BT3A0D0.wav   <=== bd:6
-rw-r--r--  1 kengosuzuki  staff  15924 10 27 00:23 BT3A0D3.wav   <=== bd:7
-rw-r--r--  1 kengosuzuki  staff  28594 10 27 00:23 BT3A0D7.wav   <=== bd:8
-rw-r--r--  1 kengosuzuki  staff  42880 10 27 00:23 BT3A0DA.wav   <=== bd:9
-rw-r--r--  1 kengosuzuki  staff   8706 10 27 00:23 BT3AAD0.wav   <=== bd:10
・・・・

このようにサンプルファイルにサンプル番号が対応づけられているので、TidalCyclesは特定のサンプルの番号を指定して自在に操ることができます。

TidalCyclesの書式

既にTidalCyclesのコード記述例が登場していますが、ここでは少し掘り下げて説明します。

TidalCyclesでは以下のような書式でコードを記述するわけですが、それぞれ名前と役割が割り振られています。

まずダブルクオーテーション(“)で囲まれている全体をパターンと呼びます(“bd bd bd bd”)。そしてそのパターンを構成するサンプル一つ一つをステップと呼びます(bd)。

ちなみによくシーケンスという単語がチュートリアルでたくさん登場すると思いますが、これは繰り返されるパターンのことをシーケンスと呼ぶと私は解釈しています。チュートリアルを読む限り、厳密に使い分けているようには思えなかったので、パターン自体のこともシーケンスと呼ぶのかもしれません。間違っていたらぜひご指摘お願いします。

Functionとは関数のことで、TidalCyclesには数多くの便利な関数が用意されています。有名なのは上図に登場している三つの関数かと思います。それぞれの関数の意味は以下の通りです。

関数説明
d1d1というコネクションを確立する。dの次に数値を指定する(d1~ d9)。
$右で評価したパラメータを左の関数に渡す。
sound記述したパターンが音を表すものであると定義する。

これらの関数の処理の流れとしては、まずsound関数の処理が行われた後、その結果を$がd1関数に渡します。

つまり、”bd bd bd bd”という音のパターンがd1コネクションを通じて、SuperDirtに伝わって処理され、音が生成されるわけです。

以上の内容は以下のサイトを参考にしました。もっと詳しく知りたい方はぜひこちらをチェックして見てください。

All the functions – TidalCycles userbase

sound – TidalCycles userbase

What is a pattern? – TidalCycles userbase

Understanding the $ – TidalCycles userbase

Cycle

TidalCyclesの核となる部分、それが”Cycle”です(カタカナだとカッコ悪いので訳しません)。

Cycleとは、TidalCyclesにおけるループの時間のことです。音を鳴らしていない時でも、Cycleはずっとグルグルグルグルと動作しています。

例えば以下のパターンにおけるCycleの状態を図解してみます。4つのbdがひたすらループされるだけの単純なパターンです。

d1 $ sound "bd bd bd bd"

まず、左図にCycle、右図に均等に4分割したパターンを表しています。音を再生するときは、この二つの図を合体してスタートさせるというイメージです。

Ctrl + eで実行してからの1Cycle分の流れは以下の通りになります。左上の番号はステップ数を表しています。

このように1Cycle分の時間を、記述されたパターンに基づいて分割します。それをグルグルグルグルとループさせているわけです。

まだパッとこないと思うので、もっと単純なパターンから複雑なパターンまでそれぞれCycleを図解してみます。また、以降から図で表したCycleをCycle図とします。

以下のパターンはステップが一つだけの単純なパターンです。

d1 $ sound "cp"

これをCycle図で表すとこのようになります。

ステップが1つしかないので、1Cycleでcpが1回鳴るだけです。これは分かりやすいと思います。

では以下のようにステップを3つに増やしたパターンのCycle図はどうなるでしょうか。

d1 $ sound "bd bd bd"

1Cycle分の時間を三つに均等に分割するので、このように表せます。

つまり三連符みたいな感じです。これがループで鳴り続けることになります。

では最後に8つのステップ数からなるパターンの例をみていきます。

d1 $ sound "bd bd bd bd hh hh hh hh"

これをCycle図で表すとこのようになります。

1Cycle分の時間を8つに均等に分割しています。ここで注意するべきことは、ステップ数が増えたからといって、1Cycle分の時間が増えるわけではないということです。

cpsやbpsで1Cycle分の時間を変更することはできますが、特に何もしないならば、1Cycle分の時間は常に一定です。

以上のようにCycle図を用いて説明してきましたが、こんな図がなくても理解できると思う方も多いと思います。しかし、実際に本格的なパターンを記述した際は、なぜこのようなリズムになるのか疑問が次々と湧いてくるはずです。

そこで思考を止めて、感覚で乗り切る方法もアリかと思いますが、より素晴らしいパフォーマンスができるようにするためには、自分の記述したパターンを常に把握している必要があると思います(例えば、これを記述するとどうリズムが変化するか予想できる等)。

そのためにもCycle図を用いて日頃から気になったパターンを分析してみることで、生成されるリズムへの理解が深まるのではないかと考えています。

これから紹介する基本パターンは、実践的なパターンとはいえないですが、今紹介したパターンよりも複雑ではあるので、ぜひCycle図を描きながら試してもらえば思います。

基本パターンの図解&実践

ここからは上述したCycle図を用いながら、基本パターンを図解&実践します。

Cycle図だけで理解することは難しいので、基本パターンを実際に鳴らしながら、Cycle図を見てもらえるとより理解が深まるかと思います。

複数のシーケンス

複数のシーケンスを同時に演奏させたい場合は、以下のように複数のコネクションを使用します。

d1 $ sound "bd sn:1 bd sn:2"

d2 $ sound "hh hh hh hh"

d3 $ sound "~ ~ ~ cp:3"

この例の場合、d1、d2、d3の3つのコネクションを使用して、同時に音を生成しています。

Cycle図でそれぞれのパターンを表すと以下のようになります。

それぞれのコネクションで何をしているのか分かりやすくするために、Cycleをコネクションごとに用意して図解しています。実際は以下のように1つのサイクル上で行われます。

複数のコネクションを使用する際には、細かい点に注意する必要があります。

例えばコネクション間は1行空けなければなりません。

d1 $ sound "bd sn:1 bd sn:2"
=========(1行空ける)=========
d2 $ sound "hh hh hh hh"

1行空けないとどうなるかというと、まとめて1つのコネクションとして扱われるようになってしまいます。

また、シーケンスを再生する場合は、以下のようにそれぞれのコネクション上にて1回ずつ実行してあげる必要があります。

d1 $ sound "bd sn:1 bd sn:2"    <=== Ctrl + e

d2 $ sound "hh hh hh hh"        <=== Ctrl + e

d3 $ sound "~ ~ ~ cp:3"         <=== Ctrl + e

サイレンス

特定のシーケンスの再生を止めたい場合は、コネクション名 + silenceという行を用意し、Ctrl + eで実行します。

例えばd1、d2、d3コネクションを用意し、同時演奏していたとします。

d1 $ sound "bd sn:2 bd sn:2"

d2 $ sound "hh*8"

d3 $ sound "bottle"

d1 silence

そこで、d1 silenceを実行してあげることで、d1だけがストップします。

もし全部の演奏をストップさせたい場合は、hushを使用します。

hush

vim-tidalの場合は、ctrl + hを押すことでも全ての演奏をストップさせることができます。楽なので個人的にはこちらの方法をオススメします。

サブシーケンス

シーケンスの中にさらにシーケンスを作成することができます。これをサブシーケンスと呼びます。サブシーケンスは以下のように[]で括ることで使用できます。ここではサブシーケンスの中にサブシーケンスがあるという複雑な入れ子構造にしています。

d1 $ sound "[db [db db]] sn [db db [db [db db]]] [sn sn]"

このパターンをCycleはどのように扱っているのでしょうか。段階ごとにCycle図を用いて解説します。

複雑なパターンはまず、大きな4つのステップから構成されていると考えることが重要です。そこから一段階ずつ細かくしていくことで、混乱せずにパターン全体を把握できるようになります。

左図では例のパターンを、”[bd [bd bd]]”、”sn”、”[bd [bd [bd bd]]]”、”[sn sn]”という4つのステップに大きく分割しています。次に右図では、これらの4つのステップをさらに一段階細かく分解しています。例えば”[bd [bd bd]]”は”bd”と”[bd bd]”という2つのステップから構成されていると考え、分割します。

このように一段階ずつ[]を外し、丁寧に細かく分割していくと、最終的には以下の右図になります。

ポリリズム

TidalCyclesではポリリズムを表現することもできます。以下のように, で区切ります。

d1 $ sound "[bd bd bd, cp cp cp cp]"

こうすることで、”bd bd bd”と”cp cp cp cp”が別のパートとして認識され、リズムが異なるのに一つのコネクション上で同時に実行できます。つまり、以下のように二つのコネクションでできることを一つのコネクション上で実現させているわけです。

d1 $ sound "bd bd bd"

d2 $ sound "cp cp cp cp"dd

これをCycle図で表すとこのようになります。

スタート地点は同じですが、1Cycleを3分割したbdのリズムと、4分割にしたcpのリズムが同時並行で鳴り続けます。

spc(step per cycle)

spcとは、1Cycleごとに1step変更して再生するということを意味します。以下のようにspcを使用する箇所を<>で括ります。

d1 $ sound "bd <bass bass:1 bass:2> bd sn:1"

この場合、1Cycle目では”bd bass bd sn:1″、2Cycle目では”bd bass:1 bd sn:1″、3Cycle目では”bd bass:2 bd sn:1″という感じです。4Cycle目以降は最初に戻っての繰り返しです。

これをCycle図で表すと以下のようになります。

Speed Up & Speed Down

TidalCyclesではステップ数を増減させることでSpeed Up & Speed Downができます。

まずはSpeed Upです。これはステップの後に*と数値を指定してあげることで、その数値分だけステップを繰り返します。

d1 $ sound "bd*4"

このパターンでは、bdを4つ繰り返します。つまり、”bd*4″ = “bd bd bd bd”ということになるわけです。Cycle図はこのようになります。

“bd”だけのパターンよりも”bd*4″というパターンの方が、1Cycleを分割するステップ数が増えるので、Speed Upしたということになります。

それでは次にSpeed Downを説明します。Speed Downをするには/と数値を指定してあげます。そうすると、数値分のCycleを贅沢に使って再生されます。

つまり以下のパターンでは、”bd sn”というパターンを2Cycle分で再生してくださいという意味になります。

d1 $ sound "[bd sn]/2"

Cycle図で表すとこのようになります。

なかなか感覚が掴めない場合は、色々なパターンでSpeed Downさせて数をこなすしかないです。

次に以下のパターンでは4Cycle分で”bd sn”というパターンが再生されます。

d1 $ sound "[bd sn]/4"

これをCycle図で表すとこのようになります。

4Cycleを贅沢に使って再生されるので、Cycle2とCycle4では何も再生されません。このパターンで/4するとかなりSpeed Downすると思います。

Vimのカスタマイズ

ここからはライブコーディングに活かせそうなオススメの.vimrc設定を紹介していきます。

Vimには操作性や視認性の向上のために、様々なオプションが用意されています。また、プラグインという拡張機能も利用することが可能です。

ライブコーディングに限らず、編集しやすい、見やすいといった感覚は非常に重要なものであると考えているため、カスタマイズすることを強く推奨します。

本当はTidalCyclesで活かせそうなVim操作も紹介したかったのですが、まだVim初心者であるため、ここでは設定だけの内容にとどめています。次回以降、操作編としてまとめようかと思います。

~/.vimrc

Vimのカスタマイズは、自身のホームディレクトリにある.vimrcファイルを編集します。

Vimはほとんどの環境でデフォルトでインストールされていると思います。しかし、.vimrcファイルはカスタマイズしていない限り存在しないので、新たに作る必要があります。

私は以下のように.vimrcファイルを編集しています。

% cat ~/.vimrc

set noswapfile
set showcmd
set wildmenu
set backspace=2
set whichwrap=b,s,h,l,<,>,[,],~
set title
set fileencodings=utf-8
set relativenumber
set laststatus=2
set list listchars=tab:▸▸,eol:$
set smartindent
set ts=2
set shiftwidth=2
set cursorline
set hlsearch
set incsearch
set ignorecase
set smartcase
set showmatch
set matchtime=1

set termguicolors
syntax on
colorscheme iceberg
hi LineNr guifg=#5e658b
hi SpecialKey guifg=#6b7089

nnoremap Y y$
nnoremap + <C-a>
nnoremap - <C-x>

call plug#begin()
Plug 'tidalcycles/vim-tidal'
Plug 'itchyny/lightline.vim'
call plug#end()

let g:lightline = {'colorscheme': 'iceberg'}

今回はこれらのオプションやプラグインを一つずつ紹介するわけではなく、ライブコーディングに活かせそうなものを5つ厳選して紹介します。

① set relativenumber

1つ目はrelativenumberオプションです。これは現在の行から相対的に行番号を割り当ててくれます。

つまり今の自分のカーソル位置が常に0行目になります。この行番号があることで数え間違えることなく、目的の行へ瞬時に移動することができます。

どこかしらの行に移動したい場合は、数字+j or kを押すだけで瞬時に移動できます。

例えば、上の画像のようにd3の行にカーソルがあるとします。この時、d1の行にカーソルを持っていきたい場合は4kと入力し、d5の行にカーソルを持っていきたい場合は、4jと入力します。kやjを連打することでも可能ですが、このように数行離れている場合は、キーストロークが少なくなるので編集スピードが速くなります。

行番号を付けるオプションは他にもnumberオプションがありますが、こちらはファイルの先頭から絶対的に行番号を割り当てます。どちらがいいかは好みかなと思います。

② set showmatch

showmatchは入力した括弧に対応した括弧を一瞬ハイライトしてくれるオプションです。

このように入れ子構造のパターンを記述する際は、どの括弧同士が対応しているのか把握することが大切です。

括弧が足りないまま実行してエラーが発生してしまうことを防ぐために、入力するたびにハイライトしてくれる機能は欠かせないです。

③ set matchtime=1

matchtimeに数字を指定してあげることで、上述したshowmatchのハイライトスピードを調節することができます。デフォルトではmatchtime=5で、これは0.1秒×5を意味します。

上述したshowmatchの例ではすでにmatchtime=1が適用されているのですでに速いですが、適用しないとこれくらいのスピードになります。

ハイライトされる瞬間は操作が効かないので、編集スピードをあげるならば限りなく短い時間に設定してあげるべきです。matchtime=1(0.1秒×1)のスピードだとこうなります。

④ nnoremap + <C-a>

ここからはキーマッピングの設定です。Vimには現在のカーソル位置移行にある数字を加算・減算することができます。やり方としては”数値 + <C-a>”を入力するのですが、キー入力に時間がかかって不便です。

そこで、+を入力しただけで<C-a>が入力されたことになるように、キーをマッピングします。こうすることで、簡単に数字を加算することができます。

わざわざ数値にカーソルを合わせなくても、現在のカーソル位置から最初に見つかった数値に勝手に移動して、加算してくれます。以下のようにサンプルの番号を変える時に使えそうです。

ノーマルモードのまま変化を加えられるのでありかなと思います(rキー+数字でいい気もしますが)。

⑤ nnoremap – <C-x>

上述した加算機能の減算バージョンです。同じようにマッピングすることで、ノーマルモードのまま変化を加えることができます。

以下の例ではサンプルの番号を3ずつ減らしています。

最後に

vim-tidalを活かすためのチュートリアルといいながら、実際はTidalCyclesの基本構造とパターンの図解がメインになってしまいました。

なので次回以降、Vimの操作編としてTidalCyclesで活かせそうなものを厳選して紹介しようかと考えています。

間違えている解釈があった場合は、遠慮なくコメントで指摘してくださるととても喜びます。

ぜひよろしくお願いいたします。

Comments

Copied title and URL