2017/08/20

Ardourクイックスタート

Ardourクイックスタート
Ardour自由でオープンなソフトウェア(GPLv2)として配布されていることが特徴のDAWです。 この文章ではFedora26にArdour5をインストールして、基本的な使い方を紹介します。
ArdourクイックスタートはGitHub Pagesで読むこともできます。

1 インストール

Fedora26の場合はdnfからインストールできます。
sudo dnf install ardour5
初回起動時に表示されるWelcome to Ardourでの設定はデフォルトのままで問題ありません。
Ardourを起動するとSession Setupが開くのでNew Sessionからセッションを作って起動します。

1.1 プラグイン

ArdourでサポートされているプラグインLADSPALV2AU (Macのみ)、VSTです。Windows向けにコンパイルされたVSTをLinux上で利用することもできますが非推奨となっています。
LV2とLADSPAのプラグインはFedora26の公式リポジトリでいくつか配布されているので dnf search で探すことができます。
sudo dnf search lv2
sudo dnf search ladspa
手始めにYoshimiCalf Plug-insamsynthをインストールします。
sudo dnf install yoshimi lv2-calf-plugins lv2-amsynth-plugin

1.2 JACKのリアルタイムスケジューリング

セッションを開いた時に以下の警告が出て起動に失敗することがあります。
WARNING: Your system has a limit for maximum amount of locked memory. This might cause Ardour to run out of memory before your system runs out of memory.

You can view the memory limit with 'ulimit -l', and it is normally controlled by  /etc/security/limits.conf
この問題はカーネルのリアルタイムスケジューリングを設定することで解決します。以下はFedora 26で必要な設定です。
リアルタイムスケジューリングの設定ファイルを作成して開きます。
sudo nano /etc/security/limits.d/99-realtime.conf
99-realtime.confに以下の内容を追加します。
@realtime   -  rtprio     99
@realtime   -  memlock    unlimited
リアルタイムスケジューリングを適用するrealtimeグループを作ってユーザを追加します。
sudo groupadd realtime
sudo gpasswd -a username realtime
realtimeグループからユーザを除外するときは gpasswd -d が使えます。
sudo gpasswd -d username realtime

2 動画チュートリアルとマニュアル

JHoermann // Linux audio productionさんの動画チュートリアルがまとまっています。
よくわからない機能があれば機能名をコピーしてThe Ardour Manualのサイドバーにある検索窓から調べることができます。以下は押さえておくと便利なマニュアルのページです。

3 ワークフロー

3.1 セッションの開始

新しいセッションを作ります。

3.2 EditorとMixer画面の切り替え

Alt+Mでも画面の切り替えができます。EditorとMixerのボタンを右クリックするとメニューが表示されて別ウィンドウとして表示(Detach)もできます。
メニューバーのViewからShow Editor Mixer (Shift+E)を表示すればEditor画面にMixer Stripを表示することもできます。

3.3 MIDIトラックの追加

MIDIトラックを追加します。
鍵盤の音域を変更します。

3.4 プラグインのGUIを表示

プラグイン側で用意されたGUIの他に、ArdourのGeneric Plugin Editorも使うことができます。
動画ではメニューからGUIを表示していますが、プラグインをダブルクリックでもGUIを表示できます。

3.5 MIDIノートの入力

まずはDraw ModeMIDI Regionを作ります
MIDIノートの入力はDraw Mode (D)、範囲選択はInternal Edit Mode (E)で行います。
Grid Controlsでスナップの設定ができます。
Draw Modeでは以下のショートカットが使えます。
  • Shift+右クリックで削除
  • Ctrl+左クリックで一つずつ選択
  • Ctrl+左ドラッグで選択した要素をコピー
Stretch Mode (T)を使えばRegion単位で長さを伸縮できます。

3.6 テンポの変更

Transport Clocksからテンポを変更できます。

3.7 ループ再生

RulerのLoop Rangeは、Regionを選択してショートカットのLで設定することもできます。

3.8 MixerでAuxセンド

Busを追加してAuxセンドを使います。

3.9 プラグインの追加

Mixer Stripにプラグインを追加します。プラグインはドラッグで順番を変更できます。

3.10 オートメーション

