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

内蒙古城乡建设部网站首页东莞市建设信息网

内蒙古城乡建设部网站首页,东莞市建设信息网,网页设计对板式上有哪些要求,广州有什么好玩的室内导航app引导中经常遇到破音#xff0c;这里也将之前经历过的方案收集以下#xff0c;方便以后选择#xff1a; 1 对于开始和结尾破音#xff1a; 可以用升降音来处理 两种方式 一种是 直接对开始和结束的时间段进行音量直接渐进改变。这里配的是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 { LinkedBlockingQueuebyte[] datas new LinkedBlockingQueuebyte[]();         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(time0) {                     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(datasnull||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://www.hkea.cn/news/14409759/

相关文章:

  • 以个人名义做地方门户网站北京企业建设网站公司
  • 如何建企业仢网站做旅游攻略的网站代码
  • 站长统计app软件知名品牌营销策略
  • 网站设计参考文献怎么给自己的网站更换域名
  • 无极门户网站网站建设与管理中专专业
  • cms织梦织梦修改网站源码二度云自助建站系统
  • 长治网上制作网站自己做一个网站需要多少钱
  • 公司网站如何建立西班牙语网站设计哪家好
  • 做酒招代理的网站网站建设思维导图模版
  • 好看的个人网站主页网上学编程
  • 婚庆网站模板下载wordpress文章 相册
  • 企业网站开发摘要登录页面设计图片
  • 网站建设多少钱信息三合一网站建设推广
  • 福州公司建设网站西安大雁塔附近酒店推荐
  • 建设网站需要注册证书吗重庆中心城区恢复
  • 瓷砖网站模板平顶山专业做网站公司
  • flash网站欣赏建站优化易下拉系统
  • 建设部网站招标投标文件建设网站租服务器
  • 直播网站功能怎么做开网站公司
  • 如何分析企业网站网站服务费做管理费用
  • 检查网站收录问题学建设网站及功能
  • 如何做网站的seo如果搭建网站
  • 文本怎样做阅读链接网站在线看网站建设
  • 建设一个个人网站不需要开发者模式小米
  • 哪个网站可以做会计试题网站模板中文版
  • 珠海网站制作外包网站页面统计代码是什么意思
  • 扬州外贸网站建设网站一屏的尺寸
  • 建网站建网站的公司wordpress 数据库权限
  • 外国游戏概念设计网站网站怎么免费注册
  • 个人网站教程红色旅游网站页面建设