類似楽曲検索(洋楽版)を作ってみました!

類似楽曲検索(邦楽版)を作ってみましたが、今度は、類似楽曲検索(洋楽版)も作ってみました!


音楽信号に含まれるボーカルの声質やサウンドの類似度をコンピュータで分析。
お気に入りの曲と似た雰囲気の曲をの検索出来るサイトを構築中。

↓こちら。

類似楽曲検索『ちゃむちゃん(洋楽版)』
類似楽曲検索『ちゃむちゃん(邦楽版)』

ffmegでm4aからmp3など、色々出来るようにインストール。

ffmegで、m4aからmp3へのコンバートなど色々出来るよう、忘れっぽいので、家のffmegのconfigureのオプションめも。

./configure --prefix=/Volumes/Ramdisk/sw --enable-gpl --enable-pthreads --enable-version3 --enable-libspeex --enable-libvpx --disable-decoder=libvpx --enable-libmp3lame --enable-libtheora --enable-libvorbis --enable-libx264 --enable-avfilter --enable-libopencore_amrwb --enable-libopencore_amrnb --enable-filters --enable-libgsm --enable-libvidstab --arch=x86_64 --enable-runtime-cpudetect

ffmpegで複数のmp4動画を連結する。

ffmpegで複数のmp4動画を連結する。

ffmpeg -i imput1.mp4 -i imput2.mp4 -strict -2 -filter_complex 'concat=n=2:v=1:a=1' output.mp4
  • i imput1.mp4 -i imput2.mp4 の部分が入力ファイル。
  • filter_complex 'concat=n=2:v=1:a=1' の部分が入力された動画を連結しますよと指定で、concat=n=2の数字の「2」が連結する動画数で、「v=1:a=1」が画像、音声とも連結しますよという意味。

音声がAACの場合は「-strict -2 」オプションも必要。

それで連結された動画が↓これ。
http://youtube.com/watch?v=YxZWDeJqWgg

地震の振動を耳で聞けるサイトを作ってみました。

先日「Pythonで地震計の地震加速度のデータから地震震度を計算する」という記事をUPしましたが、K-NETさんの地震計のデーターをもとに、地震の波形をピッチを上げて地震の振動をステレオサウンドで耳で聞けるサイトを作ってみました。


先日、2015年01月14日 21時02分頃に起きた京都府南部地震(M3.8)だとこんな感じ。

http://youtube.com/watch?v=x-7WpHgd2rA


大阪府 豊能郡能勢町今西259 能勢町立岐尼小学校敷地内
北緯34.9707度, 東経135.3900度

震源からの距離:10.56km(震度 3)


↓上のような地震動が他、以下のような震源マップや地震波形も地震毎にmatplotlibで画像で見れるようにしてますので、よかったら、ご利用ください。
地震ウォッチ - ちゃむちゃん



Pythonで地震計の地震加速度のデータから地震震度を計算する

興味本意で^^;地震情報関係のサイトを今作っているのですが、地震計のデータから地震の計測震度を計算する必要が出てきて、Python地震計の地震加速度のデータから計測震度を計算する関数を作ったので、ちょっとメモ。

防災科学技術研究所 強震観測網(K-NET,KiK-net) さんで公開されてる地震計の地震加速度のデータファイルから、地震の計測震度をPythonで計算してみる。


K-NETさんで公開されてる地震計のデータファイルは↓こんな感じのフォーマットなので、

----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8
Origin Time       2006/01/18 23:25:00<LF>         (1) 地震発生時刻
Lat.              37.798<LF>                      (2) 震央北緯
Lon.              142.200<LF>                     (3) 震央東経
Depth. (km)       36<LF>                          (4) 震源深さ
Mag.              5.7<LF>                         (5) マグニチュード
Station Code      MYG002<LF>                      (6) 観測点コード
Station Lat.      38.7262<LF>                     (7) 観測点北緯
Station Lon.      141.5109<LF>                    (8) 観測点東経
Station Height(m) 79<LF>                          (9) 観測点標高
Record Time       2006/01/10 23:25:46<LF>         (10) 記録開始時刻
Sampling Freq(Hz) 100Hz<LF>                       (11) サンプリング周波数
Duration Time(s)  108<LF>                         (12) 計測時間
Dir.              N-S<LF>                         (13) チャンネル
Scale Factor      3920(gal)/6182761<LF>           (14) スケールファクタ
Max Acc. (gal)    48.060<LF>                      (15) 最大加速度
Last Correction   2006/01/18 23:25:31<LF>         (16) 最終校正時刻
Memo.             <LF>                            (17) 備考
    8009     9006     7998     8001     8009     8007     8002     8005<LF>
    8006     8003     8003     8005     8005     8003     8001     8004<LF>
 :
 :
 :
    8006     8006     8000     8000     8005     8009     8004     7999<LF>
    8003     8007     8004     8000     8000     8005     8009     8005<LF>
