2017/07/14

SuperColliderでファイルへの録音と再生

SuperColliderが読み込めるファイルフォーマットを確認します。libsndfileが使われているので、少なくともlibsndfileの対応表にあるファイルは読めるはずです。

まずはRecorderでテスト用のファイルを作ります。

{
  SinOsc.ar(
    SinOsc.ar(
      XLine.kr(1, 100, 0.5)).exprange(*XLine.kr([20, 800], [7000, 200], 1)
    )
  ) * 0.1
}.play;
s.record(duration: 1); // sはデフォルトのServer。

thisProcess.platform.recordingsDir.postln; // 保存先のディレクトリを出力。

デフォルトでは Recorder で録音した音の保存先は thisProcess.platform.recordingsDir 、ファイル名は"SC_%y%m%d_%H%M%S.aiff"となります。ファイル名は秒単位で更新されるので、1秒以下の録音を繰り返し行う場合は明示的にファイル名を指定する方がよさそうです。今回録音したファイル名は SC_170704_063246.aiff となりました。

ffmpegでwavに変換します。利用できるコーデック名は ffmpeg -codecs で確認できます。wavの場合はpcm_*となっているコーデックが使えます。エンディアンを指定する必要があるのでlscpuで確認しています。

Fedora26ではdnfにrpmfusionのリポジトリを追加することでffmpegをインストールできるようになります。

$ sudo dnf install ffmpeg
$ cd path/to/recordingsDir
$ lscpu | grep Endian
Byte Order:          Little Endian
$ ffmpeg -i SC_170704_063246.aiff -c:a pcm_s16le test.wav

wavからmp3、ogg、opus、flacに変換します。aiffも名前をtest.aiffに変更します。

$ lame --preset "insane" test.wav test.mp3
$ oggenc -q 10 test.wav
$ opusenc --bitrate 256 test.wav test.opus
$ flac -8 test.wav
$ cp SC_170704_063246.aiff test.aiff

SoundFileでファイルを読み込んで再生できるか試します。

(
~checkFile = { | path(nil) |
  f = SoundFile.new;
  f.openRead(path);
  f.play;
  f.inspect;
  f.close;
};
);

~dir = thisProcess.platform.recordingsDir;
~checkFile.value(~dir +/+ "test.aiff"); // OK
~checkFile.value(~dir +/+ "test.wav");  // OK
~checkFile.value(~dir +/+ "test.mp3");  // could not be opened
~checkFile.value(~dir +/+ "test.ogg");  // OK
~checkFile.value(~dir +/+ "test.opus"); // could not be opened
~checkFile.value(~dir +/+ "test.flac"); // OK

Window.closeAll; // inspectウィンドウをまとめて閉じる。

今のところmp3とopusは再生できないようです。

mp3を再生

lameをインストールします。

sudo dnf install lame

QuarksのMP3をインストールします。上側にあるメニューのLanguage > QuarksからGUIでインストールすることもできます。

Quarks.install(MP3);

インストール後にCtrl+Shift+Lでクラスライブラリを再コンパイルするとMP3が使えるようになります。

MP3がlameのパスを正しく指定しているか確認します。

File.exists(MP3.lamepath);

mp3が再生できることを確認します。

b = MP3.readToBuffer(s, thisProcess.platform.recordingsDir +/+ "test.mp3");
b.play;