![見出し画像](https://assets.st-note.com/production/uploads/images/150499049/rectangle_large_type_2_836b132bb439d68aaabce8c9313f0cac.jpeg?width=1200)
ピッチによるソート、または音楽の無意味化
どうすれば音楽を「無意味化」できるだろうか? 音楽とは何か、意味とは何か、と問うのも一興であるが、とりあえず波形データをピッチ(音高)の高低順にソート(並び替え)してしまえば、紛れもなく無意味になるであろう。
例えば、以下はJohn von Neumannの名言を、ASCIIコード順にソートしたものである(スペースを除く)。
,,.Aaaaaaabbccddeeeeeeeeeeeffgghiiiiiiiilmmmmmnnnnnnnnnnoooooooprrrrrsssssssstttttttttuuvwyy
以下、ピッチ情報による波形データのソートについて検討する。まず課題となる音声ファイルを作る。Score.recordNRTを用いて、ランダムなピッチを15秒間演奏したものを、音声ファイルとして直接出力する。
// Example 1
(
SynthDef(\x, {|pch, dur|
var env, frq, sig;
env = Env([0, 1, 0.5, 0.5, 0], [0.01, 0.01, dur-0.05, 0.02]).ar(2);
frq = pch.midicps;
sig = PMOsc.ar(frq, frq, 1, 0, env);
Out.ar(0, sig);
}).store;
p = Pbind(
\instrument, \x,
\pch, Pwhite(36, 84, inf),
\dur, Pwhite(0.1, 0.5, inf),
);
z = p.asScore(15);
z.score.postcs;
o = ServerOptions.new.numOutputBusChannels = 1;
Score.recordNRT(z.score, outputFilePath: "any.wav".resolveRelative, options: o);
)
出力した音声ファイル(any.wav)を聴いてみる。この段階で既に無意味ではないのか……については(音と意味に関する詳しい検討を要するので、本稿では)措くとする。
// Example 2
(
f = Buffer.read(s, "any.wav".resolveRelative);
SynthDef(\playbuf, {
a = PlayBuf.ar(1, f.bufnum, doneAction: 2);
Out.ar(0, a!2);
}).play;
)
次にany.wavをピッチ順にソートするが、かなり込み入ったプログラミングになってしまった。このような場合、最初からクラスファイルとして書くと書きやすく、保守性も担保される。PitchSortクラスの中身については後述する。
クラスファイル(*.sc)は下記を問い合わせて示される、いずれかのディレクトリに置き、SCを起動(再起動またはリコンパイル)することで使用できる。
Platform.userExtensionDir
Platform.systemExtensionDir
Example 3はany.wavのピッチによる降順ソートを行う。
// Example 3
p = PitchSort("any.wav".resolveRelative).do;
ソート処理した音声はsorted.wavとして出力される。聴いて確認してみると、時々外しているようだが、概ねピッチの高い音から低い音に並び替えられている。
// Example 4
(
f = Buffer.read(s, "sorted.wav".resolveRelative);
SynthDef(\playbuf, {
a = PlayBuf.ar(1, f.bufnum, doneAction: 2);
Out.ar(0, a!2);
}).play;
)
さて、any.wavのような音源であれば、比較的良い結果が出るが、既存曲の音源などの場合はどうか。Berio「Sequenza I」やWebern「Kinderstück」など試したが、ほとんど上手く行かなかった。Pitchのパラメータの調整や入力前の音声へのフィルタ処理、あるいは元音源のノイズ除去、コンプレッションなどの下拵えも必要かも知れない。
ところで、Kermit-Canfield (2014)によれば、Pitchの他、すぐに使えるピッチトラッカーとしてSuperColliderにはTartiniとQitchが存在する。どちらもExtensionで、筆者は未使用だが、Tartiniは比較的導入がしやすいようである。いずれ試してみよう。
PitchSortの中身について簡単に述べる。まず音声ファイルを読み込み、Score.recordNRTを用いて(実時間よりも速く)ピッチ情報を取得、別途、波形処理ソフトでも確認できるように一旦pch.wavに書き出す(PitchSort.score)。
その後、再度pch.wavを読み込み、各周波数の開始位置と持続時間を集計する。但し、pch.wavのデータはコントロールレート(kr)であるため、64サンプル毎でしか記録されていない。Pitchの出力はコントロールレートしか用意されていないが、K2A.arを用いてオーディオレートに変換すると何故か補完が行われるため、後の処理に支障を来す。
そのため、些か遠回りだが読み込んだpch.wavを64サンプルごとにサンプル&ホールドするという方法でオーディオレートに変換する(PitchSort.sort)。その後はソート済みのデータ(開始サンプル、持続サンプル数、周波数)に従って、入力音源を再構成し、出力する(PitchSort.audio)。
さて、音楽を無意味化すること、それ自体の意味について問うのも一興ではある――筆者は何度となくPitchSortのアルゴリズムを用いてライブパフォーマンスを行っている――が、本稿の真の目的は、波形データの非実時間処理(Score.recordNRT)と、クラスファイルの実例を示すことであった。音楽の無意味化という意味不明の課題でも、プログラミングにおいては良い練習になるかも知れない。
話は変わるが、何らかのデータを音に変換する可聴化(sonification)に基づく音楽作品は何故「必ずや」失敗するのか。筆者は過去に一度だけ、2011年3月11日前後の詳細な地震データに基づく制作をしたことがあった(元データについては本稿で初めて述べる)。あえて元データを「音楽化」することなく、単に「可聴化」するに留めたことには、恐らく何らかの意図があったと思うが、当然今となっては覚えていない。
補足:ソートアルゴリズムによる興味深い作品として、Erik Carlson「Alphabetized Winterreise」を挙げよう。シューベルト「冬の旅」全曲を歌詞に基づいてソートしたものだが、実演には最低二人の歌手が必要であり、現在も未初演と思われる。近年、既存の録音の編集によるリアライズが確認できるようになったが、楽譜よりも面白いとは思えない。何故だろうか。