Java PCM音頻變聲

項目中須要用到對PCM人聲音頻數據進行變聲處理。苦苦掙扎了一週終於找到了純Java實現的一套框架——TarsosDSP。功能很是強大!能夠實時音頻處理!固然我只用到了對文件處理。實際上邏輯是同樣的java

TarsosDSP的GitHub地址:https://github.com/JorenSix/T...。將它整合至本身的項目工程。git

具體Java工具類代碼:github

/**
     * 變聲
     * @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) {
        // 這裏根據本身PCM格式修改對應參數。咱們項目裏音頻格式是固定的,因此寫死
        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;
    }
}

能夠經過這個工具方法播放音頻:ide

/**
     * 播放PCM
     *
     * 不要在非桌面環境調用。。。鬼知道會發生什麼
     * @param rawPcmInputStream 原始PCM數據輸入流
     * @throws LineUnavailableException
     */
    public static void play(final InputStream rawPcmInputStream) throws LineUnavailableException {
        // 這裏根據本身PCM格式修改對應參數。咱們項目裏音頻格式是固定的,因此寫死
        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();
    }
相關文章
相關標籤/搜索