代码分析JAVA中PCM人声音频变声处理
程序员文章站
2023-12-12 13:54:34
项目中需要用到对pcm人声音频数据进行变声处理。苦苦挣扎了一周终于找到了纯java实现的一套框架——tarsosdsp。功能非常强大!可以实时音频处理!当然我只用到了对文件...
项目中需要用到对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(); }
推荐阅读