2017-08-04 1 views
0

円は、サークルのサイズを変更するだけの単純な音楽視覚化アプリケーションを作成しようとしています。したがって、現在再生中の音楽パートが大声であれば、それは大きくなるはずです。小さくなければなりません。円での単純な音楽の視覚化

円を視覚化する方法onDrawの方法で円を描画するカスタム表示クラスを作成しました。

現在のオーディオから情報を取得するには、AndroidのVisualizer Classが見つかりましたが、setDataCaptureListenerも使用しました。

mVisualizer = new Visualizer(mMediaPlayer.getAudioSessionId()); 
mVisualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[0]); 
mVisualizer.setDataCaptureListener(
    new Visualizer.OnDataCaptureListener() { 
      public void onWaveFormDataCapture(Visualizer visualizer,byte[] bytes, int samplingRate) { 
         mVisualizerView.updateVisualizer(bytes); 
        } 

        public void onFftDataCapture(Visualizer visualizer,byte[] bytes, int samplingRate) { 

        } 
       }, (int)(Visualizer.getMaxCaptureRate()/1.5), true, false); 

しかし、私の問題は、私は本当に私は一般の音楽の変化を(大声で得たかどうか?)を見つけるために、戻って与えられたバイト配列を使用する方法がわからないということです。

私はちょうど配列の平均を取得しようとしましたが、これは完全に悪い結果をもたらします。サークルは薬のように彼のサイズを変えました。だから私は多分配列はあまりにも多くのアウトライン/極値(本当だった)を考えたので、私は配列の中央値を計算したと思った。これは私に良い結果をもたらしましたが、それでも私が望むものではありません。非常に滑らかではなく、複雑になります。私はいつも本当に効率的ではない配列をソートする必要があります。何が間違っていると思いますか?

本当に私はこのAudioFXセクションの初心者です。これは私にとってばかげた質問です。

ありがとうございました!

EDIT:

private float schwelle = 5000; 
private float last = 0; 
... 

    float summe = 0; 

    for (Byte currentByte: mBytes) 
     summe += currentByte; 

    if (summe > schwelle && summe > last) 
    { 
     last = summe; //make it bigger 
    } 
    else { 
     last -= 100; //make circle smaller 
    } 

    canvas.drawCircle(getWidth()/2,getHeight()/2,last/100,mForePaint); 

答えて

0

本当に良いGitプロジェクトがhttps://github.com/felixpalmer/android-visualizerです。 私は自分でこれを思いついた:(gitソリューションよりもずっと簡単な)

三角法を使って円の輪郭に波形を描くために配列の値を使うことができ、円より大きな配列の合計が一定treshholdより大きい場合:

class StarWaveformRenderer implements Renderer { 
private Paint p = new Paint(); 

private static final int BOOST_TRASH_HOLD = 10000; 


private float stretchFade = 1; //circle fades after a prominent beat 

@Override 
public void render(Canvas canvas, byte[] data) { 
    if (data == null || data.length == 0) 
     return; 

    int centerX = canvas.getWidth()/2; 
    int centerY = canvas.getHeight()/2; 
    float stretch = stretchFade; 

    int sum = RenderUtils.sum(data); 
    p.setColor((p.getColor() + sum/2)); //change color of circle 
    if (sum > BOOST_TRASH_HOLD) {//prominent beat 

     stretch = (float) Math.min(canvas.getWidth(), canvas.getHeight())/Byte.MAX_VALUE/3; //maximum 

     stretchFade = stretch; 
    } 

    double radDif = 2 * Math.PI/data.length; //the angle between each element of the array 
    double radPos = 0; 

    float lX = (float) Math.cos(radPos) * data[0] + centerX; 
    float lY = (float) Math.sin(radPos) * data[0] + centerY; 
    float cX; 
    float cY; 


    for (byte b : data) { 
     cX = (float) Math.cos(radPos) * b * stretch + centerX; 
     cY = (float) Math.sin(radPos) * b * stretch + centerY;//calculate position of outline, stretch indicates promince of the beat 

     canvas.drawLine(lX, lY, cX, cY, p); 

     lX = cX; 
     lY = cY; 
     radPos += radDif; 

    } 


    stretchFade = Math.max(1, stretchFade/1.2f);//beat fades out 

} 

}

あなたがあなた自身のレンダラーをプログラムの開発及び利用者は、彼が使用したいいずれかを選択させることができます。配列をonWaveformDataCaptureからonRenderメソッドに渡すだけです。波形を分析するための

Utilsの(変なの振幅が保存されているようなもの):

class RenderUtils { 
private static final byte SHIFT = Byte.MAX_VALUE; 


static int sum(byte[] data) { 
    int sum = 0; 
    for (byte b : data) 
     sum += b; 
    return sum; 
} 


static int toAmplitude(byte b) { 
    return b > 0 ? b + SHIFT : -b;//+127=high positive;+1=low positive;-127=low negative;-1=high negative 
} 

static float toAmplitude(float f) { 
    return f > 0 ? f + SHIFT : -f;//+127=high positive;+1=low positive;-127=low negative;-1=high negative 
} 

}

+0

うーんは...あなたの助けをありがとう、私は合計でそれを実行しようとしましたし、ゴミ箱プリンシプルですが、それはまだ私が望むものではありません。同期サークルのように見えません。 (私は円の周りに空想的な線を追加しませんでした:-))。私は試したコードで投稿を更新しました。 –

関連する問題