代码分析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注解失效问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教2024-05-05Spring中InitializingBean的使用详细解析
这篇文章主要介绍了Spring中InitializingBean的使用详细解析,InitializingBean是Spring提供的拓展性接口,提供了属性初始化后的处理方法,它只有一个afterPropertiesSet方法,凡是继承该接口的类,在bean的属性初始化后都会执行该方法,需要的朋友可以参考下2024-02-02SpringBoot结合ElasticSearch实现模糊查询的项目实践
本文主要介绍了SpringBoot结合ElasticSearch实现模糊查询的项目实践,主要实现模糊查询、批量CRUD、排序、分页和高亮功能,具有一定的参考价值,感兴趣的可以了解一下2024-03-03SpringBoot启动失败的解决方法:A component required a&nb
这篇文章主要介绍了解决SpringBoot启动失败:A component required a bean of type ‘xxxxxxx‘ that could not be found.,目前解决方法有两种,一种是不注入bean的方式,另一种是使用@Component的方式,本文给大家详细讲解,需要的朋友可以参考下2023-02-02
最新评论