[EOF]
----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8


東西、南北、上下動のアスキーフォーマットの地震計のテキストデータ(つまり文字列)を読み込んでそれぞれ、dataEW、dataNS、dataUDという変数にセットしてあげて、calc(dataEW, dataNS, dataUD)と呼び出すと、地震計が記録したデータから計測震度が計算出来る。

ちなみに、計測震度の計算方法は気象庁 | 計測震度の算出方法にあるとおり、以下。(詳しくはネットで見つけたこちらのPDFが参考になります。『地震動強さ指標 と新 しい気象庁震度 との対応関係』)

  1. ディジタル加速度記録3成分(水平動2成分、上下動1成分)のそれぞれの フーリエ変換を求める。
  2. 地震波の周期による影響を補正するフィルターを掛ける。
  3. フーリエ変換を行い、時刻歴の波形にもどす。
  4. 得られたフィルター処理済みの3成分の波形をベクトル的に合成をする。
  5. ベクトル波形の絶対値がある値 a 以上となる時間の合計を計算したとき、これがちょうど 0.3秒となるような a を求める。
  6. 5.で求めたaを、 I = 2 log a + 0.94 により計測震度 I を計算する。計算されたIの小数第3位を四捨五入し、小数第2位を切り捨てたものを計測震度とする。
#!/usr/bin/env python
# -*- coding: utf-8 -*- 

import numpy as np 
from scipy import sqrt, power, exp, log10
from scipy.fftpack import fft, ifft, fftfreq
import tarfile


def getEarthquake(data):

    tokens = data.split() 
    
    # Scale Factor の値を取り出す 
    (Scale, Factor) = tokens[tokens.index('Factor')+1].split('(gal)/') 
    
    # サンプリング周波数
    fs = tokens[tokens.index('Freq(Hz)')+1].rstrip('Hz')

    # 波形データを取り出す 
    items=tokens[tokens.index('Memo.')+1:] 

    w0 = np.array(items, dtype=np.float64) 
    w0 = float(Scale)  / float(Factor) * (w0 - w0[0])
    maxgal = max(abs(w0)) 

    return maxgal, fs, w0
    


def calc(dataEW, dataNS, dataUD):

    # 波形データを取り出す 
    (maxgalE, fsE, sigE) = getEarthquake(dataEW)
    (maxgalN, fsN, sigN) = getEarthquake(dataNS)
    (maxgalU, fsU, sigU) = getEarthquake(dataUD)

    # サンプリング周波数
    fs = int(fsE)

    # サンプル数
    L = len(sigE)

    # 地震波形をフーリエ変換してフーリエスペクトルを求める
    spectrumE = fft(sigE)
    spectrumN = fft(sigN)
    spectrumU = fft(sigU)

    # 周波数軸の値を計算 
    freqList = abs( fftfreq(L, d=1.0/fs) )

    # フィルターの作成 
    # 周期効果フィルター用の関数窓を作成
    winX = sqrt( 1 / freqList[1:] )
    winX=np.concatenate(([0],winX))
    # ハイカットフィルター用の関数窓を作成
    y = freqList / 10.
    winY = 1.0/sqrt(1.0 + 0.694*power(y,2) + 0.241*power(y,4) + 0.0557*power(y,6) + 0.009664*power(y,8) + 0.00134*power(y,10) + 0.000155*power(y,12))
    # ローカットフィルター用の関数窓を作成
    winZ = sqrt(1.0 - exp( power( -1.0 * (freqList / 0.5), 3) ))
    # 3つの関数窓を合成
    win = winX * winY * winZ

    # スペクトルにフィルターをかける
    spectrum_winE = win * spectrumE 
    spectrum_winN = win * spectrumN
    spectrum_winU = win * spectrumU

    # フィルターをかけたスペクトルを逆フーリエ変換して時系列の波形に戻す。
    resyn_sigE = ifft(spectrum_winE)
    resyn_sigN = ifft(spectrum_winN)
    resyn_sigU = ifft(spectrum_winU)

    # 3成分のベクトル合成波形を求める。
    S2 = sqrt(power(resyn_sigE,2) + power(resyn_sigN,2) + power(resyn_sigU,2))

    # 0.3秒間の地震波形のサンプル数は「int(0.3*fs)」個なので、合成波形データを降順でソートして、地震加速度の大きい方から数えて「int(0.3*fs)」個目の加速度から地震計の計測震度を求める
    maxS2 = sorted(S2, reverse=True)
    I = 2*log10(maxS2[int(0.3*fs)]) + 0.94
    I = int( round(I.real,2) * 10 ) / 10.0
    
    return I

