<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>NASKIT &#187; HT-03A</title>
	<atom:link href="http://naskit.com/category/ht03a/feed/" rel="self" type="application/rss+xml" />
	<link>http://naskit.com</link>
	<description>AndroidとかUnityとか</description>
	<lastBuildDate>Sun, 15 Apr 2012 09:14:00 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>EVOゲットした</title>
		<link>http://naskit.com/2011/10/01/evo%e3%82%b2%e3%83%83%e3%83%88%e3%81%97%e3%81%9f/</link>
		<comments>http://naskit.com/2011/10/01/evo%e3%82%b2%e3%83%83%e3%83%88%e3%81%97%e3%81%9f/#comments</comments>
		<pubDate>Fri, 30 Sep 2011 18:04:55 +0000</pubDate>
		<dc:creator>saikoro</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[EVO]]></category>
		<category><![CDATA[HT-03A]]></category>

		<guid isPermaLink="false">http://naskit.com/?p=727</guid>
		<description><![CDATA[au のEVO Wimax をゲットした。 HT-03Aをゲットして2年。縛りもなくなって解約するつもりだったのだが、EVOがNMP一括激安販売してたし、毎月割2800円以上ってことで2年間月4600円くらいで使えるって [...]]]></description>
			<content:encoded><![CDATA[<p>au のEVO Wimax をゲットした。</p>
<p>HT-03Aをゲットして2年。縛りもなくなって解約するつもりだったのだが、EVOがNMP一括激安販売してたし、毎月割2800円以上ってことで2年間月4600円くらいで使えるってので購入したのだ。</p>
<p>イーモバイルHTC Ariaで格安テザリングができるので良かったのだが家の中で電波が届かなくて電話が出来なかったので、Ariaを寝かすことにした。</p>
<p>それにしてもHT-03A, S31HT, ISW11HTって3台ともHTCですな。<br />
まるで熱烈HTCファンみたいやないか。<br />
やっぱグローバル機がええですわ。うん。</p>
<p>ISW11HTの特徴はなんといっても＋Wimaxで パケット料金にプラス525円でWimaxテザリングができるってこと。Wimaxが圏外なら3G回線でもテザリングができる。<br />
基本料金980円IS NET315円 パケット定額 5400円 プラスWimax525円だったかな。<br />
これ1台でOKってのがよい。</p>
<p>auの通信方式のWCDMA2000ってのは3Gのパケット通信と通話が同時にできないらしくコンテンツダウンロード中に電話があると通信が止まってしまうらしい。<br />
これはスマートフォンではキッツイことですな。<br />
でもISWシリーズの端末ならWimaxで通信中は通話もできるようで、これならメイン携帯1台持ちでも使えそう。</p>
<p>2011年の春モデルだったのだけどもこんなに安くなるとは驚きだけども、これからISWシリーズがたくさん出るので在庫一掃セールだったのだろうな。<br />
バッテリーの消費が激しいのが弱点だけどもAndroid2.3にアップデートしてから心なしかマシになった気がする。<br />
EZWEBのメールもできるようになったし、au-oneマーケットも対応した。</p>
<p>これから2年間はこれ1台でいけそうだ。</p>
<p>また悪いクセが出ませんように。</p>
<div class="plus-one-wrap"><g:plusone size="medium" href="http://naskit.com/2011/10/01/evo%e3%82%b2%e3%83%83%e3%83%88%e3%81%97%e3%81%9f/"></g:plusone></div>]]></content:encoded>
			<wfw:commentRss>http://naskit.com/2011/10/01/evo%e3%82%b2%e3%83%83%e3%83%88%e3%81%97%e3%81%9f/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ToyCamのアクティブインストールが1万件越え</title>
		<link>http://naskit.com/2010/05/11/toycam%e3%81%ae%e3%82%a2%e3%82%af%e3%83%86%e3%82%a3%e3%83%96%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab%e3%81%8c1%e4%b8%87%e4%bb%b6%e8%b6%8a%e3%81%88/</link>
		<comments>http://naskit.com/2010/05/11/toycam%e3%81%ae%e3%82%a2%e3%82%af%e3%83%86%e3%82%a3%e3%83%96%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab%e3%81%8c1%e4%b8%87%e4%bb%b6%e8%b6%8a%e3%81%88/#comments</comments>
		<pubDate>Mon, 10 May 2010 18:28:21 +0000</pubDate>
		<dc:creator>saikoro</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[HT-03A]]></category>
		<category><![CDATA[ToyCam]]></category>

		<guid isPermaLink="false">http://naskit.com/?p=393</guid>
		<description><![CDATA[ToyCamのアクティブインストールが1万件越え]]></description>
			<content:encoded><![CDATA[<p>ToyCamのアクティブインストールが1万件を越えていた。</p>
<p>HT-03Aをゲットしてから8ヶ月。スマフォといえばサイレントカメラというノリで作成したが、正直いってココまで伸びるとは思わなかった。最近追加したしょぼいトイカメラ風エフェクトは貢献していないのだろうな・・。多分Xperia効果だろう。Desire効果もあるかもしれん。</p>
<p>もっといいアプリが出たらそっちに乗り換えようと思っていたのだが、食い物屋さんで出てきた料理をTwitterにアップするときなんかに使えているので満足である。</p>
<p>0.6.1までバージョンアップしてきたが共有機能でメールなどを送ったときにクラッシュする問題も解決したい。<br />
多分アプリのライフサイクルがちゃんと管理できていないっぽい。全部書き直したいな・・。<br />
あとXperiaのフォーカスボタン（シャッター半押し）やフラッシュ点灯にも対応したい。Xperiaもってないケド・・。Desireでも動くのかな？</p>
<p>それとアプリケーションのパッケージに使っていたドメインの有効期限が終わるのでパッケージ名を変えるつもり。<br />
アプリのパッケージ名ってAndroidマーケットの中でユニークになるはずなのだが、勝手に企業のドメインをパッケージ名にしてトラぶったりしないのだろうか？<br />
まぁ、自分で登録しているドメインを使ってたら問題ないと思うが、実際のところどうなんでしょ。あまりパッケージ名の衝突って聞かないな。</p>
<p>とにかく、適当でぐちゃぐちゃになってるソースをキレイに整理するところからはじめなければならぬ。<br />
あと、AndRoboiceもそろそろ何とかしなければならぬ。</p>
<div class="plus-one-wrap"><g:plusone size="medium" href="http://naskit.com/2010/05/11/toycam%e3%81%ae%e3%82%a2%e3%82%af%e3%83%86%e3%82%a3%e3%83%96%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab%e3%81%8c1%e4%b8%87%e4%bb%b6%e8%b6%8a%e3%81%88/"></g:plusone></div>]]></content:encoded>
			<wfw:commentRss>http://naskit.com/2010/05/11/toycam%e3%81%ae%e3%82%a2%e3%82%af%e3%83%86%e3%82%a3%e3%83%96%e3%82%a4%e3%83%b3%e3%82%b9%e3%83%88%e3%83%bc%e3%83%ab%e3%81%8c1%e4%b8%87%e4%bb%b6%e8%b6%8a%e3%81%88/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>eneloopスティックブースターでHT-03Aを充電してみた</title>
		<link>http://naskit.com/2010/05/08/eneloop%e3%82%b9%e3%83%86%e3%82%a3%e3%83%83%e3%82%af%e3%83%96%e3%83%bc%e3%82%b9%e3%82%bf%e3%83%bc%e3%81%a7ht-03a%e3%82%92%e5%85%85%e9%9b%bb%e3%81%97%e3%81%a6%e3%81%bf%e3%81%9f/</link>
		<comments>http://naskit.com/2010/05/08/eneloop%e3%82%b9%e3%83%86%e3%82%a3%e3%83%83%e3%82%af%e3%83%96%e3%83%bc%e3%82%b9%e3%82%bf%e3%83%bc%e3%81%a7ht-03a%e3%82%92%e5%85%85%e9%9b%bb%e3%81%97%e3%81%a6%e3%81%bf%e3%81%9f/#comments</comments>
		<pubDate>Sat, 08 May 2010 06:31:31 +0000</pubDate>
		<dc:creator>saikoro</dc:creator>
				<category><![CDATA[HT-03A]]></category>
		<category><![CDATA[eneloop]]></category>

		<guid isPermaLink="false">http://naskit.com/?p=369</guid>
		<description><![CDATA[eneloopスティックブースター（KBC-D1AS）でHT-03Aを充電してみた]]></description>
			<content:encoded><![CDATA[<p>三洋電機製のeneloopスティックブースター（KBC-D1AS）でHT-03Aを充電してみた。<br />
<a href="http://naskit.com/wp-content/uploads/IMG_0544_w640.jpg"><img src="http://naskit.com/wp-content/uploads/IMG_0544_w640-300x216.jpg" alt="eneloop stick booster and ht03a" title="eneloop_01" width="300" height="216" class="alignnone size-medium wp-image-370" /></a></p>
<p>発売されて以来ずっと品薄状態が続いていたeneloopスティックブースター（以下KBC-D1AS）だが、最近ようやく物が増えてきたのだろうか。ネットショップの価格も2000円前後に落ち着いてきた。一時2700円というとんでもないプレミア価格になっていたがそこまで出すならリチウムバッテリーも視野に入るというものだ。</p>
<p>別にリチウムバッテリーでもよかったのだが、すでにあまり活用されていない単3のeneloopが12本もあるので有効利用するため―という意味もある。単3電池でUSB出力する商品は他にもあるけどeneloopの1.2Vｘ2本で2.4Vの電源をちゃんと5VにしてUSB出力してくれるのか不安だったので同じメーカーのKBC-D1ASを選んだ。<br />
同じ三洋電機で<a href="http://www.amazon.co.jp/gp/product/B002S0N8X6?ie=UTF8&#038;tag=saikoblog-22&#038;linkCode=as2&#038;camp=247&#038;creative=7399&#038;creativeASIN=B002S0N8X6">KBC-E1AS</a><img src="http://www.assoc-amazon.jp/e/ir?t=saikoblog-22&#038;l=as2&#038;o=9&#038;a=B002S0N8X6" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />という単3電池2本からUSB出力できる商品もあるが、サイズが微妙（W66×D25×H60mm）なのでやめておいた。値段が少し高いのはUSB経由で電池を充電することもできるからなのだが、充電は急速充電器で十分なので必要なかった。</p>
<p>んでamazonでポチっと購入して届いたので早速HT-03Aを充電してみることにした。最近はamazonで購入できるものはなるべくamazonで購入しているなー。理由はコンビニ配送。平日はほとんど自宅にいない一人暮らしには宅配BOXのように使える。<br />
再配送の時間帯に家にいなくても良いし。</p>
<p><a href="http://naskit.com/wp-content/uploads/IMG_0547_w640.jpg"><img src="http://naskit.com/wp-content/uploads/IMG_0547_w640-300x207.jpg" alt="eneloop stick booster" title="eneloop_02" width="300" height="207" class="alignleft size-medium wp-image-377" /></a><br />
シルバーのボディと白のキャップ。キャップ部分にon-offのスイッチとUSBの口。<br />
ちょっと太い油性ペン。ちょっと細いペンケース。みたいな感じ。<br />
<br style="clear:both" /></p>
<p>つめの部分が弱そうでこれが折れたり潰れたりするとキャップが閉まらなくなくなるので要注意だな。</p>
<p><a href="http://naskit.com/wp-content/uploads/IMG_0551_w640.jpg"><img src="http://naskit.com/wp-content/uploads/IMG_0551_w640-150x150.jpg" alt="" title="eneloop_03" width="150" height="150" class="alignleft size-thumbnail wp-image-381" /></a> <a href="http://naskit.com/wp-content/uploads/IMG_0552_w640.jpg"><img src="http://naskit.com/wp-content/uploads/IMG_0552_w640-150x150.jpg" alt="" title="eneloop_04" width="150" height="150" class="alignleft size-thumbnail wp-image-382" /></a><br />
キャップを閉めるときはキャップの「－」状の出っ張りとボディの矢印マークのところを位置あわせして丁寧に扱わねばならない。<br />
もし、壊れたらテープとかベルクロで固定するかなぁー。<br />
<br style="clear:both" /></p>
<p><a href="http://naskit.com/wp-content/uploads/IMG_0553_w640.jpg"><img src="http://naskit.com/wp-content/uploads/IMG_0553_w640-300x225.jpg" alt="" title="eneloop_05" width="300" height="225" class="alignleft size-medium wp-image-385" /></a><br />
バッテリー状態「31%」のHT-03Aに接続してキャップのところのスイッチをONにする。電池はKBC-D1ASに付属の電池をそのまま利用する。HT-03AのLEDがオレンジに点灯して充電が始まった。常に開発者モードにしているので充電中はスリープしないのだが、終話ボタンを押してディスプレイを切ってしばらく放置した。<br />
<br style="clear:both" /></p>
<p><a href="http://naskit.com/wp-content/uploads/IMG_0554_w640.jpg"><img src="http://naskit.com/wp-content/uploads/IMG_0554_w640-300x225.jpg" alt="" title="eneloop_06" width="300" height="225" class="alignleft size-medium wp-image-389" /></a><br />
一時間半くらいでオレンジのLEDが消えたので、どこまで充電できたか確認した。66%まで回復していた。<br />
スリープ時でもWiFiはONのままの設定だったし、工場出荷時のままの電池を使ったのでこんなもんだろうと思った。<br />
充電器でフル充電したバッテリーならどんなもんかな？？半分くらいは充電できるのだろうか？<br />
KBC-D1ASと予備のeneloop4本をつねに持ち歩いてたら大丈夫であろう。<br />
良い買い物であった。<br />
<br style="clear:both" /></p>
<p><iframe src="http://rcm-jp.amazon.co.jp/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=545454&#038;fc1=DDDDDD&#038;lc1=7AB8FF&#038;t=saikoblog-22&#038;o=9&#038;p=8&#038;l=as1&#038;m=amazon&#038;f=ifr&#038;md=1X69VDGQCMF7Z30FM082&#038;asins=B002S0N8ZY" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe></p>
<div class="plus-one-wrap"><g:plusone size="medium" href="http://naskit.com/2010/05/08/eneloop%e3%82%b9%e3%83%86%e3%82%a3%e3%83%83%e3%82%af%e3%83%96%e3%83%bc%e3%82%b9%e3%82%bf%e3%83%bc%e3%81%a7ht-03a%e3%82%92%e5%85%85%e9%9b%bb%e3%81%97%e3%81%a6%e3%81%bf%e3%81%9f/"></g:plusone></div>]]></content:encoded>
			<wfw:commentRss>http://naskit.com/2010/05/08/eneloop%e3%82%b9%e3%83%86%e3%82%a3%e3%83%83%e3%82%af%e3%83%96%e3%83%bc%e3%82%b9%e3%82%bf%e3%83%bc%e3%81%a7ht-03a%e3%82%92%e5%85%85%e9%9b%bb%e3%81%97%e3%81%a6%e3%81%bf%e3%81%9f/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Xperiaのタッチパネルはノープレッシャー</title>
		<link>http://naskit.com/2010/04/09/xperia%e3%81%ae%e3%82%bf%e3%83%83%e3%83%81%e3%83%91%e3%83%8d%e3%83%ab%e3%81%af%e3%83%8e%e3%83%bc%e3%83%97%e3%83%ac%e3%83%83%e3%82%b7%e3%83%a3%e3%83%bc/</link>
		<comments>http://naskit.com/2010/04/09/xperia%e3%81%ae%e3%82%bf%e3%83%83%e3%83%81%e3%83%91%e3%83%8d%e3%83%ab%e3%81%af%e3%83%8e%e3%83%bc%e3%83%97%e3%83%ac%e3%83%83%e3%82%b7%e3%83%a3%e3%83%bc/#comments</comments>
		<pubDate>Thu, 08 Apr 2010 18:11:18 +0000</pubDate>
		<dc:creator>saikoro</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[HT-03A]]></category>
		<category><![CDATA[Xperia]]></category>

		<guid isPermaLink="false">http://naskit.com/?p=314</guid>
		<description><![CDATA[再びXperiaネタ
タッチパネルの圧力取得について]]></description>
			<content:encoded><![CDATA[<p>DoCoMoの<strong>ニュータイプ</strong>、Xperiaのタッチパネルについてである。</p>
<p>Androidのタッチパネルではタッチした強さを取得できる。<br />
はずなんだ。</p>
<p>取得方法は<br />
onTouchEvent(MotionEvent event) 内の <strong><a href="http://developer.android.com/reference/android/view/MotionEvent.html#getPressure()" target="_blank">getPressure() メソッド</a></strong>で0.0から1.0の値が取得できるはず。<br />
少なくともHT-03Aでは取得できていたが、Xperiaでは常に1.0が返ってくるようだ。</p>
<p>こんなコードを書いてしらべた。</p>
<pre class="brush: java; title: ; notranslate">
// package略
// import略

public class Main extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        int a = event.getAction();
        String act = &quot;&quot;;
        if (a == MotionEvent.ACTION_CANCEL) {
            act = &quot;ACTION_CANCEL&quot;;
        }
        if (a == MotionEvent.ACTION_DOWN) {
            act = &quot;ACTION_DOWN&quot;;
        }
        if (a == MotionEvent.ACTION_MOVE) {
            act = &quot;ACTION_MOVE&quot;;
        }
        if (a == MotionEvent.ACTION_OUTSIDE) {
            act = &quot;ACTION_OUTSIDE&quot;;
        }
        if (a == MotionEvent.ACTION_UP) {
            act = &quot;ACTION_UP&quot;;
        }
        ((TextView)findViewById(R.id.touch_action)).setText(act);
        ((TextView)findViewById(R.id.touch_x)).setText(&quot;&quot;+event.getX());
        ((TextView)findViewById(R.id.touch_y)).setText(&quot;&quot;+event.getY());
        int size = event.getHistorySize();

        String histPress = &quot; size=&quot; + size;
        for (int i = 0;i &lt; size;i++) {
            if (i &gt; 1) break;
            histPress = histPress + &quot;,&quot; + event.getHistoricalPressure(i);
        }
        ((TextView)findViewById(R.id.touch_pressure)).setText(histPress);

        String histSize = &quot; size=&quot; + size;
        for (int i = 0;i &lt; size;i++) {
            if (i &gt; 1) break;
            histSize = histSize + &quot;,&quot; + event.getHistoricalSize(i);
        }
        ((TextView)findViewById(R.id.touch_size)).setText(histSize);

        return true;
    }
}

