精华内容
下载资源
问答
  • From:... ... ... 做音乐播放器,有时会要求EQ均衡器,但android默认的样式是水平的,这时就需要费点心思了。  先是实现默认SeekBar样式的EQ均衡器:      这是4.0以上默认样式的SeekB

    From:http://www.cnblogs.com/wenjiang/archive/

    2013/05/10/3071103.html

         做音乐播放器,有时会要求EQ均衡器,但android默认的样式是水平的,这时就需要费点心思了。

         先是实现默认SeekBar样式的EQ均衡器:

        

        

          这是4.0以上默认样式的SeekBar,2.3或以下就像是进度条一样。

          要实现这样的效果,其实并不难,先贴上源码:

    复制代码
    public class MainActivity extends Activity {
        private MediaPlayer mMediaPlayer;
        private Equalizer mEqualizer;
        private LinearLayout mLayout;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setVolumeControlStream(AudioManager.STREAM_MUSIC);
    
            mLayout = new LinearLayout(this);
            mLayout.setOrientation(LinearLayout.VERTICAL);
            setContentView(mLayout);
    
            mMediaPlayer = new MediaPlayer();
            try {
                mMediaPlayer.setDataSource("/sdcard/陪我去流浪.mp3");
                mMediaPlayer.prepare();
                mMediaPlayer.start();
            } catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (SecurityException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IllegalStateException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            setEqualize();
        }
    
        @TargetApi(Build.VERSION_CODES.GINGERBREAD)
        private void setEqualize() {
            mEqualizer = new Equalizer(0, mMediaPlayer.getAudioSessionId());
            mEqualizer.setEnabled(true);
    
            short bands = mEqualizer.getNumberOfBands();
    
            final short minEqualizer = mEqualizer.getBandLevelRange()[0];
            final short maxEqualizer = mEqualizer.getBandLevelRange()[1];
    
            for (short i = 0; i < bands; i++) {
                final short band = i;
    
                TextView freqTextView = new TextView(this);
                freqTextView.setLayoutParams(new ViewGroup.LayoutParams(
                        ViewGroup.LayoutParams.MATCH_PARENT,
                        ViewGroup.LayoutParams.MATCH_PARENT));
    
                freqTextView.setGravity(Gravity.CENTER_HORIZONTAL);
    
                freqTextView
                        .setText((mEqualizer.getCenterFreq(band) / 1000) + "HZ");
                mLayout.addView(freqTextView);
    
                LinearLayout row = new LinearLayout(this);
                row.setOrientation(LinearLayout.HORIZONTAL);
    
                TextView minDbTextView = new TextView(this);
                minDbTextView.setLayoutParams(new ViewGroup.LayoutParams(
                        ViewGroup.LayoutParams.MATCH_PARENT,
                        ViewGroup.LayoutParams.MATCH_PARENT));
    
                minDbTextView.setText((minEqualizer / 100) + " dB");
    
                TextView maxDbTextView = new TextView(this);
                maxDbTextView.setLayoutParams(new ViewGroup.LayoutParams(
                        ViewGroup.LayoutParams.MATCH_PARENT,
                        ViewGroup.LayoutParams.MATCH_PARENT));
                maxDbTextView.setText((maxEqualizer / 100) + " dB");
    
                LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
                        ViewGroup.LayoutParams.MATCH_PARENT,
                        ViewGroup.LayoutParams.MATCH_PARENT);
    
                SeekBar seekbar = new SeekBar(this);
                seekbar.setLayoutParams(layoutParams);
                seekbar.setMax(maxEqualizer - minEqualizer);
                seekbar.setProgress(mEqualizer.getBandLevel(band));
                seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
    
                    @Override
                    public void onStopTrackingTouch(SeekBar seekBar) {
                    }
    
                    @Override
                    public void onStartTrackingTouch(SeekBar seekBar) {
                    }
    
                    @TargetApi(Build.VERSION_CODES.GINGERBREAD)
                    @Override
                    public void onProgressChanged(SeekBar seekBar, int progress,
                            boolean fromUser) {
                        // TODO Auto-generated method stub
                        mEqualizer.setBandLevel(band,
                                (short) (progress + minEqualizer));
                    }
                });
                row.addView(minDbTextView);
                row.addView(seekbar);
                row.addView(maxDbTextView);
                mLayout.addView(row);
            }
        }
    
        @TargetApi(Build.VERSION_CODES.GINGERBREAD)
        @Override
        protected void onPause() {
            // TODO Auto-generated method stub
            super.onPause();
            if (isFinishing() && mMediaPlayer != null) {
                mMediaPlayer.release();
                mEqualizer.release();
                mMediaPlayer = null;
            }
        }
    }
    复制代码

          这里我采用了手动设置Layout布局的方式,因为上面的Layout采用LinearLayout实现,并且每个SeekBar的属性设置都一样,考虑到SeekBar的数量较多,采用这个方式可能会更好点,至少我们不需要写太繁琐的Layout布局文件。
          撇开那些Layout的布局代码,我们看看最主要的部分:SeekBar和Equalizer的设置。

          android系统提供内置的Equalizer支持,我们可以直接声明并且使用。但必须注意,当我们在代码中使用Equalizer的时候,其实就是调整音量(EQ均衡器是改变音频使得声音发生变化,像是洪亮或者低沉)。所以,我们需要在我们的代码中声明这么一句:

    setVolumeControlStream(AudioManager.STREAM_MUSIC);

          因为涉及到硬件方面的修改,我们需要权限:

    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

          它允许我们进行全局的音频设置。
          我们再来看看这句:

    mEqualizer = new Equalizer(0, mMediaPlayer.getAudioSessionId());

          每个MediaPlayer都有自己独一无二的SessionId,我们需要将Equalizer附加到这个MediaPlayer上,就必须获取该SessionId。然后我们再创建一个优先级为0的Equalizer对象。所谓的优先级,是因为一个Equalizer engine可以被多个应用程序共享,所以我们必须设置优先级,优先级0代表该应用程序为正常级别。
         要想启动Equalizer,我们还必须这样子:

    mEqualizer.setEnabled(true);

        这就是学过单片机的同学非常熟悉的"使能"。

        然后我们再获取支持的频谱:

     short bands = mEqualizer.getNumberOfBands();

        不同的硬件设备支持的频谱是不一样的,像是电脑能支持的频谱就比手机要多得多。
        接着就是获取频谱中的等级范围,我们只需要获取最低和最高即可。

    final short minEqualizer = mEqualizer.getBandLevelRange()[0];
    final short maxEqualizer = mEqualizer.getBandLevelRange()[1];

         接下来就是遍历频谱,设置SeekBar了:

    复制代码
    seekbar.setMax(maxEqualizer - minEqualizer);
    seekbar.setProgress(mEqualizer.getBandLevel(band));
    
    seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
    
        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {}
    
        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {}
    
        @TargetApi(Build.VERSION_CODES.GINGERBREAD)
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            mEqualizer.setBandLevel(band, (short) (progress + minEqualizer));
        }
    });
    复制代码

          我们必须设置SeekBar的最大进度范围,也就是进度顶端所代表的值。接着就是实现SeekBar进度改变时,Equalizer的音频也跟着相应的改变,这就需要监听SeekBar。
          好了,到了这里,基本的EQ均衡器已经实现了,但我们想要的并不是功能的实现,而是界面的实现(这往往是我们这些移动互联网开发者的恶梦,美工设计师们从来都没有考虑过我们要设计出他们的界面有时是多么难甚至不可能的一件事啊!)。

          既然默认的SeekBar样式无法满足我们的要求,我们只能自定义自己想要的SeekBar了。幸好,android还是提供了这种支持:只要继承自AbsSeekBr,我们就能得到自己想要的SeekBar了。

          依然先上源码:

    复制代码
    public class VerticalSeekBar extends AbsSeekBar {
        private Drawable mThumb;
        private int height;
        private int width;
    
        public interface OnSeekBarChangeListener {
            void onProgressChanged(VerticalSeekBar VerticalSeekBar, int progress,
                    boolean fromUser);
    
            void onStartTrackingTouch(VerticalSeekBar VerticalSeekBar);
    
            void onStopTrackingTouch(VerticalSeekBar VerticalSeekBar);
        }
    
        private OnSeekBarChangeListener mOnSeekBarChangeListener;
    
        public VerticalSeekBar(Context context) {
            this(context, null);
        }
    
        public VerticalSeekBar(Context context, AttributeSet attrs) {
            this(context, attrs, android.R.attr.seekBarStyle);
        }
    
        public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        public void setOnSeekBarChangeListener(OnSeekBarChangeListener l) {
            mOnSeekBarChangeListener = l;
    
        }
    
        void onStartTrackingTouch() {
            if (mOnSeekBarChangeListener != null) {
                mOnSeekBarChangeListener.onStartTrackingTouch(this);
            }
        }
    
        void onStopTrackingTouch() {
            if (mOnSeekBarChangeListener != null) {
                mOnSeekBarChangeListener.onStopTrackingTouch(this);
            }
        }
    
        void onProgressRefresh(float scale, boolean fromUser) {
            Drawable thumb = mThumb;
            if (thumb != null) {
                setThumbPos(getHeight(), thumb, scale, Integer.MIN_VALUE);
                invalidate();
            }
            if (mOnSeekBarChangeListener != null) {
                mOnSeekBarChangeListener.onProgressChanged(this, getProgress(),
                        fromUser);
            }
        }
    
        private void setThumbPos(int w, Drawable thumb, float scale, int gap) {
            int available = w + getPaddingLeft() - getPaddingRight();
            int thumbWidth = thumb.getIntrinsicWidth();
            int thumbHeight = thumb.getIntrinsicHeight();
            available -= thumbWidth;
            available += getThumbOffset() / 2;
            int thumbPos = (int) (scale * available);
            int topBound, bottomBound;
            if (gap == Integer.MIN_VALUE) {
                Rect oldBounds = thumb.getBounds();
                topBound = oldBounds.top;
                bottomBound = oldBounds.bottom;
            } else {
                topBound = gap;
                bottomBound = gap + thumbHeight;
            }
            thumb.setBounds(thumbPos, topBound, thumbPos + thumbWidth, bottomBound);
        }
    
        protected void onDraw(Canvas c) {
            c.rotate(-90);
            c.translate(-height, 0);
            super.onDraw(c);
        }
    
        protected synchronized void onMeasure(int widthMeasureSpec,
                int heightMeasureSpec) {
            height = View.MeasureSpec.getSize(heightMeasureSpec) / 2;
            width = 50;
            this.setMeasuredDimension(width, height);
        }
    
        @Override
        public void setThumb(Drawable thumb) {
            mThumb = thumb;
            super.setThumb(thumb);
        }
    
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(h, w, oldw, oldh);
        }
    
        public boolean onTouchEvent(MotionEvent event) {
            if (!isEnabled()) {
                return false;
            }
            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                setPressed(true);
                onStartTrackingTouch();
                trackTouchEvent(event);
                break;
    
            case MotionEvent.ACTION_MOVE:
                trackTouchEvent(event);
                attemptClaimDrag();
                break;
    
            case MotionEvent.ACTION_UP:
                trackTouchEvent(event);
                onStopTrackingTouch();
                setPressed(false);
                break;
    
            case MotionEvent.ACTION_CANCEL:
                onStopTrackingTouch();
                setPressed(false);
                break;
            }
            return true;
        }
    
        private void trackTouchEvent(MotionEvent event) {
            final int Height = getHeight();
            final int available = Height - getPaddingBottom() - getPaddingTop();
            int Y = (int) event.getY();
            float scale;
            float progress = 0;
            if (Y > Height - getPaddingBottom()) {
                scale = 0.0f;
            } else if (Y < getPaddingTop()) {
                scale = 1.0f;
            } else {
                scale = (float) (Height - getPaddingBottom() - Y)
                        / (float) available;
            }
    
            final int max = getMax();
            progress = scale * max;
    
            setProgress((int) progress);
        }
    
        private void attemptClaimDrag() {
            if (getParent() != null) {
                getParent().requestDisallowInterceptTouchEvent(true);
            }
        }
    
        public boolean dispatchKeyEvent(KeyEvent event) {
            if (event.getAction() == KeyEvent.ACTION_DOWN) {
                KeyEvent newEvent = null;
                switch (event.getKeyCode()) {
                case KeyEvent.KEYCODE_DPAD_UP:
                    newEvent = new KeyEvent(KeyEvent.ACTION_DOWN,
                            KeyEvent.KEYCODE_DPAD_RIGHT);
                    break;
                case KeyEvent.KEYCODE_DPAD_DOWN:
                    newEvent = new KeyEvent(KeyEvent.ACTION_DOWN,
                            KeyEvent.KEYCODE_DPAD_LEFT);
                    break;
                case KeyEvent.KEYCODE_DPAD_LEFT:
                    newEvent = new KeyEvent(KeyEvent.ACTION_DOWN,
                            KeyEvent.KEYCODE_DPAD_DOWN);
                    break;
                case KeyEvent.KEYCODE_DPAD_RIGHT:
                    newEvent = new KeyEvent(KeyEvent.ACTION_DOWN,
                            KeyEvent.KEYCODE_DPAD_UP);
                    break;
                default:
                    newEvent = new KeyEvent(KeyEvent.ACTION_DOWN,
                            event.getKeyCode());
                    break;
                }
                return newEvent.dispatch(this);
            }
            return false;
        }
    }
    复制代码

           代码很长,但关键是我上面标记的几个方法。
           onDraw()该方法就是实现竖直SeekBar的关键。我们可以看到,关键就是那个c.rotate(-90),它实现了我们的竖直:通过反转-90度。setThumbPos()方法是为了调整thumb的大小,这个很重要,尤其是当我们开始排版的时候,thumb很可能因为布局的问题而显示不完全或者根本就不见了。onMeasure()针对的是进度条的设置。至于具体的大小怎样设置,得看大家自己的具体应用了。

           这个是实现的效果:

          

          前面的代码基本保持不变,只要将SeekBar改为VerticalSeekBar就可以了:

    复制代码
    for (short i = 0; i < bands; i++) {
                final short band = i;
                int index = (int) i;
                VerticalSeekBar seekBar = (VerticalSeekBar) findViewById(seekBars[index]);
                seekBar.setMax(maxEqualizer - minEqualizer);
                seekBar.setProgress(mEqualizer.getBandLevel(band));
    
                seekBar.setOnSeekBarChangeListener(new VerticalSeekBar.OnSeekBarChangeListener() {
    
                    @Override
                    public void onProgressChanged(VerticalSeekBar VerticalSeekBar,
                            int progress, boolean fromUser) {
                        mEqualizer.setBandLevel(band,
                                (short) (progress + minEqualizer));
    
                    }
    
                    @Override
                    public void onStartTrackingTouch(VerticalSeekBar VerticalSeekBar) {
                        // TODO Auto-generated method stub
    
                    }
    
                    @Override
                    public void onStopTrackingTouch(VerticalSeekBar VerticalSeekBar) {
                        // TODO Auto-generated method stub
    
                    }
                });
    复制代码

           为了实现我上面的布局效果,我这次使用了RelativeLayout布局文件,至于那些间距的调整,就留给读者们了。

          这样的效果还是不行的,因为有个致命的缺陷:android2.3的默认样式和android4.0的默认样式是不一样的!别看我上面的效果挺美观的,在android2.3上可不是这样。

          最好的解决方法就是替换默认样式。

          替换默认样式的方法很简单:在res目录下,新建drawable文件夹,然后我们在该目录下新建一个xml文件:

    复制代码
    <?xml version="1.0" encoding="utf-8"?>
    <layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    
        <item android:id="@android:id/secondaryProgress">
            <clip android:drawable="@drawable/progress2" />
        </item>
        <item android:id="@android:id/progress">
            <clip android:drawable="@drawable/progress1" />
        </item>
    
    </layer-list>
    复制代码

         我们可以使用layer-list来替换默认样式,secondaryProgress指的是我们进度条中剩下的进度,progress指的就是我们当前的进度。
         分别设置好它们的替换图片后,我们再在SeekBar中这样设置:

    复制代码
    <com.example.eqpratice.VerticalSeekBar
                android:id="@+id/sec"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_toRightOf="@id/fir"
                android:progressDrawable="@drawable/progress"
                android:secondaryProgress="100"
                android:thumb="@drawable/thumb" />
    复制代码

         这里android: secondaryProgress="100"设置的是我们thumb能达到的最大进度,这个是要设置的,不然会出现thumb超出进度条的情况。
         现在的效果如图:

         

            大家可以根据自己的需要,自定义自己想要的样式。

            因为是菜鸟,很多东西都是一笔带过,写得不好或者是有错的,还请各位大神指教。

         

    展开全文
  • 做这个xmms的均衡器是上周五和今天,昨天的功夫,呵呵,发个截图吧: 看上去不怎么好看,但也花不了不少心思。试了试,可以正常用了,以后要加上自定音效,保存等功能。不过到此这个播放器基本已经快完成了,只有...

    做这个xmms的均衡器是上周五和今天,昨天的功夫,呵呵,发个截图吧:

    选择音效均衡器界面

     

    看上去不怎么好看,但也花不了不少心思。

    试了试,可以正常用了,以后要加上自定音效,保存等功能。

    不过到此这个播放器基本已经快完成了,只有一点完善了!

    选了"Dance"音效后,听起来真的不错,呵呵!

    展开全文
  • 均衡器 FX,低音增强器和音量增强器(Eq和Bass)可以改善您 Android 手机的音质。Equalizer FX Pro 是安卓手机上的一个低音均衡器软件,能处理音频相关信号,提供各种均衡器处理内容,有多种主题特色可选,音乐制作...
  • 诺基亚N81的扬声器的均衡器默认设置与内设超重低音设置均不能让人有满意的效果,此外放模式属于新建手动设置模式,该设置完成后的外放效果较之前简直判若两“机”,也绝非目前市场上任何一款音乐手机能够比拟的....
      
    

    诺基亚N81的扬声器的均衡器默认设置与内设超重低音设置均不能让人有满意的效果,此外放模式属于新建手动设置模式,该设置完成后的外放效果较之前简直判若两“机”,也绝非目前市场上任何一款音乐手机能够比拟的.


     

    官方推荐

     

    attachimg.gif

     

     

     

    从左到右、自下而上第一柱调到第9波点,第二柱调到第6波点,第三柱调到第5波点,第四柱调到第7波点,第五柱调到第8.5波点

     

     

    本人多次测试(小弟耳力很强悍),调好后,比原来音质有明显提高。
    打开音乐=》正在播放=》选项=》爵士音乐=》选项=》编辑将第1根调至第7格,第2根调至第4格,第3根调至第2格,第4根调至第2格,第5根调至第4格。大家播放音乐听听效果吧~~(音质更清晰了吧)

     

     

     

     

     

    首先打开播放器=>选项=>音频设置。 
    分别有均衡器平衡、立体声扩展、响亮几个文件.均衡器先不要理,平衡设置为默认中间位置,立体声选择关闭,响亮选择开,之后再打开均衡器.建立一个新预设名称,打开预设里编辑的选项后自左而右的顺序可以看到五根音频柱: 
    1是调节高音(如果听摇滚音乐的话那个要调高一点,非常震撼) 
    2是强化弱音(弱音是一种吉他技巧,一般不用调太高 3格就够了) 
    3是调节中音(不需要调太高2格就够了) 
    4是调节高音量(应该调高一点 吉他和小提琴类的高音乐器表现得很明显) 
    5是强化高音(这个就不用调太高了 2格就够 调多了高音就变了) 

    每个音柱上自下而上分别为11个波点,现在简单附上以下几种常见的均衡设置 


    然后先说外放~~~~~~~~~~~~~~~~~ 
    外放时,将立体声关闭·响亮打开· 这样是最佳效果 

    一、外放最理想的模式: 
    从左到右、自下而上第一柱调到第5波点,第二柱调到第6波点,第三柱调到第5波点,第四柱调到第3波点,第五柱调到第5波点.之后返回启动。 
    二、低音强化模式: 
    从左到右、自下而上第一柱调到第四波点,第二,三,四柱调到第二波点,第五柱调到第四波点,好了之后按右边返回健,然后启动,这时听起来低音效果强化了. 
    三、天籁之音模式: 
    前面操作同二,第一根柱子调到第六波点,第二柱调到第四波,第三柱调到第二波点,第四柱调到第四波点。第五柱调到第六波点。好了之后也按右健返回后启动即可. 
    四、双重低音模式: 
    前面操作同上,第一根柱调到第6波点,第二根柱调到第5波点,第三根柱调到第4波点,第四根柱调到第3波点,第五根柱调到第2波点,确认后按右健返回后启动 
    五、适合通用类型的音乐播放: 
    前面操作同上,第一根柱调到第9波点,第二根柱调到第8波点,第三根柱调到第6波点,第四根柱调到第2波点,第五根柱调到第7波点,确认后按右健返回后启动. 

    再说耳机~~~~~~~~ 
    使用耳机时,将立体声打开·响亮打关闭· 这样是最佳效果,用今年春晚上的话说--飞一般的感觉 

    第一柱调到第9点;第二柱调到第3点;第三柱调到最顶第11点,第四柱也是最顶第11点,第五柱调到9与10点中间,这样的效果低音下潜较好,中音出得来,高音清而不毛刺,整体通透而平均,适合各类音乐 

    加一个非主流调整方案(虽然不太明白非主流什么意思,但好像是挺流行的词) 

    把所有六根柱都调到最高,比较适合流行歌曲,但根据音乐文件的流量Hz不同,开最大音量时可能会有破音,建议使用中高音播放

     

     

     

     

     

     

     

     

     

     

    要使我们的N81能有完美的音质,那均衡器设置的设置测试必不可少的,借鉴了一些帖子的经验发下自己收藏的10个均衡器设置(N81的每根柱都有10个大波点,注意以下有的柱点是调到1/2波点):

            第一根是调节高音(就是我们听摇滚时候的震撼重低音)
         

            第二根是调节强化弱音
               
            第三根是调节中音
         
            第四根是调节高音音量
         
            第五根是强化高音

     

     

      

     

      

     

      

     

     

     

     

    刚刚研究出的结果,效果没的说,给大家分享:
    从下至上数 第一条  调到第九格

                    第二条  调到第三格
                    第三条  调到第六格
                    第四条  调到七格与八格中间
                    第五条  调到第九格
    高音中音低音完美无缺啊!!!<要注意把响亮关闭立体声打开>
    我用的PX200耳机效果很好,不感保证不同耳机的效果
    另外上一首非常好听的音乐,也可以用这首歌来测试一下

     

     

     

     

     

     

    全方位体验 五大品牌18款音乐手机横评

    编辑选择奖——诺基亚N81

        在数项测试中遥遥领先的N81最大的特点是全面,无论是耳机音质还是外放效果,N81的表现都非常突出,而凭借诺基亚强大技术支持的强大功能音乐播放界面和快捷键,诺基亚N81在音乐播放方面表现出了很好的专业度。也许是国内消费者对其游戏功能的过高期待掩盖了其更加优秀的音乐光芒,很多消费者并没有把N81当作一款专业的音乐手机来看待,然而洗净黄沙始建金,N81的凭借其当然不让的优秀表现成为了2007年度最优秀的音乐手机。唯一能阻碍该机成为音乐爱好者必备手机的障碍只是其稍高的售价了。


    全方位体验 五大品牌18款音乐手机横评

    最佳音乐表现奖——三星SGH-F308

        采用双面设计的三星SGH-F308有音乐和手机两个互不干扰的界面,该机的音乐面简直就是一个MP3。在本次横评中,三星F308在待机时间、音质表现以及传输速度等音乐手机最为看重的评测项目中表现的异常的抢眼。如果我们是用MP3播放器的标准来衡量的话,F308肯定会取代N81成为本次参评的18款产品中最优秀。但是由于F308在手机基本功能方面以及易用性上表现出的一些不成熟,该机的总分还是低于N81,不过突破性的设计和专业的音乐表现还是让我们不得不把年度最佳音乐表现奖授予三星SGH-F308。

    全方位体验 五大品牌18款音乐手机横评

    全方位体验 五大品牌18款音乐手机横评
    点击查看详细得分对比表格

    展开全文
  • <div><p>每次更新负载均衡器的时候就报如下错误,但实际上这个 LoadBalanceId并没有错误,更不是找不到,我怀疑这个和删除SLB需要手机短信验证有关。 <pre><code> Error applying plan: 2 error...
  • \\\近日,Facebook开源了Katran,一个四层网络负载均衡器软件包,已经被用在Facebook的网络负载均衡器当中。Katran是一种基于软件的负载均衡解决方案,利用了两项最新的内核工程创新:eXpress Data Path(XDP)和...
    \

    看新闻很累?看技术新闻更累?试试下载InfoQ手机客户端,每天上下班路上听新闻,有趣还有料!

    \
    \\

    近日,Facebook开源了Katran,一个四层网络负载均衡器软件包,已经被用在Facebook的网络负载均衡器当中。Katran是一种基于软件的负载均衡解决方案,利用了两项最新的内核工程创新:eXpress Data Path(XDP)和eBPF虚拟机。Katran被部署在Facebook的PoP服务器上,用于提高网络负载均衡的性能和可扩展性,并减少在没有数据包流入时的循环等待。

    \\

    Facebook面临的挑战

    \\

    为了管理Facebook的流量,他们部署了一个分布式PoP服务器作为数据中心的代理。鉴于极高的请求量,PoP和数据中心都面临着巨大挑战,比如如何将大量的后端服务器作为单一的虚拟单元提供给外部,以及如何在后端服务器之间高效地分配工作负载。

    \\

    他们为每个位置分配虚拟IP地址(VIP),发送到VIP的数据包被无缝地分发给后端服务器。在实现分发算法时,需要考虑到后端服务器通常是在应用层处理请求,并且会终结TCP连接。于是网络负载均衡器(通常称为第四层负载均衡器或L4LB)需要负责处理数据包方面的问题。

    \\

    be6f97c7d607fd7c10de13fc149f1525.png

    \\

    图1:网络负载均衡器将来自客户端的数据包发送给后端服务器。

    \\

    对高性能负载均衡器的要求

    \\

    L4LB的性能对降低延迟和扩展后端服务器来说尤其重要,因为L4LB需要处理每个传入的数据包。L4LB的性能通常通过每秒可以处理的数据包峰值(pps)来衡量。一般来说,工程师们首选基于硬件的解决方案,因为这样可以使用加速器,如专用集成电路(ASIC)或可编程门阵列(FPGA)来减轻主CPU的负担。然而,基于硬件的解决方案有个缺点,就是它限制了系统的灵活性。为了有效满足Facebook的需求,网络负载均衡器必须:

    \\
    • 可在商用Linux服务器上运行。\\t
    • 与服务器上的其他服务共存。\\t
    • 允许低中断维护。\\t
    • 方便调试。\

    为了满足这些需求,他们设计了一个高性能的软件网络负载均衡器。第一代L4LB基于IPVS内核模块,满足了Facebook四年多的需求。不过,它与其他服务很难共存,特别是后端服务。在第二次迭代中,他们利用eXpress数据路径(XDP)框架和新的BPF虚拟机(eBPF)让软件负载均衡器和其他服务运行在一起。

    \\

    0f1872620e589d659c05ae45e40b6482.png

    \\

    图2:两代L4LB之间的差别

    \\

    第一代L4LB:基于OSS软件

    \\

    第一代L4LB使用了大量的开源组件来实现大部分功能,因此能够在几个月内取代基于硬件的解决方案。该设计有四个主要组成部分:

    \\
    • VIP发布:该组件通过与位于L4LB前面的网络元件(通常为交换机)对等交互向互联发布虚拟IP地址。然后,交换机使用等价多路径(ECMP)机制在L4LB之间分发数据包。\\t
    • 后端服务器选择:为了将来自某个客户端的所有数据包发送到相同的后端服务器,L4LB使用了一致性哈希,哈希值取决于传入的5元组(源地址、源端口、目标地址、目标端口和协议)数据包。一致性哈希可确保属于相同连接的所有数据包将被发送到相同的后端。\\t
    • 转发面板:一旦L4LB选择了合适的后端服务器,数据包将被转发到该服务器。为了突破一些限制,比如L4LB与后端主机需要同处于一个L2域中,他们使用了简单的IP-in-IP封装,这样就可以将L4LB和后端主机放置在不同的机架中。他们使用了IPVS内核模块,后端服务器的回送接口上配置了相应的VIP,所以它们可以将返回的数据包直接发送到客户端(而不是L4LB)。\\t
    • 控制面板:该组件执行其他各种功能,包括对后端服务器执行健康检查,提供简单的接口用于添加或删除VIP,并提供简单的API来检查L4LB和后端服务器的状态。\

    每个L4LB还将每个5元组保存起来作为查找表,避免重复计算后续数据包的哈希值。这只是一种优化措施,并不会影响到正确性。这种设计符合上述的工作负载要求,但存在一个不足:L4LB和后端服务共存于同一台设备上增加了设备出现故障的可能性。为此,他们在不相关的一组机器上运行L4LB和后端服务。由于L4LB数量比后端服务器少,因此更容易受突发流量负载的影响。

    \\

    3e7a2e3c16344fb20ee087752844d33b.png

    \\

    图3:第一代L4LB概览

    \\

    Katran:重新设计转发面板

    \\

    Katran就是第二代L4LB,通过完全重新设计转发面板,显著提高之前版本的性能。两项最新的内核工程创新为新设计提供了动力:

    \\
    • XDP提供了一种高速的可编程网络数据路径,无需使用完整的内核旁路方法,并可与Linux网络栈结合使用。\\t
    • eBPF虚拟机提供了一种灵活、高效且更可靠的方式来与Linux内核进行交互,并通过在内核中的特定点运行用户程序来扩展功能。eBPF已经为几个领域带来了巨大的改进,包括追踪和过滤。\

    第二代系统的总体架构与第一代L4LB相似:首先,ExaBGP向互联网发布特定的Katran实例负责哪个VIP。其次,发往VIP的数据包通过ECMP机制发送到Katran实例。最后,Katran将数据包转发给正确的后端服务器。它们之间的主要区别在于最后一步。

    \\

    高效的数据包处理:Katran结合使用XDP和BPF程序来转发数据包。在驱动器模式下启用XDP时,数据包处理例程(BPF程序)会在网络接口卡(NIC)收到数据包之后以及在内核截获之前运行。XDP在每个传入数据包上调用BPF程序。如果NIC具有多个队列,则为每个队列并行调用该程序。用于处理数据包的BPF程序是无锁的,并使用单CPU内核版本的BPF映射。因为具备了这种并行性,性能与NIC的RX队列数量呈线性关系。Katran还支持“通用XDP”操作模式(而不是驱动模式),不过需要以牺牲性能为代价。

    \\

    开销更小且更稳定的哈希:Katran使用Maglev哈希算法的扩展版来选择后端服务器。扩展版哈希算法具备了更好的弹性,能够更均匀的分布负载,可以为不同的后端服务器设置不同的权重。其中最后一项最为重要,他们因此能够轻松处理PoP和数据中心的硬件更新:通过设置适当的权重来更新硬件。计算哈希值的代码体积很小,完全可以放入L1缓存中。

    \\

    更具弹性的本地状态:Katran在处理数据包和计算哈希值时需要与本地状态表发生交互。他们发现,通常情况下,计算哈希值比查找本地状态表中的5元组更容易,因为在本地状态表中有时候需要遍历到最后一级缓存才能找到目标。为此,他们将查找表实现为LRU缓存。LRU缓存大小可在启动时配置,并作为可调参数,以便在计算和查找之间取得平衡。此外,Katran提供了一个运行时“仅计算”开关,以便在主机发生灾难性内存压力的情况下完全忽略LRU缓存。

    \\

    RSS封装:接收端伸缩(Received Side Scaling,RSS)是针对NIC的一项重要优化,旨在通过将数据包发送到单独的CPU来均匀地在CPU之间分布负载。不同流中的数据包使用不同的外部IP来封装,但相同流中的数据包总是被分配相同的外部IP。

    \\

    a661b20647edd56b3fd3d0b049d6c475.png

    \\

    图4:Katran为高速处理数据包提供了一条快速路径,无需借助内核旁路。

    \\

    这些特性显著提升了L4LB的性能、灵活性和可扩展性。如果没有数据包流入,Katran几乎不消耗CPU。与内核旁路解决方案(如DPDK)相比,XDP可以让Katran与任何应用程序一起运行,而不会遭受性能损失。现在,Katran与Facebook的PoP后端服务器一起运行,增强了对负载峰值的处理能力和主机故障恢复能力。

    \\

    其他注意事项

    \\
    • Katran仅适用于直接服务回退(Direct Service Return,DSR)模式。\\t
    • Katran是决定数据包最终目的地的组件,因此网络需要首先将数据包路由到Katran,这要求网络拓扑是基于L3的。\\t
    • Katran不能转发分段的数据包,也不能自行进行数据包分段。这个问题可以通过增加网络内部的最大传输单元(MTU)或通过在后端更改TCP MSS来解决。\\t
    • Katran不支持包含IP选项设置的数据包,最大数据包大小不能超过3.5KB。\\t
    • Katran的设计是基于这样的前提,即它将被用在“单臂负载均衡器”中。\

    Katran的GitHub地址:https://github.com/facebookincubator/katran

    \\

    感谢郭蕾对本文的审校。

    \\

    给InfoQ中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ@丁晓昀),微信(微信号:InfoQChina)关注我们。

    展开全文
  • 高级均衡器-10频段 路线图 想法是成为macOS的终极音频工具箱(某些功能可能不是开源的) 专家均衡器-极限频段+频谱分析仪 混响-空间音频吸引力 音量混合器-每个应用程序应用不同的音量级别 输入音频源-将效果应用...
  • GSM是个严格的TDMA系统,为了避免时隙和时隙之间互相...此外,为了应对多径效应带来的时间色散问题,GSM设计了训练序列和自适应均衡器,以保证可以测算无线信道的特点,从而对接收机的一些参数进行校正以保证最好...
  • 超爽的手机均横

    2013-08-01 22:13:40
    一款支持2.3及以上系统的音效均衡器,可以设置手机播放音乐时的音效,增强你的音乐播放效果和质量,让你的android手机带来前所未有的音乐聆听体验。 功能特点: 媒体音量控制 五波段均衡器 低音增强效果 虚拟...
  • 摇动即可更改功能:摇动手机即可更改播放曲目支持所有类型的音频文件强大的开源均衡器耳机/蓝牙控件通过将曲目添加到收藏夹来创建自定义播放列表智能记忆功能会自动应用以前选择的控件用户友好-出色的用户界面和UX ...
  •  该系列产品具有许多立体声功能,包括增强的立体声系统、数字均衡器、动态范围控制器、声场控制器等,可提供高质量、高性能的音频。  这些音频IC还具有增强的游戏和环绕声功能,可产生128和弦,且具有多效应器和...
  •  该系列产品具有许多立体声功能,包括增强的立体声系统、数字均衡器、动态范围控制器、声场控制器等,可提供高质量、高性能的音频。  这些音频IC还具有增强的游戏和环绕声功能,可产生128和弦,且具有多效应器和...
  • Nginx负载均衡

    2016-05-25 10:46:00
    负载均衡(做分发服)1、基于浏览器的分发基于浏览器的分发,按照在不同平台的浏览器请求进行分发,比如手机浏览器讲究资源小速度快节省流量,所以将自手机浏览器的请求分发到专供处理移动平台的web服务器上,而在...
  • LVS负载均衡入门

    2020-06-02 16:26:58
    是一个基于四层的负载均衡调度,即IP+Port的负载均衡; 2. LVS网络拓扑图 如下图所示,用户通过浏览器发起请求,先经过DNS解析,然后到达服务器的LVS,LVS根据轮训算法把请求发送到后端的服务器。通过使用这个...
  • 为了在一定的信噪比范围内获得较好的误码率指标,首先要合理设计基带信号,选择调制解调方式,采用时域、频域均衡等技术使误码率尽可能降低。在通信系统中常用的调制方法一般为QPSK和M阶QAM调制(M=4,8,16,32,64...
  • MSCode微服务平台基于Spring Cloud、Spring Boot、Activiti7工作流和阿里巴巴组件,提供分布式版本和单体式版本以及代码生成的所有源码和详尽文档,适配电脑、平板和手机,快速开发办公(OA)、电商、金融、财务、...
  • 模拟器采用双向(Source/Sink模式)设计,电流可充可放,每个通道还可以吸收和提供直流电能,用于测试均衡电流,不仅可满足BMS电池管理系统、PCM/BPU电池保护板、CMS电容管理(支持多种故障模拟来验证BMS/PCM/BPU/...
  • 手机当电脑的播放器

    2019-04-10 15:41:26
    others 手机当电脑的播放器 2年 ago mqzi 安卓端最新soundwire:http://okzpdc7px.bkt.clouddn.com/com.georgie.SoundWireFree.apk 电脑端:... 最新的好像还支持手机上的均衡器,之前的都不...
  • 天天动听播放器支持歌词和歌曲图片下载,皮肤随心更换,更有炫丽震撼的可视化效果,同时预置丰富的均衡器效果,支持音效增强,简洁人性化的操作,给追求音乐品质的呢带来了手机听歌的全新体验。天天动听已经成为拇指...
  • 奥地利微电子公司发布其新系列媒体播放器 IC 中的首款器件AS... 音频后置处理器可作为异步采样率转换器(ASRC)提供接近透明的音质、具有限制功能的多通道混音器,以及 10 段图形均衡器,并支持 24 位动态范围的 192KHz
  • 奥地利微电子公司(Austria microsystems)发布其新系列媒体播放器IC中的... 音频后置处理器可作为异步采样率转换器(ASRC)提供接近透明的音质、具有限制功能的多通道混音器,以及 10 段图形均衡器,并支持 24 位动态
  • * 内置音调均衡器,可调整高中低音和人声均衡 * 支持Mp3合并 * 可剪切Mp3/Wma/Wave格式的文件(后续版本将增加更多格式的支持,敬请期待) * 剪切出来的Mp3可自由设定压缩强度,一个3M多的Mp3最小可压缩至0.8M ...
  • 在日常工作中我们都会使用haproxy作为负载均衡器,因为后端应用服务器多更改麻烦,因此决定在负载均衡器实现。 只需要再frondend或listen或backend,添加 1 2 3 4 5 rspidel^Server:.* rspidel^X-...
  • 触摸手机这里ü

    2014-08-20 18:04:57
    在M001配备了像MP3后台播放支持均衡出色的多媒体支持功能;内置3D立体声扬声。该M001具有键盘输入,所有这些使得更多的用户友好的应用程序的唯一功能。手机可以扩展到2 GB这使用户能够存储数据和音乐。数据和音乐...
  • 奥地利微电子公司发布其新系列媒体... 音频后置处理器可作为异步采样率转换器(ASRC)提供接近透明的音质、具有限制功能的多通道混音器,以及10段图形均衡器,并支持24 位动态范围的192KHz采样率高清音频处理。三套
  • VCO混频(混频Mixer)——放大(可编程增益放大PGA)——滤波——IQ解调(IQ调制)——(进入基带部分)GMSK解调——信道均衡——解密——去交织——语音解码——滤波—DAC——放大——话音输出。

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 136
精华内容 54
关键字:

手机均衡器