自分の興味の赴くままにIT技術系のネタを取りとめもなくメモっています。
Ruby言語やLinuxのネタが多いです。

March 04, 2006 [長年日記]

[Misc] midiファイルをテンポを変えつつmp3へ変換する

唐突感があるけど自分用メモ、とJazzを練習しているLinuxユーザーの方へ(ニッチだ・・・)。

Jazzのアドリブを練習するとき、特に和音の出せない管楽器ではなかなか自分の吹いてる音があってるのかわからない。誰かバック弾いてくれ〜と思っても友達イナイ。っていう人向けにJazzのCD付き教則本として「マイナスワン」というシリーズが売ってる。主旋律が入っていないので、それに合わせて練習できる(要はカラオケ)。

・・・・なんだけど、オレみたいな下手っぴでは、もっと遅いバージョンじゃないと吹けない、なんてことも多々ある。

そこで、オレが最近編み出した(今さら知ったとも言う)のは、midiファイルからテンポを変更しつつをmp3化してiPodに落としそれを聴きながら練習する、ってこと。これはイイ!

#ポータブルMIDIプレーヤ買えばその場でテンポ変えつつ練習できるよ!

#なんていう富豪的アプローチはなしの方向で(^^;)。

ということで手順。

まずは1つのテンポでmidiを作る。Rosegardenがかなり使えると思う。一から作ることもあるけど単純なものでも結構面倒くさい。Jazzのスタンダードであればインターネットでフリーのmidiファイルが公開されてたりするので、それを頂いてきてメロディの部分をざっくり削除して、思う存分繰り返しを入れる。んで保存、が楽なのでオススメ。