// layout/main.xml
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    android:orientation=&quot;vertical&quot;
    android:layout_width=&quot;fill_parent&quot;
    android:layout_height=&quot;fill_parent&quot;
    &gt;
    &lt;TextView
        android:layout_width=&quot;fill_parent&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:text=&quot;@string/title&quot;/&gt;

    &lt;LinearLayout
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:orientation=&quot;horizontal&quot;&gt;
        &lt;TextView
            android:layout_width=&quot;wrap_content&quot;
            android:layout_height=&quot;wrap_content&quot;
            android:text=&quot;MotionEvent.getX()=&quot; /&gt;
        &lt;TextView
            android:layout_width=&quot;wrap_content&quot;
            android:layout_height=&quot;wrap_content&quot;
            android:id=&quot;@+id/touch_x&quot;
            android:text=&quot;0&quot; /&gt;
    &lt;/LinearLayout&gt;
    &lt;LinearLayout
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:orientation=&quot;horizontal&quot;&gt;
        &lt;TextView
            android:layout_width=&quot;wrap_content&quot;
            android:layout_height=&quot;wrap_content&quot;
            android:text=&quot;MotionEvent.getY()=&quot; /&gt;
        &lt;TextView
            android:layout_width=&quot;wrap_content&quot;
            android:layout_height=&quot;wrap_content&quot;
            android:text=&quot;0&quot;
            android:id=&quot;@+id/touch_y&quot; /&gt;
    &lt;/LinearLayout&gt;
    &lt;LinearLayout
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:orientation=&quot;horizontal&quot;&gt;
        &lt;TextView
            android:layout_width=&quot;wrap_content&quot;
            android:layout_height=&quot;wrap_content&quot;
            android:text=&quot;MotionEvent.getSize()=&quot; /&gt;
        &lt;TextView
            android:layout_width=&quot;wrap_content&quot;
            android:layout_height=&quot;wrap_content&quot;
            android:text=&quot;0&quot;
            android:id=&quot;@+id/touch_size&quot; /&gt;
    &lt;/LinearLayout&gt;
    &lt;LinearLayout
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:orientation=&quot;horizontal&quot;&gt;
        &lt;TextView
            android:layout_width=&quot;wrap_content&quot;
            android:layout_height=&quot;wrap_content&quot;
            android:text=&quot;MotionEvent.getPressure()=&quot; /&gt;
        &lt;TextView
            android:layout_width=&quot;wrap_content&quot;
            android:layout_height=&quot;wrap_content&quot;
            android:text=&quot;0&quot;
            android:id=&quot;@+id/touch_pressure&quot; /&gt;
    &lt;/LinearLayout&gt;
    &lt;LinearLayout
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:orientation=&quot;horizontal&quot;&gt;
        &lt;TextView
            android:layout_width=&quot;wrap_content&quot;
            android:layout_height=&quot;wrap_content&quot;
            android:text=&quot;MotionEvent.getAction()=&quot; /&gt;
        &lt;TextView
            android:layout_width=&quot;wrap_content&quot;
            android:layout_height=&quot;wrap_content&quot;
            android:id=&quot;@+id/touch_action&quot; /&gt;
    &lt;/LinearLayout&gt;

