Text-to-Speech with FreeTTS in Java

Overview

FreeTTS is a free, open-source speech synthesis system written entirely in Java. It provides a complete implementation of text-to-speech conversion.

1. Setup and Dependencies

Maven Dependencies

<!-- pom.xml -->
<dependencies>
<!-- FreeTTS Core -->
<dependency>
<groupId>com.sun.speech</groupId>
<artifactId>freetts</artifactId>
<version>1.2.2</version>
</dependency>
<!-- JSAPI Implementation -->
<dependency>
<groupId>javax.speech</groupId>
<artifactId>jsapi</artifactId>
<version>1.0</version>
</dependency>
<!-- Audio Support -->
<dependency>
<groupId>javax.sound</groupId>
<artifactId>sampled</artifactId>
<version>1.0</version>
</dependency>
</dependencies>

Manual JAR Download (Alternative)

If Maven dependencies don't work, download these JARs manually:

  • freetts.jar
  • jsapi.jar
  • cmu_time_awb.jar (voice packages)
  • cmu_us_kal.jar (voice packages)

2. Basic Text-to-Speech

Simple TTS Implementation

import com.sun.speech.freetts.Voice;
import com.sun.speech.freetts.VoiceManager;
public class BasicTextToSpeech {
private Voice voice;
public BasicTextToSpeech() {
initializeVoice();
}
private void initializeVoice() {
// Set property to use FreeTTS
System.setProperty("freetts.voices", 
"com.sun.speech.freetts.en.us.cmu_us_kal.KevinVoiceDirectory");
// Get voice manager
VoiceManager voiceManager = VoiceManager.getInstance();
// Get available voices
System.out.println("Available voices:");
Voice[] voices = voiceManager.getVoices();
for (Voice v : voices) {
System.out.println(" - " + v.getName() + " (" + v.getDomain() + ")");
}
// Select a voice (kevin16 is commonly available)
voice = voiceManager.getVoice("kevin16");
if (voice == null) {
System.err.println("Cannot find voice: kevin16");
return;
}
// Allocate resources
voice.allocate();
System.out.println("Voice initialized: " + voice.getName());
}
public void speak(String text) {
if (voice == null) {
System.err.println("Voice not initialized");
return;
}
try {
voice.speak(text);
} catch (Exception e) {
System.err.println("Error speaking text: " + e.getMessage());
}
}
public void setRate(float wordsPerMinute) {
if (voice != null) {
voice.setRate(wordsPerMinute);
}
}
public void setPitch(float pitch) {
if (voice != null) {
voice.setPitch(pitch);
}
}
public void setVolume(float volume) {
if (voice != null) {
voice.setVolume(volume);
}
}
public void destroy() {
if (voice != null) {
voice.deallocate();
}
}
public static void main(String[] args) {
BasicTextToSpeech tts = new BasicTextToSpeech();
// Basic speech
tts.speak("Hello, this is a text to speech demonstration.");
// With different settings
tts.setRate(120f); // words per minute
tts.setPitch(150f); // pitch shift
tts.setVolume(0.8f); // volume (0.0 to 1.0)
tts.speak("This text is spoken with different voice settings.");
tts.destroy();
}
}