FabricでリモートのMySQLのDBデータをローカルマシンから乗せ替える

Webの開発環境がローカルのPCにあって、

例えば、リモートサーバーにあるMySQLのDBの内容を、そっくりそのまま、ローカルPC内のDBの内容で定期的に乗せ替えたい場合に便利な小技ですが、

Python 製のデプロイ管理ツールFabricを使って、タスクを自動化。

以下は、dbnameというDBに4つのテーブルTABLE1、TABLE2、TABLE3、TABLE4というテーブルがあるとして、その内容を、ローカルPCのmySQLからエクスポートして、リモートのmySQLにインポートする例。

以下内容のテキストファイルをabfile.pyという名前で用意しておくと「fab musicLoad」とコマンドを打つだけで、ローカルDBのエクスポートから、リモートへのファイル転送、リモートDBへのインポートまで、一連でやってくれます。

from fabric.api import run, sudo, local, cd, lcd, put, env

env.hosts = 'hoge.com'
env.port = 12345
env.user = 'hoge'
env.password = 'xxxxxxxx'

def musicLoad():

    with lcd('upload_data'):
        local('mysqldump -uroot music -pパスワード --tables TABLE1 > TABLE1.sql')
        local('mysqldump -uroot music -pパスワード --tables TABLE2 > TABLE2.sql')
        local('mysqldump -uroot music -pパスワード --tables TABLE3 > TABLE3.sql')
        local('mysqldump -uroot music -pパスワード --tables TABLE4 > TABLE4.sql')
        local('tar cvzf uodataSql.sql.tgz TABLE*.sql')
        put('uodataSql.tgz', '/var/www/xxxx/sql/uodataSql.tgz')


    with cd('/var/www/xxxx/sql'):
        run('tar xvaf uodataSql.tgz')
        run('mysql -u root -pパスワード -e "DROP   DATABASE dbname2"', warn_only=True)
        run('mysql -u root -pパスワード -e "CREATE DATABASE dbname2"')
        run('mysql -u root -pパスワード dbname2 < TABLE1.sql')
        run('mysql -u root -pパスワード dbname2 < TABLE2.sql')
        run('mysql -u root -pパスワード dbname2 < TABLE3.sql')
        run('mysql -u root -pパスワード dbname2 < TABLE4.sql')

    with cd('/var/lib/mysql/'):
        run('mysql -u root -pパスワード -e "DROP   DATABASE dbname_bakup"', warn_only=True)

        sudo('/etc/init.d/mysqld stop')
        sudo('mv dbname dbname_bakup')
        sudo('mv dbname2 dbname')
        sudo('/etc/init.d/mysqld start')

MySQLでデータベース名を簡単に変更する方法

MySQLで既存のデータベース名を、コマンドラインから新しいデータベース名に変更するのが以外に面倒なので、簡単な方法。

MySQLで作成した「testDB」という名前のデータベースというのは、実は「/var/lib/mysql/testDB」というディレクトリーにテーブル毎のファイルが作成されているという構造なので、「testDB」というDB名から「testDB2」というDB名に名前を変更したいなら、「/var/lib/mysql/testDB」というディレクトリーを「/var/lib/mysql/testDB2」というディレクトリーに名前を変更してやれば、基本的にDB名を変更出来ます。

実際やるときには、MySQLサーバーを止めてから以下の感じで。

/etc/init.d/mysqld stop
cd /var/lib/mysql/
mv testDB testDB2
/etc/init.d/mysqld start