2012年2月25日土曜日

[Cubase] Mystic・Prologue・Spectorの同時発音数の設定方法

How to make Mystic, Prologue, Spector change the number of voices

Cubaseにはシンセサイザーがたくさん付属しています。
なぜかMystic・Prologue・Spectorの3つは同時発音数の設定方法がマニュアルに書いてありません。
初期設定ではモノフォニック(単音)しか鳴らせません。

設定箇所は画面右上(max voices)、コンソールの外側です。
ちなみに画面左上(pitchbend range)でピッチベンド幅が設定できます。2で1音階、12で1オクターブです。

左上がピッチベンド幅、右上が同時発音数
いじっているうちに偶然気がつきました。

同時発音数を2以上に設定した場合はポルタメント効果はなくなります。(このことはマニュアルに書いてあります)

この3つのシンセは音色が個性的なので効果音を作るのに重宝します。
ただしパラメーターが多くて初期状態から音色を作るのは難しいのでプリセットを少し加工して使ってます。
音色をねらって作るのは難しいです。

もうすぐSteinbergからPadshopというシンセサイザーが発売される聞いてふと思い出しました。
http://japan.steinberg.net/jp/products/vst/padshop/start.html
Padshopも難しそうですが音作りの幅は広そうです。

以上、参考になれば幸いです。

2012年2月18日土曜日

[Android] BitmapクラスのOutOfMemoryErrorを防ぐ #2

How to correct the OutOfMemoryError of Bitmap class #2
前回は画像表示のたびにBitmapFactory.decodeResourceを実行して、表示後にrecycle()メソッドで解放する方法でOutOfMemoryErrorを防ぎました。
この方法は安定して動作しますが、表示のたびにファイルにアクセスしてデコード処理を実行するので効率が悪いような気がします。

そこで他の方法を考えました。
Bitmapクラスは画像を整数の配列に変換する getPixelsメソッド と、整数の配列を画像に戻す setPixelsメソッド があります
画像を配列に変換したり、配列を画像に変換する処理はCPUとメモリー(RAM)の間のデータ転送が主な内容になるはずです。
ファイルアクセスやデコード処理が1回で済むのでもっと効率が上がりそうです。

今回は1024×1024ピクセルの4枚の画像を整数の配列に変換することをを試してみます。
成功すればBitmapFactory.decodeResourceは各画像につき1度しか実行されないので効率が上がるはずです。

Main3
結果
整数の配列の確保(new int[1024 * 1024])でOutOfMemoryErrorが起きてしまいました。
Android1.6と2.1のエミュレーターで確認しました。
Androidのint型は4バイトなのでint[1024 * 1024]の配列は連続した4MBの空きメモリー(RAM)が必要になるわけですが、それを4つも確保するのは難しいようです。
int[1024][1024]の2次元配列を使う方法に直して試みましたがやっぱりOutOfMemoryErrorが起きました。

RAM容量の多い端末で正常動作するかもしれませんが、エミュレーターで動作しない方法なのでお勧めできません。

ちなみにgetPixelsメソッドはJNI(Android-NDK)のOpenGLでポリゴンのテクスチャを貼り付けるときに必須のメソッドです。
http://blog.fujiu.jp/2011/08/android-android-ndk.html

今回はわざと大きい画像や配列を扱ってエラーが出ることを確認しました。
将来のAndroid端末は今以上にRAMの大容量化、画面の高解像度化が予測されます。
Android-SDKやOSも進化して大きいBitmapを扱いやすくなってます。
古い端末でも簡単に扱えるようになったらいいですね。


以上、参考になれば幸いです。

2012年2月11日土曜日

[Android] BitmapクラスのOutOfMemoryErrorを防ぐ

How to correct the OutOfMemoryError of Bitmap class

Android端末は種類が多く、画面解像度も機種ごとに違うので画像の扱いは大きな悩みどころです。
たとえばSurfaceViewに画像を表示する場合、大きめの画像データ(1024×1024ピクセル)を用意して画面解像度に合わせて縮小表示する方法が一番簡単のように思います。
ところが、Androidは大きい画像を下手に扱うと BitmapFactoryクラスが OutOfMemoryError が発生することがよくあります。

すでに多くの開発者がOutOfMemoryErrorを回避する方法を公開しています。
今更ながらMtkもいくつか方法を考えてみました。

4枚の1024×1024ピクセルの画像を1秒ごとに表示するアプリケーションで説明します。
画像は画面解像度に収まるように拡大縮小表示します。