Advanced Voice Configuration

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;
import javax.sound.sampled.AudioFileFormat;
public class AdvancedTextToSpeech {
private VoiceManager voiceManager;
private Voice voice;
public AdvancedTextToSpeech(String voiceName) {
initializeVoice(voiceName);
}
private void initializeVoice(String voiceName) {
System.setProperty("freetts.voices", 
"com.sun.speech.freetts.en.us.cmu_us_kal.KevinVoiceDirectory," +
"com.sun.speech.freetts.en.us.cmu_time_awb.AlanVoiceDirectory");
voiceManager = VoiceManager.getInstance();
voice = voiceManager.getVoice(voiceName);
if (voice == null) {
System.err.println("Voice not found: " + voiceName);
System.out.println("Available voices:");
for (Voice v : voiceManager.getVoices()) {
System.out.println(" - " + v.getName());
}
return;
}
voice.allocate();
System.out.println("Voice loaded: " + voice.getName());
}
public void speakToFile(String text, String outputFilePath) {
if (voice == null) {
System.err.println("Voice not initialized");
return;
}
try {
// Create audio player that writes to file
AudioPlayer audioPlayer = new SingleFileAudioPlayer(
outputFilePath.replace(".wav", ""), 
AudioFileFormat.Type.WAVE
);
voice.setAudioPlayer(audioPlayer);
voice.speak(text);
audioPlayer.close();
System.out.println("Speech saved to: " + outputFilePath);
} catch (Exception e) {
System.err.println("Error saving speech to file: " + e.getMessage());
} finally {
// Reset to default audio player
voice.setAudioPlayer(null);
}
}
public void speakWithDetails(String text) {
if (voice == null) return;
System.out.println("Speaking: " + text);
System.out.println("Voice: " + voice.getName());
System.out.println("Rate: " + voice.getRate() + " wpm");
System.out.println("Pitch: " + voice.getPitch());
System.out.println("Volume: " + voice.getVolume());
System.out.println("Pitch Range: " + voice.getPitchRange());
long startTime = System.currentTimeMillis();
voice.speak(text);
long endTime = System.currentTimeMillis();
System.out.println("Speech duration: " + (endTime - startTime) + "ms");
}
public void listAllVoices() {
System.out.println("=== Available Voices ===");
Voice[] voices = voiceManager.getVoices();
for (Voice v : voices) {
System.out.println("Name: " + v.getName());
System.out.println("  Description: " + v.getDescription());
System.out.println("  Domain: " + v.getDomain());
System.out.println("  Style: " + v.getStyle());
System.out.println("  Gender: " + v.getGender());
System.out.println("  Age: " + v.getAge());
System.out.println("  Language: " + v.getLocale());
System.out.println();
}
}
public Voice getVoice() {
return voice;
}
public void destroy() {
if (voice != null) {
voice.deallocate();
}
}
public static void main(String[] args) {
AdvancedTextToSpeech tts = new AdvancedTextToSpeech("kevin16");
// List available voices
tts.listAllVoices();
// Speak with details
tts.speakWithDetails("This is an advanced text to speech demonstration.");
// Save to file
tts.speakToFile("This speech will be saved to a file.", "output_speech.wav");
tts.destroy();
}
}

3. Voice Management and Customization

Multiple Voice Manager

