代码分析JAVA中PCM人声音频变声处理

 更新时间:2018年01月15日 08:39:41   投稿:laozhang  
本篇文章通过代码实例给大家分析了JAVA中PCM人声音频变声处理的问题,有兴趣的朋友跟着学习分考下吧。

项目中需要用到对PCM人声音频数据进行变声处理。苦苦挣扎了一周终于找到了纯Java实现的一套框架——TarsosDSP。功能非常强大!可以实时音频处理!当然我只用到了对文件处理。实际上逻辑是一样的

TarsosDSP的GitHub地址:https://github.com/JorenSix/TarsosDSP 将它整合至自己的项目工程。

具体Java工具类代码:

  /**
   * 变声
   * @param rawPcmInputStream 原始PCM数据输入流
   * @param speedFactor 变速率 (0,2) 大于1为加快语速,小于1为放慢语速
   * @param rateFactor 音调变化率 (0,2) 大于1为降低音调(深沉),小于1为提升音调(尖锐)
   * @return 变声后的PCM数据输入流
   */
  public static InputStream speechPitchShift(final InputStream rawPcmInputStream,double speedFactor,double rateFactor) {
    TarsosDSPAudioFormat format = new TarsosDSPAudioFormat(16000,16,1,true,false);
    AudioInputStream inputStream = new AudioInputStream(rawPcmInputStream, JVMAudioInputStream.toAudioFormat(format),AudioSystem.NOT_SPECIFIED);
    JVMAudioInputStream stream = new JVMAudioInputStream(inputStream);
    WaveformSimilarityBasedOverlapAdd w = new WaveformSimilarityBasedOverlapAdd(WaveformSimilarityBasedOverlapAdd.Parameters.speechDefaults(speedFactor, 16000));
    int inputBufferSize = w.getInputBufferSize();
    int overlap = w.getOverlap();
    AudioDispatcher dispatcher = new AudioDispatcher(stream, inputBufferSize ,overlap);
    w.setDispatcher(dispatcher);
    AudioOutputToByteArray out = new AudioOutputToByteArray();
    dispatcher.addAudioProcessor(w);
    dispatcher.addAudioProcessor(new RateTransposer(rateFactor));
    dispatcher.addAudioProcessor(out);
    dispatcher.run();
    return new ByteArrayInputStream(out.getData());
  }

其中数据转录器(AudioOutputToByteArray)代码如下:

public class AudioOutputToByteArray implements AudioProcessor {
  private boolean isDone = false;
  private byte[] out = null;
  private ByteArrayOutputStream bos;
  public AudioOutputToByteArray() {
    bos = new ByteArrayOutputStream();
  }
  public byte[] getData() {
    while (!isDone && out == null) {
      try {
        Thread.sleep(10);
      } catch (InterruptedException ignored) {}
    }
    return out;
  }
  @Override
  public boolean process(AudioEvent audioEvent) {
    bos.write(audioEvent.getByteBuffer(),0,audioEvent.getByteBuffer().length);
    return true;
  }
  @Override
  public void processingFinished() {
    out = bos.toByteArray().clone();
    bos = null;
    isDone = true;
  }
}

可以通过这个工具方法播放音频:

  /**
   * 播放PCM
   *
   * 不要在非桌面环境调用。。。鬼知道会发生什么
   * @param rawPcmInputStream 原始PCM数据输入流
   * @throws LineUnavailableException
   */
  public static void play(final InputStream rawPcmInputStream) throws LineUnavailableException {
    TarsosDSPAudioFormat format = new TarsosDSPAudioFormat(16000,16,1,true,false);
    AudioInputStream inputStream = new AudioInputStream(rawPcmInputStream, JVMAudioInputStream.toAudioFormat(format),AudioSystem.NOT_SPECIFIED);
    JVMAudioInputStream stream = new JVMAudioInputStream(inputStream);
    AudioDispatcher dispatcher = new AudioDispatcher(stream, 1024 ,0);
    dispatcher.addAudioProcessor(new AudioPlayer(format,1024));
    dispatcher.run();
  }

相关文章

  • 如何解决Mybatis-plus中@TableLogic注解失效问题

    如何解决Mybatis-plus中@TableLogic注解失效问题

    这篇文章主要介绍了如何解决Mybatis-plus中@TableLogic注解失效问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-05-05
  • Spring中InitializingBean的使用详细解析

    Spring中InitializingBean的使用详细解析

    这篇文章主要介绍了Spring中InitializingBean的使用详细解析,InitializingBean是Spring提供的拓展性接口,提供了属性初始化后的处理方法,它只有一个afterPropertiesSet方法,凡是继承该接口的类,在bean的属性初始化后都会执行该方法,需要的朋友可以参考下
    2024-02-02
  • 修改jvm-sandbox源码导致线程安全分析

    修改jvm-sandbox源码导致线程安全分析

    这篇文章主要为大家介绍了修改jvm-sandbox源码导致线程安全分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • JHipster如何修改JDL中的entity

    JHipster如何修改JDL中的entity

    这篇文章主要介绍了JHipster如何修改JDL中的entity问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • Java泛型extends及super区别实例解析

    Java泛型extends及super区别实例解析

    这篇文章主要介绍了Java泛型extends及super区别实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-08-08
  • Spring Bean的定义及三种创建方式

    Spring Bean的定义及三种创建方式

    本文主要介绍了Spring容器获取Bean的9种方式小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • SpringBoot结合ElasticSearch实现模糊查询的项目实践

    SpringBoot结合ElasticSearch实现模糊查询的项目实践

    本文主要介绍了SpringBoot结合ElasticSearch实现模糊查询的项目实践,主要实现模糊查询、批量CRUD、排序、分页和高亮功能,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • Java在指定路径上创建文件提示不存在解决方法

    Java在指定路径上创建文件提示不存在解决方法

    在本篇文章里小编给大家整理的是一篇关于Java在指定路径上创建文件提示不存在解决方法,有需要的朋友们可以参考下。
    2020-02-02
  • java 数据结构中栈和队列的实例详解

    java 数据结构中栈和队列的实例详解

    这篇文章主要介绍了java 数据结构中栈和队列的实例详解的相关资料,主要使用数组与线性表的方法来实现,需要的朋友可以参考下
    2017-09-09
  • SpringBoot启动失败的解决方法:A component required a bean of type ‘xxxxxxx‘ that could not be found.

    SpringBoot启动失败的解决方法:A component required a&nb

    这篇文章主要介绍了解决SpringBoot启动失败:A component required a bean of type ‘xxxxxxx‘ that could not be found.,目前解决方法有两种,一种是不注入bean的方式,另一种是使用@Component的方式,本文给大家详细讲解,需要的朋友可以参考下
    2023-02-02

最新评论