フィルターバンク (Julia Advent Calendar 2020)

このエントリはJulia Advent Calendar 2020の25日目のものです。Juliaを音に関する研究によく使っているので、その中から一つ紹介したいと思います。

音の加工をするときにフィルタというものを使うことがあります。フィルタは、特定の周波数の音を除去したり強調したりするエフェクタです。フィルタを使って音を周波数帯域ごとに分割する、フィルターバンクというものもあります。周波数帯域ごとにどんな音が含まれているのかを調べるときに使えますし、一部の帯域だけを強調したりするグラフィック・イコライザとして使用することもできます。

グライコとして使うのであれば、フィルタバンクで分割した音をすべて再合成すると元の音に戻ることが必須になります。元に戻るということを必須条件にしているフィルタバンクには直交ミラーフィルタ(QMF)というものもありますが、今回はもっと簡単な原理のものを紹介します。

続きを読む

周波数から音名を得る (Julia Advent Calendar 2020)

このエントリはJulia Advent Calendar 2020の24日目のものです。Juliaを音に関する作業によく使っているので、その中から一つ紹介したいと思います。

音の高さをあらわす方法にはいくつかあります。周波数を使うと「1秒あたりの周期の数」として物理的にも明確な値が得られます。

音楽の分野ではドレミファソラシドやCDEFGABCといったものが使われます(音名・階名表記 - Wikipedia)。国際式では、ピアノ中央のド(約262 Hz)をC4として、ピッチクラスのC~Bとオクターブ番号を組み合わせています。さらに細かい音高をあらわすときには、十二平均律に限りますがセント値(セント (音楽) - Wikipedia)を使うこともあります。セント値は半音の1/100となり、1200セントがちょうど1オクターブになります。

さらにMIDI規格ではC4をノート番号60とし、半音ごとにノート番号を1ずつ増減させます。チューニングの基準とすることが多いA4(440 Hz)は、ノート番号69番です。セント値まで含めたいという目的で、IRCAMで開発されたOpenMusicでは、MIDIセント値が採用されています。これはMIDIノート番号を100倍して、下2桁にセント値を含めようというものです。たとえばA4の35セント上は6935になります。

これら音高をあらわす単位の変換はときどき使うことがあるので、そのために作ったJuliaのプログラムを紹介します。

続きを読む

RでOSを判別する方法

先日、JuliaでOSを判別する方法を書きました。

marui.hatenablog.com

Rでも同じことをやりたい場合があるので、メモしておきます。Sys.info()関数を使うと、システムについてのさまざまな情報が得られます。その中でもsysnameがOSの種類を取ってくるものです。

if (Sys.info()["sysname"] == "Darwin") {
  setwd("/Volumes/GoogleDrive/マイドライブ/")
} else {
  setwd("G:/マイドライブ/")
}

JuliaでOSを判別する方法

普段使用しているコンピュータが2台あります。一つはMacBook Proで、もう一つは自作のWindows PCです。それらのあいだでデータの共有・同期を行うのにはGoogle Driveを使用しています。

Juliaについても同様で、Google Drive_juliaという名前のディレクトリを作って、その中にいろいろなユーティリティを入れてあります。パッケージ化していないものについてはinclude()で読み込むようにしているのですが、Google Driveの場所がMac(/Volumes/GoogleDrive内)とWin(Gドライブ内)とで違うので、使用しているOSの判別をして適切なディレクトリ名を指定する必要があります。

JuliaでOSの判別をするときにはSys.KERNELも使えますが、おそらくSys.isapple()などを使うのが良いのでしょう。例えば僕のコードでは以下のようにOSの判別をさせています。

if Sys.isapple()
  include("/Volumes/GoogleDrive/マイドライブ/_julia/audioutils.jl");
elseif Sys.iswindows()
  include("g:\\マイドライブ\\_julia\\audioutils.jl");
end

詳しくは以下の公式ドキュメントをどうぞ。

本日の給油

給油日 オドメーター (km) 給油量 (L) 単価 (円/L) 燃費 (km/L) 距離単価 (円/km)
2020-02-22 10890.0 2.67 141.95 51.20 2.77
2020-03-16 11037.1 3.46 138.73 42.51 3.26
2020-03-20 11217.6 2.83 133.92 63.78 2.10
2020-03-21 11407.0 3.11 142.12 60.90 2.33
2020-03-22 11612.2 3.50 138.57 58.63 2.36
2020-09-21 11760.8 3.04 130.59 48.88 2.67

じつに半年ぶりの給油。遠出をする雰囲気でもないし、職場や買物に行くなどの短距離くらいしか乗っていなかったので燃費も悪くなってしまった。新しいバイクを買おうと思っていたのも無期延期になってしまったしな……。

ゲーム機の世代とは?