&lt;/LinearLayout&gt;
</pre>
<p><a href="http://naskit.com/wp-content/uploads/xperia_pressure_ss01.png"><img src="http://naskit.com/wp-content/uploads/xperia_pressure_ss01-200x300.png" alt="" title="xperia_pressure_ss01" width="200" height="300" class="size-medium wp-image-324" /></a><a href="http://naskit.com/wp-content/uploads/xperia_pressure_ss02.png"><img src="http://naskit.com/wp-content/uploads/xperia_pressure_ss02-200x300.png" alt="" title="xperia_pressure_ss02" width="200" height="300" class="alignright size-medium wp-image-325" /></a></p>
<p>同様にタッチした範囲もgetSize()で取得できるのだが、Xperiaは常に0.0を返すのであった。<br />
これは機種依存なのかもしれない。<br />
マルチタッチをサポートしてたらタッチした範囲は求められそうだが、Xperiaのタッチパネルには<a href="http://japanese.engadget.com/2010/03/29/xperia-x10/" target="_blank">こんな情報</a>もあり、機種的に取得ができないのかもしれん。</p>
<p>幅広い端末をサポートするなら、タッチパネルのプレッシャーを測り知ろうとしてはならぬのかもしれない。<br />
Xperiaを猛烈に強くタッチしても｢私にプレッシャーをかけるパイロットとは・・・」などとは言ってくれなさそうである。</p>
<p>はたしてXperia君はAndroidOS2.X にアップデートして真のニュータイプになれるのであろうか。</p>
<div class="plus-one-wrap"><g:plusone size="medium" href="http://naskit.com/2010/04/09/xperia%e3%81%ae%e3%82%bf%e3%83%83%e3%83%81%e3%83%91%e3%83%8d%e3%83%ab%e3%81%af%e3%83%8e%e3%83%bc%e3%83%97%e3%83%ac%e3%83%83%e3%82%b7%e3%83%a3%e3%83%bc/"></g:plusone></div>]]></content:encoded>
			<wfw:commentRss>http://naskit.com/2010/04/09/xperia%e3%81%ae%e3%82%bf%e3%83%83%e3%83%81%e3%83%91%e3%83%8d%e3%83%ab%e3%81%af%e3%83%8e%e3%83%bc%e3%83%97%e3%83%ac%e3%83%83%e3%82%b7%e3%83%a3%e3%83%bc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Androidで音声処理4</title>
		<link>http://naskit.com/2010/03/17/android%e3%81%a7%e9%9f%b3%e5%a3%b0%e5%87%a6%e7%90%864/</link>
		<comments>http://naskit.com/2010/03/17/android%e3%81%a7%e9%9f%b3%e5%a3%b0%e5%87%a6%e7%90%864/#comments</comments>
		<pubDate>Tue, 16 Mar 2010 17:35:44 +0000</pubDate>
		<dc:creator>saikoro</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[HT-03A]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[Androboice]]></category>
		<category><![CDATA[WAV]]></category>

		<guid isPermaLink="false">http://naskit.com/?p=275</guid>
		<description><![CDATA[Androboiceってアプリ作ったときのメモ ピッチシフト編]]></description>
			<content:encoded><![CDATA[<p>ピッチシフトについてメモ</p>
<p>音声データを再生するときに早送りにしたり、ゆっくり再生すると声が高くなったり低くなったりする。<br />
再生するスピードを変えずに声の高さだけを変えることをピッチシフトと言うらしい。</p>
<p>やり方はいろいろあるようで、音声データを短い時間に区切って間引いたり、かさ増ししたりして音データをつなげなおすと音程が変わる方法や、フーリエ変換で音の周波数を求め、周波数を変更して逆フーリエ変換で戻してやる方法があるようだ。</p>
<p>Androboiceではとりあえず間引いたりかさ増しする方法で実現している。</p>
<p>音を1オクターブ高くするには周波数を2倍にすればよいらしい。だから短い時間に区切って音データを半分に間引いて、間引いたデータを区切ったデータの後ろにくっつけて長さを同じにする。それを全てのデータ分実行すると再生速度そのままで1オクターブ高い音が作れる。</p>
<pre class="brush: plain; title: ; notranslate">
0,1,2,3,4,5,6,7,8,9
を
0,2,4,6,8,0,2,4,6,8
にする
</pre>
<p>これで2倍の高さの音になる。</p>
<p>この「0,1,2,3,4,5,6,7,8,9」って音の幅はどれくらいかというと8000Hzで約33msec分で240サンプル分を間引き処理してつなげている。</p>
<pre class="brush: plain; title: ; notranslate">
0,1,2,3,4,5,6 .....237,238,239,    240,241,242,243, ... 7998,7999
これを
0,2,4,6, ... 236,238,0,2,4,6, ... 236,238,      240,242,244, ... 7996,7998
こんな具合で1秒間の処理おわり
</pre>
<p>238と240のつなぎ目は滑らかにならないので雑音のようになるのだが、なめらかにする処理は省略した。分からないので。</p>
<p>なぜ30msecで区切ることにしたのかというと、自分の声を録音して波形編集ソフトで変換してみて、大体30msecくらいならうまくいくかなーと思ったから。人の声は大体300Hzくらいなので1秒間に300回なんらかの波が繰り返されていることになる。んで30msecなら6回から10回くらい繰り返しているので、「これなら加工しやすいだろう」となんとなく感覚で決めた。</p>
<p>まあ、waveデータを加工して音作りをしている人にとっては大したことないのかもしれないが、良い勉強になった。</p>
<p>フーリエ変換バージョンもあるのだが、1秒の音を変換するのに9秒くらいかかってしまう。これではFFTとは言えないくらい遅い。<br />
floatの配列を使って演算しているのだが、これがボトルネックなのだろう。FixPointで計算するかJNIを使うしかないかもしれない。<br />
また勉強することが増えた。</p>
<div class="plus-one-wrap"><g:plusone size="medium" href="http://naskit.com/2010/03/17/android%e3%81%a7%e9%9f%b3%e5%a3%b0%e5%87%a6%e7%90%864/"></g:plusone></div>]]></content:encoded>
			<wfw:commentRss>http://naskit.com/2010/03/17/android%e3%81%a7%e9%9f%b3%e5%a3%b0%e5%87%a6%e7%90%864/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Androidで音声処理3</title>
		<link>http://naskit.com/2010/03/07/android%e3%81%a7%e9%9f%b3%e5%a3%b0%e5%87%a6%e7%90%863/</link>
		<comments>http://naskit.com/2010/03/07/android%e3%81%a7%e9%9f%b3%e5%a3%b0%e5%87%a6%e7%90%863/#comments</comments>
		<pubDate>Sat, 06 Mar 2010 22:51:04 +0000</pubDate>
		<dc:creator>saikoro</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[HT-03A]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[Androboice]]></category>
		<category><![CDATA[WAV]]></category>

		<guid isPermaLink="false">http://naskit.com/?p=267</guid>
		<description><![CDATA[Androboiceってアプリを作ったときのメモ]]></description>
			<content:encoded><![CDATA[<h2>Androboiceってアプリを作ったときのメモ</h2>
<p><a class="wp-caption" href="http://naskit.com/2010/02/26/androidで音声処理2/" target="_self">前回</a>の続き。</p>
<p>で、AndroidでPCMデータの再生</p>
<p>AudioTrackクラスで前回rec.rawとして保存した生PCMデータを再生できる。以下コード</p>
<pre class="brush: java; title: ; notranslate">
// 各種例外処理は略
// サンプルレート 8kHz
int SAMPLE_RATE = 8000;
// オーディオトラック取得
audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
		SAMPLE_RATE,
		AudioFormat.CHANNEL_CONFIGURATION_MONO,
		AudioFormat.ENCODING_PCM_16BIT,
		AudioTrack.getMinBufferSize(SAMPLE_RATE,
									AudioFormat.CHANNEL_CONFIGURATION_MONO,
									AudioFormat.ENCODING_PCM_16BIT) ,
		AudioTrack.MODE_STREAM);

// 録音したファイル取得
File recFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + &quot;/rec.raw&quot;);
InputStream is = new FileInputStream(recFile);
// バイトデータの配列
long length = mOutFile.length();
byte[] byteData = new byte[(int)length];
// ファイルのデータを全て読み込み
int offset = 0, numRead = 0;
while (offset &lt; byteData.length
		&amp;&amp; (numRead = is.read(byteData, offset, byteData.length - offset)) &gt;= 0) {
	offset += numRead;
}
is.close();

