文字转语音系列(三):揭秘FreeTTS实现过程

项目中有相关的功能,就简单研究了一下。

说明

FreeTTS 是一个基于 Java 的开源文本转语音(TTS)引擎,旨在将文字内容转换为自然语音输出。
FreeTTS 适合对 英文语音质量要求低、预算有限且需要离线运行 的场景,但若需中文支持或高质量语音,建议选择其他方案(如商业 API 或 eSpeak)。

实现方式

Java 库,依赖 freetts.jar 和语音库文件。

优缺点


具体实现

gradle添加依赖(没成功)

我在build.gradle文件中添加以下依赖,然后重新构建,发现报错。于是乎就换了种方式添加依赖(手动引入jar包)。

dependencies {
    implementation 'com.sun.speech.freetts:freetts:1.2.2'
}

1、 下载FreeTTS 的 JAR 包

  • 访问 FreeTTS 官网 下载最新版本(例如 freetts-1.2.2.zip)。
  • 下载地址:https://sourceforge.net/projects/freetts/files/latest/download

  • 解压后的文件目录如下:
  • 将以下文件复制到项目的 libs 目录(需手动创建,与build.gradle放在同级目录):
    (1)freetts.jar(位于解压后的 lib 目录)
    (2)语音包(例如 cmu_time_awb.jar, cmu_us_kal.jar,位于 lib 目录)
    保险起见,我将jar包全部放到libs目录下了
  • 2、配置依赖

    build.gradle 文件中添加对本地 JAR 的依赖,并重新构建

    dependencies {
        // 引入 libs 目录下的所有 JAR 文件
        implementation fileTree(dir: 'libs', include: ['*.jar'])
    }
    

    3、代码实现

    最终测试发现,只读英文,不读中文。

    import com.sun.speech.freetts.Voice;
    import com.sun.speech.freetts.VoiceManager;
    import com.sun.speech.freetts.audio.AudioPlayer;
    import com.sun.speech.freetts.audio.SingleFileAudioPlayer;
    
        /**
         * 文字转语音
         *
         * @param text
         */
        public static void freeTTSToSpeak(String text) {
            try {
                VoiceManager voiceManager = VoiceManager.getInstance();
                System.out.println("可用语音列表:");
                for (Voice voice : voiceManager.getVoices()) {
                    System.out.println(" - " + voice.getName());
                }
                Voice voice = voiceManager.getVoice("kevin16");
                if (voice == null) {
                    System.err.println("未找到指定语音,请检查语音包是否已添加。");
                    return;
                }
                voice.allocate();
                voice.speak(text);
                voice.deallocate();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    
    /**
         * 使用FreeTTS实现文本转音频
         * 只支持英文
         *
         * @param text
         */
        public static void freeTTSToSpeakFile(String text) {
            VoiceManager voiceManager = VoiceManager.getInstance();
            System.out.println("可用语音列表:");
            for (Voice voice : voiceManager.getVoices()) {
                System.out.println(" - " + voice.getName());
            }
            Voice voice = voiceManager.getVoice("kevin16");
            if (voice == null) {
                System.err.println("未找到指定语音,请检查语音包是否已添加。");
                return;
            }
            try {
                // 创建音频播放器,指定输出路径和格式(WAV 或 AU)
                //文件默认保存在项目根目录(或根据 IDE 配置的当前工作目录)。
                //AudioPlayer audioPlayer = new SingleFileAudioPlayer("output", javax.sound.sampled.AudioFileFormat.Type.WAVE);
    
                //文件生成路径可自定义,路径需存在且可写
                AudioPlayer audioPlayer = new SingleFileAudioPlayer("D:/tts_output/output", javax.sound.sampled.AudioFileFormat.Type.WAVE);
    
                // 分配语音资源并绑定音频播放器
                voice.setAudioPlayer(audioPlayer);
                voice.allocate();
                // 语音播放
                voice.speak(text);
                // 关闭资源并保存文件
                voice.deallocate();
                audioPlayer.close();
                // 确保文件写入完成
                System.out.println("音频文件已保存为: output.wav");
            } catch (Exception e) {
                e.printStackTrace();
            } 
        }
    

    测试文件

    可查看绑定的资源文件

    注意事项

    1. 生成音频文时默认保存在项目根目录
    2. 如果要自定义文件生成目录的时候,文件夹要存在。比如代码中的tts_output文件夹,要提前创建好。
    3. 支持的音频格式:WAV 格式、AU 格式,不直接支持生成MP3格式文件。但是可以转换,具体怎么转换我没研究(#.#)
    4. 无法合成中文语音,尝试保存中文文本会无声音输出
    5. 多次运行代码会覆盖同名文件,可通过时间戳生成唯一文件名。
    String fileName = "output_" + System.currentTimeMillis();
    AudioPlayer audioPlayer = new SingleFileAudioPlayer(fileName, AudioFileFormat.Type.WAVE);
    

    作者:Strawberry_ahh

    物联沃分享整理
    物联沃-IOTWORD物联网 » 文字转语音系列(三):揭秘FreeTTS实现过程

    发表回复