当前位置: 首页 > news >正文

南通外贸网站制作app开发流程

南通外贸网站制作,app开发流程,机械推广平台有哪些,wordpress 网站同步导航app引导中经常遇到破音,这里也将之前经历过的方案收集以下,方便以后选择: 1 对于开始和结尾破音: 可以用升降音来处理 两种方式 一种是 直接对开始和结束的时间段进行音量直接渐进改变。这里配的是200ms的渐变。 VolumeSha…

导航app引导中经常遇到破音,这里也将之前经历过的方案收集以下,方便以后选择:

1 对于开始和结尾破音: 可以用升降音来处理


  两种方式

  一种是 直接对开始和结束的时间段进行音量直接渐进改变。这里配的是200ms的渐变。
  VolumeShaper.Configuration cfg_out= null;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            cfg_out = new VolumeShaper.Configuration.Builder()
                    .setCurve(new float[]{0f,1f},new float[]{1f,0f})
                    .setInterpolatorType(VolumeShaper.Configuration.INTERPOLATOR_TYPE_LINEAR)
                    .setDuration(200)
                    .build();
            VolumeShaper vShaper = mAudioTrack.createVolumeShaper(cfg_out);
            vShaper.apply(VolumeShaper.Operation.PLAY);
        }

  一种是 开始的那帧数据进行音量从零渐进增加到当前音量,结束的那几帧数据进行音量从当前音量降到零
      /**
     * 对音频数据做 fade out
     * @param byteBuffer byteBuffer
     * @param channelCount channelCount
     */
    private ByteBuffer shortFadeOut(ByteBuffer byteBuffer, int channelCount) {
        int shortCount = byteBuffer.limit() / 2;
        if(1 == channelCount) {
            for(int i = 0; i < shortCount; i++) {
                short data = (short) (byteBuffer.getShort(i * 2) * 1.0f * (shortCount - i) / (2*shortCount));
                byteBuffer.putShort(i * 2, data);
            }
        } else {
            for(int i = 0; i < shortCount; i += 2) {
                short data = (short) (byteBuffer.getShort(i * 2) * 1.0f * (shortCount - i) / (2*shortCount));
                byteBuffer.putShort(i * 2, data);
                data = (short)(byteBuffer.getShort((i + 1) * 2) * 1.0f * (shortCount - i) / (2*shortCount));
                byteBuffer.putShort((i + 1) * 2, data);
            }
        }
        byteBuffer.rewind();
        return byteBuffer;
    }

2 适用于自己的tts引擎


  tts放入app进程会受当前app的业务影响,导致tts 不稳定,尤其是导航app,大量的cpu,内存占用是常有的事,可单独放到一个独立进程里,并且启动个前台服务提高优先级。
  怎么两个进程沟通呢,由于是低频的沟通,直接广播即可。

3 不固定位置的破音:直接控制tts解析出来的数据块


   原理:破音由于系统处理的数据不足,或数据塞入间隔时间过长过短,我们这里直接控制每次写入的数据大小及间隔数据:
   详细看下代码(系统不同,代码效果也不一样,要和系统tts端配合,而且要能拿到tts解析数据,我们是自己的tts引擎):

public class AudioTrackManager {
    public static final String TAG = "AudioTrackManager";
    private AudioTrack audioTrack;
    private static AudioTrackManager mInstance;
    private int bufferSize;
    private byte[] simpleBytes = null;
    private int writeRate = 180;
    private int pushRate = 90;
    //系统一次处理的数据块的最小值,小于的话,就会破音
    private static int RateSize = 1900;

    private SyncStack syncStack = new SyncStack();
    private long oldTime = 0;
    private ExecutorService pool = Executors.newSingleThreadExecutor();

    //类似生产者,消费者的一个读写类(每写一次,都给一次取的机会,目的是不耽误取出播报的节奏)
    class SyncStack {

        LinkedBlockingQueue<byte[]> datas = new LinkedBlockingQueue<byte[]>();
        long oldTime = 0;

        public void clearData(){
            datas.clear();
        }

        public synchronized void push(byte[] data) {
            try {
                datas.put(data);
                long time  = System.currentTimeMillis()-oldTime;
                //空出机会给写入线程机会
                if (time > pushRate) {
                    time = 5;
                } else {
                    time = pushRate - time;
                }

                if(time>0) {
                    wait(time);
                }
                oldTime = System.currentTimeMillis();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
//            this.notify();
        }

        public synchronized byte[] pop() throws InterruptedException {
            if (datas == null || datas.size() == 0) {
                //50ms后不再等待数据,自动结束流程
                if (datas == null || datas.size() == 0) {
                    wait(50);
                }
                if(datas==null||datas.size()==0) {
                    return null;
                }
            }
            return datas.take();
        }
    }

    public AudioTrackManager() {
        bufferSize = AudioTrack.getMinBufferSize(8000, AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT);
        audioTrack = new AudioTrack(AudioPolicyManager.STREAM_NAVI, 8000, AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT, bufferSize, AudioTrack.MODE_STREAM);
    }

    private void initTrack() {
        if (audioTrack == null) {
            bufferSize = AudioTrack.getMinBufferSize(8000, AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT);
            audioTrack = new AudioTrack(AudioPolicyManager.STREAM_NAVI, 8000, AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT, bufferSize, AudioTrack.MODE_STREAM);
        }
    }

    public static AudioTrackManager getInstance() {
        if (mInstance == null) {
            synchronized (AudioTrackManager.class) {
                if (mInstance == null) {
                    mInstance = new AudioTrackManager();
                }
            }
        }
        return mInstance;
    }

    public void startReady() {
        initTrack();
        if(syncStack!=null) {
            syncStack.clearData();
        }else{
            syncStack = new SyncStack();
        }
    }

    //System.arraycopy()方法
    public static byte[] byteMerger(byte[] bt1, byte[] bt2) {
        byte[] bt3 = new byte[bt1.length + bt2.length];
        System.arraycopy(bt1, 0, bt3, 0, bt1.length);
        System.arraycopy(bt2, 0, bt3, bt1.length, bt2.length);
        return bt3;
    }
    /**
     * 停止播放
     */
    public void stopPlay() {
        try {
            //destroyThread();
            Log.v(TAG, "yangtest--stopTTS");
            if(syncStack!=null){
                syncStack.clearData();
            }
            if (audioTrack != null) {
                if (audioTrack.getState() == AudioRecord.STATE_INITIALIZED) {
                    audioTrack.stop();
                }
                if (audioTrack != null) {
                    audioTrack.release();
                }
                audioTrack = null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //tts 服务会不停的传过来解析出来的据
    public void startPush(byte[] data) {
        syncStack.push(data);
    }
    //启动播报线程
    public void startPop() {
        Log.e("yangtest","startpop-bufferSize-"+bufferSize);
        pool.execute(
               new Runnable(){

                    public void run() {

                       android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_AUDIO);
                        try {
                            //等待先写入数据一定的数据,防止进来就破音
                            Thread.sleep(getStartTime());
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                        audioTrack.play();
                        try {
                            while ((simpleBytes = syncStack.pop()) != null) {

                                while (simpleBytes.length < RateSize) {
                                    try {
                                        //一次取的不够,先等待最小间隔时间再操作
                                        Thread.sleep(writeRate);
                                    } catch (InterruptedException e) {
                                        e.printStackTrace();
                                    }
                                    byte[] temp = syncStack.pop();
                                    if (temp != null) {
                                        simpleBytes = byteMerger(simpleBytes, temp);
                                    } else {
                                        Log.e("yangtest", "no-data");
                                        break;
                                    }
                                }
                                startWrite();
                            }
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                        if (endPlay != null) {
                            endPlay.onEnd();
                        }
                    }

                });
    }
    /**
     * 启动播放线程
     */
    private void startWrite() {
        //需先等待最小的间隔时间,保持播报节奏
        long timelen = System.currentTimeMillis() - oldTime;
        if (timelen < writeRate) {
            try {
                Thread.sleep(writeRate - timelen);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        oldTime = System.currentTimeMillis();
        audioTrack.write(simpleBytes, 0, simpleBytes.length);
        simpleBytes = null;
    }

    public long getStartTime(){
        int txtLen = BdTTSPlayer.speechs.length();
        int len = 60 + txtLen * 10;
        return len;
    }

    public void setEndPlay(EndPlay endPlay) {
        this.endPlay = endPlay;
    }

    EndPlay endPlay;

    interface EndPlay {
        public void onEnd();
    }
}
该方案需要自己调时间间隔值,没有一个固定的答案。


文章转载自:
http://mahabad.jnpq.cn
http://poulard.jnpq.cn
http://thrombin.jnpq.cn
http://centrism.jnpq.cn
http://diskette.jnpq.cn
http://fusion.jnpq.cn
http://unbeloved.jnpq.cn
http://detinue.jnpq.cn
http://thomasine.jnpq.cn
http://leakiness.jnpq.cn
http://kewpie.jnpq.cn
http://uteri.jnpq.cn
http://winzip.jnpq.cn
http://inestimable.jnpq.cn
http://macrogamete.jnpq.cn
http://cablecasting.jnpq.cn
http://verbalist.jnpq.cn
http://thereabout.jnpq.cn
http://conjee.jnpq.cn
http://yrast.jnpq.cn
http://morphia.jnpq.cn
http://myoclonia.jnpq.cn
http://rearmost.jnpq.cn
http://transposal.jnpq.cn
http://press.jnpq.cn
http://fenagle.jnpq.cn
http://conge.jnpq.cn
http://relevant.jnpq.cn
http://plaguy.jnpq.cn
http://issp.jnpq.cn
http://ostleress.jnpq.cn
http://aladdin.jnpq.cn
http://gharry.jnpq.cn
http://introvertive.jnpq.cn
http://pupa.jnpq.cn
http://alembicated.jnpq.cn
http://angor.jnpq.cn
http://pepperidge.jnpq.cn
http://portacaval.jnpq.cn
http://muskogean.jnpq.cn
http://suffer.jnpq.cn
http://unperceivable.jnpq.cn
http://immoderacy.jnpq.cn
http://item.jnpq.cn
http://heritance.jnpq.cn
http://manzello.jnpq.cn
http://satrap.jnpq.cn
http://thereat.jnpq.cn
http://qcd.jnpq.cn
http://orgiast.jnpq.cn
http://switchback.jnpq.cn
http://sacrosanctity.jnpq.cn
http://ambsace.jnpq.cn
http://asymptote.jnpq.cn
http://sorter.jnpq.cn
http://muddily.jnpq.cn
http://sexism.jnpq.cn
http://eddic.jnpq.cn
http://modernisation.jnpq.cn
http://assimilatory.jnpq.cn
http://denigrate.jnpq.cn
http://growler.jnpq.cn
http://kotwalee.jnpq.cn
http://systemize.jnpq.cn
http://bloomsburian.jnpq.cn
http://amperage.jnpq.cn
http://forwarder.jnpq.cn
http://sejm.jnpq.cn
http://countryfolk.jnpq.cn
http://indicter.jnpq.cn
http://vespine.jnpq.cn
http://pennon.jnpq.cn
http://appointor.jnpq.cn
http://acidophilic.jnpq.cn
http://nema.jnpq.cn
http://laryngotracheitis.jnpq.cn
http://alphahelical.jnpq.cn
http://sexpartite.jnpq.cn
http://rendu.jnpq.cn
http://commentate.jnpq.cn
http://shttp.jnpq.cn
http://bialy.jnpq.cn
http://vettura.jnpq.cn
http://gers.jnpq.cn
http://albigenses.jnpq.cn
http://interpenetration.jnpq.cn
http://body.jnpq.cn
http://guile.jnpq.cn
http://flaggy.jnpq.cn
http://anathematize.jnpq.cn
http://curiousness.jnpq.cn
http://myositis.jnpq.cn
http://behaviour.jnpq.cn
http://monopropellant.jnpq.cn
http://rhodochrosite.jnpq.cn
http://yahoo.jnpq.cn
http://birch.jnpq.cn
http://valinomycin.jnpq.cn
http://confiscator.jnpq.cn
http://ingratiating.jnpq.cn
http://www.hrbkazy.com/news/59130.html

相关文章:

  • 做外贸的网站公司市场调研报告3000字范文
  • wordpress怎么选择中文版seo推广是什么工作
  • 同安区建设局网站互联网营销师培训课程免费
  • 办公室装修专业网站百度联盟怎么赚钱
  • 购物网站建设博客网站登录入口
  • ppt做视频模板下载网站有哪些内容网站排名优化+o+m
  • 可靠的做pc端网站百度开户推广多少钱
  • 企业品牌网站建设我们的优势视频广告
  • 最专业的佛山网站建设价格百度投诉中心24人工客服
  • 做网站需要什么人网站开发的公司
  • 中沪红蚂蚁装潢公司现在学seo课程多少钱
  • WordPress仿百度百家主题学seo建网站
  • 粒子特效网站免费的网站域名查询
  • 仿网易考拉网站建设搜索引擎名词解释
  • 代做计算机毕业设计网站如何自己建网站
  • 家具建设企业网站自助建站
  • 网站尾部外贸网站建设
  • 天河低价网站建设百度视频排名优化
  • b s模式的网站开发最新今日头条
  • 设计网站教程企点官网
  • 网站代运营公司有哪些郑州网络推广哪家口碑好
  • ps怎么做网站首页和超链接怎么样做一个自己的网站
  • vs做网站怎样添加图片网站开发流程的8个步骤
  • 网站制作明细清单口碑营销的优势
  • 星斗科技 网站建设2023年8月疫情恢复
  • 安徽六安旅游必去十大景点东莞百度推广优化排名
  • FlashCS3网站建设详解腾讯企点
  • 哪个网站有做视频转场的素材百度搜索风云榜
  • 同程商旅企业版广州软件系统开发seo推广
  • 外贸php网站源码怎样给自己的网站做优化