WindowsにSWIG導入
SWIG (Simplified Wrapper and Interface Generator) は、 C/C++ で書かれたプログラムやライブラリをPythonやJavaなどのスクリプト言語から使えるようにするためのツール。PybindやCythonなど、類似品もありますが、2次元の物理エンジンpybox2dがSwig依存でしたので導入。
MINGW+MSYSの導入
まずSWIGをビルドする環境を整えます。
おおよその流れはこちら ⇒ MinGW+MSYSのインストール(2014年5月) | The Textbook of RayTracing @TDU
- g++
- MinGW AutoTools(autoconf, automake)
- MYSYS ( bison / flex / tar / gzip / bzip2 / base / autoconf, automake)
は必ず必要なのでチェックを忘れないようにしましょう.
また、環境変数のPathに
の追加を忘れないように!
SWIGとPCREの準備
- Githubからswigをクローン (C:\MinGW\msys\1.0\home[ユーザー名]に展開)
- ~/Swig/直下にPCREからダウンロードしてきたtarファイルを置く (pcre-8.39.tar.gzまたはpcre-8.39.tar.bz2など)
SWIG/PCREのビルドとインストール
前項の続きから、
- “C:\MinGW\msys\1.0\msys.bat"を起動
- ~/Swig/Tools/pcre-build.shを実行し、PCREをビルド
- ~/Swig/autogen.shを実行⇒configureが生成される
- ~/Swig/configureを実行
- makeでビルド [make; make install]
$ cd ~/Swig
$ ~/Swig/Tools/pcre-build.sh
$ ~/Swig/autogen.sh
$ ./configure
$ make
$ make install
これで、C:\MinGW\msys\1.0\home[ユーザー名]\swig.exeが吐き出されるので、パスのとおる所に移せばインストール完了。 とりえあえず、C:\MinGW\binにコピーしておきました。
FAQ的な
Error: Unknown directive が出る
Error: Unknown directive ‘%exception'や Error: Unknown directive ’%pythoncode'が吐き出される場合ですが、~/Swig/Lib/の中身が参照できるところに入っていますか?
下記いずれかで直ると思います。
- make installを忘れない
- swig.exeからの相対パスが./Lib/になる場所にLib以下をコピー
- C:\MinGW\msys\1.0\local\share\swig\3.0.11以下にLibをコピー
参考の記事:// Swigが参照するパスについて
Configure中にsyntax error near unexpected token ‘fi'がでる
syntax error near unexpected token ‘fi’ · Issue #815 · swig/swig · GitHub
環境によっては出るようです。
Line 5855 and line 5975 have “else” tokens that should be removed.
とあるようにfiの直前のelseを消しましょう。空のelseがあるのが良くありません。
代替手段(2017-03-01追記)
Anacondaでもswigの準備があるようです
conda install swig
いろいろ苦労したのがコマンド1つで解決
[Python] タスクトレイ アイコンのツールチップ テキストを取得する
タスクトレイ(通知領域)に収められているアイコンのツールチップには、タスク自動化などで使える情報がたくさんあります。 例えばGoogleフォトバックアップでは「写真100枚をバックアップしました」などとお知らせしてくれます。
これをPythonで取得して使えるようなlist形式にします。
ツールチップのイメージ
2つの通知領域
Windows 7以降には、常時表示される通知アイコンと通常隠れていて表示をOn/Offできるものがあります。
(それぞれの切り替えには下記を参照してください)
⇒ Windows 10 タスクバーの通知領域のアイコンを非表示にする
それぞれのアイコンのツールチップは別々のWindowにぶら下がっており、Spy++などでハンドルを見ると
- 常時表示される通知領域
- Shell_TrayWnd > TrayNotifyWnd > SysPager > ToolbarWindow32 以下の"ボタン"としての性格
- 通常非表示の通知領域
- NotifyIconOverflowWindow > ToolbarWindow32 以下の"ボタン"としての性格
を持つことがわかります。
ツールチップテキストの取得
WindowsのAPIをふんだんに使うので、まずPython for Windows Extensionsが必要になります。Anacondaの人は、最初から入っていると思います。
ツールバーのWindowハンドルをFindWindow/FindWindowExで取得したら、 あとはメモリからテキストを読み込んでいくだけの簡単なお仕事になります。
# -*- coding: utf-8 -*- import win32gui, win32process, win32api, win32con import ctypes, copy PAGE_READWRITE = 0x04 MEM_COMMIT = 0x1000 MEM_RESERVE = 0x2000 MEM_RELEASE = 0x8000 TB_BUTTONCOUNT = 0x418 TB_GETBUTTONTEXT = 0x42D tipslist = [] def GetTips(hWnd): threadId, processId = win32process.GetWindowThreadProcessId(hWnd) pHandle = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, 0, processId) VirtualM = ctypes.windll.kernel32.VirtualAllocEx(pHandle.handle, 0, 256, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE) # タスクアイコン数取得 count = win32api.SendMessage(hWnd, TB_BUTTONCOUNT, 0, 0) for i in range(count): res = win32api.SendMessage(hWnd, TB_GETBUTTONTEXT, i, VirtualM) STR = ctypes.create_string_buffer(1024) print i,res, STR ctypes.windll.kernel32.ReadProcessMemory(pHandle.handle, VirtualM, STR, 1024, 0) tipslist.append(copy.copy(STR.value.decode('cp932'))) print STR.value.decode('cp932') ctypes.windll.kernel32.VirtualFreeEx(pHandle.handle, VirtualM, 0, MEM_RELEASE) ctypes.windll.kernel32.CloseHandle(pHandle.handle) # 常時表示のタスクトレイからWindow Handle取得 hW = win32gui.FindWindow("Shell_TrayWnd", None) hW = win32gui.FindWindowEx(hW, 0, "TrayNotifyWnd", None) hW = win32gui.FindWindowEx(hW, 0, "SysPager", None) hW = win32gui.FindWindowEx(hW, 0, "ToolbarWindow32", None) GetTips(hW) # 通常非表示のタスクトレイからWindow Handle取得 hW = win32gui.FindWindow("NotifyIconOverflowWindow", None) hW = win32gui.FindWindowEx(hW, 0, "ToolbarWindow32", None) GetTips(hW) # 取得した結果の表示 print("\nタスクアイコン数:", len(tipslist)) print(tipslist)
WAVファイル, MP3ファイルを無音部分で分割
仕事で音声ファイルを無音部分で分割する必要がでてきたけど、 Audacityでやっても分割前の空音が残ってしまったり、保存時のファイル名指定が面倒だったり、 なかなか思い通りにならなかったのでPythonで処理しました。
必要なものなどのメモ書き。
環境
ライブラリのインストール
AnacondaでFFMPEGはmenpoさんが公開しているので、これを使った。
conda install -c menpo ffmpeg
また、pydubはpipでインストール.
pip install pydub
ファイルの読み込み~無音部分での分割
pydubにsplit_on_silenceというクラスがあるので、これを使うだけ。
from pydub import AudioSegment from pydub.silence import split_on_silence sound = AudioSegment.from_file("./untitled1.wav", format="wav") chunks = split_on_silence( sound, # 1500ms以上の無音がある箇所で分割 min_silence_len=1500, # -30dBFS以下で無音とみなす silence_thresh=-30, # 分割後500msだけ、無音を残す keep_silence=500 ) # 分割数の表示 print len(chunks)
表示された分割数で所望数通り、分割されているか確認してね。 silence_threshやmin_silence_lenのパラメータで多少の調整は必要。
ファイル名リストの作成~保存
作成したいファイル名が連番でなかったので、リストで作成(ここは好きにすればよい)。 その名前に従って分割した音声ファイルを保存。前節の分割数とfilelistの要素数が同じになるように注意。
filelist = ["file_hoge1","hogegennhogehoge","foo_bar","lucky_you",] for i, chunk in enumerate(chunks): chunk.export(u"./分割/"+filelist[i]+".wav", format="wav")
Easy peasy Japanesey!