我创建了一个带有自己的AndroID库函数的音乐播放器,包括很多东西(如流派,动态播放列表和可视化).目前,我在创建当前AudioStream的Spectrum时创建的Visualisations有些麻烦.
我已经阅读了以下问题(和答案)来获得关于机器人FFT的想法:
What kind of output should I see from getFft?
Android 2.3 Visualizer – Trouble understanding getFft()
现在我的问题:我从getFFTs系数得到的频谱似乎有些“奇怪”.我注意到我渲染的光谱在播放歌曲时似乎显示出很多“噪音”,因此我尝试使用一些测试声音.其中一个是简单的8khz声音,它应该只会在图形中产生一个峰值.不幸的是,结果如下所示:
http://img4.imageshack.us/img4/4181/spectrum8khz.png
底部出现的噪音在图表的整个宽度上闪烁.高杆保持在仅位置稍微闪烁的位置.
当我使用从1kHz到20kHz缓慢移动的测试声时,它看起来如下(大约2-3kHz):
http://img846.imageshack.us/img846/7373/spectrum3khz1khz20khz.png
峰值从左向右移动,每个峰值都快一点,因此随着时间的推移,峰值之间的距离会增加.不可见的是,一旦它们离开屏幕右侧(但幅度较小),峰值会从右向左返回.此外,所有峰值都会在屏幕略大于0.5的位置连接到一个大峰值.
这是我用来检索数据的代码:
for (int i = 1; i < n / 2; i++) { byte rfk = mRawSpecdata[2*i]; byte ifk = mRawSpecdata[2*i+1]; float magnitude = (float)Math.sqrt(rfk * rfk + ifk * ifk); mFormattedSpecdata[i-1] = magnitude / 128f;}
在上面的代码中,我mRawSpecdata是Visualiser getFFT()函数的结果.捕获数据的长度为1024.当前斜率从1开始,因为mRawSpecdata [0]包含DC且mRawSpecdata [1]包含n / 2.
为了解决我的问题,我还试图摆弄频率箱的DC和相位.想到也许我不得不对幅度应用一些计算来“清理”图形.但是我没有成功(也许是因为我根本没有得到DC /阶段的东西!).
我花了两周的时间在晚上搜索谷歌并尝试不同的计算,但没有什么真正帮助.
那么这笔交易是什么?我做错了什么或留下了什么?
在那之后,困扰我的另一个问题是如何正确地扩展量值.
我的目标是获得介于0f和1f之间的值.
非常感谢
乱闹
P.S.:从运行AndroID 2.3的手机通过eclipse拍摄的屏幕截图.
P.P.S.:我还检查了各种其他玩家的声音(如winamp),在那里我看到了频谱的正确行为.
解决方法 通过使用以下计算得到了很好的结果,获得了像 this图像这样的可视化器.我正在使用近19个图像进行显示.这些是通过getFFT()方法输入响应.并且确保启用均衡器和可视化器,否则它给出高值并且fft值响应设备音量.实际上我不能因为我的英语而给出了代码的解释.所以我在这里通过代码.
VisualizerVIEw:
public class VisualizerVIEw extends VIEw { private byte[] mBytes; private float[] mPoints; Paint mForePaint = new Paint();// private int wIDth;// height; private Paint mPaint; Bitmap mBmpArray[]; int wTilesize; int hTilesize; int no_of_colomuns; private Bitmap peakBitmap; private float changeFromtop,changeFromleft; private int images_drawn_starting_point ; int magnitudePoints[]; int max[] = new int[34]; int temp[]=new int[32]; private final int[][] images = { { R.drawable.blue_fade_1,R.drawable.blue_fade_2,R.drawable.blue_fade_3,R.drawable.blue_fade_4,R.drawable.blue_fade_5,R.drawable.blue_fade_6,R.drawable.blue_fade_7,R.drawable.blue_fade_8,R.drawable.blue_fade_9,R.drawable.blue_fade_10,R.drawable.blue_fade_11,R.drawable.blue_fade_12,R.drawable.blue_fade_13,R.drawable.blue_fade_14,R.drawable.blue_fade_15,R.drawable.blue_fade_16,R.drawable.blue_fade_17,R.drawable.blue_fade_18,R.drawable.blue_fade_19 }}; private final int IMAGES_LENTH = 19; public VisualizerVIEw(Context context) { super(context); mBmpArray = new Bitmap[20]; init(); } public VisualizerVIEw(Context context,AttributeSet attrs) { super(context,attrs); init(); } public VisualizerVIEw(Context context,AttributeSet attrs,int defStyle) { super(context,attrs,defStyle); init(); } @OverrIDe protected voID onSizeChanged(int w,int h,int olDW,int oldh) { super.onSizeChanged(w,h,olDW,oldh); images_drawn_starting_point = h; int temp; wTilesize = w / 34; // hTilesize = h / 30; temp = h - ((IMAGES_LENTH - 1) ); hTilesize = temp / (IMAGES_LENTH ); no_of_colomuns = ( w / (wTilesize)); magnitudePoints = new int[no_of_colomuns]; changeFromleft = wTilesize + 3f;//For spacing left changeFromtop = hTilesize + 2.5f;//For spacing Right } public voID init() { mPaint = new Paint(); mPaint.setcolor(color.BLACK); mPaint.setstrokeWIDth(5f); } @OverrIDe public voID draw(Canvas canvas) { super.draw(canvas); int h = canvas.getHeight(); int w = canvas.getWIDth(); canvas.drawRect(new Rect(0,w,h),mPaint); if (mBytes == null) { return; } if (mPoints == null || mPoints.length < mBytes.length * 4) { mPoints = new float[mBytes.length * 4]; } double magnitude; //VisualizerActivity.theme_color=0 for (int j = 0; j < IMAGES_LENTH; j++) loadTile(j,getResources().getDrawable(images[VisualizerActivity.theme_color][j])); for (int i = 0; i < no_of_colomuns; i++) { byte rfk = mBytes[2 * i]; byte ifk = mBytes[2 * i + 1]; magnitude = ((rfk * rfk + ifk * ifk)); int dbValue = (int) (10 * Math.log10(magnitude)); magnitude = Math.round(dbValue * 8); try { magnitudePoints[i] = (int) magnitude; } catch (Exception e) { e.printstacktrace(); } } int left; int top; int index; try { index = 0; left = 0; int m = 1; if (VisualizerActivity.theme_STYLE == 0) { // common for (int i = 0; i < no_of_colomuns; i++) { top = images_drawn_starting_point; index = 18; for (int j = 0; j < IMAGES_LENTH; j++) { if (j > magnitudePoints[m] / IMAGES_LENTH) { canvas.drawBitmap(mBmpArray[0],left,top,mPaint); index++; } else { canvas.drawBitmap(mBmpArray[index--],mPaint); } top -= changeFromtop;// hTilesize+1.5; } m++; left += changeFromleft;// wTilesize+2.5; } } } catch (Exception e) { e.getMessage(); } } public voID loadTile(int key,Drawable tile) { try { Bitmap bitmap = Bitmap.createBitmap(wTilesize,hTilesize,Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); tile.setBounds(0,wTilesize,hTilesize); tile.draw(canvas); mBmpArray[key] = bitmap; } catch (Exception e) { e.printstacktrace(); } } public voID updateVisualizerWithFft(byte[] bytes) { if (AudioPlayer.player != null) { if (AudioPlayer.player.isPlaying()) { mBytes = bytes; } } invalIDate(); }}
在VisualizerActivity.java中:
AudioPlayer.mVisualizer.setCaptureSize(Visualizer .getCaptureSizeRange()[1]); AudioPlayer.mVisualizer.setDataCaptureListener( new Visualizer.OnDataCaptureListener() { public voID onWaveFormDataCapture( Visualizer visualizer,byte[] bytes,int samplingRate) { // mVisualizerVIEw.updateVisualizer(bytes); } public voID onfftDataCapture(Visualizer visualizer,int samplingRate) { mVisualizerVIEw.updateVisualizerWithFft(bytes); } },Visualizer.getMaxCaptureRate() / 2,false,true);总结
以上是内存溢出为你收集整理的来自Android的FFT输出(Visualiser)的不良频谱?全部内容,希望文章能够帮你解决来自Android的FFT输出(Visualiser)的不良频谱?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)