// 出力
audioTrack.play();
audioTrack.write(byteData, 0, byteData.length);
</pre>
<p>コードは<a href="http://www.supergnes.com/blog/?p=70">ここ</a>を参考にした。<br />
これでスピーカーから音が出る。<br />
が、しかしDroidとかMilestoneとかG1とかで動かないらしい。<br />
AudioTrackが取得できない条件があるみたい。サンプルレートが問題なのだろうか。<br />
手元にないのでわからんが。。。2.0のエミュレータでは動くのだが・・・まいった;(</p>
<p>AudioTrackとAudioRecordクラスは指定したフレームごとにコールされるリスナを登録できるらしい。<br />
それを使えば録音・再生のシークバーとかを実装できるのかな。うまくいかないのだが・・。</p>
<p>なんにせよ情報が少なすぎる・・。Audioまわりを詳しくまとめた書籍があったら買うのだが。</p>
<div class="plus-one-wrap"><g:plusone size="medium" href="http://naskit.com/2010/03/07/android%e3%81%a7%e9%9f%b3%e5%a3%b0%e5%87%a6%e7%90%863/"></g:plusone></div>]]></content:encoded>
			<wfw:commentRss>http://naskit.com/2010/03/07/android%e3%81%a7%e9%9f%b3%e5%a3%b0%e5%87%a6%e7%90%863/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Androidで音声処理2</title>
		<link>http://naskit.com/2010/02/26/android%e3%81%a7%e9%9f%b3%e5%a3%b0%e5%87%a6%e7%90%862/</link>
		<comments>http://naskit.com/2010/02/26/android%e3%81%a7%e9%9f%b3%e5%a3%b0%e5%87%a6%e7%90%862/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 17:03:55 +0000</pubDate>
		<dc:creator>saikoro</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[HT-03A]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[Andro]]></category>
		<category><![CDATA[Androboice]]></category>
		<category><![CDATA[RIFF]]></category>
		<category><![CDATA[WAV]]></category>

		<guid isPermaLink="false">http://naskit.com/?p=256</guid>
		<description><![CDATA[Androboiceってアプリを作ったときのメモ
AudioRecordでのwavファイルの録音]]></description>
			<content:encoded><![CDATA[<h2>Androboiceってアプリを作ったときのメモ</h2>
<p><a class="wp-caption" href="http://naskit.com/2010/02/24/android%E3%81%A7%E9%9F%B3%E5%A3%B0%E5%87%A6%E7%90%861/" target="_self">前回</a>の続き。</p>
<p>で、Androidでどうやって録音するか。</p>
<p>AudioRecordクラスでは前回の音データが取得できる。以下コード。</p>
<pre class="brush: java; title: ; notranslate">
// サンプルレート 8kHz
int SAMPLE_RATE = 8000;
// フラグ
isRecoding = true;
// プロセスの優先度を上げる
android.os.Process.setThreadPriority(
          android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
// バッファサイズを求める サンプルレート8kHz  モノラル 16ビット/サンプル
int audioBuf = AudioRecord.getMinBufferSize(SAMPLE_RATE,
                     AudioFormat.CHANNEL_CONFIGURATION_MONO,
                     AudioFormat.ENCODING_PCM_16BIT) * 2;
// レコーダの取得  サンプルレート8kHz  モノラル 16ビット/サンプル
AudioRecord audioRecord =  new AudioRecord(MediaRecorder.AudioSource.MIC,
                           SAMPLE_RATE,
                           AudioFormat.CHANNEL_CONFIGURATION_MONO,
                           AudioFormat.ENCODING_PCM_16BIT,
                           audioBuf);
// バッファ
byte[] buffer = new byte[audioBuf];
// 録音用ファイル取得  SDカード状態チェック略
File recFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + &quot;/rec.raw&quot;);
recFile.createNewFile();
// ファイル書き込み  例外処理略
FileOutputStream out =  new FileOutputStream(recFile);
// 録音開始
audioRecord.startRecording();
// フラグが落ちるまでループ  例外処理略
while(isRecoding) {
	// バッファを読み込んで書き込む
	audioRecord.read(buffer, 0, audioBuf);
}
// 終了処理 例外処理略
audioRecord.stop();
out.close();
out = null;
</pre>
<p>実際はスレッドなんかで実行してフラグで録音ループを抜ける。これでSDカードにrec.rawってファイルができる。<br />
ファイルの中身はサンプルレート8000Hz、1サンプルあたり16ビット、モノラルのバイトデータ。ヘッダ情報のないWindowsのwavファイルのデータチャンクのところ。これにRIFFとかfmtチャンクを加えればwavファイルの出来上がり。<br />
逆に言うと、サンプルレート8000Hz、1サンプルあたり16ビット、モノラルのwavファイルの先頭からヘッダ情報の40バイトをちぎったのと同じデータなのだ。</p>
<p>んで、1サンプル16ビット＝2バイトずつデータが並んでいて、16ビットなので65536段階の強弱の信号が記録されている。<br />
16ビットでサンプルした場合は、符号付き(-32768 ～ +32767)であらわすらしい。 無音は 0。<br />
8ビットでサンプルした場合は、符号なし（0~ +255）無音は128であらわす。</p>
<p>8ビットの場合はそのままJavaのbyte型の変数の配列に1サンプルずつデータが入っているが、<br />
16ビットでサンプルした場合はエンディアンに気をつけないといけない。<br />
取得できるデータはwavファイルと同じリトルエンディアンであるらしく、前8ビットには下の桁、後ろ8ビットには上の桁（2進数的に）<br />
が収まっている。</p>
<pre class="brush: plain; title: ; notranslate">
byte[] buff = new buff[2];
リトルエンディアン 16bitの1
前8ビット    後ろ8ビット
00000001  00000000        // 2進数
0x0100                    // 16進数
buff[0]  == 0x01
buff[1]  == 0x00

リトルエンディアン 16bitの32767
11111111  01111111       //  2進数
0xFF7F                    // 16進数
buff[0]  == 0xFF
buff[1]  == 0xF7

リトルエンディアン 16bitの-32768
00000000 10000000        //  2進数
0x0080                     // 16進数
buff[0]  == 0x00
buff[1]  == 0x80
</pre>
<p>このようにバイナリエディタなんかでダンプしただけではパッと見て分かりにくいデータなのだ。<br />
これが分かるまで苦労した。バイナリデータは触ったことなかったし。<br />
Windowsの電卓ソフトの関数電卓モードを活用させてもらった。</p>
<p>んで、上のサンプルで保存したrec.rawファイルにヘッダをつけてwavファイルにする。以下コード</p>
<pre class="brush: java; title: ; notranslate">

// WAVヘッダをつけて保存
// 各種例外処理略 チェック処理略
public void addWavHeader() {
	// 録音したファイル
	File recFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + &quot;/rec.raw&quot;);
	// WAVファイル
	File wavFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + &quot;/rec.wav&quot;);
	// ストリーム
    FileInputStream in = new FileInputStream(recFile);
	FileOutputStream out = new FileOutputStream(wavFile);

	// ヘッダ作成  サンプルレート8kHz
	byte[] header = createHeader(8000, (int)recFile.length());
	// ヘッダの書き出し
	out.write(header);

	// 録音したファイルのバイトデータ読み込み
	int n = 0,offset = 0;
	byte[] buffer = new byte[(int)recFile.length()];
	while (offset &lt; buffer.length
			&amp;&amp; (n = in.read(buffer, offset, buffer.length - offset)) &gt;= 0) {
		offset += n;
	}
	// バイトデータ書き込み
	out.write(buffer);

	// 終了
	in.close();
	out.close();
}

