LoginSignup
1
2

More than 3 years have passed since last update.

鳥の鳴き声の録音

Last updated at Posted at 2018-08-09

自宅の近くに飛んでくる鳥の鳴き声を録音してみました。

録音はFreeBSDなMIPSルーターにUSBモジュールを接続して、Macの古いマイクを利用し自作のコマンドで行いました。録音フォーマットは44.1kHzの16BitモノでWAVEファイルにしました。

録音したものをMacのAudacityで開いてみるとこのようになっています。AudacityはApp Storeではなくインターネットからダウンロードしたものですが、開発者の証明書が貼ってあるようで、そのまま利用できるようです。

スクリーンショット 2018-08-10 7.24.40.png

実際のデータはSoundCloudに上げてあります。

これの単位時間(0.1秒)のゼロクロスとパワーをざっくりrubyスクリプトで計算してみました。ゼロクロスとは波形データがゼロを通過するすなわち符号が逆転することで、パワーは振幅になります。雑音に比べて鳥の鳴き声は一般的に高い音が含まれるので、ゼロクロスが多くなるという理屈です。人間の音声認識でも使われる手法です。

WAVEデータのサンプルは無音が0で上下32767(0x7fff)から-32767(0xffff)まで変動します。Audacityの波形の1.0が32767で-1.0が-32767になります。

# check zero cross script

io = File.open(ARGV[0], "rb")
# skip wav header
io.seek(44)

i = 0
while TRUE do
  sample = io.read(4410*2)
  if sample.size != 4410*2 then
    break
  end

  m = sample.unpack("s*")

  zero = 0
  power = m[0].abs;

  num = 1
  while num < 4410 do
    if (m[num - 1] < 0 && m[num] > 0) ||
      (m[num - 1] > 0 && m[num] < 0) then
      zero = zero + 1
    end
    power = power + m[num].abs;
    num = num + 1
  end

  sec = i / 10.0
  power = power / 1000000
  val = power * zero
  print sec.to_s + "," + zero.to_s + "," + power.to_s + "," + val.to_s + "\n"
  i = i + 1
end

結果

0.0,696,3,2088
0.1,660,3,1980
0.2,659,2,1318
0.3,774,2,1548
0.4,1343,13,17459
0.5,1311,10,13110
0.6,1314,11,14454
0.7,1270,8,10160
0.8,1317,9,11853
0.9,1172,4,4688
1.0,1096,6,6576
1.1,1057,4,4228
1.2,780,2,1560
1.3,661,2,1322
1.4,709,2,1418
1.5,626,3,1878
1.6,693,2,1386
1.7,707,2,1414
1.8,711,2,1422
1.9,750,2,1500
2.0,651,2,1302
2.1,673,2,1346
2.2,669,2,1338
2.3,654,3,1962
2.4,692,3,2076
2.5,830,3,2490
2.6,1063,4,4252
2.7,965,4,3860
2.8,988,4,3952
2.9,883,3,2649
3.0,807,3,2421
3.1,737,3,2211
3.2,800,3,2400
3.3,757,4,3028
3.4,712,3,2136
3.5,764,3,2292
3.6,798,3,2394
3.7,786,3,2358
3.8,761,3,2283
3.9,779,3,2337
4.0,724,3,2172
4.1,798,3,2394
4.2,740,3,2220
4.3,727,3,2181
4.4,737,3,2211
4.5,707,3,2121
4.6,722,3,2166
4.7,997,4,3988

最初が秒数で、次がゼロクロス数で、次が振幅の絶対値の合計を1000000で割ったもの、次が2番目の値と3番目の値を掛けたものになります。

振幅の合計を1000000で割っているのは数字が大きくなり分かりにくくなるためです。

FreeBSDではmixerコマンドでマイクのボリュームを変更できます。ボリームを変更するとゼロクロスはボリュームには影響しませんが、振幅は変わります。

最初の大きな鳴き声の0.4秒のところは、かなりきっちり判別ができますが、2.6秒や4.7秒の鳴き声は数字にはでていますが、微妙な感じです。何らか他の要素を加えないと判定は難しい気がします。

その時点の値ではなく、その直前の値との差で判断するのが良さそうです。

この録音はよく撮れた方で実際にはいろいろ試行錯誤が必要です。

とりあえず始まりを判定して適当な長さの録音を行い、それを認識ロジックに放り込むことを考えているので、終わりに判定は行いません。

鳥によって鳴くときの音量は違いますが、どの程度の距離にいるかでも違ってきます。8mのところと16mのところでは4分の1の音圧になります。周りの雑音にもよりますが、どの程度の距離までを対象にするかを検討する必要もありそうです。

これを始めたのは夏で、時間によっては蝉の鳴き声に消されてあまりうまく行えませんでした。また今年(2018)は猛暑で鳥が少ない気がします。涼しくなると夜中は鈴虫などが入ってきてしまうのでしょうね。

自動観測は24x7でやるのは無理があり、環境雑音の評価や天候なども考慮して、行うのが良い気がします。天候の情報は天気概況などをネットから拾って判断する方法もあると思います。

鳥の鳴き声録音用のAndroidアプリも作ってあるのですが、こちらは録音開始と停止を人間が行い、停止前5秒を保存するようにしてあります。

AudacityはpluginがPythonで書けるようなので、このロジックの検証用のpluginがあると良いのですが、python分からないので作れません。

1
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2