gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 01:43:33 25 4
gpt4 key购买 nike

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

为了可视化圆,我刚刚创建了一个自定义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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com