import com.sun.speech.freetts.Voice;
import com.sun.speech.freetts.VoiceManager;
import com.sun.speech.freetts.VoiceDirectory;
import com.sun.speech.freetts.ValidationException;
import java.util.List;
import java.util.ArrayList;
public class VoiceManagerSystem {
private List<VoiceInfo> availableVoices;
private Voice currentVoice;
public VoiceManagerSystem() {
loadAvailableVoices();
}
private void loadAvailableVoices() {
availableVoices = new ArrayList<>();
System.setProperty("freetts.voices", 
"com.sun.speech.freetts.en.us.cmu_us_kal.KevinVoiceDirectory," +
"com.sun.speech.freetts.en.us.cmu_time_awb.AlanVoiceDirectory");
VoiceManager voiceManager = VoiceManager.getInstance();
Voice[] voices = voiceManager.getVoices();
for (Voice voice : voices) {
availableVoices.add(new VoiceInfo(
voice.getName(),
voice.getDescription(),
voice.getGender(),
voice.getAge(),
voice.getLocale().toString()
));
}
}
public boolean setVoice(String voiceName) {
if (currentVoice != null) {
currentVoice.deallocate();
}
VoiceManager voiceManager = VoiceManager.getInstance();
currentVoice = voiceManager.getVoice(voiceName);
if (currentVoice != null) {
currentVoice.allocate();
return true;
}
return false;
}
public void speak(String text) {
if (currentVoice == null) {
System.err.println("No voice selected");
return;
}
currentVoice.speak(text);
}
public void speakWithVoice(String text, String voiceName) {
if (setVoice(voiceName)) {
speak(text);
} else {
System.err.println("Failed to set voice: " + voiceName);
}
}
public List<VoiceInfo> getAvailableVoices() {
return new ArrayList<>(availableVoices);
}
public VoiceInfo getCurrentVoiceInfo() {
if (currentVoice == null) return null;
return new VoiceInfo(
currentVoice.getName(),
currentVoice.getDescription(),
currentVoice.getGender(),
currentVoice.getAge(),
currentVoice.getLocale().toString()
);
}
public void setVoiceProperties(float rate, float pitch, float volume) {
if (currentVoice != null) {
currentVoice.setRate(rate);
currentVoice.setPitch(pitch);
currentVoice.setVolume(volume);
}
}
public void destroy() {
if (currentVoice != null) {
currentVoice.deallocate();
}
}
public static class VoiceInfo {
private final String name;
private final String description;
private final String gender;
private final String age;
private final String language;
public VoiceInfo(String name, String description, String gender, String age, String language) {
this.name = name;
this.description = description;
this.gender = gender;
this.age = age;
this.language = language;
}
// Getters
public String getName() { return name; }
public String getDescription() { return description; }
public String getGender() { return gender; }
public String getAge() { return age; }
public String getLanguage() { return language; }
@Override
public String toString() {
return String.format("Voice: %s (%s, %s, %s) - %s", 
name, gender, age, language, description);
}
}
public static void main(String[] args) {
VoiceManagerSystem voiceSystem = new VoiceManagerSystem();
// List available voices
System.out.println("=== Available Voices ===");
for (VoiceInfo voice : voiceSystem.getAvailableVoices()) {
System.out.println(voice);
}
// Test different voices
for (VoiceInfo voice : voiceSystem.getAvailableVoices()) {
System.out.println("\nTesting voice: " + voice.getName());
voiceSystem.speakWithVoice(
"Hello, I am " + voice.getName() + ". How are you today?", 
voice.getName()
);
try {
Thread.sleep(1000); // Pause between voices
} catch (InterruptedException e) {
e.printStackTrace();
}
}
voiceSystem.destroy();
}
}

4. Speech Synthesis with SSML-like Features

Enhanced Speech with Controls