1024×1024ピクセルのこんな画像を4種類用意します。
それぞれのファイル名はimage1.png、image2.png、image3.png、image4.pngとしました。
Androidのプロジェクトのresフォルダーの下にdrawableフォルダーを作成し、この4つの画像を保存します。

OutOfMemoryErrorが出るサンプルです。Android1.6のエミュレーターで確認しています。
※Android2.1のエミュレーターでは正常に動作しましたが実機ではOutOfMemoryErrorが起こり不安定です。
Main.java(Activity)
※Android1.6以上、パーミッション不要のため、マニフェストは省略します
Android1.6エミュレーターでアプリを実行すると
bmp2 = BitmapFactory.decodeResource ・・・
でOutOfMemoryErrorが発生します。
1024×1024ピクセルの画像(Bitmapのインスタンス)をメモリー(RAM)に置くことができないようです。

次はOutOfMemoryErrorが起きないように修正したサンプルです。
Main2.java(Activity)
Bitmapの表示のたびにファイルからロードし、次のbitmapファイルを開く前にrecycle()メソッドを実行します
表示するたびにファイルにアクセスするのは効率が悪いような気がしますが、Bitmapをメモリー(RAM)に置いておけないのだから仕方ありません。

今回はSurfaceViewを使いました。
GLSurfaceViewでポリゴンにテクスチャを貼り付けるときも GLUtils.texImage2D の直前でBitmapをロードし直後にrecycle()すると安定する思います

次回は他の方法を試してみる予定です。
公開しました http://blog.fujiu.jp/2012/02/android-bitmapoutofmemoryerror-2.html


以上、参考になれば幸いです。

2012年2月4日土曜日

[Java] thisとは #2

What is "this" #2

AndroidアプリケーションのJavaソースにthisを使うことがよくあります。
たとえばToastです。

Main.java(Activity)

ToastクラスのmakeTextメソッドにthisを渡しています。
thisはインスタンス化されたクラス自信です。
このソースはMainクラスの中のthisなので、インスタンス化されたMainクラス自身ということになります。

・なぜmakeTextメソッドにthisを書くのか?
Toastクラスのリファレンスを見てみます。
http://developer.android.com/intl/ja/reference/android/widget/Toast.html
makeTextメソッドの説明にはこう書かれてます。
makeText(Context context, CharSequence text, int duration)
Android-SDKをインストールしたeclipseならマウスをメソッドにホバーするとリファレンスが表示されます。

1壱番目の引数はContextを渡すことになってます。

上のサンプルでmakeTextメソッドに渡したのはContextクラスではなくMainクラスのthisです。
正常に動くけど渡すべきクラスが違うように見えます。

・なぜMainクラスのthisで動くのか?
上のサンプルのMainクラスは次のように定義しています。
public class Main extends Activity
MainクラスはActivityクラスを継承しています。
はActivityクラスのリファレンスを見てみます。
http://developer.android.com/intl/ja/reference/android/app/Activity.html
ここにはこんなことが書かれてます。

java.lang.Object
android.content.Context
android.content.ContextWrapper
android.view.ContextThemeWrapper
android.app.Activity
Activityがどのクラスを継承しているかを説明しています。

ActivityクラスはContextThemeWrapperクラスを継承したサブクラスで
ContextThemeWrapperクラスはContextWrapperクラスを継承したサブクラスで
ContextWrapperクラスはContextクラスを継承したサブクラスです。

つまりMainクラスはContextクラスを継承しているのでContextクラスとして振る舞うことができるのです。
makeTextメソッドに渡したthisはContextクラスを継承したMainクラスだからToastが正常に表示されたわけです。
ServiceクラスもContextクラスを継承しています。
http://developer.android.com/intl/ja/reference/android/app/Service.html
ServiceクラスもでToastを表示するときもmakeTextメソッドにthisを渡します。

・Contextのサブクラス以外のthis
Android-SDKのApiDemosのRotationVectorDemo.javaにこんなコードがあります。

mSensorManager.registerListener(this, mRotationVectorSensor, 10000);

registerListenerメソッドの第1引数はSensorEventListenerインターフェイスを渡すことになってます。
このMyRendererクラスの定義です。
class MyRenderer implements GLSurfaceView.Renderer, SensorEventListener
MyRenderer クラスはSensorEventListenerインターフェイスを継承しています。
SensorEventListenerインターフェイスを継承したクラスのthisはSensorEventListenerとして振る舞うのでregisterListenerメソッドに渡せば動作するわけです。

前回の [Java] thisとは で書ききれなかったAndroidアプリケーションのソースのthisについての説明でした。

以上、参考になれば幸いです。