// Wavファイルのヘッダを作成する（PCM16ビット モノラル）
// sampleRate  サンプルレート
// datasize データサイズ
// これなんかもっとキレイに書けると思うが 。。 Ringroidのソースなんかキレイかも
public static byte[] createHeader(int sampleRate, int datasize) {
	byte[] byteRIFF = {'R', 'I', 'F', 'F'};
	byte[] byteFilesizeSub8 = intToBytes((datasize + 36));	// ファイルサイズ-8バイト数
	byte[] byteWAVE = {'W', 'A', 'V', 'E'};
	byte[] byteFMT_ = {'f', 'm', 't', ' '};
	byte[] byte16bit = intToBytes(16);					// fmtチャンクのバイト数
	byte[] byteSamplerate = intToBytes(sampleRate);		// サンプルレート
	byte[] byteBytesPerSec = intToBytes(sampleRate * 2);	// バイト/秒 = サンプルレート x 1チャンネル x 2バイト
	byte[] bytePcmMono = {0x01, 0x00, 0x01, 0x00};		// フォーマットID 1 =リニアPCM  ,  チャンネル 1 = モノラル
	byte[] byteBlockBit = {0x02, 0x00, 0x10, 0x00};		// ブロックサイズ2バイト サンプルあたりのビット数16ビット
	byte[] byteDATA = {'d', 'a', 't', 'a'};
	byte[] byteDatasize = intToBytes(datasize);			// データサイズ

	ByteArrayOutputStream out = new ByteArrayOutputStream();
	try {
		out.write(byteRIFF);
		out.write(byteFilesizeSub8);
		out.write(byteWAVE);
		out.write(byteFMT_);
		out.write(byte16bit);
		out.write(bytePcmMono);
		out.write(byteSamplerate);
		out.write(byteBytesPerSec);
		out.write(byteBlockBit);
		out.write(byteDATA);
		out.write(byteDatasize);

	} catch (IOException e) {
		return out.toByteArray();
	}

	return out.toByteArray();
}
// int型32ビットデータをリトルエンディアンのバイト配列にする
public static byte[] intToBytes(int value) {
	byte[] bt = new byte[4];
	bt[0] = (byte)(value &amp; 0x000000ff);
	bt[1] = (byte)((value &amp; 0x0000ff00) &gt;&gt; 8);
	bt[2] = (byte)((value &amp; 0x00ff0000) &gt;&gt; 16);
	bt[3] = (byte)((value &amp; 0xff000000) &gt;&gt; 24);
	return bt;
}
</pre>
<p>これでSDカードにrec.wavってファイルができるはず。あとは標準の音楽ソフトかパソコンで再生すればOK牧場。<br />
WAVファイルを保存してゴニョゴニョできるソフトはそんなに多くないので、うまくやれば人気のアプリになりそう。<br />
3gppとちがって加工しやすいし。3gpのフォーマット読んだだけで心が折れそうになったし・・。</p>
<p>PCでWAVファイルとかゴニョゴニョしてた人たちには大したことないかもしれないが、苦労した。<br />
良い勉強になった。<br />
はて、次はAudioTrackで再生の予定。</p>
<div class="plus-one-wrap"><g:plusone size="medium" href="http://naskit.com/2010/02/26/android%e3%81%a7%e9%9f%b3%e5%a3%b0%e5%87%a6%e7%90%862/"></g:plusone></div>]]></content:encoded>
			<wfw:commentRss>http://naskit.com/2010/02/26/android%e3%81%a7%e9%9f%b3%e5%a3%b0%e5%87%a6%e7%90%862/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Androidで音声処理1</title>
		<link>http://naskit.com/2010/02/24/android%e3%81%a7%e9%9f%b3%e5%a3%b0%e5%87%a6%e7%90%861/</link>
		<comments>http://naskit.com/2010/02/24/android%e3%81%a7%e9%9f%b3%e5%a3%b0%e5%87%a6%e7%90%861/#comments</comments>
		<pubDate>Tue, 23 Feb 2010 19:16:56 +0000</pubDate>
		<dc:creator>saikoro</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[HT-03A]]></category>
		<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[Androboice]]></category>

		<guid isPermaLink="false">http://naskit.com/?p=238</guid>
		<description><![CDATA[Androboiceってアプリを作ったときのメモ]]></description>
			<content:encoded><![CDATA[<h2><strong>Androboice</strong>ってアプリを作ったときのメモ</h2>
<p>AndroidではAudioRecordとAudioTrackという方法でマイクの音を音データにしたり、音データをスピーカーに送ることができる。<br />
その前にまず、そもそも音データってなに？ってところから始まる。他のOSとかで音データを触ったことがないから。</p>
<p style="text-align: left;">音ってのは空気の振動で、コンピュータで音データを扱うということは空気の振動を0と1に置き換えること、0と1の信号を使って空気を振動させることになる。 私の理解では。<br />
<a href="http://naskit.com/wp-content/uploads/sound_mic.png"><img class="size-medium wp-image-240 aligncenter" title="sound_mic" src="http://naskit.com/wp-content/uploads/sound_mic-300x123.png" alt="" width="300" height="123" /></a></p>
<p style="text-align: left;">大きな音がマイクに入ると、大きな電流がコンピュータに流れ、小さな音だと小さな電流がコンピュータに流れる。</p>
<p style="text-align: left;">コンピュータは流れてきた電流を<span style="color: #ff00ff;">一定時間ごとに</span>データを記録していく。大・小・大・小・中・大・小・・・・などと。</p>
<p style="text-align: left;">実際には20,000 ・-20,000 ・ 200 ・100 ・ -100 ・・・・みたいな感じで。</p>
<p style="text-align: left;">記録した音データに何らかの処理をして、マイクの逆パターンでスピーカーに大・小・大・小・中・大・小・・・・と電流を送れば音が出る。</p>
<p style="text-align: left;">
<p style="text-align: left;">
<p style="text-align: left;">
<p style="text-align: left;">
<p style="text-align: left;">
<p style="text-align: left;">
<p style="text-align: left;"><strong>サンプリングレート</strong></p>
<p style="text-align: left;">一定時間ごとにマイクからの電流を計測して記録する（サンプリングする）けど、どれくらいの間隔で記録するかは『1秒間に何回記録するか「<strong>Hｚ　ヘルツ</strong>」』であらわす。</p>
<p style="text-align: left;">音楽CDだと1秒間に44,100回＝44100Hz。他にも22,050Hzとか16,000Hzとか11,025Hzとか8,000Hzとかがよく使われるみたい。実際の音波はもっと細かいけど連続毎秒44,100回記録しておけば、それ以上記録してても人間の耳には違いが分からないらしい。</p>
<p style="text-align: left;">
<p style="text-align: left;">
<p style="text-align: left;">
<h4>ビット/サンプル  BitPerSample</h4>
<p style="text-align: left;">マイクから流れてくる電流を記録するときどれくらいの細かさで記録するかは16ビットとか8ビットとかがよく使われるらしい。</p>
<p style="text-align: left;">それぞれ、65,535段階か256段階。16ビットとか8ビットはコンピュータでデータを扱いやすい。音楽CDは16ビットらしい。</p>
<p style="text-align: left;">
<p style="text-align: left;">だから、<strong>モノラル</strong>でサンプリングレート44100Hzで16Bit/Sampleで10秒間録音したら、データサイズは</p>
<p style="text-align: left;">1チャンネル x 44,100回 x 10秒 x 16Bit = 7,056,000Bit = 882キロバイトになると。</p>
<p style="text-align: left;">
<p style="text-align: left;"><strong>ステレオ</strong>でサンプリングレート44100Hzで16Bit/Sampleで80分間録音したら、データサイズは</p>
<p style="text-align: left;">2チャンネル x 44,100回 x 4,800秒 x 16Bit = 6,773,760,000Bit =846,720キロバイト(約800MB)になると。</p>
<p style="text-align: left;">80分のCD-Rの容量と大体あったので、こんな考えで間違ってはいないだろう。</p>
<p style="text-align: left;">
<p style="text-align: left;">これらのデータを切ったりつなげたりすれば、マイクからの音にエフェクトをかけられると思った。<strong><span style="color: #808080;"><a class="wp-caption" href="http://naskit.com/2010/02/26/android%E3%81%A7%E9%9F%B3%E5%A3%B0%E5%87%A6%E7%90%862/" target="_self">つづく</a></span></strong>。</p>
<p style="text-align: left;">
<div class="plus-one-wrap"><g:plusone size="medium" href="http://naskit.com/2010/02/24/android%e3%81%a7%e9%9f%b3%e5%a3%b0%e5%87%a6%e7%90%861/"></g:plusone></div>]]></content:encoded>
			<wfw:commentRss>http://naskit.com/2010/02/24/android%e3%81%a7%e9%9f%b3%e5%a3%b0%e5%87%a6%e7%90%861/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>HT-03Aでプレビューの映像データをビットマップデータに変換するところ補足</title>
		<link>http://naskit.com/2009/12/11/ht-03a%e3%81%a7%e3%83%97%e3%83%ac%e3%83%93%e3%83%a5%e3%83%bc%e3%81%ae%e6%98%a0%e5%83%8f%e3%83%87%e3%83%bc%e3%82%bf%e3%82%92%e3%83%93%e3%83%83%e3%83%88%e3%83%9e%e3%83%83%e3%83%97%e3%83%87%e3%83%bc-2/</link>
		<comments>http://naskit.com/2009/12/11/ht-03a%e3%81%a7%e3%83%97%e3%83%ac%e3%83%93%e3%83%a5%e3%83%bc%e3%81%ae%e6%98%a0%e5%83%8f%e3%83%87%e3%83%bc%e3%82%bf%e3%82%92%e3%83%93%e3%83%83%e3%83%88%e3%83%9e%e3%83%83%e3%83%97%e3%83%87%e3%83%bc-2/#comments</comments>
		<pubDate>Thu, 10 Dec 2009 16:33:11 +0000</pubDate>
		<dc:creator>saikoro</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[HT-03A]]></category>
		<category><![CDATA[no-category]]></category>
		<category><![CDATA[ToyCam]]></category>

		<guid isPermaLink="false">http://naskit.com/?p=135</guid>
		<description><![CDATA[前回のエントリのキモの部分の補足説明]]></description>
			<content:encoded><![CDATA[<p><a href="http://naskit.com/wp-content/uploads/yuv420sp_argb8888.png"><img src="http://naskit.com/wp-content/uploads/yuv420sp_argb8888.png" alt="yuv420sp_argb8888" title="yuv420sp_argb8888" width="300" height="202" class="alignnone size-full wp-image-143" /></a><br/><a href="http://naskit.com/2009/11/25/ht-03a%E3%81%A7%E3%83%97%E3%83%AC%E3%83%93%E3%83%A5%E3%83%BC%E3%81%AE%E6%98%A0%E5%83%8F%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E3%83%93%E3%83%83%E3%83%88%E3%83%9E%E3%83%83%E3%83%97%E3%83%87%E3%83%BC/">前回のエントリ</a>のキモの部分の補足説明<br />
<span id="more-135"></span><br />
カメラのプレビューコールバックにはプレビューで取得した画像がByte配列で入ってくる。<br />
これはカメラのオプション設定で</p>
<pre class="brush: java; title: ; notranslate">
mCamparam = mCamera.getParameters();
mCamparam.setPreviewFormat(PixelFormat.JPEG); // プレビューで取得できる画像形式の指定。デフォルトはPixelFormat.YCbCr_420_SP
// その他設定など
・・・・・・・・
// パラメータセット
mCamera.setParameters(mCamparam);
</pre>
<p>上記のようにすればJPEG形式のByte列のはずなのだが、なぜかnullしか帰ってこない。<br />
だからデフォルトのYUV420形式のデータをビットマップ形式に変換してやる必要がある。<br />
それが下のところ。</p>
<pre class="brush: java; title: ; notranslate">
    /**
     * YUV420データをBitmapに変換する
     * @param rgb
     * @param yuv420sp
     * @param width
     * @param height
     */
    // YUV420 to BMP
    public static final void decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width, int height) {
        final int frameSize = width * height;

        for (int j = 0, yp = 0; j &lt; height; j++) {
            int uvp = frameSize + (j &gt;&gt; 1) * width, u = 0, v = 0;
            for (int i = 0; i &lt; width; i++, yp++) {
                int y = (0xff &amp; ((int) yuv420sp[yp])) - 16;
                if (y &lt; 0) y = 0;
                if ((i &amp; 1) == 0) {
                        v = (0xff &amp; yuv420sp[uvp++]) - 128;
                        u = (0xff &amp; yuv420sp[uvp++]) - 128;
                }

                int y1192 = 1192 * y;
                int r = (y1192 + 1634 * v);
                int g = (y1192 - 833 * v - 400 * u);
                int b = (y1192 + 2066 * u);

                if (r &lt; 0) r = 0; else if (r &gt; 262143) r = 262143;
                if (g &lt; 0) g = 0; else if (g &gt; 262143) g = 262143;
                if (b &lt; 0) b = 0; else if (b &gt; 262143) b = 262143;

                rgb[yp] = 0xff000000 | ((r &lt;&lt; 6) &amp; 0xff0000) | ((g &gt;&gt; 2) &amp; 0xff00) | ((b &gt;&gt; 10) &amp; 0xff);
            }
        }
    }
</pre>
<p>この変換部分は<a href="http://code.google.com/p/android/issues/detail?id=823">ここ</a>に載っているとおり。<br />
んで、YCbCr_420_SPって言う形式はよく分からないがコードから察するにこういう形式ではないか、と推測した。</p>
<pre class="brush: plain; title: ; notranslate">
水平・垂直2×2ピクセルのうち、Cb信号を上2ピクセルから1ピクセル取り、Cr信号を下2ピクセルから1ピクセル取る方式。
フレームごとにCbとCrの位置を反転させる。輝度信号は1ピクセルごとにとる。

Y			輝度信号		CIE の色度図のY軸だから
U (B-Y)		色差信号(Cb)
V (R-Y)		色差信号(Cr)

YUV420 4x4ピクセルの画像のデータフォーマット
　1セル1Byte
　Y : 8Bit/1ピクセルのY信号
　U : 8Bit/2x2ピクセルのU信号
　V : 8Bit/2x2ピクセルのV信号 

　各ピクセルのインデックス 0～F
　x ⇒
y +--+--+--+--+
↓| 0| 1| 2| 3|
　+--+--+--+--+
　| 4| 5| 6| 7|
　+--+--+--+--+
　| 8| 9| A| B|
　+--+--+--+--+
　| C| D| E| F|
　+--+--+--+--+

4x4
+------+------+------+------+
|Y    0|Y    1|Y    2|Y    3|
|      |      |      |      |
+------+------+------+------+
|Y    4|Y    5|Y    6|Y    7|
|      |      |      |      |
+------+------+------+------+
|Y    8|Y    9|Y    A|Y    B|
|      |      |      |      |
+------+------+------+------+
|Y    C|Y    D|Y    E|Y    F|
|      |      |      |      |
+------+------+------+------+
|V  0,1|U  0,1|V  2,3|U  2,3|
|   4,5|   4,5|   6,7|   6,7|
+------+------+------+------+
|V  8,9|U  8,9|V  A,B|U  A,B|
|   C,D|   C,D|   E,F|   E,F|
+------+------+------+------+

横一列にすると・・（view sourceで広げると見やすい）
+------+------+------+    +------+------+------+------+------+------+------+------+------+------+
|Y    0|Y    1|Y    2| 略 |Y    E|Y    F|V  0,1|U  0,1|V  2,3|U  2,3|V  8,9|U  8,9|V  A,B|U  A,B|
|      |      |      | ～ |      |      |   4,5|   4,5|   6,7|   6,7|   C,D|   C,D|   E,F|   E,F|
+------+------+------+    +------+------+------+------+------+------+------+------+------+------+
</pre>
<p>これで正しいのだろうか？？<br />
推測してもしなくても結果はかわらないが。。<br />
人間の目は黄色い光には敏感で、その他の色は基準の信号からの差分信号にすることでデータ量を抑えているらしい。</p>
<p>これを応用したら特定の色だけアルファを全開にしてクロマキーみたいにしたり、全体の色を緑っぽくしたり変換するなどのエフェクトをかけられそうだ。</p>
<p>ちなみに前回のエントリのviewのところで、FrameLayoutを使ってホーム画面のような画像を前面にかぶせてしまえば、写真を撮っているのかどうかわからない状態で画像を保存できるはず。。。やらないが。</p>
<div class="plus-one-wrap"><g:plusone size="medium" href="http://naskit.com/2009/12/11/ht-03a%e3%81%a7%e3%83%97%e3%83%ac%e3%83%93%e3%83%a5%e3%83%bc%e3%81%ae%e6%98%a0%e5%83%8f%e3%83%87%e3%83%bc%e3%82%bf%e3%82%92%e3%83%93%e3%83%83%e3%83%88%e3%83%9e%e3%83%83%e3%83%97%e3%83%87%e3%83%bc-2/"></g:plusone></div>]]></content:encoded>
			<wfw:commentRss>http://naskit.com/2009/12/11/ht-03a%e3%81%a7%e3%83%97%e3%83%ac%e3%83%93%e3%83%a5%e3%83%bc%e3%81%ae%e6%98%a0%e5%83%8f%e3%83%87%e3%83%bc%e3%82%bf%e3%82%92%e3%83%93%e3%83%83%e3%83%88%e3%83%9e%e3%83%83%e3%83%97%e3%83%87%e3%83%bc-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HT-03Aでプレビューの映像データをビットマップデータに変換して保存する</title>
		<link>http://naskit.com/2009/11/25/ht-03a%e3%81%a7%e3%83%97%e3%83%ac%e3%83%93%e3%83%a5%e3%83%bc%e3%81%ae%e6%98%a0%e5%83%8f%e3%83%87%e3%83%bc%e3%82%bf%e3%82%92%e3%83%93%e3%83%83%e3%83%88%e3%83%9e%e3%83%83%e3%83%97%e3%83%87%e3%83%bc/</link>
		<comments>http://naskit.com/2009/11/25/ht-03a%e3%81%a7%e3%83%97%e3%83%ac%e3%83%93%e3%83%a5%e3%83%bc%e3%81%ae%e6%98%a0%e5%83%8f%e3%83%87%e3%83%bc%e3%82%bf%e3%82%92%e3%83%93%e3%83%83%e3%83%88%e3%83%9e%e3%83%83%e3%83%97%e3%83%87%e3%83%bc/#comments</comments>
		<pubDate>Tue, 24 Nov 2009 17:31:39 +0000</pubDate>
		<dc:creator>saikoro</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[HT-03A]]></category>
		<category><![CDATA[ToyCam]]></category>

		<guid isPermaLink="false">http://naskit.com/?p=116</guid>
		<description><![CDATA[HT-03Aでプレビューの映像データをビットマップデータに変換して保存する方法。


カメラのプレビュー画像を画面に表示するには、SurfaceView を継承したビュークラスを作成して、Activityにセットする。
こんなアクティビティを作成する。以後ソース。]]></description>
			<content:encoded><![CDATA[<p>HT-03Aでプレビューの映像データをビットマップデータに変換して保存する方法。</p>
<p>カメラのプレビュー画像を画面に表示するには、SurfaceView を継承したビュークラスを作成して、Activityにセットする。<br />
こんなアクティビティを作成する。以後ソース。<br />
<span id="more-116"></span></p>
<pre class="brush: java; title: ; notranslate">
import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Window;
import android.view.WindowManager;

public class CameraActivity extends Activity {

	private CameraPreview mCameraPreview; // カメラプレビュー

	/**
	 *  アクティビティ起動
	 */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // フルスクリーン・タイトルなし・ディスプレイを常に明るく
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN
        					| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        // カメラプレビュー
        mCameraPreview = new CameraPreview(this);
        setContentView(mCameraPreview);
    }

    /**
     *  キー操作
     */
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
    	// HT-03Aならトラックボールを押し込んだ
    	if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
			mCameraPreview.takePicture();	// 撮影
			return true;
    	} else {
    		return super.onKeyDown(keyCode, event);
    	}
    }

    /**
     * 復帰
     */
    @Override
    public void onResume() {
    	super.onResume();
    	// カメラ復帰処理
    	mCameraPreview.onResume();
    }

    /**
     * 退避
     */
    @Override
    public void onPause() {
    	super.onPause();
    	// カメラ退避処理
    	mCameraPreview.onPuse();
    }

}
</pre>
<p>つづいてカメラプレビュー</p>
<pre class="brush: java; title: ; notranslate">
// import 略