import com.sun.speech.freetts.Voice;
import com.sun.speech.freetts.VoiceManager;
import com.sun.speech.freetts.audio.AudioPlayer;
public class EnhancedSpeechSynthesizer {
private Voice voice;
private SpeechEventListener eventListener;
public EnhancedSpeechSynthesizer(String voiceName) {
initializeVoice(voiceName);
}
private void initializeVoice(String voiceName) {
System.setProperty("freetts.voices", 
"com.sun.speech.freetts.en.us.cmu_us_kal.KevinVoiceDirectory");
VoiceManager voiceManager = VoiceManager.getInstance();
voice = voiceManager.getVoice(voiceName);
if (voice != null) {
voice.allocate();
}
}
public void speakWithEmphasis(String text, EmphasisLevel emphasis) {
if (voice == null) return;
float originalRate = voice.getRate();
float originalPitch = voice.getPitch();
float originalVolume = voice.getVolume();
// Adjust voice properties based on emphasis
switch (emphasis) {
case LOW:
voice.setRate(originalRate * 0.8f);
voice.setVolume(originalVolume * 0.7f);
break;
case NORMAL:
// Use default settings
break;
case HIGH:
voice.setRate(originalRate * 1.2f);
voice.setVolume(originalVolume * 1.1f);
voice.setPitch(originalPitch * 1.1f);
break;
case VERY_HIGH:
voice.setRate(originalRate * 1.4f);
voice.setVolume(originalVolume * 1.3f);
voice.setPitch(originalPitch * 1.2f);
break;
}
voice.speak(text);
// Restore original settings
voice.setRate(originalRate);
voice.setPitch(originalPitch);
voice.setVolume(originalVolume);
}
public void speakWithPauses(String text, int pauseMilliseconds) {
if (voice == null) return;
String[] sentences = text.split("[.!?]+");
for (String sentence : sentences) {
String trimmed = sentence.trim();
if (!trimmed.isEmpty()) {
voice.speak(trimmed);
pause(pauseMilliseconds);
}
}
}
public void speakNumber(int number, boolean asDigits) {
if (asDigits) {
// Speak as individual digits
String digits = Integer.toString(number);
for (char digit : digits.toCharArray()) {
voice.speak(Character.toString(digit));
pause(200);
}
} else {
// Speak as whole number
voice.speak(Integer.toString(number));
}
}
public void spellWord(String word) {
if (voice == null) return;
for (char letter : word.toCharArray()) {
voice.speak(Character.toString(letter));
pause(150);
}
}
public void setSpeechEventListener(SpeechEventListener listener) {
this.eventListener = listener;
}
private void pause(int milliseconds) {
try {
Thread.sleep(milliseconds);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
public void speak(String text) {
if (voice != null) {
if (eventListener != null) {
eventListener.onSpeechStart(text);
}
voice.speak(text);
if (eventListener != null) {
eventListener.onSpeechEnd(text);
}
}
}
public void destroy() {
if (voice != null) {
voice.deallocate();
}
}
public enum EmphasisLevel {
LOW, NORMAL, HIGH, VERY_HIGH
}
public interface SpeechEventListener {
void onSpeechStart(String text);
void onSpeechEnd(String text);
void onSpeechError(String text, String error);
}
public static void main(String[] args) {
EnhancedSpeechSynthesizer tts = new EnhancedSpeechSynthesizer("kevin16");
// Test different speech styles
tts.speak("Normal speech demonstration.");
tts.speakWithEmphasis("This is low emphasis speech.", EmphasisLevel.LOW);
tts.speakWithEmphasis("This is high emphasis speech!", EmphasisLevel.HIGH);
tts.speakWithEmphasis("This is very high emphasis speech!", EmphasisLevel.VERY_HIGH);
// Test speech with pauses
tts.speakWithPauses("This is a sentence. This is another sentence. And this is the final sentence.", 500);
// Test number speaking
tts.speakNumber(12345, false); // As whole number
tts.speakNumber(12345, true);  // As individual digits
// Test spelling
tts.spellWord("JAVA");
tts.destroy();
}
}

5. Audio File Generation

Batch Speech Generation

import com.sun.speech.freetts.Voice;
import com.sun.speech.freetts.VoiceManager;
import com.sun.speech.freetts.audio.SingleFileAudioPlayer;
import javax.sound.sampled.AudioFileFormat;
import java.io.File;
import java.util.List;
import java.util.ArrayList;
public class BatchSpeechGenerator {
private Voice voice;
private String outputDirectory;
public BatchSpeechGenerator(String voiceName, String outputDir) {
this.outputDirectory = outputDir;
initializeVoice(voiceName);
createOutputDirectory();
}
private void initializeVoice(String voiceName) {
System.setProperty("freetts.voices", 
"com.sun.speech.freetts.en.us.cmu_us_kal.KevinVoiceDirectory");
VoiceManager voiceManager = VoiceManager.getInstance();
voice = voiceManager.getVoice(voiceName);
if (voice != null) {
voice.allocate();
}
}
private void createOutputDirectory() {
File dir = new File(outputDirectory);
if (!dir.exists()) {
dir.mkdirs();
}
}
public SpeechGenerationResult generateSpeechFile(String text, String filename) {
if (voice == null) {
return new SpeechGenerationResult(false, "Voice not initialized", null);
}
try {
String filePath = outputDirectory + File.separator + filename;
SingleFileAudioPlayer audioPlayer = new SingleFileAudioPlayer(
filePath.replace(".wav", ""), 
AudioFileFormat.Type.WAVE
);
voice.setAudioPlayer(audioPlayer);
voice.speak(text);
audioPlayer.close();
voice.setAudioPlayer(null); // Reset to default
return new SpeechGenerationResult(true, "Success", filePath);
} catch (Exception e) {
return new SpeechGenerationResult(false, e.getMessage(), null);
}
}
public List<SpeechGenerationResult> generateMultipleFiles(List<SpeechRequest> requests) {
List<SpeechGenerationResult> results = new ArrayList<>();
for (SpeechRequest request : requests) {
System.out.println("Generating: " + request.getFilename());
SpeechGenerationResult result = generateSpeechFile(
request.getText(), 
request.getFilename()
);
results.add(result);
}
return results;
}
public void generateNumberSequence(int start, int end, String prefix) {
for (int i = start; i <= end; i++) {
String filename = String.format("%s_%03d.wav", prefix, i);
generateSpeechFile(Integer.toString(i), filename);
}
}
public void setVoiceProperties(float rate, float pitch, float volume) {
if (voice != null) {
voice.setRate(rate);
voice.setPitch(pitch);
voice.setVolume(volume);
}
}
public void destroy() {
if (voice != null) {
voice.deallocate();
}
}
public static class SpeechRequest {
private final String text;
private final String filename;
public SpeechRequest(String text, String filename) {
this.text = text;
this.filename = filename;
}
public String getText() { return text; }
public String getFilename() { return filename; }
}
public static class SpeechGenerationResult {
private final boolean success;
private final String message;
private final String filePath;
public SpeechGenerationResult(boolean success, String message, String filePath) {
this.success = success;
this.message = message;
this.filePath = filePath;
}
public boolean isSuccess() { return success; }
public String getMessage() { return message; }
public String getFilePath() { return filePath; }
}
public static void main(String[] args) {
BatchSpeechGenerator generator = new BatchSpeechGenerator("kevin16", "audio_output");
// Generate individual files
generator.generateSpeechFile("Welcome to our application", "welcome.wav");
generator.generateSpeechFile("Goodbye, thank you for using our service", "goodbye.wav");
// Generate multiple files from list
List<SpeechRequest> requests = new ArrayList<>();
requests.add(new SpeechRequest("Please enter your username", "enter_username.wav"));
requests.add(new SpeechRequest("Please enter your password", "enter_password.wav"));
requests.add(new SpeechRequest("Login successful", "login_success.wav"));
requests.add(new SpeechRequest("Login failed", "login_failed.wav"));
List<SpeechGenerationResult> results = generator.generateMultipleFiles(requests);
// Print results
for (SpeechGenerationResult result : results) {
System.out.println((result.isSuccess() ? "SUCCESS" : "FAILED") + 
": " + result.getMessage() + 
(result.getFilePath() != null ? " -> " + result.getFilePath() : ""));
}
// Generate number sequence
generator.generateNumberSequence(1, 10, "number");
generator.destroy();
System.out.println("Batch speech generation completed!");
}
}

6. Real-time Speech Application

Interactive TTS Application

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class TextToSpeechGUI extends JFrame {
private EnhancedSpeechSynthesizer tts;
private JTextArea textArea;
private JComboBox<String> voiceComboBox;
private JSlider rateSlider, pitchSlider, volumeSlider;
private JButton speakButton, pauseButton, stopButton, saveButton;
public TextToSpeechGUI() {
initializeTTS();
initializeGUI();
}
private void initializeTTS() {
tts = new EnhancedSpeechSynthesizer("kevin16");
}
private void initializeGUI() {
setTitle("Text-to-Speech Application");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
// Create components
createTextPanel();
createControlPanel();
createVoicePanel();
pack();
setLocationRelativeTo(null);
setSize(600, 500);
}
private void createTextPanel() {
JPanel textPanel = new JPanel(new BorderLayout());
textPanel.setBorder(BorderFactory.createTitledBorder("Text to Speak"));
textArea = new JTextArea(10, 40);
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
JScrollPane scrollPane = new JScrollPane(textArea);
textPanel.add(scrollPane, BorderLayout.CENTER);
add(textPanel, BorderLayout.CENTER);
}
private void createControlPanel() {
JPanel controlPanel = new JPanel(new FlowLayout());
controlPanel.setBorder(BorderFactory.createTitledBorder("Controls"));
speakButton = new JButton("Speak");
pauseButton = new JButton("Pause");
stopButton = new JButton("Stop");
saveButton = new JButton("Save to File");
speakButton.addActionListener(new SpeakButtonListener());
pauseButton.addActionListener(e -> {/* Pause functionality */});
stopButton.addActionListener(e -> {/* Stop functionality */});
saveButton.addActionListener(new SaveButtonListener());
controlPanel.add(speakButton);
controlPanel.add(pauseButton);
controlPanel.add(stopButton);
controlPanel.add(saveButton);
add(controlPanel, BorderLayout.SOUTH);
}
private void createVoicePanel() {
JPanel voicePanel = new JPanel(new GridLayout(4, 2, 5, 5));
voicePanel.setBorder(BorderFactory.createTitledBorder("Voice Settings"));
// Voice selection
voicePanel.add(new JLabel("Voice:"));
voiceComboBox = new JComboBox<>(new String[]{"kevin16", "alan"});
voicePanel.add(voiceComboBox);
// Rate slider
voicePanel.add(new JLabel("Speech Rate:"));
rateSlider = new JSlider(50, 300, 150);
rateSlider.setMajorTickSpacing(50);
rateSlider.setPaintTicks(true);
rateSlider.setPaintLabels(true);
voicePanel.add(rateSlider);
// Pitch slider
voicePanel.add(new JLabel("Pitch:"));
pitchSlider = new JSlider(50, 200, 100);
pitchSlider.setMajorTickSpacing(25);
pitchSlider.setPaintTicks(true);
pitchSlider.setPaintLabels(true);
voicePanel.add(pitchSlider);
// Volume slider
voicePanel.add(new JLabel("Volume:"));
volumeSlider = new JSlider(0, 100, 80);
volumeSlider.setMajorTickSpacing(20);
volumeSlider.setPaintTicks(true);
volumeSlider.setPaintLabels(true);
voicePanel.add(volumeSlider);
add(voicePanel, BorderLayout.NORTH);
}
private class SpeakButtonListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
String text = textArea.getText().trim();
if (!text.isEmpty()) {
// Update voice settings
String selectedVoice = (String) voiceComboBox.getSelectedItem();
tts.setVoiceProperties(
rateSlider.getValue(),
pitchSlider.getValue(),
volumeSlider.getValue() / 100.0f
);
// Speak in a separate thread to keep UI responsive
new Thread(() -> tts.speak(text)).start();
}
}
}
private class SaveButtonListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
String text = textArea.getText().trim();
if (!text.isEmpty()) {
JFileChooser fileChooser = new JFileChooser();
fileChooser.setDialogTitle("Save Speech as WAV");
fileChooser.setSelectedFile(new File("speech.wav"));
if (fileChooser.showSaveDialog(TextToSpeechGUI.this) == JFileChooser.APPROVE_OPTION) {
File file = fileChooser.getSelectedFile();
// Implementation for saving to file would go here
JOptionPane.showMessageDialog(TextToSpeechGUI.this,
"Speech saved to: " + file.getAbsolutePath());
}
}
}
}
@Override
public void dispose() {
if (tts != null) {
tts.destroy();
}
super.dispose();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new TextToSpeechGUI().setVisible(true);
});
}
}

