android - 带圆圈的简单音乐可视化

标签 android audio visualization

我试图建立一个简单的音乐可视化应用程序,该应用程序应该调整一个圆圈的大小。因此,如果当前正在播放的“音乐声部”很大,则它应该变大,否则,它应该变小。

为了可视化圆,我刚刚创建了一个自定义View类,该类在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解决方案简单得多)

您可以使用三角函数使用数组的值在圆形轮廓上绘制波形,如果数组的总和大于特定的网格,则使圆的起始半径更大:

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方法。

用于分析波形的实用程序(幅度存储有点奇怪):
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
}

}

关于android - 带圆圈的简单音乐可视化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45514303/

相关文章:

audio - unity3d 中的无缝循环

android - 使用摩托罗拉 Moto G(或 Moto X)录制立体声音频

android - 共享偏好不断消失

android - 使用改造在服务器上上传文件

android - SQLiteDatabase 通过 NullPointerException

c++ - 隐藏 PCM 流中的丢包

node.js - 任何用于在 Node.js 中可视化模块依赖关系的库?

r - 如何使用 ggplot 在 R 中创建不均匀的 facet_wrap 网格?

r - 如何显示趋势线的图例?

java - 如何通过匹配 userType 和 android 中的验证状态来获取列表?