溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

代碼分析JAVA中PCM人聲音頻變聲處理

發(fā)布時間:2020-08-23 16:53:01 來源:腳本之家 閱讀:195 作者:laozhang 欄目:編程語言

項目中需要用到對PCM人聲音頻數(shù)據(jù)進行變聲處理??嗫鄴暝艘恢芙K于找到了純Java實現(xiàn)的一套框架——TarsosDSP。功能非常強大!可以實時音頻處理!當然我只用到了對文件處理。實際上邏輯是一樣的

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

具體Java工具類代碼:

  /**
   * 變聲
   * @param rawPcmInputStream 原始PCM數(shù)據(jù)輸入流
   * @param speedFactor 變速率 (0,2) 大于1為加快語速,小于1為放慢語速
   * @param rateFactor 音調(diào)變化率 (0,2) 大于1為降低音調(diào)(深沉),小于1為提升音調(diào)(尖銳)
   * @return 變聲后的PCM數(shù)據(jù)輸入流
   */
  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());
  }

其中數(shù)據(jù)轉錄器(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
   *
   * 不要在非桌面環(huán)境調(diào)用。。。鬼知道會發(fā)生什么
   * @param rawPcmInputStream 原始PCM數(shù)據(jù)輸入流
   * @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();
  }

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI