niszetの日記

細かい情報を載せていくブログ

rsoundが動いたときの記録。

R力が足らない…

さて、例のrsoundですが私の環境ではしばらくの間、うまく動いていませんでした。
今は動いているものの、うまく更新が出来ず…。とりあえず動いているので触らないことにしています。

さて、この記事自体はずいぶん前に下書きを書いていたのですが、公開にしていないことに気づいて加筆訂正して公開しようと思った次第。

rsoundについて

rsoundはCsoundをRから呼ぶためのライブラリです。

notchained.hatenablog.com

github.com

Csoundはcppで書かれているので、Rcppを使ってCsoundのライブラリを呼ぶ形で作られているのですが、このrsound.dllを作るところで詰んでました。

これは主に僕のRcpp/cppまわりの理解が足りていなかったのですが、反省も兼ねて記録を残しておきます。

Rcppについて

最初は何が問題だったのかわからなかったので、Rcpp自体を勉強することにしました。
rsoundは公開時期がちょっと昔なので、Rtoolsのバージョンupに起因する可能性があったためです。Yutaniさんにご指摘いただきました。 調べた結果、Rtoolsの環境周りはシロっぽいのでした。このとき参考にした本やサイトなどを列挙しておきます。

全部を理解できたわけではないのですが、津駄さんのこの資料がまとまっていて読みやすいと思います。

www.slideshare.net

RcppはAoRPにも載っていますが、分量的には少ないですね。 www.oreilly.co.jp

R言語徹底解説もチラ見してみました。まだ全然読んでない…。 www.kyoritsu-pub.co.jp

あとはパーフェクトRでしょうか。この本、情報量がかなりあるんですが僕はまだあまり読めていません… gihyo.jp

日本語で読めるというのは、最初のとっかかりの時点では重要なので、こういった情報が沢山手に入るのはRの強みですね。

Rcppまわりのトラブルをネットで調べた

一時期、rstanを導入するブーム?がありましたが、そのときに結構な方が色々ハマっていたようです。その時の記録も参考にしました。
結果、これもシロだったのですが。

こちらのリンク集がかなり広範囲に渡っているので、今後お世話になりそうです。 須通り_統計_C++は未経験だけどRcppで開発したい!(1) 環境構築編

中でもこちらは後に書くとおり、Sys.setenvで解決したので参考になりました。

Rcpp 俺様備忘録

こちらも。Macに限らず、です。 suryu.me

ビルドの方法について

最初、Rcpp::sourceCppでビルドしようとしていましたが、うまくいかない。 パッケージ開発入門を読むと、Build&Reloadを使うと良いと書いてあるのでそれに従う。これはRstudioのショートカットキーとしてCtrl+Shift+Bでもできますね。ショートカットキー便利です。覚えましょう。

www.oreilly.co.jp

RStudio (非公式日本語版)

g++のパスとバージョンについて(無罪だった)

私はmingwが動いている環境なので、whichでg++を探してみましたが、問題がなかった(ほかに入っているものもバージョンは同じ) 色々入れるとPATHが頻繁に書き換わるので、今何を参照しているのかはちゃんと見た方が良いですね…。

tjo.hatenablog.com

ファイルパスに空白が入るのはダメ?

これは結局わからず。C直下にCsoundを入れることにしましたが、少なくともこれだけではダメでしたので。たぶん関係ない。

コンパイル時のLとIのオプションについて

私の場合はこれが原因でした。
Rcppはsrc/Makevars にファイルがあればコレに書かれた設定を読んで実行されますが、このオプション周りが良くなかったようです。

最終的にはSys.setenvを使用して以下のように設定をしました。

> Sys.setenv("PKG_LIBS"="-Lc:/Csound6_x64/bin/ -lcsound64 -Lc:/Csound6_x64/bin/ -lcsnd6")
> Sys.setenv("PKG_CXXFLAGS"='-Ic:/Csound6_x64/include')

これでようやく動いたのでした。
Rcppの文法とかではなくて、環境変数?とかオプションまわりだったのでなかなか初学者には厳しい戦いでした…

なんだかリンク集になってしまいましたが、いつか誰かの何かに役に立つと良いなぁ…(当時の自分に見せたい。笑)

Csoundでwavを生成するところまで

実行環境について

そういえば、書いていませんでした。
* OS: Windows10 Pro
* Csound : Version 0.9.3-beta

で行っています。

Rに食わせるwavを作っておく

初手からあまり込み入ったことをすると詰むので、まずは簡単にサイン波を作るところから行きましょう。

こちらの例

write.flossmanuals.net

から転載します。
Csoundは素人なので、素人説明になりますが、マニュアルのリンクも併せて貼っておきますので、本当の意味はそちらでご確認いただきたく。

こちらで、気になったワードを検索するのが手っ取り早いかなと思います。
The Canonical Csound Reference Manual

<CsoundSynthesizer>
<CsOptions>
-odac
</CsOptions>
<CsInstruments>
instr 1
aSin      poscil    0dbfs/4, 440
          out       aSin
endin
</CsInstruments>
<CsScore>
i 1 0 1
</CsScore>
</CsoundSynthesizer>

何も考えず、上記のソースをコピペして、Runボタンを押してみてください。ラの音が聞こえるはずです。
440の部分が音の周波数を表しています。単位はHz。Hzは1秒間に振動する回数ですね。
440Hzはラの音の高さになります。 instr ~ endinは音を鳴らす音源の定義だと思ってもらえればよくって、今回は440Hzの音を生成するブロックなのです。
これをaSinという変数に代入して、out aSinでaSinに定義した音を出力するところまでを含んだ音源だと思えば今はたぶん良いのだと思います。

CsScoreのブロックはそのままスコアを定義していますが、i 1 0 1 は instr 1 を 0 秒から 1 秒間 実行せよということで、結果としてラのRunボタンを押すとラの音が1秒間聞こえるのです。

さて、このままでもいいのですが、Rでwavを見るときに440個の波を見るのは面倒くさいですね。 ということで1Hzの音にしてみましょう。下記のとおりです。

<CsoundSynthesizer>
<CsOptions>
-odac
</CsOptions>
<CsInstruments>
instr 1
aSin      poscil    0dbfs/4, 1
          out       aSin
endin
</CsInstruments>
<CsScore>
i 1 0 1
</CsScore>
</CsoundSynthesizer>

単純に440を1に変えただけですね。
さて、これを同じようにRunすると実行しているようだけど何も聞こえない。1Hzは人間の聞こえる周波数の外なので実行してもわからないのでした。
まぁ、ちゃんとできてるに違いない!ということで、気にせずにwav形式で出力します。Recordというボタンを押すと、現在エディットしているファイル名に.wavの拡張子がついて、マイドキュメントあたりにあると思います。linuxだとhomeディレクトリかな?

これをバイナリエディタで開いてみると…?

52 49 46 46 08 00 00 00 57 41 56 45 66 6D 74 20
10 00 00 00 01 00 02 00 44 AC 00 00 10 B1 02 00
04 00 10 00 64 61 74 61 00 00 00 00 00 00 00 00
01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00
05 00 00 00 07 00 00 00 08 00 00 00 09 00 00 00

で始まる、数字の羅列と、Stirlingなどであれば右側に変な文字列が並んでいると思います。

これでとりあえず準備は完了です。
ひょっとしたら、環境によっては出方が違うかもしれませんが…

さて、次回はバイナリエディタとにらめっこしつつ、Rでこれを読んでいきます。

しかし、本業多忙のためちょっと更新が開いてしまいます。
上のバイナリを、wavのフォーマットとにらめっこして、仕様通りなのかを見ると良いかもしれませんです。

Csoundでwavファイルを生成したが

Csoundwindowsで使うべきではないのでは…

Csoundが生成する波形、本当に自分が書いたとおりなのだろうか?
…ということを確かめるために、wavファイルをRに取り込んで、値を見てみようとしてみました。
こんなことしなくても、Csoundの機能としてlinuxでは波形を見れるような記述があるが、そのopcode書いても見れませんでした。
ほかの機能でwindows上でも見れるのかしら…。

Csoundのdisplayというopcodeですが、X11とか書いてあるので、たぶんwindowsでは使えないです(サンプルコードを実行しても見れませんでした)

display

wavのお勉強

wav、あるいはwaveファイルってずっと無圧縮のデータしか存在しないのだと思っていました。が、調べてみると別にそういうわけではないということがわかりました。
しかし、実際はそんなwavファイルは見たことはないなぁ…。

wavのファイル構造については色々なサイトを参考にさせていただきました。ありがとうございました。
wav ファイルフォーマット

WAVEファイルの構造

WAV形式音声ファイル

Csoundでwavファイルを作成して再生してみようとする->再生できない

CsoundでRecordあたりを押すとwavファイルが生成されます。これをMedia Playerで再生しようとしてみたのですが、エラーが出て再生ができませんでした。
ちなみに、foobar2000でもダメだったのでMSが悪いわけではないのだと思います。

この後Rでwavを取り込むのですが、バイナリエディタでまずは上記のサイトにあるような値があるのかを見てみたのです。
このとき、バイナリエディタはStirlingを使いましたが別に何でも良いと思います。お好きなバイナリエディタで見ると良いのです。

で、wavにはファイルサイズなどの情報がヘッダに書き込まれていますが、これの値が0になっているのです。
おそらくこれが原因ではないかなぁと疑っています。実際、Rで取り込むときもこれが厄介だったのですが、ファイルサイズからヘッダサイズを引くなどで対応できるので、まぁ何とかなるかな、という感じです。拡張のあるヘッダだとダメですが、Csoundで生成したwavに限ることにすればおそらく問題はないでしょう。

ひとまず今日はここまで。次回に続く…。

もうちょっと図と表、コードなどを載せるべきですね。

dplyrとpurrrあたりを修行中

dplyrとmapの使い方が難しい。

結局、これは使わなくて良いきがするのだけど、spreadについてちょっと触っていて気付いたもの。
何かの値が入った列をvalueに指定すると、それが列名になりますね。 これを選択することがうまくいかなかった。具体的には下記の例でselect(-20)では意図したものになりませぬ。``で囲ってあげる必要があるのでした。

as_data_frame(list("a"=c(9999,1010200000,20),"b"=c(10,2000,300),"c"=c("a","b","c"))) %>%
 spread(key="a",value=b) %>% select(-`20`)

結果はこんな感じ。

## A tibble: 3 × 3
#      c `9999` `1010200000`
#* <chr>  <dbl>        <dbl>
#1     a     10           NA
#2     b     NA         2000
#3     c     NA           NA

spread重複があるとNAになったりするので、それを事前に知れたらいいのになぁ…。distinctとか? ゆるーく調べてみます。

Csoundで純正律と平均律の違いを聞いてみる

純正律平均律

さて、昨日書いたコードはいわゆる平均律によるものでした。
純正律平均律について、語れるほど詳しくないのでwikipediaの記事をとりあえず貼っておきます。

純正律 - Wikipedia

平均律 - Wikipedia

簡単に言えば、平均律はオクターブ(周波数が倍、半分)の周波数を12等分したもの。純正律は和音を構成する音の比が整数になる、という感じですね。平均律は普段使っている楽器がそうなっているのでなんとなくわかるものの、純正律の半音上げ/下げがどうなるのかは要勉強。A#とBbは違う音だと言っているんですよね。よくわかりませんねぇ。

ということで、聞き比べのためにwikipediaに書いてあった関係式を使ってCsoundのコードを書いてみました。 音の差わかりますか?確かに違う気もするけど…気のせいにも思えるなぁ。

<CsoundSynthesizer>
<CsOptions>
-odac
</CsOptions>
<CsInstruments>
instr 1
aSin      poscil    0dbfs/4, 440*2^(3/12) ;do
          out       aSin
endin

instr 2
aSin      poscil    0dbfs/4, 440*2^(3/12)*5/4 ;mi ;7/12
          out       aSin
endin

instr 3
aSin      poscil    0dbfs/4, 440*2^(3/12)*3/2 ;so ;10/12
          out       aSin
endin


instr 11
aSin      poscil    0dbfs/4, 440*2^(3/12) ;do
          out       aSin
endin

instr 12
aSin      poscil    0dbfs/4, 440*2^(7/12) ;mi ;
          out       aSin
endin

instr 13
aSin      poscil    0dbfs/4, 440*2^(10/12) ;so ;
          out       aSin
endin

</CsInstruments>
<CsScore>
; chord C
i 1 0 2 
i 2 0 2
i 3 0 2

i 11 2.2 2
i 12 2.2 2
i 13 2.2 2

</CsScore>
</CsoundSynthesizer>

Csoundの練習 和音を作ってみる

Csoundで和音を作る

Csoundはなんでも出来るのでは?というくらいに全部の仕様を把握するには時間がかかりそうなので、まずは気になったことを手習いでやってみましょう、ということで。今日は和音を作ってみました。サンプルにあったものをコピペして、所望の周波数に変換、同時に発音させて和音にする、というだけです。

意図通りに鳴ったので、おそらく理解は正しい…はず。
Csoundシンタックスハイライトはないのかな。とりあえずコードも貼っておきます。

<CsoundSynthesizer>
<CsOptions>
-odac
</CsOptions>
<CsInstruments>
instr 1
aSin      poscil    0dbfs/4, 440*2^(3/12) ;do
          out       aSin
endin

instr 2
aSin      poscil    0dbfs/4, 440*2^(7/12) ;mi
          out       aSin
endin

instr 3
aSin      poscil    0dbfs/4, 440*2^(10/12) ;so
          out       aSin
endin

</CsInstruments>
<CsScore>
; chord C
i 1 0 1
i 2 0 1
i 3 0 1

</CsScore>
</CsoundSynthesizer>

Rで音楽を作るための準備

Rで音楽を作るまでの長い道のり

色々あって、シンセサイザーについて勉強中です。

さて、yutaniさんのrsound
notchained.hatenablog.com

ですが、今の環境ではうまく入らない…。
なので、いったんローカルにもってきて自分のライブラリとして作ってしまおうかと(まだできてない)
単純にライブラリを作るだけのR力が私に足りない…のです。

なお、playitbyrはCRANにはない
* playitbyr
CRAN - Package playitbyr

GitHubには一応あるよ
* playitbyr
github.com

playitbyrに関連して、audiolyzR
* audiolyzR
CRAN - Package audiolyzR

というライブラリもあるらしい。が、動くかわかりません(cranにはまだあるぽい?)

Csoundについて

調べると1500くらい文法に関わるものがあるということで、それを全部R側で対応するのは難しい。
ということで、構文だけは持っておきながら文字列で引き渡すのが正解かなという感じですね。

Csoundについては、ここで

サンプルを実行すると面白い。filterのあたりでシンセぽい音が出てきて感動できる、かも。
write.flossmanuals.net

文法はここで調べられる。
The Csound Book - Chapter 1

ほかのパッケージ

tuneR

tuneRというパッケージがある。

CRAN - Package tuneR

これは直接wave形式のファイルを書き出すようですね

e1071

STFTについては、e1071にも含まれているようである。
R: Computes the Short Time Fourier Transform of a Vector

seewave

seewaveパッケージは波形を見れるようだ。ただし通常のplotを使っている(未調査)ようである。
CRAN - Package seewave

Rwave

Rwaveというパッケージはwaveletなどの変換ができる、SのパッケージをRに移植したような説明が書かれている。
CRAN - Package Rwave

signal

signalというパッケージはMatlab/Octaveの関数をRに移植したような感じですね。
CRAN - Package signal

以下、調査中 * SMF, standard MIDI Formatについて * シンセサイザーの基礎 * WAVEファイルの基礎

参考している書籍

  • C言語ではじめる 音のプログラミング ―サウンドエフェクトの信号処理― shop.ohmsha.co.jp

  • シンセサイザーの全知識 本格派を目指すキミに! という本も読んでいますが、これはもうamazonで在庫がないですねぇ。

おまけ

Tokyo.R 61 参加してきました!
第61回R勉強会@東京(#TokyoR) : ATND

LTもセッションも楽しかったですし、懇親会も参加して色々な方とお話が出来ました。
もうちょっとR力を高めて参加したいな。rsoundを引っ提げて、とかね!頑張りましょう。先は長い~~