こんど発売になるPlay Station 5は第9世代のゲームコンソールだということなんですが、ここで出てくる世代ってなんだろう?と思いました。Play Station 5が第9世代なら、そこからさかのぼっていけばPlay Station 1は第5世代。スーパーファミコンが第4世代、ファミコンが第3世代。その前って? ……もしかして第2世代がカセットビジョンとかAtariとか? それじゃ第1世代は何になるの?

ja.wikipedia.org

Wikipediaなどで調べてみたところ、据え置きタイプについては次のようになっているようです。太字は僕が所有していたことがあるもの。

  • 第1世代:オデッセイ、ホームポンなど(1970年代)……80年代後半になってから中古のオデッセイを入手して遊んでました。
  • 第2世代:Atari 2600、カセットビジョンなど(1970年代後半~1980年代前半)……アタリショックが起きた世代
  • 第3世代:ファミコンセガマーク3、Commodore 64など(1980年代前半~中盤)……ゲームができるパソコンとして、当時はZX 81が欲しかった。ひとつのキーに4つも5つも機能が割り当てられててすごいと思った。MSXもこの世代かな。
  • 第4世代:スーパーファミコンPCエンジンメガドライブなど(1980年代後半~1990年代前半)……僕はパソコンのほうに行ってしまっていたのでPC98を使っていたし、あこがれていたのはMac SEAtari STでした*1
  • 第5世代:Play StationセガサターンNINTENDO 64(1990年代中盤~後半)……ピピンとかマーティとかもあったね。従来のゲーム機メーカー以外(主にPCメーカー)も参入して、いろいろな機種がお星さまになりました。
  • 第6世代:Play Station 2ドリームキャストゲームキューブXbox(2000年代はじめごろ)……DVDプレイヤーにもなるということでPS2は爆発的に普及したよね。
  • 第7世代:Play Station 3WiiXbox 360など(2000年代中盤~後半)……コントローラが無線になった!
  • 第8世代:Play Station 4Wii UXbox One(2010年代前半)……スマートフォンの普及でコンソールゲームがちょっと目立たない時期かも
  • 第9世代:Nintendo SwitchOculus Questなど(2010年代後半~)……Play Station 5やXbox Series Xもここにいれてしまっていいの?

SwitchとPS5とかは性能も方向も違うので同じ世代に分類してしまっていいのか疑問。Switchはどちらかというと遅れてやって来た第8世代なのではないかという気もするし。

Wikipediaには携帯タイプも世代分類がされているのだけど、据え置き機として第9世代に入っているNintendo Switchが携帯機としては第8世代になっていたりして不思議な感じ。任天堂ソニーの携帯ハードはすべての世代のものを持ってるなぁ。PCエンジンGTワンダースワンも持ってた。なんとなく携帯タイプのほうが好きなのかも。

*1:Atari ST用に登場したNotatorという楽譜作成ソフトがシーケンサ機能を強化してオーディオも扱えるNotator Logicになり、その後AppleのLogicへとつながっていくのです

東京都のCOVID-19データを取ってくる(Julia版)

先月のエントリでRを使って東京都の新規陽性者数を取得してくるプログラムを作りました。

marui.hatenablog.com

今日はそれをJuliaでやってみたいと思います。とは言っても、Rでやっていることとほとんど同じで、HTTPパッケージを使って東京都のサイトにアクセスし、CSVで読み込んできたものを、DataFramesでデータフレームにしているだけです。

using DataFrames, CSV, HTTP

# read data from prefectural government website of Tokyo
daturl = "https://stopcovid19.metro.tokyo.lg.jp/data/130001_tokyo_covid19_patients.csv";
dat = CSV.read(HTTP.get(daturl).body, header=1);

## data cleaning
dat2 = DataFrame(公表日 = CategoricalArray(dat[:,5]),
                 居住地 = CategoricalArray(dat[:,8]),
                 年代   = CategoricalArray(dat[:,9]),
                 性別   = CategoricalArray(dat[:,10]),
                 退院済 = CategoricalArray(dat[:,16]))

## summarize
describe(dat2)

実行結果は以下のようになります。

julia> describe(dat2)
5×8 DataFrame. Omitted printing of 1 columns
│ Row │ variable │ mean    │ min                │ median  │ max                │ nunique │ nmissing │
│     │ Symbol   │ Nothing │ CategoricalValue…  │ Nothing │ CategoricalValue…  │ Int64   │ Union…   │
├─────┼──────────┼─────────┼────────────────────┼─────────┼────────────────────┼─────────┼──────────┤
│ 1   │ 公表日   │         │ Date("2020-01-24") │         │ Date("2020-08-14") │ 178     │          │
│ 2   │ 居住地   │         │ -                  │         │ -                 │ 8       │ 389      │
│ 3   │ 年代     │         │ -                  │         │ 不明               │ 13      │          │
│ 4   │ 性別     │         │ -                  │         │ 男性               │ 5       │          │
│ 5   │ 退院済   │         │ 1                  │         │ 1                  │ 1       │ 6507     │

あとは煮るなり焼くなり……。