Avatar

【書籍】コードからわかる Androidプログラミングのしくみ
を購入した。

サブタイトルは「開発で困ったときの解決アプローチ」である。

原著があり、タイトルは「Unlocking Android A Developer’s Guide」というらしい。
サンプルコードも原著のサイトからダウンロードするようになっている。

内容は入門用というわけではなく、アプリを開発した経験がないと難しいかな。
ページは索引も含めて464ページ。イラストは少なく、コードと解説がギッシリである。

Androidの概要・eclipseを使った開発環境・ユーザーインターフェース・IntentとService・データの永続化関連・ネットワーク関連・電話機能関連・通知関連・マルチメディア(内OpenGLESに10ページ)・GPSをしっかりと解説していて、そのあとサンプルアプリケーションの作成やネイティブアプリケーションのビルド方法(NDKが出る前のやり方)となっている。

そして、監修者付録として AppWidgetの作り方・AsyncTaskの解説・AndroidNDKの解説がある。

さらっと読んだだけだが濃いぃー内容だった。何度も読み返すことになりそうだ。

これまでAndroidの開発入門書を2冊読んだけど、まだまだ知らないことが沢山あるのだなと思った。
入門書と日本語のWebの情報でもなんとかアプリは作れてしまうがアプリ開発者なら読んでおいて損はない。

Tagged with: .
Avatar

ピッチシフトについてメモ

音声データを再生するときに早送りにしたり、ゆっくり再生すると声が高くなったり低くなったりする。
再生するスピードを変えずに声の高さだけを変えることをピッチシフトと言うらしい。

やり方はいろいろあるようで、音声データを短い時間に区切って間引いたり、かさ増ししたりして音データをつなげなおすと音程が変わる方法や、フーリエ変換で音の周波数を求め、周波数を変更して逆フーリエ変換で戻してやる方法があるようだ。

Androboiceではとりあえず間引いたりかさ増しする方法で実現している。

音を1オクターブ高くするには周波数を2倍にすればよいらしい。だから短い時間に区切って音データを半分に間引いて、間引いたデータを区切ったデータの後ろにくっつけて長さを同じにする。それを全てのデータ分実行すると再生速度そのままで1オクターブ高い音が作れる。

0,1,2,3,4,5,6,7,8,9
を
0,2,4,6,8,0,2,4,6,8
にする

これで2倍の高さの音になる。

この「0,1,2,3,4,5,6,7,8,9」って音の幅はどれくらいかというと8000Hzで約33msec分で240サンプル分を間引き処理してつなげている。

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秒間の処理おわり

238と240のつなぎ目は滑らかにならないので雑音のようになるのだが、なめらかにする処理は省略した。分からないので。

なぜ30msecで区切ることにしたのかというと、自分の声を録音して波形編集ソフトで変換してみて、大体30msecくらいならうまくいくかなーと思ったから。人の声は大体300Hzくらいなので1秒間に300回なんらかの波が繰り返されていることになる。んで30msecなら6回から10回くらい繰り返しているので、「これなら加工しやすいだろう」となんとなく感覚で決めた。

まあ、waveデータを加工して音作りをしている人にとっては大したことないのかもしれないが、良い勉強になった。

フーリエ変換バージョンもあるのだが、1秒の音を変換するのに9秒くらいかかってしまう。これではFFTとは言えないくらい遅い。
floatの配列を使って演算しているのだが、これがボトルネックなのだろう。FixPointで計算するかJNIを使うしかないかもしれない。
また勉強することが増えた。

Tagged with: , , , .
Avatar

Androboiceってアプリを作ったときのメモ

前回の続き。

で、AndroidでPCMデータの再生

AudioTrackクラスで前回rec.rawとして保存した生PCMデータを再生できる。以下コード

// 各種例外処理は略
// サンプルレート 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() + "/rec.raw");
InputStream is = new FileInputStream(recFile);
// バイトデータの配列
long length = mOutFile.length();
byte[] byteData = new byte[(int)length];
// ファイルのデータを全て読み込み
int offset = 0, numRead = 0;
while (offset < byteData.length
		&& (numRead = is.read(byteData, offset, byteData.length - offset)) >= 0) {
	offset += numRead;
}
is.close();

// 出力
audioTrack.play();
audioTrack.write(byteData, 0, byteData.length);

コードはここを参考にした。
これでスピーカーから音が出る。
が、しかしDroidとかMilestoneとかG1とかで動かないらしい。
AudioTrackが取得できない条件があるみたい。サンプルレートが問題なのだろうか。
手元にないのでわからんが。。。2.0のエミュレータでは動くのだが・・・まいった;(

AudioTrackとAudioRecordクラスは指定したフレームごとにコールされるリスナを登録できるらしい。
それを使えば録音・再生のシークバーとかを実装できるのかな。うまくいかないのだが・・。

なんにせよ情報が少なすぎる・・。Audioまわりを詳しくまとめた書籍があったら買うのだが。

Tagged with: , , , .