7. Voice Effects and Processing

Audio Effects and Voice Modulation

import com.sun.speech.freetts.Voice;
import com.sun.speech.freetts.VoiceManager;
import com.sun.speech.freetts.audio.AudioPlayer;
import javax.sound.sampled.*;
public class VoiceEffectsProcessor {
private Voice voice;
private AudioProcessor audioProcessor;
public VoiceEffectsProcessor(String voiceName) {
initializeVoice(voiceName);
this.audioProcessor = new AudioProcessor();
}
private void initializeVoice(String voiceName) {
System.setProperty("freetts.voices", 
"com.sun.speech.freetts.en.us.cmu_us_kal.KevinVoiceDirectory");
VoiceManager voiceManager = VoiceManager.getInstance();
voice = voiceManager.getVoice(voiceName);
if (voice != null) {
voice.allocate();
}
}
public void speakWithEcho(String text, int echoDelay, float decay) {
// Custom audio player with echo effect
EchoAudioPlayer echoPlayer = new EchoAudioPlayer(echoDelay, decay);
voice.setAudioPlayer(echoPlayer);
voice.speak(text);
voice.setAudioPlayer(null);
}
public void speakWithReverb(String text, float reverbLevel) {
// Implementation for reverb effect
ReverbAudioPlayer reverbPlayer = new ReverbAudioPlayer(reverbLevel);
voice.setAudioPlayer(reverbPlayer);
voice.speak(text);
voice.setAudioPlayer(null);
}
public void speakWithSpeedVariation(String text, float speedFactor) {
float originalRate = voice.getRate();
voice.setRate(originalRate * speedFactor);
voice.speak(text);
voice.setRate(originalRate);
}
public void destroy() {
if (voice != null) {
voice.deallocate();
}
}
// Custom AudioPlayer implementations would go here
private static class EchoAudioPlayer implements AudioPlayer {
// Implementation for echo effect
// This is a simplified version - actual implementation would be more complex
public EchoAudioPlayer(int delay, float decay) {
// Initialize echo parameters
}
// Implement all AudioPlayer methods...
public void begin(int size) {}
public boolean write(byte[] audioData) { return true; }
public boolean write(byte[] audioData, int offset, int length) { return true; }
public void drain() {}
public void flush() {}
public void close() {}
public float getVolume() { return 1.0f; }
public void setVolume(float volume) {}
public long getTime() { return 0; }
public void resetTime() {}
public void pause() {}
public void resume() {}
public void showMetrics() {}
public void startFirstSampleTimer() {}
public AudioFormat getAudioFormat() { return null; }
public void setAudioFormat(AudioFormat format) {}
public void cancel() {}
}
private static class ReverbAudioPlayer implements AudioPlayer {
// Implementation for reverb effect
public ReverbAudioPlayer(float reverbLevel) {
// Initialize reverb parameters
}
// Implement all AudioPlayer methods...
public void begin(int size) {}
public boolean write(byte[] audioData) { return true; }
public boolean write(byte[] audioData, int offset, int length) { return true; }
public void drain() {}
public void flush() {}
public void close() {}
public float getVolume() { return 1.0f; }
public void setVolume(float volume) {}
public long getTime() { return 0; }
public void resetTime() {}
public void pause() {}
public void resume() {}
public void showMetrics() {}
public void startFirstSampleTimer() {}
public AudioFormat getAudioFormat() { return null; }
public void setAudioFormat(AudioFormat format) {}
public void cancel() {}
}
public static void main(String[] args) {
VoiceEffectsProcessor processor = new VoiceEffectsProcessor("kevin16");
// Test different effects
processor.speakWithEcho("This text has echo effect", 200, 0.5f);
try { Thread.sleep(1000); } catch (InterruptedException e) {}
processor.speakWithReverb("This text has reverb effect", 0.7f);
try { Thread.sleep(1000); } catch (InterruptedException e) {}
processor.speakWithSpeedVariation("This text is spoken faster", 1.5f);
processor.destroy();
}
}

Key Features Covered:

  1. Basic TTS Setup - Simple text-to-speech implementation
  2. Voice Management - Multiple voice support and configuration
  3. Speech Customization - Rate, pitch, volume control
  4. File Generation - Save speech to audio files
  5. Batch Processing - Generate multiple speech files
  6. GUI Application - Interactive text-to-speech tool
  7. Voice Effects - Audio effects and modulation

This comprehensive FreeTTS implementation provides everything needed to integrate text-to-speech capabilities into Java applications, from basic usage to advanced features like batch processing and voice effects.

Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper