Overtoneオボエガキ

version date memo
0.1 2014/12/29 first
1.0 2015/1/1 実行, ネット動画関連追加

環境

OS Luxubuntu 12.04
Overtone 0.9.1
Clojure 1.6.0
Leiningen 2.5.0

必要な外部ソフトウェア

Linuxで行う場合、此処に書いてあるソフトウェアが必要なので、インストールする
Installing and starting jack · overtone/overtone Wiki · GitHub

# supercollider-serverは別に要らないかも知れない
sudo apt-get install supercollider-server
# Javaはインストール済みとする
sudo apt-get install jack-tools ant fftw3 qjackctl

プロジェクトの作成

次のリンクを参照する Clojureで音楽を奏でる | DevelopersIO
Leiningenを利用する

lein new music
cd music

依存するライブラリをmusic/project.cljに記述
Overtoneの最新バージョンは、GitHub - overtone/overtone: Collaborative Programmable Musicで確認する事

(defproject music "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.6.0"]
                 [overtone "0.9.1"]
                 ])
# 下記のコマンドで、必要なライブラリのダウンロード
lein deps
# 別ターミナルで、qjackでaudio serverを立ち上げておく
# (又は、qjaclctlで起動しておく)
jackd -r -d alsa -r 44100
# musicフォルダに移動し、REPLを起動
cd music
lein repl
;; 下記を実行
(use 'overtone.live)
;; ダメな場合は下記を実行(外部サーバを立ち上げる)
;; (よくわからないがOS-Xでinternal-serverの起動が出来ないっぽい)
(use 'overtone.core)
(boot-external-server)

毎回明示的に、外部サーバを立ち上げるのは面倒なので、デフォルトの設定を変更する。
下記のファイルを修正する。
~/.overtone/config.clj

;; サーバの指定が、内部サーバ(下記)となっているので
:server :internal,
;; 外部サーバに変更する(下記)
:server :external,
;; 上記の様に変更すると、下記コマンドで起動するようになる
(use 'overtone.live)

実行

ファイルロード@REPL

leinを利用したサンプルプログラムと実行方法については、下記を参照の事。
Overtone: Clojureで音楽を書こう : サルノオボエガキ
ファイルは、src/[プロジェクト名]/core.cljと同じ階層に置いておき、use, requireでロード出来る。
use/requireの話は、下記リンクが詳しい
require と use - 水底で思うこと

;; src/music/core.clj
;; namespaceとファイル名は一致させた方が良いみたい
(ns music.core
  :use [...])
;; 上記の設定の場合、下記の様にロードする
;; (ファイル名さえ合っていればロードは可能。
;;  REPL上ではWarningが出る)
(use 'music.core)       ; 名前空間を保持しない(Pythonのfrom A import A1の様なもの)
(require 'music.core)   ; 名前空間を保持する(Pythonのimport A.A1の様なもの)
;; 再読み込みの場合
;; (:reload-allで全再読み込み)
(use 'music.core :reload-all)
(require 'music.core :reload-all)
ファイル名について("-"問題)

詳しくは調査していないが、名前空間をat-allとしたい場合は、ファイル名をat_all.cljとしないとダメなようである。
下記リンクを実行しようとして、ファイル名をat-all.cljにした際に、use/requireが出来なかった。
因みにREPLでロードするときは、(use 'at-all)で良い。
overtone/at_all.clj at master · overtone/overtone · GitHub

(use 'overtone.live)でExceptionが発生する

(use 'overtone.live)で下記のようなエラーが発生した。

Exception Can't connect to native server - no compatible libraries for your system are available.  overtone.sc.machinery.server.connection/boot-internal-server (connection.clj:202)

(use 'overtone.core)を実行し、(boot-external-server)を実行すると、取り敢えず起動すると書いてあったので、
(参考: https://groups.google.com/forum/#!topic/overtone/Bi3R3jGewsI)
実行してみるが、下記のエラーが出て結局実行できない。

Connecting to external SuperCollider server: 127.0.0.1:48427
Exception in thread "Thread-10" java.io.IOException: Cannot run program "scsynth" (in directory "."): error=2, そのようなファイルやディレクトリはありません
	    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1047)
	    at java.lang.Runtime.exec(Runtime.java:617)
	    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	    at java.lang.reflect.Method.invoke(Method.java:606)
	    at clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:93)
	    at clojure.lang.Reflector.invokeInstanceMethod(Reflector.java:28)
	    at overtone.sc.machinery.server.connection$external_booter.invoke(connection.clj:231)
	    at overtone.sc.machinery.server.connection$external_booter.invoke(connection.clj:227)
	    at overtone.sc.machinery.server.connection$boot_external_server$fn__3997.invoke(connection.clj:309)
	    at clojure.lang.AFn.run(AFn.java:24)
	    at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.IOException: error=2, そのようなファイルやディレクトリはありません
	    at java.lang.UNIXProcess.forkAndExec(Native Method)
	    at java.lang.UNIXProcess.<init>(UNIXProcess.java:186)
	      at java.lang.ProcessImpl.start(ProcessImpl.java:130)
	      at java.lang.ProcessBuilder.start(ProcessBuilder.java:1028)
	      ... 12 more

overtoneのソースを見てみると、(use 'overtone.live)実行時のエラーは、scsynthが無い場合に発生するエラーらしいので、scsynthを下記コマンドによりインストールする。
Linuxの場合は、必要なソフトウェアがインストールされているかどうか確認する。(必要な外部ソフトウェア)
インストール後、(use 'overtone.live)は相変わらず、Exceptionを吐くが、(boot-external-server)は無事起動するようになった。

ネット動画(youtube, niconico)とかが固まる件

LeiningのREPLを起動し、JACKでSuperColliderの接続を行うとネットの動画(youtube, niconico)が固まる。
詳細な原因は不明であるが、JACKを終了すると、通常に再生されるので、JACKとFlash側の連携がとれていないんだろうと思い、調べてみるとPulseAudioとJACKの統合が必要との事であった。
下記のページを参考に、PulseAudioとJACKの統合を行う。
2.3.3. PulseAudio を JACK と統合する

# /etc/pulse/default.paをスーパユーザ権限で開く
sudo vim /etc/pulse/default.pa
# "#load-module module-alsa-sink"と書かれているコードの次辺りに下記のコードを記述する
load-module module-jack-sink
load-module module-jack-source

この設定を記述後、PC再起動なり、JACKの再起動なりを行うとQjackCtlの設定に"PulseAudio JACK Sink"と"PulseAudio JACK Source"が出てくるようになる。

JACKの接続を停止した場合

JACKの接続を停止し、再度接続を開始すると、ネット動画が固まるようになる。
取り敢えず、下記の手順で復旧できる。
1) ブラウザを落とす
2) JACKの接続を停止する
3) JACKの接続を開始する
4) ブラウザを起動する

stopメソッドについて

(use 'overtone.live) や (use 'overtone.core)をREPL上で実行しない場合、stopメソッドの名前空間のuseを行わないので、(stop)を実行してもエラーになる。
stopメソッドは、overtone.sc.serverに定義されているので、下記コマンドを打つか、overtone.live, overtone.coreの何れかをuseする必要がある。

;; 直に指定して実行する
(overtone.sc.server/stop)
;; 名前空間をuseして実行する
(use 'overtone.live)      ; 又は (use 'overtone.core)
(stop)

Clojureオボエガキ

version date memo
0.1 2014/12/27 first
0.2 2014/12/29 Vim,Leiningen追加

環境

OS Ubuntu 12.04
Clojure 1.2.1
Emacs 24.3.1
Vim Vi IMproved 7.3
Leiningen 2.5.0
Java 1.7.0_67

Leiningenインストール

Clojure自体はJVM上で動作するので、Javaのインストールは別途行って置くこと。
今回は、Clojureプログラミングを行うにあたって、プロジェクトの作成や実行環境などを提供するツールであるLeiningenをインストールする。
インストールは、Clojure 超入門 - Qiitaを参照する。

ダウンロード&インストール
# Download
wget https://raw.github.com/technomancy/leiningen/stable/bin/lein
sudo mv lein /usr/bin/ # 移動
sudo chmod +x lein     # 実行権限附与
lein self-install      # インストール

~/.lein以下にインストールされる

Emacs環境構築

ClojureプログラミングをEmacsで行う際の環境構築
パッケージ管理はCaskで行う
(2014/12/29 未完)

Caskのインストール

(参考) package.elから Caskに切り替えました - syohex’s diary

# インストール
curl -fsSkL https://raw.github.com/cask/cask/master/go | python
# Cask Update
cask upgrade

.bashrcファイルに次の設定を加える

# [user-name]には自分のユーザ名を入れる
export PATH=$PATH:/home/[user-name]/.cask/bin
パッケージのインストール

Caskファイルの作成
(作成場所は、任意で良いが、ファイルの措いてある場所にパッケージがインストールされる)
(参照) EmacsでモダンClojure開発環境構築 - Qiita

;; リポジトリの指定
(source gnu)
(source melpa)

;; インストールするパッケージ
;; Clojure
(depends-on "clojure-mode")
(depends-on "cider")
(depends-on "ac-nrepl")
(depends-on "clojure-cheatsheet")
(depends-on "clojure-test-mode")
(depends-on "slamhound")

;; Other
(depends-on "smartparens")
(depends-on "rainbow-delimmiters")    

インストール

# Caskファイルのある場所に移動
cd ~/cask
# インストール
cask install

この場合、パッケージ群は、~/cask/.cask/emacs-version以下にインストールされる

TODO

Vim環境構築

ClojureプログラミングをVimで行う際の環境構築
パッケージ管理はNeoBundleで行う

NeoBundle使い方

過去にまとめたもの vim環境設定 - オボエガキ用

Vimプラグイン

次のリンクにあるものを利用した http://blog.ieknir.com/blog/beginning-clojure-with-vim/
.vimrc辺りに下記を記述する。

" NeoBundleインストールファイル記述箇所に書く
NeoBundle 'guns/vim-clojure-static'
NeoBundle 'kien/rainbow_parentheses.vim'
NeoBundle 'tpope/vim-fireplacce'
NeoBundle 'tpope/vim-classpath'
...
" rainbow_parentheses.vimの色付け設定
au VimEnter * RainbowParenthesesToggle
au Syntax * RainbowParenthesesLoadRound
au Syntax * RainbowParenthesesLoadSquare

記述後、Vimを再起動しインストール

実行してみる

Leiningen実行を参考にしプロジェクトを作成する
src/hello/core.cljを開く
Vimのコマンドで :Eval (foo "x") と実行すると"Hello, World!"が出力される

便利コマンド

参考 : fireplaceを使うと、VimでClojureを書くのが苦労じゃなくなる - pompopo.log

:Eval (...) " (...)の部分を評価
:%Eval      " ファイル全体を評価
cpp         " カーソルが含まれる括弧を評価
cqc         " 一行限定のREPLを開く

Leiningen実行

詳しくは、次を参照のこと Leiningen入門(再) - CLOVER🍀
下記によりREPL環境を起動する

mkdir work     # 作業フォルダ作成
cd work        # 移動
lein new hello # プロジェクト(hello)作成
cd hello       # プロジェクトフォルダに移動
lein repl      # nREPL起動

Common Lispオボエガキ

version date memo
0.1 2014/12/09 first
0.2 2014/12/21 export周りの微修正

環境

OS Ubuntu 12.04
Common Lisp 2.49

パッケージ

詳しい仕組みはよくわからないが、取り敢えず下記でどうにかパッケージングができる。
詳細は後日調べる。

; -------------------------------
; ライブラリ側(mylib.lisp)
; -------------------------------
(provide :|mylib|) ; イマイチ何に効いてくるのか分からない(provide)
(defpackage :|mylib2| ; パッケージ名の定義
  (:use common-lisp) ; Common Lispを使うことの宣言?
  ; シンボル名を記述する。定義したシンボル名の前に":"を付ける
  ; (関数、マクロ、変数等を記述する。)
  (:export :hello)
)
(in-package :|mylib2|)
; ここから関数等定義
(defun hello ()
  "HELLOと出力する関数"
  (print 'HELLO))

; -------------------------------
; 呼び出し側(main.lisp)
; -------------------------------
(require :|mylib|) ; ファイル名(mylib.lispの拡張子を除いた部分)
(use-package :|mylib2|) ; パッケージ名(mylib2)
(hello) ; => HELLO

ショートカットキー関連

version date memo
0.1 2014/11/24 first
0.2 2015/03/01 vim関連追加

環境

OS Ubuntu 12.04
Emacs 24.3.1
vim VI Improved 7.3

vim

機能 モード コマンド 備考
入力補完 Input Ctrl-n, Ctrl-p
範囲選択(行) Input Shift-v
範囲選択 Input Ctrl-v
vim設定ファイル再読み込み Command :source .vimrcのパス
置換 Command :%substitute/変換前文字列/変換後文字列/gc ファイル全体に対して行う(gcを省くと勝手に全部変更)
範囲選択と組み合わせ可能
%sでもよい

PythonTips

version date memo
0.1 2014/11/15 first

環境

OS Ubuntu 12.04
Python 2.7.3

概要

2年ぐらいPythonをやっていて溜まってきたTipsを書く

関数型言語っぽい実装

curry化

PythonのDecorator機能を用いて、curry化を実装出来る。
下記URLに実装と使い方が載っている。
PythonDecoratorLibrary - Python Wiki
実際にプログラムに組み込む際は、上記ファイルを「curry.py」などで保存して、「from curry import curried」をimport文で記述すると良い。

メソッドチェーン的な何か

此処の記事の「f_chain」を利用してメソッドチェーン的なものを利用する。
Python で Clojure っぽい関数チェーン。 - 水底で思うこと
下記の様にすると、partialが不要になり、便利さが更に加速する。

@curried
def cmap(f, x): # curry化対応map
    return map(f, x)
f_chain(a, sorted, reversed, cmap(str), '-'.join, print)

Iteration関連のゆーてぃりてぃ

Iterableかどうか

下記URL参照
A-Liaison BLOG: Pythonで変数の型をチェックする方法(Javaでいうinstanceofが使いたい)

def isiterable(x):
    return isinstance(x, basestring) or hasattr(x, '__iter__')
最終要素のフラグ付きループ

Iterableなデータ(iter, string, list, dict...)を渡すと、最終要素かどうかのフラグと要素を返すiteratorを返す。

def last_flagged(x):
    if not isiterable(x):
        raise TypeError("Invalid Type, Must be iterable: %s" % type(x))
    seq = iter(x)
    cur = next(seq)
    for y in seq:
        yield False, cur
	cur = y
    else:
        yield True, cur
# 使い方
for flag, x in last_flagged([1,2,3]):
    print flag, x
# => False, 1
#    False, 2
#    True, 3
タプルキーの分解

辞書形式でデータを登録する際に、キーをタプルで登録しておいて、後でキーの階層化を行う関数。
これを使うので注意

from collections import defaultdict

def split_keys(dic):
    if not isinstance(dic, dict):
        raise TypeError("Invalid Type, Must be dict: %s" % type(dic))
    result = dict()
    for mul_key, val in dic.items():
        target = result # ループ用
        for flag, key in last_flagged(mul_key):
            if flag:
                target[key] = val
                continue
            # keyを持っていない場合は初期化
            if not target.has_key(key):
                target[key] = {}
            target = target[key] # 次の階層へ
    return result
## 使い方
dic = {}
dic[(1,2,3)] = 10
dic[(1,2,4)] = 20
dic[(1,3,3)] = 30
dic[(1,3,4)] = 40
print split_keys(dic)
# => {1: {2: {3: 10, 4: 20}, 3: {3: 30, 4: 40}}}
# 但し
# dic[(1,2)] = 10
# などタプルのサイズが違うものが混じっているとエラーになるので注意
辞書をデフォルト値で持つdefaultdict

defaultdict(dict)としようとすると、エラーになってしまうが、どうにかしてdefaultdictの初期値をdict(又はdefaultdict)にしたいという場合。
下記参照
dictionary - Multiple levels of 'collection.defaultdict' in Python - Stack Overflow

dic = defaultdict(lambda : dict)
dic[1][2] = 2
# => {1: {2: 2}}
dic2 = defaultdict(lambda : defaultdict(int))	
dic2[1][2] += 1
# => {1: {2: 1}} # 初期値が0なので1となる

Pythonの文法関連

PEP8準拠

PEP8とか言うpythonのコーディング規約がある。
そのスタイルに則って作業を行えば、Pythoniaにとって読みやすいコードが出来るはず。
スタイルチェックとか自力でやるのは面倒だよね。
ということで、pep8というコマンドがあるらしい。

pep8解説記事
Python のソースコードを自動で PEP8 に準拠させるツール autopep8 | CUBE SUGAR STORAGE
PEP8翻訳
https://dl.dropboxusercontent.com/u/555254/pep-0008.ja.html

Haskellでゲーム

version date memo
0.1 2014/08/31 first

環境

OS Ubuntu 12.04
GHC 7.4.1

概要

Haskellでゲームが作りたいので、参考となりそうなサイト等をまとめる。

SDLインストール

参考
http://www23.atpages.jp/k0n0f/?p=69
しつこいがまだライフゲームだ(RepaとSDLで) - Qiita
ゲーム
Google Code Archive - Long-term storage for Google Code Project Hosting.
# SDL本体インストール
sudo apt-get install libsdl1.2-dev
sudo apt-get install libsdl-image1.2-dev
sudo apt-get install libsdl-ttf2.0-dev
sudo apt-get install libsdl-mixer1.2-dev
sudo apt-get install libsdl-gfx1.2-dev
# C言語 To Haskell?
sudo apt-get install c2hs
# CabalでSDLのインストール
cabal install sdl

ちゃんとインストールされているかの確認は、上記のゲームをDLしてコンパイルしてみると良い。