大佬教程收集整理的这篇文章主要介绍了来自Android的FFT输出(Visualiser)的不良频谱?,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我创建了一个带有自己的Android库@L_874_3@的音乐播放器,包括很多东西(如流派,动态播放列表和可视化).目前,我在创建当前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()@L_874_3@的结果.捕获数据的长度为1024.当前斜率从1开始,因为mRawSpecData [0]包含DC且mRawSpecData [1]包含n / 2.
为了解决我的问题,我还试图摆弄频率箱的DC和相位.想到也许我不得不对幅度应用一些计算来“清理”图形.但是我没有成功(也许是因为我根本没有得到DC /阶段的东西!).
我花了两周的时间在晚上搜索谷歌并尝试不同的计算,但没有什么真正帮助.
那么这笔交易是什么?我做错了什么或留下了什么?
在那之后,困扰我的另一个问题是如何正确地扩展量值.
我的目标是获得介于0f和1f之间的值.
非常感谢
乱闹
P.s.:从运行Android 2.3的手机通过eclipse拍摄的屏幕截图.
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)的不良频谱?所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。