横向きのスライダとして表示されるパラメータはオートメーションができます。Automation ModeをWriteかTouchに設定した上で、録音を開始してフェーダを動かすことでオートメーションを記録できます。
オートメーションを行うパラメータはEditorから選択することもできます。

3.11 フリーズ

Ardourでは今のところMIDIトラックのプラグイン出力を直接フリーズできる機能は無いようです。
以下のスクリーンキャストではAudioトラックを用意して録音しています。パッチベイの表示は右クリックで行っていますが、左クリック -> Routing Gridでも同じ画面が表示されます。

4 スクリプティング

ArdourではLuaを使ってスクリプトを書くことができます。Luaの文法についてはProgramming in Lua (first edition)が参考になります。スクリプティングに関する資料としてはマニュアルのリファレンスソースコードに含まれている例があります。

4.1 Minimal Example

まずはThe Ardour Manual - Lua ScriptingのScript Layoutにあるminimal exampleを試します。以下の内容を~/.config/ardour5/scripts/rewind.luaに保存します。
ardour {
    ["type"]    = "EditorAction",
    name        = "Rewind",
}

function factory (unused_params)
    return function ()
        Session:goto_start()  -- rewind the transport
    end
end
Ardourを開いて上のメニューからEdit -> Lua Scripts -> Script Managerを選択します。Script Managerが開いたらAction ScriptsにRewindをセットします。Callで実行してプレイヘッドが曲の最初に戻れば成功です。
以下の動画ではCallのかわりにEdit -> Runで実行しています。Editで開くエディタはスクリプトの出力が表示されるのでデバッグのときに便利です。

4.2 MIDI Regionの変更

MIDIノートのベロシティをランダマイズするスクリプトです。
ardour {
    ["type"]    = "EditorAction",
    name        = "Randomize Velocity",
    license     = "MIT",
    author      = "Uhhyou",
    description = [[Randomize midi notes velocity in selected region.]]
}

function factory() return function ()
    math.randomseed(os.time())

    -- selection中のMidiRegionだけで処理を行う。
    local selection = Editor:get_selection()
    for regions in selection.regions:regionlist():iter() do
        local midi_region = regions:to_midiregion()
        if not midi_region:isnil() then
            local model = midi_region:model()

            -- アンドゥ履歴で表示されるコマンド名を指定する。
            local midi_command = model:new_note_diff_command("RandomizeVelocity")

            local note_list = ARDOUR.LuaAPI.note_list(model)
            for note in note_list:iter () do
                -- NotePtrからMIDIノートを書き換えることはできないようなので
                -- 古いノートを消して新しいノートを加えている。
                local new_note = ARDOUR.LuaAPI.new_noteptr(
                    note:channel(),
                    note:time(),
                    note:length(),
                    note:note(),
                    math.random(15, 127)
                )
                midi_command:add(new_note)
                midi_command:remove(note)
            end

            model:apply_command(Session, midi_command)
        end
    end
end end
ベロシティ以外もランダマイズするように変更します。
function factory() return function ()
    function clamp(value, min, max)
        return math.max(min, math.min(value, max))
    end

    math.randomseed(os.time())
    local chord = {0, 2, 4, 5, 7, 9}

    local selection = Editor:get_selection()
    for region in selection.regions:regionlist():iter() do
        local midi_region = region:to_midiregion()
        if not midi_region:isnil() then
            local model = midi_region:model()
            local midi_command = model:new_note_diff_command("RandomizeNote")
            local note_list = ARDOUR.LuaAPI.note_list(model)
            for note in note_list:iter () do
                local new_note = ARDOUR.LuaAPI.new_noteptr(
                    note:channel(),
                    Evoral.Beats(note:time():to_double() + math.random() / 4.0),
                    Evoral.Beats(
                        note:length():to_double()* (1.5 + math.random()) / 2.0),
                    clamp(note:note() + chord[math.random(#chord)], 0, 127),
                    math.random(15, 127)
                )
                midi_command:add(new_note)
                midi_command:remove(note)
            end

            model:apply_command(Session, midi_command)
        end
    end
end end
関数を書くときは、他のスクリプトの関数名との衝突を避けるために function factory() return function () ... end end の中に入れます。関数名が衝突した場合はスクリプトが実行できないことがあります。