public class CameraPreview extends SurfaceView
	implements SurfaceHolder.Callback {

	private SurfaceHolder mHolder;			// サーフェースホルダー
	private Context mContext;				// コンテクスト
	private Camera mCamera;					// カメラ
	private Camera.Parameters mCamparam;	// カメラ設定
	private boolean mProgress;				// 撮影実行中フラグ
	private boolean mHasSurface;			// サーフェースの存在フラグ
	private boolean mCameraPreviewing;		// プレビュー実行フラグ
	private Bitmap mBitmap;					// 撮影されたビットマップ

	/**
	 * コンストラクタ
	 * @param context
	 */
	public CameraPreview(Context context) {
		super(context);
		mContext = context;
		mHolder = getHolder();
		initSurface();

	}
	/**
	 * サーフェース作成後のコールバック
	 */
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
		mCamparam = mCamera.getParameters();
		mCamparam.setPreviewSize(width, height);
		mCamera.setParameters(mCamparam);
		startCameraPreview();

	}
	/**
	 * 画面の作成コールバッック
	 */
	public void surfaceCreated(SurfaceHolder holder) {
		mCamera = Camera.open();
		mCamparam = mCamera.getParameters();
		try {
			mCamera.setPreviewDisplay(holder);
		} catch(Exception e) {
			mCamera.release();
			mCamera = null;
		}
		mHasSurface = true;
	}
	/**
	 * 画面の破棄コールバック
	 */
	public void surfaceDestroyed(SurfaceHolder holder) {
		cameraDestroy();
		mHasSurface = false;
	}
	/**
	 * 再開
	 */
	public void onResume() {
		if (mHasSurface) {
			surfaceCreated(mHolder);
			startCameraPreview();
		} else {
			initSurface();
		}
	}
	/**
	 * 一時停止
	 */
	public void onPuse() {
		cameraDestroy();
	}
	/**
	 * サーフェースの初期化
	 */
	private void initSurface() {
		mHolder.addCallback(this);
		mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
	}

	/**
	 * プレビューの開始
	 */
    private void startCameraPreview() {
        if (!mCameraPreviewing) {
            mCamera.startPreview();
            mCameraPreviewing = true;
        }
    }
    /**
     * プレビューの停止
     */
    private void stopCameraPreview() {
        if (mCameraPreviewing) {
            mCamera.stopPreview();
            mCameraPreviewing = false;
        }
    }

    /**
	 * カメラの開放
	 */
	private void cameraDestroy() {
		if (mCamera != null) {
			stopCameraPreview();
			mCamera.release();
			mCamera = null;
		}
	}

	/**
	 * 撮影コマンド
	 */
	public void takePicture() {
		if (!mProgress) {
			mProgress = true;
			mCamera.setPreviewCallback(savePreviewImage);　// ここでプレビューコールバックをセット
		}
	}

	/**
	 * プレビューコールバック
	 *   prepareSavePreviewImageコールバックで登録され、プレビュー画像を取得する
	 */
	private final Camera.PreviewCallback savePreviewImage =
		new Camera.PreviewCallback() {

			public void onPreviewFrame(byte[] data, Camera camera) {
				mCamera.setPreviewCallback(null);  // ここですぐにプレビューコールバックを解除
				stopCameraPreview();
				mProgress = true;
				saveImage(data);  // 画像の保存
　　　　　　　　　　　　　　startCameraPreview();
			}
		};

	/**
	 * カメラのプレビューデータを保存する
	 *
	 */
	private boolean saveImage(byte[] data) {

		if (data == null) {
			return false;
		}
		final int width = getWidth();
		final int height = getHeight();
		// 変換後のピクセル配列
		int[] rgb = new int[(width * height)];
		try {
			mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
			// YUV420からBitmapに変換
			decodeYUV420SP(rgb, data, width, height);
			mBitmap.setPixels(rgb, 0, width, 0, 0, width, height);
		} catch (Exception e) {
			return false;
		}
		// 取得できたBitmapインスタンスをファイルに保存するところ略

		return true;
	}

    /**
     * YUV420データをBitmapに変換する
     * @param rgb
     * @param yuv420sp
     * @param width
     * @param height
     */
    // YUV420 to BMP
    public static final void decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width, int height) {
        final int frameSize = width * height;

        for (int j = 0, yp = 0; j &lt; height; j++) {
            int uvp = frameSize + (j &gt;&gt; 1) * width, u = 0, v = 0;
            for (int i = 0; i &lt; width; i++, yp++) {
                int y = (0xff &amp; ((int) yuv420sp[yp])) - 16;
                if (y &lt; 0) y = 0;
                if ((i &amp; 1) == 0) {
                        v = (0xff &amp; yuv420sp[uvp++]) - 128;
                        u = (0xff &amp; yuv420sp[uvp++]) - 128;
                }

                int y1192 = 1192 * y;
                int r = (y1192 + 1634 * v);
                int g = (y1192 - 833 * v - 400 * u);
                int b = (y1192 + 2066 * u);

                if (r &lt; 0) r = 0; else if (r &gt; 262143) r = 262143;
                if (g &lt; 0) g = 0; else if (g &gt; 262143) g = 262143;
                if (b &lt; 0) b = 0; else if (b &gt; 262143) b = 262143;

                rgb[yp] = 0xff000000 | ((r &lt;&lt; 6) &amp; 0xff0000) | ((g &gt;&gt; 2) &amp; 0xff00) | ((b &gt;&gt; 10) &amp; 0xff);
            }
        }
    }

}
</pre>
<p>これでHT-03Aでトラックボールを押し込んだときにプレビューデータをビットマップ型に変更できる。・・・はず。<br />
あとは保存するなり送信するなり。</p>
<div class="plus-one-wrap"><g:plusone size="medium" href="http://naskit.com/2009/11/25/ht-03a%e3%81%a7%e3%83%97%e3%83%ac%e3%83%93%e3%83%a5%e3%83%bc%e3%81%ae%e6%98%a0%e5%83%8f%e3%83%87%e3%83%bc%e3%82%bf%e3%82%92%e3%83%93%e3%83%83%e3%83%88%e3%83%9e%e3%83%83%e3%83%97%e3%83%87%e3%83%bc/"></g:plusone></div>]]></content:encoded>
			<wfw:commentRss>http://naskit.com/2009/11/25/ht-03a%e3%81%a7%e3%83%97%e3%83%ac%e3%83%93%e3%83%a5%e3%83%bc%e3%81%ae%e6%98%a0%e5%83%8f%e3%83%87%e3%83%bc%e3%82%bf%e3%82%92%e3%83%93%e3%83%83%e3%83%88%e3%83%9e%e3%83%83%e3%83%97%e3%83%87%e3%83%bc/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

