代码分析JAVA中PCM人声音频变声处理
发布时间:2020-12-14 20:06:35 所属栏目:Java 来源:网络整理
导读:项目中需要用到对 PCM人声音频数据进行变声处理 。苦苦挣扎了一周终于找到了纯Java实现的一套框架――TarsosDSP。功能非常强大!可以实时音频处理!当然我只用到了对文件处理。实际上逻辑是一样的 TarsosDSP的GitHub地址:https://github.com/JorenSix/Tarso
项目中需要用到对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(),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,AudioSystem.NOT_SPECIFIED); JVMAudioInputStream stream = new JVMAudioInputStream(inputStream); AudioDispatcher dispatcher = new AudioDispatcher(stream,1024,0); dispatcher.addAudioProcessor(new AudioPlayer(format,1024)); dispatcher.run(); } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |