歌声也能加滤镜全民K歌“智能音效”“云端调音”让你无惧开嗓
原标题:歌声也能加滤镜?全民K歌“智能音效”“云端调音”让你无惧开嗓最近,作为K歌十级爱好者的小编陷入了“唱歌五分钟,调音两小时”的尴尬境遇,想拥有完美歌声又不会调音的烦恼,谁懂?终于,经过一顿摸索,小编成功找到了能满足自己“既要又要还要”需求的修音神器——全民K歌“智能音效”,它可以基于你的音高、音色和歌曲速度,实时生成四款既自然又好听的个性化调音方案,有了这个黑科技的加持,唱歌小白也能轻松美化自己的歌声!
俗话说“好东西不能独享”,解锁同款黑科技的教程已经给各位准备好啦:在结束演唱后,友友们只需在编辑界面点击“智能音效”按钮,就可以一键拥有四款不同美化重点的调音方案!友情提示:佩戴耳机录制歌曲效果更佳哦~
作为可以给友友们随时随地带来专业调音服务的神仙功能,“智能音效”让不少K歌爱好者都爱不释手。网友“L的生活片段”在演唱《不删》时,就选择了与自己歌声特点匹配度高达98%的调音方案,不仅完美保留了原有音色磁性醇厚的特点,“智能音效”的强劲助攻也让整个演唱都更具临场感,感染力瞬间拉满;网友“永远不一某”则带来了《MineMine》,他的嗓音少年感十足,在“智能音效”的加持下,让他的歌声更具穿透力,整首作品的表现力也直线上升,值得一提的是,他还别出心裁地将这首歌进行了电音风格的改编,演绎出了和原曲截然不同的味道。
除了强大的“智能音效”,全民K歌不久前推出的“云端调音”功能也让歌友们如获至宝,它可以将用户的演唱作品实时上传云端,在保留其个性化声音特质的基础上,根据专业混音模板对作品进行媲美发行级别的加工。网友“小尼吖吖吖呀呀呀”就使用这一功能演唱了《光亮》,她的声线清澈空灵,与这首歌适配度极高,“云端调音”精细的混音处理让她的歌声表现更加细腻和丰富,将原曲想要传达的直面风雨的豁达与勇气诠释地淋漓尽致。网友“你别去江湖”则带来《算什么男人》,她的歌声温柔甜美,慵懒随性的唱腔给原曲平添了几分释然的意味,经过“云端调音”后的作品,歌声更加饱满和富有立体感,高级听感妥妥拿捏了。
展开全文小编发现,全民K歌的宝藏音效特权着实让人“眼花缭乱”,除了让一众K歌爱好者如有神助的“智能音效”和“云端调音”,还有“潮流电音”“小黄人”等丰富有趣的定制音效、打造作品丰富层次的“智能和声”、能展现更多人声细节的“人声增强”等友友们来解锁。
K歌后想要美化歌声却不知从何下手?现在就来全民K歌,让“智能音效”“云端调音”等K歌黑科技助你轻松打造惊艳朋友圈的演唱作品。返回搜狐,查看更多
责任编辑:android 仿全民k歌 线谱乐谱音高图
全民k歌大家都不陌生吧,在嗨歌时有一个线谱样式的动画效果是不是很吸引人呢。
效果似乎很复杂,感觉上非自定义view莫属了,然而如何处理滑动、如何处理颜色、如何处理多段线条、如何处理数据变化......等都搞好了准备写的时候才发现————一个星期过去了......?
其实如果把每条线都当做简单的自定义view你会发现:就是一个RecyclerView+一条线而已(由于rv涉及到复用、重绘,当自己自定义时如果使用不当会出现各种问题,对于新手可以使用ScrollView+自定义View的实现方式,这样只要一次性初始化完遇到刷新调用invalidate就行了,不需要复用和重绘,数百个自定义的线只会比rv多5M内存。思路同下,具体实现就相对简单多了,可以自己试试)
思路:一个一直滑动不可拖动的rv+可以变颜色的自定义view
由于代码不算太多(强忍不说)直接贴出成品吧:
publicclassKGeActivityextendsBaseActivity{@BindView(R.id.fl_KGeXian)FrameLayoutmFl;@BindView(R.id.view_KGeXian_Xian)ViewmViewXian;RecyclerViewmRv;privateBaseAdapterRvListmAdapter;privateStartAnimatmAnimat=newStartAnimat();//滑动动画privateintmRvWidths;//rv的总长度,计算得来privateintmViewMargin=300;//分割线距左边的位置/***音乐总时长*/privateintmMusicTime=100_000;/***声谱对应控件的信息*/privateArrayListmList=newArrayList();@OverrideprotectedintgetLayouRes(){//等同于setContentViewreturnR.layout.activity_k_ge;}//等同于onCreate@OverrideprotectedvoidinitData(){//由于普通操作无法完全屏蔽事件,此处直接重写rv拦截全部事件mRv=newRecyclerView(this){@OverridepublicbooleandispatchTouchEvent(MotionEventev){returntrue;}};mFl.addView(mRv,ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT);mRv.setLayoutManager(newLinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false));//初始化adaptermAdapter=newBaseAdapterRvList(this){//等同于bind@OverrideprotectedvoidonBindVH(BaseViewHolderbaseViewHolder,inti,LineDatalineData){XianViewxv=(XianView)baseViewHolder.itemView;xv.setData(lineData);}//等同于creat@NonNull@OverrideprotectedBaseViewHolderonCreateVH(ViewGroupviewGroup,LayoutInflaterlayoutInflater){XianViewxv=newXianView(getActivity());xv.setLayoutParams(newRecyclerView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT));returnnewBaseViewHolder(xv);}};//添加一个偏移的headerViewnullView=newView(this);nullView.setLayoutParams(newRecyclerView.LayoutParams(mViewMargin,1));mAdapter.addHeaderView(nullView);mRv.setAdapter(mAdapter);mViewXian.post(newRunnable(){@Overridepublicvoidrun(){ViewGroup.MarginLayoutParamsparams=(ViewGroup.MarginLayoutParams)mViewXian.getLayoutParams();params.leftMargin=mViewMargin;mViewXian.setLayoutParams(params);}});//添加模拟数据LineDatald1=newLineData();//开始空白ld1.lineLength=1000;ld1.noData=true;mList.add(ld1);for(inti=0;i=mMusicTime){return;//结束}//模拟匹配成功finalintoneTimeLength=50;for(inti=0;i=startWidth&¤tWidthendWidth){//相交于左侧addKSizeInfo(lineData.kSizeInfo,0,endWidth-currentWidth);}else{//包含整段addKSizeInfo(lineData.kSizeInfo,0,lineData.lineLength);}mAdapter.notifyDataSetChanged();//notifyItemChanged局部刷新有闪动}elseif(endWidth0){int[]ints=kSizeInfo.get(kSizeInfo.size()-1);if(ints[1]-start>=-1){//重合就合并成一个ints[1]=end;}else{kSizeInfo.add(newint[]{start,end});}}else{kSizeInfo.add(newint[]{start,end});}}/***根据音乐时间和list数据均匀滑动*/classStartAnimat{privatelongmStartTime;//启动时间privateintmLastX;//当前滑动的长度privateRunnablemRun=newRunnable(){@Overridepublicvoidrun(){if(isFinishing()||!mRv.canScrollHorizontally(1)){Utils.toast("结束");return;}doublenow=System.currentTimeMillis();intnowX=(int)(mRvWidths*(now-mStartTime)/mMusicTime);mRv.scrollBy(nowX-mLastX,0);//rv只有bymLastX=nowX;ViewCompat.postOnAnimation(mRv,mRun);//循环移动}};/***开启滑动*/publicvoidstart(){mStartTime=System.currentTimeMillis();mLastX=0;ViewCompat.postOnAnimation(mRv,mRun);}}@OverrideprotectedvoidsetListener(){}publicstaticclassXianViewextendsViewimplementsViewInterface{//线高privateintmLineHeight=10;privatePaintmPaint;privateLineDatamData;publicXianView(Contextcontext){this(context,null,0);}publicXianView(Contextcontext,AttributeSetattrs){this(context,attrs,0);}publicXianView(Contextcontext,AttributeSetattrs,intdefStyleAttr){super(context,attrs,defStyleAttr);initData();initAttrs(attrs);}@TargetApi(Build.VERSION_CODES.LOLLIPOP)publicXianView(Contextcontext,AttributeSetattrs,intdefStyleAttr,intdefStyleRes){super(context,attrs,defStyleAttr,defStyleRes);initData();initAttrs(attrs);}@OverridepublicvoidinitData(){//此处要inflate,不需要可以删掉黄油刀ButterKnife.bind(this);//注册黄油刀mPaint=newPaint();mPaint.setStyle(Paint.Style.FILL_AND_STROKE);mPaint.setStrokeWidth(mLineHeight);}/***简单使用,高度直接写死,具体多高自行判断*/@OverrideprotectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec){if(mData!=null&&mData.lineLength>0){//有宽度直接设置super.onMeasure(MeasureSpec.makeMeasureSpec(mData.lineLength,MeasureSpec.EXACTLY),MeasureSpec.makeMeasureSpec(Utils.dip2px(getContext(),100),MeasureSpec.EXACTLY));}else{//没宽度直接是0super.onMeasure(MeasureSpec.makeMeasureSpec(0,MeasureSpec.EXACTLY),MeasureSpec.makeMeasureSpec(Utils.dip2px(getContext(),100),MeasureSpec.EXACTLY));}}@OverridepublicvoidinitAttrs(@NullableAttributeSetattrs){}@OverrideprotectedvoidonDraw(Canvascanvas){super.onDraw(canvas);if(mData==null||mData.noData){return;}mPaint.setColor(0xffdddddd);//灰inth_2=mLineHeight/2;canvas.drawLine(h_2,mData.lineY+h_2,mData.lineLength+h_2,mData.lineY+h_2,mPaint);if(mData.kSizeInfo!=null){mPaint.setColor(0xffff00ff);//红for(int[]kSize:mData.kSizeInfo){canvas.drawLine(kSize[0]+h_2,mData.lineY+h_2,kSize[1]+h_2,mData.lineY+h_2,mPaint);}}}/***设置或刷新数据*/publicvoidsetData(LineDatadata){if(mData!=null&&mData.lineLength==data.lineLength){//宽度不变只需要重绘即可mData=data;invalidate();}else{//宽度改变需要重新加载布局mData=data;requestLayout();}}/***设置线的厚度*/publicvoidsetLineHeight(intheightPx){mLineHeight=heightPx;mPaint.setStrokeWidth(mLineHeight);}}publicstaticclassLineData{/***线距上的距离*/publicintlineY;/***线的最大长度*/publicintlineLength;/***用户k歌时匹配正确的信息{开始位置,结束位置}*/publicListkSizeInfo=newArrayList();/***空白数据,不需要唱时为true,{@link#lineLength}为等待的长度*/publicbooleannoData=false;}}使用的adapter见这篇:https://blog.csdn.net/weimingjue/article/details/88190755
xml
效果图
是不是感觉很简单呢?(刚填完黑洞的博主轻松的向大家挥手)
坑已经帮大家填完了,具体暂停操作、数据处理等细节就自行解决吧