带圆圈的简单音乐可视化

问题描述:

我试图构建一个简单的音乐可视化应用程序,只需调整一个圆圈。因此,如果当前正在播放的音乐部分响亮,则应该变大,否则应该变小。带圆圈的简单音乐可视化

可视化圆我刚刚创建了一个自定义的视图类,它在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部分的初学者,我完全抱歉如果这是一个愚蠢的问题和我的企图。

谢谢你的帮助!

编辑:

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); 

一个真正好的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 

} 

}

您可以PROGRAMM自己renderes并让用户选择他想要使用哪一个。只需将数组从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

嗯......谢谢你的帮助,我只是想与和做出来,这是trashhold princip,但它仍然不是我想要的。它看起来不像一个同步的圆。 (我没有添加圈子周围的花哨线:-))。我用我试过的代码更新了我的帖子。 –