で、次に、timidity++(どこが公式サイト?http://timidity.jpっぽいけどなぜかつながらず・・・)と午後のこ〜だid3libに含まれるid3tag、shell(zsh)を使って以下のようにすると複数テンポのmp3ができる。もちろん、Rosegardenでテンポを変更したmidiファイルを作っても良いけどこっちの方が圧倒的に楽。

各ツールにはホント感謝だ。ありがたいことです。

 % foreach i in 80 100 120 150 200
 timidity -T $i -Ow FOO.MID
 gogo FOO.WAV foo_$i.mp3
 id3tag -aPractice -APractice -gJazz -sFoo_$i foo_$i.mp3
 end

  • FOO.MIDはmidiファイル名、FOO.WAVはFOO.MIDに合わせる。foo_$i.mp3は出力先ファイル名ね。foo_80.mp3みたくなる。
  • timidityの-Tオプションは原曲に対するテンポを割合(%)で指定していることに注意。なので、元々のmidiファイルをテンポ100で作っておくと吉。
  • id3tagでアーティスト名、アルバムタイトルをPractice、ジャンルをJazz、タイトルをFoo_(テンポ)に設定している。この設定はiPodで表示するのに使われる。
  • んで、あとは、iPodに転送すればOK。オレはgtkpodを使ってるのでそれで説明。

    まず、適当なディレクトリにfoo_*.mp3をコピーする。

    次に「ファイル(F)」→「ディレクトリを追加する(D)」でそのディレクトリを選択。

    アーティストなどが空欄のところにコピーしたファイルが出てくるので、gtkpod上で空欄を埋めていく。オレはpracticeって名前を付けてる。

    んで、ツールバーのところの「更新」をクリック。以上!

    あ、そうそう。例えばブルースとかでキーがC, A, F, G, Bbくらいのバージョンも欲しいなぁ、と言う場合は、timidityの-kオプションを使えばOK。

    元がCの曲であれば、Aが、"-k -3"、Fが、"-k 5"、Gが "-k 7"、Bbが "-k -2" かな、たぶん。


    March 09, 2006 [長年日記]

    [Misc] 警察のパソコン、「ウィニー」使用禁止 警察庁が通達

    ちょっと古いけど。あと、「警察職員の意識欠如」 ウィニー問題で漆間長官が苦言ね。

    感染してた警察官のパソコンのローカルフォルダには著作権違反のコンテンツがどっさりあったりして。そういうのって追求されないのかなぁ。私物パソコンだってダメだよね。岡山県警の内部情報が流出したのも問題だけど、そもそも警察官が自ら著作権違反してたってのも問題だと思うんだけどなぁ。

    なんかさ、そういうの、身内からしっかりと取り締まってくれないと、Winny作者が逮捕されたのが浮かばれないよなぁ。幇助どころか実行犯がいるのかもしれないんだもん。苦言だけだなんて身内には甘いよなぁ。

    って、自分には甘いってことでは、人のことは言えないけどさ(苦笑)。


    March 10, 2006 [長年日記]

    [Misc] rikaichan

    via スクリチ diary

    日本語を英語・ドイツ語・フランス語に翻訳するためのFirefoxエクステンションだそうです。名前が目を引きますが、スクリーンショットにもなかなかのセンスを感じますね(笑)。

    いや、アプリ自体は良い感じですよ、ホント。


    March 11, 2006 [長年日記]

    [Ruby] Ruby-GetText-Package-1.3.0

    リリースしました。今回はみなさんからいろいろなアイデア&バグレポートをいただき、特にRuby on Rails周りで機能向上しました。ぜひ、お試しくださいませ。

    目玉1:[RoR] ローカライズド・テンプレートのサポート

    例えば、app/views/foo/list.rhtmlというファイルに対し、app/views/foo/list_ja.rhtmlという名前のファイルを用意すると日本語の場合のみそちらを読み込むようになります。しかも、どちらのファイルとも、従来通り、_("")等のGetTextのメソッドを利用することが可能です。

    これはつまり、基本的には通常用意されたテンプレートを、ある特定の言語のみ特別なテンプレートを使うことができる、ということになるため、可能な限りテンプレートは1つにしてDRYに開発できるメリットを残せると思います。 Thanks to Yuguiさん。

    目玉2:[RoR] ActionMailerのサポート

    ActionMailerのテンプレートファイル(.rhtml)にも_("")等のGetTextのメソッドを利用することが可能になりました。扱いはViewのテンプレート(.rhtml)と同じですので、上のローカライズド・テンプレートも使用可能です。

    また、日本語の場合のみ、ISO-2022-JPでメール送信するようになりました。

    ActiveHeartに含まれるIso2022Mailerを作者のdrawnboyさんのご厚意で取り込まさせて頂きました。ただ、Iso2022MailerではメールのSubjectがUTF-8で変換されてしまい、私のメーラでは文字化けになってしまっていたので、その辺はmoriqさんのActionMailerに関する記事を参考にメールのSubjectもISO-2022-JPで送信するようにしてあります。

    #こういう微妙な調整は作者が日本人の特権ですね(^^)。

    目玉3:[RoR] ActiveRecord::Column.human_nameのローカライズ

    ActiveRecord::Column.human_nameがそのModelクラスから抽出したmsgidを用いて翻訳するようになりました。今まではエラーメッセージ用でしたが、scaffoldで生成したノーマルのテンプレートファイルでも自動的に翻訳される部分が増えたと思います。

    #ざんねんながら、scaffold時にすでに文字列としてカラム名が埋め込まれてる部分があって、そこはもうしょうがないんですけどね。

    Thanks to: ZnZさん

    目玉4:[RoR] @params["lang"]を最優先でチェックするようになりました

    例えば、routes.rb等で@params["lang"]をセットすると、その言語が使われるようになりました。

    Thanks to: Erkki Eilonenさん

    その他、バグ修正として、RoR周りではproductionモードで動作するようにしたのと、メモリリークの修正、あとはLocale::Objectの改善、などなど。盛りだくさんです。

    そうそう、RoRのモデルでvalidates_* のmessageをローカライズする場合、_("")の代わりにN_("")を使ってください。そうしないと、productionモードで表示文字が変わらなくなるので注意してください。

    class Article < ActiveRecord::Base
     validates_presence_of :title, :message => N_("%{fn} can't be empty")
     set_error_message_title(N_("An error is occured on %{record}"),
                             N_("%{num} errors are occured on %{record}"))
    end
    

    本日のツッコミ(全2件) [ツッコミを入れる]

    nov [ActionMailer のサポートがうれしいのですが、 multipart なメールを ja な環境で送るとおかし..]

    むとう [うぅ。multipartなメールは考えてませんでした(汗)。 よろしければサンプルコードをいただけないでしょうか。..]


    March 21, 2006 [長年日記]

    [Ruby] Ruby/CLDR-0.1.0

    最近、Ruby-GetText-Packageを開発するにあたっていろいろと「国際化」というものについて考えさせられることが多くなってきました。

    以前はこんなことを言っていたけど、これは避けて通れないような気がしてきたのでもう一歩先に踏み出すことに...。

    というわけで、すごく悩んでいたのですが、密かに新たなプロジェクトを始めることにしました。それが、このRuby/CLDRです。これがきっと人生最後のライブラリ開発になると思います(って宮崎駿みたいなこと言ってるな(苦笑))。

    で、Ruby/CLDRですがローカライゼーションのためのライブラリで、最終的には日付、通貨に代表される地域ごとの情報を適切に取得したり書式指定して表示したりするAPIを提供するライブラリを目指します。

    といっても、0.1.0では、単にCommon Locale Data Repository (CLDR) Projectが提供しているXMLロケールデータをRubyから簡単にアクセスできるようにしただけです。そこで力尽きました(苦笑)。

    以下のように使います。

     $ cat test.rb
     require 'rubygems'
     require_gem 'cldr', '= 0.1.0'
     require 'cldr'
     
     obj = CLDR::Object.new
     puts obj.core.languages["ja"]
     puts obj.calendar.dateformats[:gregorian]["full"]
     obj = CLDR::Object.new(:locale => Locale::Object.new("fr_FR"))
     puts obj.core.languages["ja"]
     puts obj.calendar.dateformats[:gregorian]["full"]
     $ ruby test.rb
     日本語
     yyyy'年'M'月'd'日'EEEE
     japonais
     EEEE d MMMM yyyy
    

    XMLデータにアクセス、と書きましたが、XMLデータに直でアクセスするような実装だとXMLのparseにも時間がかかりますし、さらに、CDLR(LDML)の複雑なルールを正しく動作させるのはとても大変なので、性能的に問題が出ます。そこでまずはXMLファイルから各言語別のリソースファイル(rubyスクリプトファイル)化するジェネレータを作って、ランタイムではそのロケールファイルを呼び出すだけにして性能を確保しています。

    ちなみに私の非力なマシン(Athlon 1.3GHz)だと、全ロケール分のリソースファイルを生成するのに38分ほどかかります。ホント大変です(苦笑)。

    #リリース時は生成済みの状態で配布されますのでご心配なく。

    APIドキュメントもありませんが、ソースを見て頂くとやっていることは今のところ極めて単純なので、まぁ、いろいろと試してみてください。

    次のフェーズとしてはFormat関連のAPIを提供しようかなと思っています。

    そのためには、CLDRが提供する各種フォーマットを適切に扱う関数群が必要になります。例えば上の例の"yyyy'年'M'月'd'日'EEEE"とか。

    結構、量があるので、どなたかご協力頂けないでしょうか。興味のある方は私までメールくださいませ。

    あ、そうそう、Ruby/CLDRはRuby-GetText-Packageに依存しています。最終的には、この2つの組み合わせで表示周りのローカライズの大部分をカバーできればいいなと考えています。

    それから、APIはしばらくunstableです。もし、今すぐ使ってみようという方がいらっしゃいましたら、gem+バージョン指定でお使いください。こういうときにはrubygemsは便利ですねぇ。

    ちょっと後先が逆になりましたが、同様のライブラリとしてICUというIBMが提供しているライブラリがあり、それのRubyバインディングICU4Rも存在します。

    実は、車輪の再発明のことを考えるとこれをそのまま使うのがホントは一番良いような気がしたのですが、ICU自体がかなり大きなライブラリだし、ICU4Rは今のところUnicodeサポートをメインに考えているようでフォーマット関連をまだサポートしていません。私的にはUnicodeサポートはRuby-2.0で解決されると思ってますし、ResourceBundleを使うんだったらRuby-GetText-Packageを使って欲しいので、ICU4R自体に私がお手伝いするのはちょっとなぁ、というわけで自分で始めることにしました。

    #将来的にICU4Rが充実してきたらこちらを辞めるかもしれません。

    あと、何かとRuby-GetText-Packageと比較されるGlobalizeですね。これも、かなり限定された範囲内で機能が重複しますが、まぁ、あれはRailsの中で使うライブラリですから今回は対象外ですね。

    っと、それ以外に、すでに同様のプロジェクトを始めている方(ICU4R以外で)がいらっしゃいましたらご連絡を。今ならまだやめれます(苦笑)。

    あ、そうそう、ファイルでかいです。3MBちょいあります(汗)。元のCLDRファイル(core.zip)の3倍ありますが、これは、元のXMLファイルが、「この部分は〜を参照」みたいな感じになっているのを、高速化のために全部展開しているためです。この辺は見直した方が良いかもしれませんね。

    最後に。ちょっと名前がなー。Ruby/Localeにしようかと思ったんだけどそういうプロジェクトもうあるしね。CLDRだといまいちピンとこないんだよなぁ。

    追記:setup.rb付け忘れました。gemじゃない人は自分でlib配下をコピーしてください。すんません。


    March 25, 2006 [長年日記]

    [Rails] Ruby-GetText-PackageでActionWebServiceのサポート

    Ruby-GetText-Package-1.3.0とActionWebServiceを一緒に使うとエラーになるとレポートがありましたので修正しました。ActionWebServiceを使ってる方でかつRuby-GetText-Packageを使おうと考えている方はCVS版を使ってください。

    その際に(需要があるかどうかは疑問だったのですが)、ActionWebServiceでlangパラメータを指定してあげると、controller側でローカライズができるようにしてみました。

    # app/apis/product_api.rb
    class ProductApi < ActionWebService::API::Base
      api_method :find_product_by_id, :expects => [:lang => :string],
                                      :returns => [{:string => String}]
    end
     
    # app/controller/backend_controller.rb
    class BackendController < ApplicationController
      wsdl_service_name 'Backend'
      web_service_api ProductApi
      def find_product_by_id(id)
       _("foo") + ...
      end
    end
    

    [Rails] config/routes.rbで言語を指定する

    こちらはRuby-GetText-Package-1.3.0ですでにサポートしているのですが、以下のようにするとURL内で言語を指定することができます。

    ActionController::Routing::Routes.draw do |map|
     map.connect 'main_ja', :lang=>'ja', :controller=>'blog', :action=>'list'
     map.connect ':controller/:lang/:action/:id'
    end
    

    1つめのmap.connectでは、http://yourhost/main_ja とするとblog_controller.rbのlistアクションを呼び出すのですが、その際に@params["lang"]に"ja"が指定されるため、Ruby-GetText-Packageは日本語を強制的に表示し(ようとし)ます。

    同様に2つめのmap.connectでは、http://yourhost/blog/ja/list/等とすると日本語を表示し(ようとし)ます。


    March 28, 2006 [長年日記]

    [Ruby] Ruby-GetText-PackageがOpenBSDで動作しない

    とのレポートをもらった。コンパイルエラーになるらしい。

    コンパイルログを見るとlanginfo.hあたりでCODESET定数が定義されていないっぽい。

    しょうがないのでVMWareにOpenBSD3.8インストール中。先は長い...。

    OpenBSD3.8ってかなり古めなインストーラなのね。最初やり方わからなかったよ(^^;)。


    March 29, 2006 [長年日記]

    [Ruby] Ruby-GetText-PackageがOpenBSDで動作しない(2)

    ってか、そもそもruby-1.8.4がコンパイルできない。

    strcpyとかsprintfとかが全部strlcpy, snprintf等に変更しないとダメらしい。厳しいのう。


    March 30, 2006 [長年日記]

    [Ruby] Ruby-GetText-PackageがOpenBSDで動作しない(3)

    自力でコンパイル通すのは断念。ftp.openbsd.orgにあったruby-1.8.1p0.tar.gzをpkg_addした。

    strcpyとかのバッファオーバフローをケアするのもわかるんだけど、rubyの最新版(1.8.4)を用意して無いってのはセキュリティ的には問題アリな気がする。まぁ、ruby使わなければいいのか...。

    いずれにせよ、1.8.1p0でrubyが動くことは確認できたので、明日はRuby-GetText-Packageの方を見てみるとするか...。