├── .idea
├── .name
├── copyright
│ └── profiles_settings.xml
├── encodings.xml
├── vcs.xml
├── modules.xml
├── libraries
│ ├── Maven__org_apache_commons_commons_exec_1_3.xml
│ └── Maven__com_googlecode_java_diff_utils_diffutils_1_3_0.xml
├── compiler.xml
├── misc.xml
└── uiDesigner.xml
├── get_pl_model.sh
├── src
└── main
│ └── java
│ └── pl
│ └── edu
│ └── pjwstk
│ └── kaldi
│ ├── files
│ ├── SegmentationList.java
│ ├── LAB.java
│ ├── julius
│ │ ├── MLF.java
│ │ ├── ConfidenceNetwork.java
│ │ ├── WordList.java
│ │ ├── AlignedSequence.java
│ │ ├── Dictionary.java
│ │ ├── LatticeNode.java
│ │ ├── WordGraph.java
│ │ ├── WordSequence.java
│ │ └── JuliusOutput.java
│ ├── RTTM.java
│ ├── CTM.java
│ ├── TextGrid.java
│ ├── Converter.java
│ ├── ClarinText.java
│ └── Segmentation.java
│ ├── programs
│ ├── Kill.java
│ ├── chmod.java
│ ├── Python.java
│ ├── FFMPEG.java
│ ├── Sox.java
│ ├── Java.java
│ ├── KaldiKWS.java
│ ├── NGram.java
│ ├── Transcriber.java
│ ├── Shout.java
│ ├── Julius.java
│ ├── Praat.java
│ └── Essentia.java
│ ├── service
│ ├── tasks
│ │ ├── ConvertEncodingTask.java
│ │ ├── TestTask.java
│ │ ├── AlignTask.java
│ │ ├── NSERTask.java
│ │ ├── ParallelTask.java
│ │ ├── KeywordSpottingTask.java
│ │ ├── SpeakerDiarizationTask.java
│ │ ├── Task.java
│ │ ├── DecodeTask.java
│ │ └── DecodeFMLLRTask.java
│ ├── ServiceTask.java
│ ├── database
│ │ ├── dbTasks.java
│ │ └── Database.java
│ └── ServiceDaemon.java
│ ├── utils
│ ├── PasswordObfuscator.java
│ ├── ProgramLauncher.java
│ ├── WAV.java
│ ├── Log.java
│ └── Diff.java
│ ├── grammars
│ ├── Akt.java
│ ├── Numbers.java
│ └── Grammar.java
│ └── ExperimentMain.java
├── pom.xml
├── KaldiJava.iml
└── README.md
/.idea/.name:
--------------------------------------------------------------------------------
1 | KJExperimenting
--------------------------------------------------------------------------------
/get_pl_model.sh:
--------------------------------------------------------------------------------
1 | wget http://mowa.clarin-pl.eu/korpusy/pl_model.tar.gz
2 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/files/SegmentationList.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.files;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 |
6 | public class SegmentationList extends Segmentation {
7 | @Override
8 | public void read(File file) throws IOException {
9 | }
10 |
11 | @Override
12 | public void write(File file) throws IOException {
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/programs/Kill.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.programs;
2 |
3 | import pl.edu.pjwstk.kaldi.utils.Log;
4 | import pl.edu.pjwstk.kaldi.utils.ProgramLauncher;
5 |
6 | public class Kill {
7 |
8 | public static void kill(int pid) {
9 |
10 | String[] cmd = { "kill", "-9", "" + pid };
11 |
12 | ProgramLauncher launcher = new ProgramLauncher(cmd);
13 |
14 | Log.verbose("Killing process: " + pid);
15 | launcher.run();
16 | Log.verbose("Done.");
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/programs/chmod.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.programs;
2 |
3 | import java.io.File;
4 |
5 | import pl.edu.pjwstk.kaldi.utils.Log;
6 | import pl.edu.pjwstk.kaldi.utils.ProgramLauncher;
7 |
8 | public class chmod {
9 |
10 | public static void run(String mode, File file) {
11 |
12 | String[] cmd = new String[] { "chmod", mode, file.getAbsolutePath() };
13 |
14 | ProgramLauncher launcher = new ProgramLauncher(cmd);
15 |
16 | Log.verbose("chmod: " + mode + " " + file.getAbsolutePath());
17 | launcher.run();
18 | Log.verbose("Done.");
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_commons_commons_exec_1_3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_googlecode_java_diff_utils_diffutils_1_3_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/files/LAB.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.files;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 | import java.io.PrintWriter;
6 |
7 | public class LAB extends Segmentation {
8 |
9 | public LAB() {
10 |
11 | }
12 |
13 | public LAB(Tier tier) {
14 |
15 | tiers.add(tier);
16 |
17 | }
18 |
19 | public void write(File file) throws IOException {
20 | PrintWriter writer = new PrintWriter(file);
21 |
22 | Tier tier = tiers.get(0);
23 |
24 | for (Segment seg : tier.segments) {
25 |
26 | long start = (long) (seg.start_time * 10000000);
27 | long end = (long) (seg.end_time * 10000000);
28 | writer.format("%d %d %s %.2f\n", start, end, seg.name,
29 | seg.confidence);
30 | }
31 | writer.close();
32 | }
33 |
34 | @Override
35 | public void read(File file) throws IOException {
36 | throw new IOException("NYI");
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/programs/Python.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.programs;
2 |
3 | import java.io.File;
4 |
5 | import pl.edu.pjwstk.kaldi.utils.Log;
6 | import pl.edu.pjwstk.kaldi.utils.ProgramLauncher;
7 | import pl.edu.pjwstk.kaldi.utils.Settings;
8 |
9 | public class Python {
10 |
11 | public static void run(File script, String[] args) {
12 |
13 | String[] cmd = new String[args.length + 2];
14 | cmd[0] = Settings.python_bin.getAbsolutePath();
15 | cmd[1] = script.getAbsolutePath();
16 | int i = 2;
17 | for (String arg : args) {
18 | cmd[i] = arg;
19 | i++;
20 | }
21 |
22 | ProgramLauncher launcher = new ProgramLauncher(cmd);
23 | launcher.setStdoutStream(new Log.Stream());
24 | launcher.setStderrStream(new Log.Stream("ERR>>"));
25 |
26 | Log.verbose("Running python script: " + script.getName());
27 | launcher.run();
28 | Log.verbose("Done.");
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | pl.edu.pja.multimedia
8 | KaldiJava
9 | 1.0-SNAPSHOT
10 |
11 |
12 | org.apache.commons
13 | commons-exec
14 | 1.3
15 |
16 |
17 | com.googlecode.java-diff-utils
18 | diffutils
19 | 1.3.0
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/programs/FFMPEG.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.programs;
2 |
3 | import java.io.File;
4 |
5 | import pl.edu.pjwstk.kaldi.utils.Log;
6 | import pl.edu.pjwstk.kaldi.utils.ProgramLauncher;
7 | import pl.edu.pjwstk.kaldi.utils.Settings;
8 |
9 | public class FFMPEG {
10 |
11 | public static void convertTo16k(File input, File output) {
12 |
13 | String[] cmd = new String[] { Settings.ffmpeg_bin.getAbsolutePath(),
14 | "-i", input.getAbsolutePath(), "-acodec", "pcm_s16le", "-ac",
15 | "1", "-ar", "16k", output.getAbsolutePath() };
16 |
17 | ProgramLauncher launcher = new ProgramLauncher(cmd);
18 |
19 | Log.verbose("FFMPEG: " + input.getAbsolutePath() + " -> "
20 | + output.getAbsolutePath());
21 | launcher.run();
22 | Log.verbose("Done.");
23 |
24 | if (launcher.getReturnValue() != 0)
25 | throw new RuntimeException("FFMPEG Retval: " + launcher.getReturnValue());
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/KaldiJava.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/programs/Sox.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.programs;
2 |
3 | import java.io.File;
4 |
5 | import pl.edu.pjwstk.kaldi.utils.Log;
6 | import pl.edu.pjwstk.kaldi.utils.ProgramLauncher;
7 |
8 | public class Sox {
9 |
10 | public static void convert(File src_file, File dest_file) {
11 |
12 | String[] cmd = new String[] { "sox", src_file.getAbsolutePath(), "-c",
13 | "1", dest_file.getAbsolutePath(), "norm", "-3", "rate", "-h",
14 | "16k" };
15 |
16 | ProgramLauncher launcher = new ProgramLauncher(cmd);
17 |
18 | Log.verbose("Coverting using SoX...");
19 | launcher.run();
20 | Log.verbose("Done.");
21 |
22 | }
23 |
24 | public static void extract(File src_file, File dest_file,
25 | double time_start, double time_end) {
26 |
27 | double duration = time_end - time_start;
28 |
29 | String[] cmd = new String[] { "sox", src_file.getAbsolutePath(),
30 | dest_file.getAbsolutePath(), "trim", "" + time_start,
31 | "" + duration };
32 |
33 | ProgramLauncher launcher = new ProgramLauncher(cmd);
34 |
35 | Log.verbose("Extracting using SoX...");
36 | launcher.run();
37 | Log.verbose("Done.");
38 |
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # KaldiJava
2 |
3 | This project contains mostly a set of classes which allow interfacing Kaldi from within Java. This is not a replacement for Kaldi (it does require a working installation of Kaldi on the computer), but it does make life easier in certain situations.
4 |
5 | The idea is to replace the standard Bash/Perl/Python scripts that are used in the Kaldi project. A common use-case for this would be when you want to include Kaldi in some web environment pipeline. Another use may be when you simply want to make your life performing experiments easier or when you require proper unicode support.
6 |
7 | ## Installation tips
8 |
9 | This project doesn't yet contain any detailed documentation.
10 |
11 | Generally you need the following steps:
12 |
13 | 1. Install Kaldi from http://kaldi-asr.org/
14 | 2. Intall any other tool from the ones included in the classes
15 | 3. Configure the Settings.java file with proper paths (or create a settings file and load it at start)
16 | 4. Modify the main program class to do what ever you need.
17 |
18 | ## Who made this
19 |
20 | This project was started ad the Polish-Japanese Academy of Information Technology in Warsaw, Poland.
21 |
22 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/programs/Java.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.programs;
2 |
3 | import java.io.File;
4 | import java.util.List;
5 |
6 | import pl.edu.pjwstk.kaldi.utils.Log;
7 | import pl.edu.pjwstk.kaldi.utils.ProgramLauncher;
8 |
9 | public class Java {
10 |
11 | private static String sep = ":";
12 |
13 | public static void java(String class_name, String[] args,
14 | List cp_files, boolean async) {
15 |
16 | String class_path = "";
17 | for (File file : cp_files) {
18 | if (!class_path.isEmpty())
19 | class_path += sep;
20 | class_path += file.getAbsolutePath();
21 | }
22 |
23 | String[] cmd_start = new String[] { "java", "-Dfile.encoding=UTF-8",
24 | "-cp", class_path, class_name };
25 | String cmd[] = new String[cmd_start.length + args.length];
26 |
27 | for (int i = 0; i < cmd_start.length ; i++)
28 | cmd[i] = cmd_start[i];
29 | for (int i = 0; i < args.length; i++)
30 | cmd[cmd_start.length + i] = args[i];
31 |
32 | ProgramLauncher launcher = new ProgramLauncher(cmd);
33 | launcher.setSuppressOutput(true);
34 | launcher.setAsynchronous(async);
35 |
36 | Log.verbose("Running Java: " + class_name);
37 | launcher.run();
38 | Log.verbose("Done.");
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/files/julius/MLF.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.files.julius;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.File;
5 | import java.io.FileInputStream;
6 | import java.io.IOException;
7 | import java.io.InputStreamReader;
8 |
9 | import pl.edu.pjwstk.kaldi.utils.Settings;
10 |
11 | public class MLF {
12 |
13 | private File file;
14 |
15 | public MLF(File file) {
16 | this.file = file;
17 | }
18 |
19 | public WordSequence load(String labfile) throws IOException {
20 | BufferedReader reader = new BufferedReader(new InputStreamReader(
21 | new FileInputStream(file), Settings.julius_default_encoding));
22 |
23 | int pos = labfile.lastIndexOf('.');
24 | labfile = labfile.substring(0, pos) + ".lab";
25 |
26 | String line;
27 | while ((line = reader.readLine()) != null) {
28 |
29 | if (line.startsWith("#"))
30 | continue;
31 |
32 | if (line.startsWith("\"") && line.contains(labfile)) {// TODO: weak
33 | // solution
34 | WordSequence ret = new WordSequence();
35 | while ((line = reader.readLine()) != null) {
36 | if (line.equals(".")) {
37 | reader.close();
38 | return ret;
39 | }
40 | ret.addWord(line);
41 | }
42 | }
43 | }
44 |
45 | reader.close();
46 | return null;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/files/julius/ConfidenceNetwork.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.files.julius;
2 |
3 | import java.util.LinkedList;
4 | import java.util.List;
5 | import java.util.Vector;
6 |
7 | public class ConfidenceNetwork {
8 |
9 | public static class Word
10 | {
11 | public String word;
12 | public double weight;
13 | public Object object;
14 |
15 | public Word(String word, double weight)
16 | {
17 | this.word=word;
18 | this.weight=weight;
19 |
20 | object=null;
21 | }
22 |
23 | public String toString()
24 | {
25 | return word+":"+weight;
26 | }
27 | }
28 |
29 | public static class Section
30 | {
31 | public List words;
32 |
33 | public Section()
34 | {
35 | words=new LinkedList<>();
36 | }
37 |
38 | public String toString()
39 | {
40 | String ret="";
41 |
42 | for(Word w:words)
43 | {
44 | ret+="("+w+") ";
45 | }
46 |
47 | return ret;
48 | }
49 | }
50 |
51 | public Vector sections;
52 |
53 | public ConfidenceNetwork()
54 | {
55 | sections=new Vector();
56 | }
57 |
58 |
59 | public double getAverageSectionWidth()
60 | {
61 | int ret=0;
62 | int count=0;
63 |
64 | for(Section s:sections)
65 | {
66 | ret+=s.words.size();
67 | count++;
68 | }
69 |
70 | return ret/(double)count;
71 | }
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/service/tasks/ConvertEncodingTask.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.service.tasks;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 | import java.security.MessageDigest;
6 |
7 | import javax.xml.xpath.XPath;
8 | import javax.xml.xpath.XPathConstants;
9 | import javax.xml.xpath.XPathExpressionException;
10 |
11 | import org.w3c.dom.Element;
12 |
13 | import pl.edu.pjwstk.kaldi.programs.FFMPEG;
14 | import pl.edu.pjwstk.kaldi.utils.Log;
15 |
16 | public class ConvertEncodingTask extends Task {
17 |
18 | private File input, output;
19 |
20 | @Override
21 | public void run() {
22 |
23 | state = State.RUNNING;
24 |
25 | try {
26 |
27 | FFMPEG.convertTo16k(input, output);
28 |
29 | state = State.SUCCEEDED;
30 |
31 | } catch (RuntimeException e) {
32 | Log.error("FFMPEG task.", e);
33 | state = State.FAILED;
34 | }
35 | }
36 |
37 | @Override
38 | public void loadSettings(XPath xpath, Element node)
39 | throws XPathExpressionException {
40 |
41 | input = new File((String) xpath.evaluate("input", node,
42 | XPathConstants.STRING));
43 | output = new File((String) xpath.evaluate("output", node,
44 | XPathConstants.STRING));
45 |
46 | }
47 |
48 | @Override
49 | public void updateHash(MessageDigest m) throws IOException {
50 | processFileHash(m, input);
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/files/julius/WordList.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.files.julius;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.File;
5 | import java.io.FileInputStream;
6 | import java.io.IOException;
7 | import java.io.InputStreamReader;
8 | import java.util.HashSet;
9 | import java.util.Set;
10 | import java.util.Vector;
11 |
12 | import pl.edu.pjwstk.kaldi.utils.Settings;
13 |
14 | public class WordList {
15 |
16 | Set words;
17 |
18 | public WordList() {
19 | words = new HashSet();
20 | }
21 |
22 | public void readFromDictionary(File file) throws IOException {
23 | words.clear();
24 |
25 | BufferedReader reader = new BufferedReader(new InputStreamReader(
26 | new FileInputStream(file), Settings.julius_default_encoding));
27 |
28 | String line;
29 | while ((line = reader.readLine()) != null) {
30 | if (line.trim().length() == 0)
31 | continue;
32 |
33 | String[] arr = line.split("\\s+");
34 |
35 | words.add(arr[0]);
36 | }
37 |
38 | reader.close();
39 | }
40 |
41 | public int countMissingWords(WordSequence sequence) {
42 | int ret = 0;
43 |
44 | for (String word : sequence.words) {
45 | if (!words.contains(word))
46 | ret++;
47 | }
48 |
49 | return ret;
50 | }
51 |
52 | public Vector getMissingWords(WordSequence sequence) {
53 | Vector ret = new Vector();
54 |
55 | for (String word : sequence.words) {
56 | if (!words.contains(word))
57 | ret.add(word);
58 | }
59 |
60 | return ret;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/service/tasks/TestTask.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.service.tasks;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 | import java.nio.file.Files;
6 | import java.security.MessageDigest;
7 |
8 | import javax.xml.xpath.XPath;
9 | import javax.xml.xpath.XPathConstants;
10 | import javax.xml.xpath.XPathExpressionException;
11 |
12 | import org.w3c.dom.Element;
13 |
14 | import pl.edu.pjwstk.kaldi.utils.Log;
15 | import pl.edu.pjwstk.kaldi.utils.Settings;
16 |
17 | public class TestTask extends Task {
18 |
19 | private File input;
20 | private String output_name;
21 |
22 | @Override
23 | public void run() {
24 |
25 | state = State.RUNNING;
26 | Log.info("Starting test task...");
27 |
28 | try {
29 |
30 | File output = new File(Settings.curr_task_dir, output_name);
31 |
32 | Files.copy(input.toPath(), output.toPath());
33 |
34 | } catch (Exception e) {
35 | Log.error("Running Test Task", e);
36 | state = State.FAILED;
37 | return;
38 | }
39 |
40 | Log.info("Completed succesfully!");
41 | state = State.SUCCEEDED;
42 | }
43 |
44 | @Override
45 | public void loadSettings(XPath xpath, Element node)
46 | throws XPathExpressionException {
47 |
48 | String input_file = (String) xpath.evaluate("input", node,
49 | XPathConstants.STRING);
50 | input = new File(input_file);
51 |
52 | output_name = (String) xpath.evaluate("output-name", node,
53 | XPathConstants.STRING);
54 | }
55 |
56 | @Override
57 | public void updateHash(MessageDigest m) throws IOException {
58 | processFileHash(m, input);
59 | m.digest(output_name.getBytes(Settings.default_encoding));
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/utils/PasswordObfuscator.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.utils;
2 |
3 | import java.nio.ByteBuffer;
4 |
5 | import javax.xml.bind.DatatypeConverter;
6 |
7 | public class PasswordObfuscator {
8 |
9 | private final static long passwordObfuscator = 2934278932478932493L;
10 |
11 | public static String obfuscatePassword(String password) {
12 |
13 | int longNumBytes = Long.SIZE / 8;
14 |
15 | ByteBuffer in = ByteBuffer.wrap(password.getBytes());
16 | ByteBuffer out = ByteBuffer.allocate(in.capacity());
17 | ByteBuffer obf = ByteBuffer.allocate(longNumBytes);
18 | obf.putLong(passwordObfuscator);
19 | obf.rewind();
20 |
21 | while (in.remaining() >= longNumBytes) {
22 | long l = in.getLong();
23 | out.putLong(l ^ passwordObfuscator);
24 | }
25 |
26 | while (in.hasRemaining()) {
27 | byte b = in.get();
28 | out.put((byte) (b ^ obf.get()));
29 | }
30 |
31 | return DatatypeConverter.printBase64Binary(out.array());
32 |
33 | }
34 |
35 | public static String deobfuscatePassword(String password) throws IllegalArgumentException {
36 |
37 | int longNumBytes = Long.SIZE / 8;
38 |
39 | ByteBuffer in = ByteBuffer.wrap(DatatypeConverter.parseBase64Binary(password));
40 | ByteBuffer out = ByteBuffer.allocate(in.capacity());
41 | ByteBuffer obf = ByteBuffer.allocate(longNumBytes);
42 | obf.putLong(passwordObfuscator);
43 | obf.rewind();
44 |
45 | while (in.remaining() >= longNumBytes) {
46 | long l = in.getLong();
47 | out.putLong(l ^ passwordObfuscator);
48 | }
49 |
50 | while (in.hasRemaining()) {
51 | byte b = in.get();
52 | out.put((byte) (b ^ obf.get()));
53 | }
54 |
55 | return new String(out.array());
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/files/RTTM.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.files;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.File;
5 | import java.io.FileReader;
6 | import java.io.IOException;
7 | import java.io.PrintWriter;
8 |
9 | import pl.edu.pjwstk.kaldi.utils.Log;
10 |
11 | public class RTTM extends Segmentation {
12 |
13 | private double timebase = 1;
14 |
15 | public RTTM(double timebase) {
16 | this.timebase = timebase;
17 | }
18 |
19 | @Override
20 | public void read(File file) throws IOException {
21 |
22 | BufferedReader reader = new BufferedReader(new FileReader(file));
23 | String line;
24 |
25 | while ((line = reader.readLine()) != null) {
26 |
27 | String[] tok = line.split("\\s+");
28 |
29 | if (tok[0].equals("SPKR-INFO"))
30 | continue;
31 |
32 | double start = Double.parseDouble(tok[3]);
33 | double len = Double.parseDouble(tok[4]);
34 | String name = tok[7];
35 |
36 | addSegment(0, start * timebase, (start + len) * timebase, name);
37 | }
38 | reader.close();
39 |
40 | renameTier(0, "RTTM");
41 |
42 | sort();
43 | }
44 |
45 | @Override
46 | public void write(File file) throws IOException {
47 |
48 | PrintWriter writer = new PrintWriter(file);
49 |
50 | if (!tiers.isEmpty()) {
51 | if (tiers.size() > 1) {
52 | Log.warn("RTTM saving only first tier!");
53 | }
54 |
55 | Tier tier = tiers.get(0);
56 |
57 | for (Segment seg : tier.segments) {
58 | // SPEAKER speaker 1 0.0 12.51 speaker_1.0
59 | writer.format("SPEAKER speaker 1 %f %f %s \n",
60 | seg.start_time / timebase,
61 | (seg.end_time - seg.start_time) / timebase, seg.name);
62 | }
63 |
64 | }
65 |
66 | writer.close();
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/files/CTM.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.files;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.File;
5 | import java.io.FileReader;
6 | import java.io.IOException;
7 | import java.io.PrintWriter;
8 |
9 | public class CTM extends Segmentation {
10 |
11 | @Override
12 | public void read(File file) throws IOException {
13 |
14 | tiers.clear();
15 |
16 | BufferedReader reader = new BufferedReader(new FileReader(file));
17 |
18 | String line;
19 | String filename = "";
20 | String name;
21 | double start, end;
22 |
23 | while ((line = reader.readLine()) != null) {
24 | String tok[] = line.split("\\s");
25 |
26 | if (tok.length < 5 || tok.length > 6) {
27 | reader.close();
28 | throw new IOException("wrong line in file " + file.getName() + ": " + line);
29 | }
30 |
31 | filename = tok[0];
32 | try {
33 | start = Double.parseDouble(tok[2]);
34 | end = start + Double.parseDouble(tok[3]);
35 | } catch (NumberFormatException e) {
36 | reader.close();
37 | throw new IOException("wrong line in file " + file.getName() + ": " + line);
38 | }
39 | name = tok[4];
40 |
41 | addSegment(0, start, end, name);
42 |
43 | if (tok.length == 6) {
44 | addSegment(1, start, end, tok[5]);
45 | }
46 | }
47 |
48 | if (tiers.size() > 0)
49 | tiers.get(0).name = filename;
50 | if (tiers.size() > 1)
51 | tiers.get(1).name = "Confidence";
52 |
53 | reader.close();
54 |
55 | }
56 |
57 | @Override
58 | public void write(File file) throws IOException {
59 |
60 | PrintWriter writer = new PrintWriter(file);
61 |
62 | Tier tier = tiers.get(0);
63 | for (Segment segment : tier.segments) {
64 | writer.format("%s 1 %1.2f %1.2f %s %1.2f\n", tier.name, segment.start_time, segment.end_time
65 | - segment.start_time, segment.name, segment.confidence);
66 | }
67 |
68 | writer.close();
69 |
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/service/tasks/AlignTask.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.service.tasks;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 | import java.security.MessageDigest;
6 |
7 | import javax.sound.sampled.UnsupportedAudioFileException;
8 | import javax.xml.xpath.XPath;
9 | import javax.xml.xpath.XPathConstants;
10 | import javax.xml.xpath.XPathExpressionException;
11 |
12 | import org.w3c.dom.Element;
13 |
14 | import pl.edu.pjwstk.kaldi.KaldiMain;
15 | import pl.edu.pjwstk.kaldi.utils.FileUtils;
16 | import pl.edu.pjwstk.kaldi.utils.Log;
17 | import pl.edu.pjwstk.kaldi.utils.Settings;
18 |
19 | public class AlignTask extends Task {
20 |
21 | private File input_audio;
22 | private File input_text;
23 |
24 | @Override
25 | public void run() {
26 |
27 | state = State.RUNNING;
28 |
29 | File clean_text = new File(Settings.curr_task_dir, "clean.txt");
30 | File textgrid = new File(Settings.curr_task_dir, "out.TextGrid");
31 | File labfile = new File(Settings.curr_task_dir, "out.lab");
32 |
33 | try {
34 | FileUtils.cleanChars(input_text, clean_text, false, true, Settings.default_encoding);
35 |
36 | KaldiMain.alignFile(input_audio, clean_text, textgrid, labfile);
37 |
38 | state = State.SUCCEEDED;
39 |
40 | } catch (IOException | UnsupportedAudioFileException e) {
41 | Log.error("Decoding task.", e);
42 | state = State.FAILED;
43 | }
44 |
45 | }
46 |
47 | @Override
48 | public void loadSettings(XPath xpath, Element node) throws XPathExpressionException {
49 |
50 | input_audio = new File((String) xpath.evaluate("input-audio", node, XPathConstants.STRING));
51 | input_text = new File((String) xpath.evaluate("input-text", node, XPathConstants.STRING));
52 |
53 | }
54 |
55 | @Override
56 | public void updateHash(MessageDigest m) throws IOException {
57 | processFileHash(m, input_audio);
58 | processFileHash(m, input_text);
59 |
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/service/tasks/NSERTask.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.service.tasks;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 | import java.security.MessageDigest;
6 |
7 | import javax.xml.xpath.XPath;
8 | import javax.xml.xpath.XPathConstants;
9 | import javax.xml.xpath.XPathExpressionException;
10 |
11 | import org.w3c.dom.Element;
12 |
13 | import pl.edu.pjwstk.kaldi.programs.Python;
14 | import pl.edu.pjwstk.kaldi.utils.Log;
15 | import pl.edu.pjwstk.kaldi.utils.Settings;
16 |
17 | public class NSERTask extends Task {
18 |
19 | File input_file;
20 |
21 | @Override
22 | public void run() {
23 |
24 | File output_file = new File(Settings.curr_task_dir, "out.TextGrid");
25 | File script = new File(Settings.python_scripts_dir,
26 | "NSER/pjatk/Main.py");
27 | File model = new File(Settings.python_scripts_dir,
28 | "NSER/svc_model_prob.pklz");
29 | File hcopy = new File(Settings.python_scripts_dir, "NSER/hcopy.conf");
30 | File sd_dir = new File(Settings.python_scripts_dir, "NSER/SD");
31 |
32 | String args[] = { "--tmp", Settings.curr_task_dir.getAbsolutePath(),
33 | "--sd", sd_dir.getAbsolutePath(), "--model",
34 | model.getAbsolutePath(), "--hcopy_conf",
35 | hcopy.getAbsolutePath(), input_file.getAbsolutePath(),
36 | output_file.getAbsolutePath() };
37 |
38 | state = State.RUNNING;
39 | Log.info("Starting test task...");
40 |
41 | Python.run(script, args);
42 |
43 | if (!output_file.exists())
44 | state = State.FAILED;
45 | else
46 | state = State.SUCCEEDED;
47 | Log.info("Completed!");
48 |
49 | }
50 |
51 | @Override
52 | public void loadSettings(XPath xpath, Element node)
53 | throws XPathExpressionException {
54 |
55 | String input_file_name = (String) xpath.evaluate("input-file", node,
56 | XPathConstants.STRING);
57 | input_file = new File(input_file_name);
58 |
59 | }
60 |
61 | @Override
62 | public void updateHash(MessageDigest m) throws IOException {
63 | processFileHash(m, input_file);
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/programs/KaldiKWS.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.programs;
2 |
3 | import java.io.File;
4 | import java.io.FileNotFoundException;
5 | import java.io.IOException;
6 | import java.util.Locale;
7 |
8 | import pl.edu.pjwstk.kaldi.utils.Log;
9 | import pl.edu.pjwstk.kaldi.utils.ProgramLauncher;
10 | import pl.edu.pjwstk.kaldi.utils.Settings;
11 |
12 | public class KaldiKWS {
13 |
14 | public static void test() throws FileNotFoundException {
15 | if (!Settings.kaldi_kws_bin.exists())
16 | throw new FileNotFoundException(Settings.kaldi_kws_bin.getAbsolutePath());
17 | }
18 |
19 | public static void get_vocab(File lattice, File vocab) throws IOException {
20 |
21 | String[] cmd = new String[] { Settings.kaldi_kws_bin.getAbsolutePath(), lattice.getAbsolutePath(),
22 | vocab.getAbsolutePath() };
23 |
24 | ProgramLauncher launcher = new ProgramLauncher(cmd);
25 |
26 | Log.verbose("KWS generating vocab: " + lattice.getAbsolutePath() + " -> " + vocab.getAbsolutePath());
27 | launcher.run();
28 | Log.verbose("Done.");
29 |
30 | }
31 |
32 | public static void detect(File lattice, File keywords, File dict, File out) throws IOException {
33 |
34 | String[] cmd = new String[] { Settings.kaldi_kws_bin.getAbsolutePath(), lattice.getAbsolutePath(),
35 | keywords.getAbsolutePath(), dict.getAbsolutePath() };
36 |
37 | ProgramLauncher launcher = new ProgramLauncher(cmd);
38 |
39 | launcher.setStdoutFile(out);
40 |
41 | Log.verbose("KWS detecting keywords: " + lattice.getAbsolutePath() + " + " + keywords.getAbsolutePath() + " + "
42 | + dict.getAbsolutePath() + " -> " + out.getAbsolutePath());
43 | launcher.run();
44 | Log.verbose("Done.");
45 |
46 | }
47 |
48 | public static void main(String[] args) {
49 | try {
50 | Locale.setDefault(Locale.ENGLISH);
51 |
52 | Log.init("debug", true);
53 |
54 | get_vocab(new File("/home/guest/Desktop/lucas_kws/paris/130514_NWSU_120A0_O.txt"),
55 | new File("/home/guest/Desktop/lucas_kws/paris/vocab.txt"));
56 |
57 | } catch (Exception e) {
58 | e.printStackTrace();
59 | }
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/service/tasks/ParallelTask.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.service.tasks;
2 |
3 | import java.io.IOException;
4 | import java.security.MessageDigest;
5 | import java.util.LinkedList;
6 | import java.util.List;
7 |
8 | import javax.xml.xpath.XPath;
9 | import javax.xml.xpath.XPathConstants;
10 | import javax.xml.xpath.XPathExpressionException;
11 |
12 | import org.w3c.dom.Element;
13 | import org.w3c.dom.NodeList;
14 |
15 | import pl.edu.pjwstk.kaldi.utils.Log;
16 |
17 | public class ParallelTask extends Task {
18 |
19 | private List tasks = new LinkedList();
20 |
21 | @Override
22 | public void run() {
23 |
24 | state = State.RUNNING;
25 |
26 | Log.info("Parallel task starting tasks in parallel...");
27 | List threads = new LinkedList();
28 | for (Task task : tasks) {
29 | Thread th = new Thread(task);
30 | th.start();
31 | threads.add(th);
32 | }
33 |
34 | Log.info("Parallel task waiting for tasks to finish...");
35 |
36 | for (Thread th : threads) {
37 | try {
38 | th.join();
39 | } catch (InterruptedException e) {
40 | // TODO: wait until actually finished?
41 | }
42 | }
43 |
44 | Log.info("All parallel tasks finished!");
45 |
46 | for (Task task : tasks) {
47 | if (task.state != State.SUCCEEDED) {
48 | Log.info("A parallel task was not succesfull!");
49 | state = State.FAILED;
50 | return;
51 | }
52 | }
53 |
54 | state = State.SUCCEEDED;
55 | Log.info("Parallel task succesful!");
56 | }
57 |
58 | @Override
59 | public void loadSettings(XPath xpath, Element node)
60 | throws XPathExpressionException {
61 |
62 | NodeList tasks = (NodeList) xpath.evaluate("task", node,
63 | XPathConstants.NODESET);
64 |
65 | for (int i = 0; i < tasks.getLength(); i++) {
66 | Element elTask = (Element) tasks.item(i);
67 |
68 | String name = elTask.getAttribute("name");
69 |
70 | Task task = getTask(name);
71 |
72 | task.loadSettings(xpath, elTask);
73 | }
74 | }
75 |
76 | @Override
77 | public void updateHash(MessageDigest m) throws IOException {
78 | for (Task task : tasks) {
79 |
80 | //TODO: also check names of tasks!
81 | task.updateHash(m);
82 | }
83 |
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/programs/NGram.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.programs;
2 |
3 | import java.io.File;
4 | import java.io.FileNotFoundException;
5 |
6 | import pl.edu.pjwstk.kaldi.utils.Log;
7 | import pl.edu.pjwstk.kaldi.utils.ProgramLauncher;
8 | import pl.edu.pjwstk.kaldi.utils.Settings;
9 |
10 | public class NGram {
11 |
12 | public static void test_mitlm() throws FileNotFoundException {
13 | if (!Settings.estimate_ngram_bin.exists())
14 | throw new
15 | FileNotFoundException(Settings.estimate_ngram_bin.getAbsolutePath()
16 | );
17 | }
18 |
19 | public static void test_srilm() throws FileNotFoundException {
20 | if (!Settings.ngram_count_bin.exists())
21 | throw new FileNotFoundException(Settings.ngram_count_bin.getAbsolutePath());
22 | }
23 |
24 | public static void estimate(File input, File vocab, File model, int order) {
25 |
26 | String[] cmd = new String[]{Settings.estimate_ngram_bin.getAbsolutePath(), "-t", input.getAbsolutePath(),
27 | "-o", "" + order, "-wv", vocab.getAbsolutePath(), "-wl", model.getAbsolutePath()};
28 |
29 | ProgramLauncher launcher = new ProgramLauncher(cmd);
30 |
31 | launcher.setStdoutStream(new Log.Stream());
32 | launcher.setStderrStream(new Log.Stream("ERR>>"));
33 |
34 | Log.verbose("Estimating N-Gram (MITLM)...");
35 | launcher.run();
36 | Log.verbose("Done.");
37 |
38 | }
39 |
40 | public static void srilm_estimate(File input, File vocab, File model, int order) {
41 |
42 | String[] cmd = new String[]{Settings.ngram_count_bin.getAbsolutePath(), "-order", "" + order, "-unk",
43 | "-map-unk", "", "-text", input.getAbsolutePath(), "-lm", model.getAbsolutePath(), "-write-vocab",
44 | vocab.getAbsolutePath(), "-wbdiscount", "-gt1min", "1", "-gt2min", "1", "-gt3min", "1"};
45 |
46 | ProgramLauncher launcher = new ProgramLauncher(cmd);
47 |
48 | launcher.setStdoutStream(new Log.Stream());
49 | launcher.setStderrStream(new Log.Stream("ERR>>"));
50 |
51 | Log.verbose("Estimating N-Gram (SRILM)...");
52 | launcher.run();
53 | Log.verbose("Done.");
54 |
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/grammars/Akt.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.grammars;
2 |
3 | import java.util.LinkedList;
4 |
5 | /**
6 | * Created by guest on 6/1/16.
7 | */
8 | public class Akt {
9 |
10 | public static Grammar male_names() {
11 | Grammar ret=new Grammar();
12 | LinkedList l=new LinkedList<>();
13 | l.add("stanisław");
14 | l.add("aleksander");
15 | l.add("jan");
16 | l.add("michał");
17 | ret.setWordList(l);
18 | return ret;
19 | }
20 |
21 | public static Grammar female_names() {
22 | Grammar ret=new Grammar();
23 | LinkedList l=new LinkedList<>();
24 | l.add("teofila");
25 | l.add("marianna");
26 | l.add("jadwiga");
27 | l.add("natalia");
28 | l.add("aleksandra");
29 | ret.setWordList(l);
30 | return ret;
31 | }
32 |
33 | public static Grammar last_names() {
34 | Grammar ret=new Grammar();
35 | LinkedList l=new LinkedList<>();
36 | l.add("doddek");
37 | l.add("dąbkowska");
38 | l.add("dudziak");
39 | l.add("ciborowska");
40 | l.add("kowalski");
41 | ret.setWordList(l);
42 | return ret;
43 | }
44 |
45 | public static Grammar places() {
46 | Grammar ret=new Grammar();
47 | LinkedList l=new LinkedList<>();
48 | l.add("lipianka");
49 | l.add("borawe");
50 | l.add("warszawa");
51 | l.add("poznań");
52 | l.add("kraków");
53 | ret.setWordList(l);
54 | return ret;
55 | }
56 |
57 | public static Grammar zgonu() {
58 |
59 | Grammar w_akt=new Grammar();
60 | w_akt.setWord("akt");
61 |
62 | Grammar num=Numbers.numbers();
63 | num.fixend();
64 |
65 | w_akt.attach(num);
66 |
67 | Grammar w_pl=new Grammar();
68 | w_pl.setWord("miejscowość");
69 | w_akt.attach(w_pl);
70 |
71 | w_akt.attach(places());
72 |
73 | Grammar w_zm=new Grammar();
74 | w_zm.setWord("zmarła");
75 | w_akt.attach(w_zm);
76 |
77 | w_akt.attach(female_names());
78 | w_akt.attach(last_names());
79 |
80 | Grammar w_fat=new Grammar();
81 | w_fat.setWord("ojciec");
82 | w_akt.attach(w_fat);
83 |
84 | w_akt.attach(male_names());
85 | w_akt.attach(last_names());
86 |
87 | Grammar w_mot=new Grammar();
88 | w_mot.setWord("matka");
89 | w_akt.attach(w_mot);
90 |
91 | w_akt.attach(female_names());
92 | w_akt.attach(last_names());
93 |
94 | return w_akt;
95 | }
96 |
97 | }
98 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/programs/Transcriber.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.programs;
2 |
3 | import java.io.File;
4 | import java.io.FileNotFoundException;
5 | import java.io.IOException;
6 | import java.util.ArrayList;
7 |
8 | import pl.edu.pjwstk.kaldi.utils.FileUtils;
9 | import pl.edu.pjwstk.kaldi.utils.Log;
10 | import pl.edu.pjwstk.kaldi.utils.ProgramLauncher;
11 | import pl.edu.pjwstk.kaldi.utils.Settings;
12 |
13 | public class Transcriber {
14 |
15 | private static File transcriber_bin;
16 | private static File rules;
17 | private static File replacement;
18 |
19 | public static void init() {
20 | transcriber_bin = new File(Settings.transcriber_dir, "transcriber");
21 | rules = new File(Settings.transcriber_dir, "transcription.rules");
22 | replacement = new File(Settings.transcriber_dir, "replacement.rules");
23 | }
24 |
25 | public static void test() throws FileNotFoundException {
26 | if (!Settings.transcriber_dir.exists())
27 | throw new FileNotFoundException(
28 | Settings.transcriber_dir.getAbsolutePath());
29 | if (!transcriber_bin.exists())
30 | throw new FileNotFoundException(transcriber_bin.getAbsolutePath());
31 | if (!rules.exists())
32 | throw new FileNotFoundException(rules.getAbsolutePath());
33 | if (!replacement.exists())
34 | throw new FileNotFoundException(replacement.getAbsolutePath());
35 | }
36 |
37 | public static void transcribe(File vocab, String vocab_enc, File dict,
38 | String dict_enc, boolean add_sent_boundaries) throws IOException {
39 |
40 | File temp_vocab = File.createTempFile("voc", ".txt");
41 | File temp_dic = File.createTempFile("dic", ".txt");
42 |
43 | ArrayList sent = new ArrayList();
44 | sent.add("");
45 | sent.add("");
46 | sent.add("");
47 | sent.add("");
48 | sent.add("sil");
49 | sent.add("SIL");
50 | sent.add("-pau-");
51 |
52 | FileUtils.removeLines(vocab, vocab_enc, temp_vocab, vocab_enc, sent,
53 | true);
54 |
55 | String[] cmd = new String[] { transcriber_bin.getAbsolutePath(), "-r",
56 | rules.getAbsolutePath(), "-w", replacement.getAbsolutePath(),
57 | "-i", temp_vocab.getAbsolutePath(), "-ie", vocab_enc, "-o",
58 | temp_dic.getAbsolutePath(), "-oe", dict_enc };
59 |
60 | ProgramLauncher launcher = new ProgramLauncher(cmd);
61 |
62 | launcher.setStdoutStream(new Log.Stream());
63 | launcher.setStderrStream(new Log.Stream("ERR>>"));
64 |
65 | Log.verbose("Transcribing...");
66 | launcher.run();
67 | Log.verbose("Done.");
68 |
69 | ArrayList dic = new ArrayList();
70 | dic.add("SIL sil");
71 | dic.add(" sil");
72 |
73 | if (add_sent_boundaries) {
74 | dic.add(" sil");
75 | dic.add(" sil");
76 | }
77 |
78 | FileUtils.appendLines(temp_dic, dict_enc, dict, dict_enc, dic, true);
79 |
80 | temp_vocab.delete();
81 | temp_dic.delete();
82 | }
83 |
84 | }
85 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/programs/Shout.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.programs;
2 |
3 | import java.io.File;
4 | import java.io.FileNotFoundException;
5 | import java.lang.reflect.Field;
6 | import java.lang.reflect.Modifier;
7 |
8 | import pl.edu.pjwstk.kaldi.utils.Log;
9 | import pl.edu.pjwstk.kaldi.utils.ProgramLauncher;
10 | import pl.edu.pjwstk.kaldi.utils.Settings;
11 |
12 | public class Shout {
13 |
14 | private static File shout_segment = new File(Settings.shout_dir,
15 | "shout_segment");
16 |
17 | private static File shout_cluster = new File(Settings.shout_dir,
18 | "shout_cluster");
19 |
20 | public static void test() throws FileNotFoundException {
21 |
22 | Field fields[] = Shout.class.getDeclaredFields();
23 | for (Field field : fields) {
24 | if (Modifier.isStatic(field.getModifiers())
25 | && field.getType().getName().equals("java.io.File")) {
26 |
27 | try {
28 |
29 | File file = (File) field.get(null);
30 |
31 | if (file == null || !file.exists())
32 | throw new FileNotFoundException("" + file);
33 |
34 | } catch (IllegalArgumentException | IllegalAccessException e) {
35 | Log.error("Internal error", e);
36 | }
37 | }
38 | }
39 | }
40 |
41 | public static void shout_segment(File audio_file, File seg_model,
42 | File out_mo) throws RuntimeException {
43 |
44 | String[] cmd = new String[] { shout_segment.getAbsolutePath(), "-a",
45 | audio_file.getAbsolutePath(), "-ams",
46 | seg_model.getAbsolutePath(), "-mo", out_mo.getAbsolutePath() };
47 |
48 | ProgramLauncher launcher = new ProgramLauncher(cmd);
49 | launcher.setStdoutStream(new Log.Stream());
50 | launcher.setStderrStream(new Log.Stream("ERR>>"));
51 |
52 | Log.verbose("shout_segment: " + audio_file.getName() + "->"
53 | + out_mo.getName());
54 | launcher.run();
55 | Log.verbose("Done.");
56 |
57 | if (launcher.getReturnValue() != 0)
58 | throw new RuntimeException("Retval: " + launcher.getReturnValue());
59 | }
60 |
61 | public static void shout_cluster(File audio_file, File seg_out,
62 | File out_mo, int max_clusters) throws RuntimeException {
63 |
64 | String[] cmd = null;
65 |
66 | if (max_clusters > 0) {
67 | cmd = new String[] { shout_cluster.getAbsolutePath(), "-a",
68 | audio_file.getAbsolutePath(), "-mi",
69 | out_mo.getAbsolutePath(), "-mo", seg_out.getAbsolutePath(),
70 | "-l", audio_file.getName(), "-mc", "" + max_clusters };
71 | } else {
72 | cmd = new String[] { shout_cluster.getAbsolutePath(), "-a",
73 | audio_file.getAbsolutePath(), "-mi",
74 | seg_out.getAbsolutePath(), "-mo", out_mo.getAbsolutePath(),
75 | "-l", audio_file.getName() };
76 | }
77 |
78 | ProgramLauncher launcher = new ProgramLauncher(cmd);
79 | launcher.setStdoutStream(new Log.Stream());
80 | launcher.setStderrStream(new Log.Stream("ERR>>"));
81 |
82 | Log.verbose("shout_cluster: " + audio_file.getName() + "->"
83 | + out_mo.getName());
84 | launcher.run();
85 | Log.verbose("Done.");
86 |
87 | if (launcher.getReturnValue() != 0)
88 | throw new RuntimeException("Retval: " + launcher.getReturnValue());
89 | }
90 |
91 | }
92 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/files/julius/AlignedSequence.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.files.julius;
2 |
3 | import java.util.Vector;
4 |
5 | import pl.edu.pjwstk.kaldi.files.Segmentation;
6 | import pl.edu.pjwstk.kaldi.files.SegmentationList;
7 |
8 | public class AlignedSequence {
9 |
10 | public static class AlignedWord {
11 | public String word;
12 | public int start, end;
13 | public double score;
14 | public boolean correct;
15 | }
16 |
17 | int max_len = 0;
18 |
19 | public Vector sequence;
20 |
21 | public AlignedSequence() {
22 | sequence = new Vector();
23 | }
24 |
25 | public void addWord(String line) {
26 | if (!line.startsWith("["))
27 | return;
28 |
29 | line = line.replace('[', ' ');
30 | line = line.replace(']', ' ');
31 |
32 | String[] args = line.split("\\s+");
33 |
34 | AlignedWord word = new AlignedWord();
35 |
36 | word.start = Integer.parseInt(args[1]);
37 | word.end = Integer.parseInt(args[2]);
38 | word.score = Double.parseDouble(args[3]);
39 | word.word = args[4];
40 | word.correct = true;
41 |
42 | if (word.end > max_len)
43 | max_len = word.end;
44 |
45 | if (word.word.equals("") || word.word.equals(""))
46 | return;
47 |
48 | sequence.add(word);
49 | }
50 |
51 | public int getLength() {
52 | return max_len;
53 | }
54 |
55 | public String toString() {
56 | String ret = "";
57 | for (AlignedWord w : sequence) {
58 | ret += w.word + " ";
59 | }
60 | return ret;
61 | }
62 |
63 | public AlignedSequence getCurrectSegments(boolean only_correct) {
64 | AlignedSequence ret = new AlignedSequence();
65 |
66 | boolean last = sequence.get(0).correct;
67 | String words = "";
68 | int start = sequence.get(0).start;
69 | int end = sequence.get(0).end;
70 | AlignedWord seq;
71 |
72 | for (AlignedWord word : sequence) {
73 | if (word.correct == last) {
74 | words += word.word + " ";
75 | end = word.end;
76 | } else {
77 | if (last || !only_correct) {
78 | seq = new AlignedWord();
79 | seq.start = start;
80 | seq.end = end;
81 | seq.correct = last;
82 | seq.word = words;
83 | ret.sequence.add(seq);
84 | if (ret.max_len < seq.end)
85 | ret.max_len = seq.end;
86 | }
87 |
88 | start = word.start;
89 | end = word.end;
90 | words = word.word + " ";
91 | last = word.correct;
92 | }
93 | }
94 |
95 | if (last || !only_correct) {
96 | seq = new AlignedWord();
97 | seq.start = start;
98 | seq.end = end;
99 | seq.correct = last;
100 | seq.word = words;
101 | ret.sequence.add(seq);
102 | if (ret.max_len < seq.end)
103 | ret.max_len = seq.end;
104 | }
105 |
106 | return ret;
107 | }
108 |
109 | public Segmentation toSegmentation(double win_off) {
110 | SegmentationList ret = new SegmentationList();
111 |
112 | ret.renameTier(0, "Julius");
113 |
114 | for (AlignedWord word : sequence) {
115 | ret.addSegment(0, word.start * win_off, word.end * win_off,
116 | word.word, word.score);
117 | }
118 |
119 | return ret;
120 | }
121 |
122 | }
123 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/service/ServiceTask.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.service;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 | import java.util.Locale;
6 |
7 | import pl.edu.pjwstk.kaldi.programs.KaldiKWS;
8 | import pl.edu.pjwstk.kaldi.programs.KaldiScripts;
9 | import pl.edu.pjwstk.kaldi.programs.KaldiUtils;
10 | import pl.edu.pjwstk.kaldi.programs.NGram;
11 | import pl.edu.pjwstk.kaldi.programs.Shout;
12 | import pl.edu.pjwstk.kaldi.programs.Transcriber;
13 | import pl.edu.pjwstk.kaldi.service.database.dbTasks;
14 | import pl.edu.pjwstk.kaldi.service.database.dbTasks.dbStatus;
15 | import pl.edu.pjwstk.kaldi.service.tasks.Task;
16 | import pl.edu.pjwstk.kaldi.utils.Log;
17 | import pl.edu.pjwstk.kaldi.utils.ParseOptions;
18 | import pl.edu.pjwstk.kaldi.utils.Settings;
19 |
20 | public class ServiceTask {
21 |
22 | public static void main(String[] args) {
23 |
24 | dbTasks.Task db_task = null;
25 |
26 | try {
27 |
28 | Locale.setDefault(Locale.ENGLISH);
29 |
30 | ParseOptions po = new ParseOptions("Kaldi Task", "Task runner for Kaldi Service.");
31 |
32 | po.addArgument(Integer.class, "task_id", "Database ID of the given task.");
33 |
34 | po.addArgument("settings", 's', File.class, "Load program settings from a file", null);
35 | po.addArgument("restart", 'r', Boolean.class, "Restart if task already exists!", "false");
36 |
37 | if (!po.parse(args))
38 | return;
39 |
40 | if (po.getArgument("settings") != null) {
41 | Settings.loadSettings((File) po.getArgument("settings"));
42 | }
43 |
44 | int id = (Integer) po.getArgument(0);
45 |
46 | db_task = dbTasks.getByID(id);
47 |
48 | try {
49 | int pid = Integer.parseInt(new File("/proc/self").getCanonicalFile().getName());
50 | dbTasks.changePID(db_task, pid);
51 | } catch (NumberFormatException | IOException | SecurityException e) {
52 | throw new RuntimeException("Cannot get PID!", e);
53 | }
54 |
55 | File task_file = new File(db_task.task_file);
56 | File task_dir = new File(task_file.getParent(), "task");
57 |
58 | if (task_dir.exists()) {
59 | if ((Boolean) po.getArgument("restart")) {
60 | File newname = File.createTempFile("task", "bak", task_dir.getParentFile());
61 | newname.delete();
62 | task_dir.renameTo(newname);
63 | } else
64 | throw new RuntimeException("Task dir already exists!");
65 | }
66 |
67 | task_dir.mkdirs();
68 |
69 | Settings.curr_task_dir = task_dir;
70 | Settings.log_dir = Settings.curr_task_dir;
71 | Settings.temp_dir = new File(Settings.curr_task_dir, "tmp");
72 | Settings.temp_dir2 = new File(Settings.curr_task_dir, "tmp2");
73 |
74 | Log.initFile("KaldiTask", true);
75 |
76 | KaldiUtils.init();
77 | KaldiUtils.test();
78 | KaldiScripts.init(Settings.curr_task_dir);
79 | KaldiScripts.test();
80 | Shout.test();
81 | Transcriber.init();
82 | Transcriber.test();
83 | NGram.test_srilm();
84 | KaldiKWS.test();
85 |
86 | Task.run(task_file);
87 |
88 | dbTasks.changeStatus(db_task, dbStatus.done);
89 |
90 | } catch (Exception e) {
91 | Log.error("Main.", e);
92 | if (db_task != null)
93 | dbTasks.changeStatus(db_task, dbStatus.dead);
94 | }
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/grammars/Numbers.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.grammars;
2 |
3 | import java.util.LinkedList;
4 | import java.util.Map;
5 | import java.util.TreeMap;
6 |
7 | /**
8 | * Created by guest on 5/23/16.
9 | */
10 | public class Numbers {
11 |
12 |
13 | public static Grammar numbers() {
14 |
15 | Grammar zero=new Grammar();
16 | zero.setWord("zero");
17 |
18 | Map join_link=new TreeMap();
19 | join_link.put(0,0);
20 | join_link.put(1,1);
21 |
22 | Grammar n1_9=new Grammar();
23 | LinkedList l1_9=new LinkedList<>();
24 | l1_9.add("jeden");
25 | l1_9.add("dwa");
26 | l1_9.add("trzy");
27 | l1_9.add("cztery");
28 | l1_9.add("pięć");
29 | l1_9.add("sześć");
30 | l1_9.add("siedem");
31 | l1_9.add("osiem");
32 | l1_9.add("dziewięć");
33 | n1_9.setWordList(l1_9);
34 |
35 | Grammar n1_99=n1_9.clone();
36 |
37 | Grammar n10_19=new Grammar();
38 | LinkedList l10_19=new LinkedList<>();
39 | l10_19.add("dziesięć");
40 | l10_19.add("jedenaście");
41 | l10_19.add("dwanaście");
42 | l10_19.add("trzynaście");
43 | l10_19.add("czternaście");
44 | l10_19.add("piętnaście");
45 | l10_19.add("szesnaście");
46 | l10_19.add("siedemnaście");
47 | l10_19.add("osiemnaście");
48 | l10_19.add("dziewiętnaście");
49 | n10_19.setWordList(l10_19);
50 |
51 | n1_99.merge(n10_19,join_link);
52 |
53 | Grammar n20_90=new Grammar();
54 | LinkedList l20_90=new LinkedList<>();
55 | l20_90.add("dwadzieścia");
56 | l20_90.add("trzydzieści");
57 | l20_90.add("czterdzieści");
58 | l20_90.add("piećdziesiąt");
59 | l20_90.add("sześcdziesiąt");
60 | l20_90.add("siedemdziesiąt");
61 | l20_90.add("osiemdziesiąt");
62 | l20_90.add("dziewiedziesiąt");
63 | n20_90.setWordList(l20_90);
64 |
65 | Grammar n2x_9x=n20_90.clone();
66 | n2x_9x.attach(n1_9,1);
67 | n2x_9x.end_nodes.add(1);
68 |
69 |
70 | Map join_link2=new TreeMap();
71 | join_link2.put(0,0);
72 | join_link2.put(2,1);
73 |
74 | n1_99.merge(n2x_9x,join_link2);
75 |
76 | Grammar n100_900=new Grammar();
77 | LinkedList l100_900=new LinkedList<>();
78 | l100_900.add("");
79 | l100_900.add("sto");
80 | l100_900.add("dwieście");
81 | l100_900.add("trzysta");
82 | l100_900.add("czterysta");
83 | l100_900.add("pięćset");
84 | l100_900.add("sześćset");
85 | l100_900.add("siedemset");
86 | l100_900.add("osiemset");
87 | l100_900.add("dziewięćset");
88 | n100_900.setWordList(l100_900);
89 |
90 | Grammar n1xx_9xx=n100_900.clone();
91 | n1xx_9xx.attach(n1_99,1);
92 | n1xx_9xx.end_nodes.add(1);
93 |
94 | Grammar n0_999=zero.clone();
95 | n0_999.merge(n1xx_9xx,join_link2);
96 |
97 | return n0_999;
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/files/julius/Dictionary.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.files.julius;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.File;
5 | import java.io.FileInputStream;
6 | import java.io.IOException;
7 | import java.io.InputStreamReader;
8 | import java.io.PrintWriter;
9 | import java.util.HashMap;
10 | import java.util.HashSet;
11 | import java.util.LinkedList;
12 | import java.util.Map;
13 | import java.util.Set;
14 |
15 | import pl.edu.pjwstk.kaldi.utils.Settings;
16 |
17 | public class Dictionary {
18 |
19 | class Transcriptions {
20 | public LinkedList transcription;
21 |
22 | public Transcriptions(String word) {
23 | transcription = new LinkedList();
24 | transcription.add(word);
25 | }
26 | }
27 |
28 | Map dictionary;
29 |
30 | public Dictionary() {
31 | dictionary = new HashMap();
32 | }
33 |
34 | public void load(File file) throws IOException, RuntimeException {
35 | BufferedReader reader = new BufferedReader(new InputStreamReader(
36 | new FileInputStream(file), Settings.julius_default_encoding));
37 |
38 | dictionary.clear();
39 |
40 | String line, word, trans;
41 | int ret;
42 |
43 | while ((line = reader.readLine()) != null) {
44 | if (line.length() == 0)
45 | continue;
46 |
47 | ret = line.indexOf(' ');
48 |
49 | if (ret < 0) {
50 | reader.close();
51 | throw new RuntimeException("Error parsing line: " + line);
52 | }
53 |
54 | word = line.substring(0, ret);
55 | trans = line.substring(ret + 1);
56 |
57 | if (dictionary.containsKey(word)) {
58 | dictionary.get(word).transcription.add(trans);
59 | } else
60 | dictionary.put(word, new Transcriptions(trans));
61 | }
62 |
63 | reader.close();
64 | }
65 |
66 | public void generateSubDictionary(File wordlist, File subdic)
67 | throws IOException, RuntimeException {
68 | BufferedReader reader = new BufferedReader(
69 | new InputStreamReader(new FileInputStream(wordlist),
70 | Settings.julius_default_encoding));
71 | PrintWriter writer = new PrintWriter(subdic,
72 | Settings.julius_default_encoding);
73 |
74 | Set added = new HashSet();
75 |
76 | writer.println(" sil");
77 | writer.println(" sil");
78 | writer.println(" sil");
79 |
80 | added.add("");
81 | added.add("");
82 | added.add("");
83 |
84 | boolean error = false;
85 | String line;
86 | String arr[];
87 | Transcriptions trans;
88 |
89 | while ((line = reader.readLine()) != null) {
90 | arr = line.split("\\s+");
91 | for (String word : arr) {
92 | word = word.trim();
93 | if (word.length() == 0)
94 | continue;
95 |
96 | if (added.contains(word))
97 | continue;
98 |
99 | added.add(word);
100 |
101 | if (!dictionary.containsKey(word)) {
102 | error = true;
103 | System.out.println("ERROR: missing word in dictionary: "
104 | + word);
105 | } else {
106 | trans = dictionary.get(word);
107 | for (String str_trans : trans.transcription)
108 | writer.println(word + " " + str_trans);
109 | }
110 |
111 | }
112 | }
113 |
114 | reader.close();
115 | writer.close();
116 |
117 | if (error) {
118 | throw new RuntimeException("Didn't find all words!");
119 | }
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/files/julius/LatticeNode.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.files.julius;
2 | import java.util.Vector;
3 |
4 | public class LatticeNode
5 | {
6 | public int id;
7 | public int time_start, time_end;
8 | public Vector left,right;
9 | public Vector left_score,right_score;
10 | public double lscore, f, f_prev, g_head, g_prev;
11 | public double forward_score, backword_score, AMavg, cmscore, graphcm;
12 | public String headphone, tailphone;
13 | public String word;
14 |
15 | public Object object;
16 |
17 | /***********
18 | * Example:
19 | *
20 | * 19: [414..448] left=15,10 right=22 left_lscore=-39.554115,-51.541363
21 | * right_lscore=-57.233547 lscore_tmp=-57.233547 wid=4411 name="dobra" lname="dobra"
22 | * f=-85518.468750 f_prev=-85517.171875 g_head=-66810.640625 g_prev=-65217.273438
23 | * forward_score=-3157.783691 backword_score=-916.954895 AMavg=-45.524776 cmscore=0.079091
24 | * graphcm=0.003168 headphone=m-d+o tailphone=r-a+tS
25 | **********/
26 | public LatticeNode(String line) throws NumberFormatException, IndexOutOfBoundsException
27 | {
28 | left=new Vector();
29 | right=new Vector();
30 | left_score=new Vector();
31 | right_score=new Vector();
32 |
33 | String [] arr = line.split("\\s+");
34 | String [] arr2;
35 |
36 | if(arr.length<2)
37 | throw new RuntimeException("Error parsing line [not enough tokens]: "+line);
38 |
39 | id=Integer.parseInt(arr[0].substring(0,arr[0].length()-1));
40 |
41 | arr2=arr[1].split("\\.\\.");
42 | time_start=Integer.parseInt(arr2[0].substring(1));
43 | time_end=Integer.parseInt(arr2[1].substring(0,arr2[1].length()-1));
44 |
45 | String key,value;
46 | for(int el=2; el");
97 | writer.println("size = " + tiers.size());
98 | writer.println("item []:");
99 |
100 | for (int i = 0; i < tiers.size(); i++) {
101 | Tier tier = tiers.get(i);
102 |
103 | writer.println("\titem [" + (i + 1) + "]:");
104 |
105 | writer.println("\t\tclass = \"IntervalTier\"");
106 | writer.println("\t\tname = \"" + tier.name + "\"");
107 |
108 | writer.println("\t\txmin = " + tier.min());
109 | writer.println("\t\txmax = " + tier.max());
110 | writer.println("\t\tintervals: size = " + tier.segments.size());
111 |
112 | for (int j = 0; j < tier.segments.size(); j++) {
113 | Segment segment = tier.segments.get(j);
114 |
115 | writer.println("\t\tintervals [" + (j + 1) + "]:");
116 | writer.println("\t\t\txmin = " + segment.start_time);
117 | writer.println("\t\t\txmax = " + segment.end_time);
118 | writer.println("\t\t\ttext = \"" + segment.name + "\"");
119 | }
120 | }
121 |
122 | writer.close();
123 |
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/utils/ProgramLauncher.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.utils;
2 |
3 | import java.io.File;
4 | import java.io.FileNotFoundException;
5 | import java.io.FileOutputStream;
6 | import java.io.OutputStream;
7 | import java.util.List;
8 | import java.util.Map;
9 |
10 | import org.apache.commons.exec.CommandLine;
11 | import org.apache.commons.exec.DefaultExecutor;
12 | import org.apache.commons.exec.ExecuteException;
13 | import org.apache.commons.exec.ExecuteResultHandler;
14 | import org.apache.commons.exec.PumpStreamHandler;
15 | import org.apache.commons.exec.environment.EnvironmentUtils;
16 |
17 | public class ProgramLauncher implements Runnable {
18 |
19 | private CommandLine cmd;
20 | private DefaultExecutor exec = new DefaultExecutor();
21 | private OutputStream ostr = System.out;
22 | private OutputStream estr = System.err;
23 | private int retVal = -1;
24 | private boolean suppressOutput = false;
25 | private boolean running = false;
26 | private boolean async = false;
27 | private String addPath = null;
28 | private String lib_env = null;
29 |
30 | public ProgramLauncher(String[] cmd_arr) {
31 | cmd = new CommandLine(cmd_arr[0]);
32 | for (int i = 1; i < cmd_arr.length; i++)
33 | cmd.addArgument(cmd_arr[i]);
34 | }
35 |
36 | public void setLibraries(List libraries) {
37 | lib_env = "LD_LIBRARY_PATH=";
38 | for (File lib : libraries) {
39 | if (lib_env.length() > 0)
40 | lib_env += ";";
41 | lib_env += lib.getAbsolutePath();
42 | }
43 | }
44 |
45 | public void addPath(File path) {
46 | if (addPath != null)
47 | addPath += ";";
48 | addPath += path.getAbsolutePath();
49 | }
50 |
51 | public void setStdoutStream(OutputStream ostr) {
52 | this.ostr = ostr;
53 | }
54 |
55 | public void setStderrStream(OutputStream estr) {
56 | this.estr = estr;
57 | }
58 |
59 | public void setStdoutFile(File stdout) throws FileNotFoundException {
60 | setStdoutStream(new FileOutputStream(stdout));
61 | }
62 |
63 | public void setCwd(File cwd) {
64 | exec.setWorkingDirectory(cwd);
65 | }
66 |
67 | public void setSuppressOutput(boolean suppressOutput) {
68 | this.suppressOutput = suppressOutput;
69 | }
70 |
71 | public void setAsynchronous(boolean async) {
72 | this.async = async;
73 | }
74 |
75 | public void run() {
76 |
77 | running = true;
78 |
79 | try {
80 | if (!suppressOutput) {
81 | PumpStreamHandler stream = new PumpStreamHandler(ostr, estr);
82 | exec.setStreamHandler(stream);
83 | }
84 |
85 | if (lib_env != null || addPath != null) {
86 | @SuppressWarnings("rawtypes")
87 | Map env = EnvironmentUtils.getProcEnvironment();
88 | if (lib_env != null)
89 | EnvironmentUtils.addVariableToEnvironment(env, lib_env);
90 | if (addPath != null) {
91 | String path = (String) env.get("PATH");
92 | if (path == null)
93 | path = (String) env.get("path");
94 | if (path == null)
95 | path = (String) env.get("Path");
96 | if (path == null)
97 | path = "";
98 | if (path.length() > 0 && !path.endsWith(";"))
99 | path += ";";
100 | path = "PATH=" + path + addPath;
101 | EnvironmentUtils.addVariableToEnvironment(env, path);
102 | }
103 |
104 | retVal = 0;
105 |
106 | if (async)
107 | exec.execute(cmd, env, blankHandler);
108 | else
109 | retVal = exec.execute(cmd, env);
110 |
111 | } else {
112 |
113 | retVal = 0;
114 |
115 | if (async)
116 | exec.execute(cmd, blankHandler);
117 | else
118 | retVal = exec.execute(cmd);
119 | }
120 |
121 | } catch (ExecuteException e) {
122 | // ignore
123 | } catch (Exception e) {
124 | Log.error("Running program: " + cmd, e);
125 | }
126 |
127 | running = false;
128 |
129 | }
130 |
131 | public int getReturnValue() {
132 | return retVal;
133 | }
134 |
135 | public boolean isRunning() {
136 | return running;
137 | }
138 |
139 | ExecuteResultHandler blankHandler = new ExecuteResultHandler() {
140 | public void onProcessFailed(ExecuteException e) {
141 | }
142 |
143 | public void onProcessComplete(int exitValue) {
144 | }
145 | };
146 | }
147 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/service/tasks/KeywordSpottingTask.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.service.tasks;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 | import java.io.PrintWriter;
6 | import java.security.MessageDigest;
7 | import java.util.Vector;
8 |
9 | import javax.xml.xpath.XPath;
10 | import javax.xml.xpath.XPathConstants;
11 | import javax.xml.xpath.XPathExpressionException;
12 |
13 | import org.w3c.dom.Element;
14 |
15 | import pl.edu.pjwstk.kaldi.files.TextGrid;
16 | import pl.edu.pjwstk.kaldi.programs.KaldiKWS;
17 | import pl.edu.pjwstk.kaldi.programs.KaldiUtils;
18 | import pl.edu.pjwstk.kaldi.programs.Transcriber;
19 | import pl.edu.pjwstk.kaldi.utils.FileUtils;
20 | import pl.edu.pjwstk.kaldi.utils.Log;
21 | import pl.edu.pjwstk.kaldi.utils.Settings;
22 |
23 | public class KeywordSpottingTask extends Task {
24 |
25 | private File input_keywords;
26 | private File words_table;
27 |
28 | @Override
29 | public void run() {
30 |
31 | state = State.RUNNING;
32 |
33 | try {
34 | File lattice = new File(Settings.curr_task_dir, "aligned_lattice");
35 | File lattice_int = new File(Settings.curr_task_dir, "kws_lattice.int");
36 | File lattice_txt = new File(Settings.curr_task_dir, "kws_lattice.txt");
37 | File kw_clean = new File(Settings.curr_task_dir, "kws_clean_words");
38 | File lat_vocab = new File(Settings.curr_task_dir, "kws_lat_vocab");
39 | File vocab = new File(Settings.curr_task_dir, "kws_vocab");
40 | File dict = new File(Settings.curr_task_dir, "kws_dict");
41 | File kws_out = new File(Settings.curr_task_dir, "kws.txt");
42 | File tg_out = new File(Settings.curr_task_dir, "out.TextGrid");
43 |
44 | if (!lattice.canRead()) {
45 | Log.error("Cannot read lattice for task: " + Settings.curr_task_dir);
46 | Log.error("Keyword spotting HAS to be run after decoding the file first!");
47 | state = State.FAILED;
48 | return;
49 | }
50 |
51 | cleanKeywords(input_keywords, kw_clean, Settings.default_encoding);
52 |
53 | KaldiUtils.lattice_copy("ark", lattice, "ark,t", lattice_int, true);
54 |
55 | KaldiUtils.int2sym("3", words_table, lattice_int, lattice_txt);
56 |
57 | KaldiKWS.get_vocab(lattice_txt, lat_vocab);
58 |
59 | FileUtils.mergeFiles(new File[] { lat_vocab, kw_clean }, vocab, Settings.default_encoding, true);
60 |
61 | FileUtils.sort_uniq(vocab, vocab, Settings.default_encoding);
62 |
63 | Transcriber.transcribe(vocab, Settings.default_encoding, dict, Settings.default_encoding, false);
64 |
65 | KaldiKWS.detect(lattice_txt, kw_clean, dict, kws_out);
66 |
67 | convertKWSToTG(kws_out, tg_out);
68 |
69 | state = State.SUCCEEDED;
70 |
71 | } catch (Exception e) {
72 | Log.error("KWS task.", e);
73 | state = State.FAILED;
74 | }
75 |
76 | }
77 |
78 | private static void cleanKeywords(File input, File output, String encoding) throws IOException {
79 |
80 | Vector keywords = FileUtils.readLines(input, Settings.default_encoding);
81 |
82 | PrintWriter writer = new PrintWriter(output, encoding);
83 |
84 | for (String kw : keywords) {
85 | kw = kw.toLowerCase().trim();
86 |
87 | kw = kw.replaceAll("[-_,]", " ");
88 |
89 | kw = kw.replaceAll("[^\\s\\w\\.ĄĆĘŁŃÓŚŹŻąćęłńóśźż]", "");
90 |
91 | if (kw.isEmpty())
92 | continue;
93 |
94 | String[] kws = kw.split("\\s+");
95 | for (String w : kws)
96 | writer.println(w);
97 | }
98 |
99 | writer.close();
100 |
101 | }
102 |
103 | private static void convertKWSToTG(File kws, File tg) throws IOException {
104 | Vector kw_lines = FileUtils.readLines(kws, Settings.default_encoding);
105 |
106 | TextGrid gridfile = new TextGrid();
107 |
108 | for (String line : kw_lines) {
109 | String[] ss = line.split("\\s+");
110 | double start = Double.parseDouble(ss[1]);
111 | double len = Double.parseDouble(ss[2]);
112 | gridfile.addSegment(0, start, start + len, ss[0] + " <" + ss[3] + ">");
113 | }
114 |
115 | gridfile.write(tg);
116 | }
117 |
118 | @Override
119 | public void loadSettings(XPath xpath, Element node) throws XPathExpressionException {
120 | input_keywords = new File((String) xpath.evaluate("input-keywords", node, XPathConstants.STRING));
121 | words_table = new File((String) xpath.evaluate("words-table", node, XPathConstants.STRING));
122 | }
123 |
124 | @Override
125 | public void updateHash(MessageDigest m) throws IOException {
126 | processFileHash(m, input_keywords);
127 | }
128 |
129 | }
130 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/service/tasks/SpeakerDiarizationTask.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.service.tasks;
2 |
3 | import java.io.File;
4 | import java.io.FileNotFoundException;
5 | import java.io.IOException;
6 | import java.security.MessageDigest;
7 | import java.util.Locale;
8 |
9 | import javax.xml.xpath.XPath;
10 | import javax.xml.xpath.XPathConstants;
11 | import javax.xml.xpath.XPathExpressionException;
12 |
13 | import org.w3c.dom.Element;
14 |
15 | import pl.edu.pjwstk.kaldi.programs.KaldiScripts;
16 | import pl.edu.pjwstk.kaldi.programs.KaldiUtils;
17 | import pl.edu.pjwstk.kaldi.programs.Lium;
18 | import pl.edu.pjwstk.kaldi.programs.Shout;
19 | import pl.edu.pjwstk.kaldi.programs.Sox;
20 | import pl.edu.pjwstk.kaldi.utils.Log;
21 | import pl.edu.pjwstk.kaldi.utils.Settings;
22 |
23 | public class SpeakerDiarizationTask extends Task {
24 |
25 | private static enum Method {
26 | shout, lium
27 | }
28 |
29 | private File input_file;
30 | private Method method;
31 |
32 | private int max_clusters;
33 |
34 | @Override
35 | public void run() {
36 |
37 | state = State.RUNNING;
38 |
39 | if (!input_file.canRead()) {
40 | Log.error("File cannot be read: " + input_file.getAbsolutePath());
41 | state = State.FAILED;
42 | return;
43 | }
44 |
45 | try {
46 |
47 | switch (method) {
48 | case shout:
49 | shout();
50 | break;
51 | case lium:
52 | lium();
53 | break;
54 | default:
55 | Log.info("Speaker diarization method not implemented!");
56 | Log.info("Method: " + method.toString());
57 | break;
58 | }
59 |
60 | state = State.SUCCEEDED;
61 |
62 | } catch (RuntimeException | FileNotFoundException e) {
63 | Log.error("Speaker diarization task.", e);
64 | state = State.FAILED;
65 | }
66 | }
67 |
68 | private void shout() throws RuntimeException, FileNotFoundException {
69 |
70 | File raw_file = new File(Settings.curr_task_dir, "file.raw");
71 | File seg_out = new File(Settings.curr_task_dir, "seg.out");
72 | File out_mo = new File(Settings.curr_task_dir, "out.mo");
73 |
74 | File seg_model = new File(Settings.shout_models, "shout.sad");
75 |
76 | if (!seg_model.canRead()) {
77 | throw new FileNotFoundException(seg_model.getAbsolutePath());
78 | }
79 |
80 | Sox.convert(input_file, raw_file);
81 | Shout.shout_segment(raw_file, seg_model, out_mo);
82 | Shout.shout_cluster(raw_file, seg_out, out_mo, max_clusters);
83 |
84 | }
85 |
86 | private void lium() throws RuntimeException, FileNotFoundException {
87 |
88 | Lium.test();
89 |
90 | Lium.diarize(input_file);
91 | }
92 |
93 | @Override
94 | public void loadSettings(XPath xpath, Element node)
95 | throws XPathExpressionException {
96 |
97 | input_file = new File((String) xpath.evaluate("input-file", node,
98 | XPathConstants.STRING));
99 |
100 | String max_clust_string = (String) xpath.evaluate("max-clusters", node,
101 | XPathConstants.STRING);
102 |
103 | try {
104 | max_clusters = Integer.parseInt(max_clust_string);
105 | } catch (NumberFormatException e) {
106 | throw new XPathExpressionException(e);
107 | }
108 |
109 | String str_method = (String) xpath.evaluate("method", node,
110 | XPathConstants.STRING);
111 |
112 | try {
113 | method = Method.valueOf(str_method);
114 | } catch (IllegalArgumentException e) {
115 | String methods = "";
116 | for (Method m : Method.values())
117 | methods += m.toString() + ",";
118 |
119 | throw new XPathExpressionException(
120 | "Method type unknown! Available methods: " + methods);
121 | }
122 | }
123 |
124 | public static void main(String[] args) {
125 | try {
126 |
127 | Locale.setDefault(Locale.ENGLISH);
128 |
129 | Log.init("SpeakerDiarizationUnitTest", true);
130 |
131 | KaldiUtils.init();
132 | KaldiUtils.test();
133 | KaldiScripts.init();
134 | KaldiScripts.test();
135 | Shout.test();
136 |
137 | SpeakerDiarizationTask task = new SpeakerDiarizationTask();
138 |
139 | Settings.curr_task_dir = new File(Settings.tasks_dir,
140 | "SpeakerDiarizartionUnitTest");
141 |
142 | Settings.curr_task_dir.mkdirs();
143 |
144 | task.input_file = new File("/home/guest/Desktop/TEMP/speaker.wav");
145 | task.method = Method.lium;
146 | task.max_clusters = 5;
147 |
148 | task.run();
149 |
150 | } catch (Exception e) {
151 | Log.error("Error running task.", e);
152 | }
153 | }
154 |
155 | @Override
156 | public void updateHash(MessageDigest m) throws IOException {
157 |
158 | String methodname = method.name();
159 |
160 | m.update(methodname.getBytes(Settings.default_encoding));
161 | processFileHash(m, input_file);
162 |
163 | }
164 | }
165 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/files/Converter.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.files;
2 |
3 | import java.io.File;
4 | import java.io.FileNotFoundException;
5 | import java.util.Locale;
6 |
7 | import javax.xml.parsers.ParserConfigurationException;
8 |
9 | import pl.edu.pjwstk.kaldi.utils.Log;
10 | import pl.edu.pjwstk.kaldi.utils.ParseOptions;
11 |
12 | public class Converter {
13 |
14 | public static enum Format {
15 | CTM, EAF, LAB, RTTM, TextGrid
16 | }
17 |
18 | public static void main(String[] args) {
19 |
20 | Locale.setDefault(Locale.ENGLISH);
21 |
22 | String fmt_str = "";
23 | for (Format fmt : Format.values())
24 | fmt_str += fmt.name() + " ";
25 |
26 | ParseOptions po = new ParseOptions(
27 | "Converter",
28 | "Converts between several file formats.\nSupported formats: "
29 | + fmt_str
30 | + "\nIf no types are given, program tries to guess from the file extenation only!");
31 |
32 | po.addArgument(File.class, "from", "source file");
33 | po.addArgument(File.class, "to", "destination file");
34 |
35 | po.addArgument("from-type", 'f', String.class, "Sets the source type",
36 | null);
37 |
38 | po.addArgument("to-type", 't', String.class, "Sets the source type",
39 | null);
40 |
41 | po.addArgument("rttm-tb", 'r', Double.class,
42 | "Sets the RTTM time-base.", "1.0");
43 |
44 | po.addArgument("tier", 't', Integer.class,
45 | "Use specific tier only, or <0 for all tiers.", "-1");
46 |
47 | if (!po.parse(args))
48 | return;
49 |
50 | try {
51 | Log.init("Converter", true);
52 | } catch (SecurityException | FileNotFoundException e1) {
53 | e1.printStackTrace();
54 | return;
55 | }
56 |
57 | try {
58 |
59 | Format from_fmt, to_fmt;
60 |
61 | String from_str = (String) po.getArgument("from-type");
62 | String to_str = (String) po.getArgument("to-type");
63 | double timebase = (Double) po.getArgument("rttm-tb");
64 | File from_file = (File) po.getArgument(0);
65 | File to_file = (File) po.getArgument(1);
66 |
67 | if (from_str != null) {
68 | try {
69 | from_fmt = Format.valueOf(from_str);
70 | } catch (IllegalArgumentException e) {
71 | throw new RuntimeException("Type " + from_str
72 | + " doesn't exist!");
73 | }
74 | } else {
75 | from_fmt = guessFormat(from_file);
76 | if (from_fmt == null) {
77 | throw new RuntimeException(
78 | "Couldn't guess format for file: "
79 | + from_file.getName()
80 | + "\nEnter it manually!");
81 | }
82 | }
83 |
84 | if (to_str != null) {
85 | try {
86 | to_fmt = Format.valueOf(to_str);
87 | } catch (IllegalArgumentException e) {
88 | throw new RuntimeException("Type " + from_str
89 | + " doesn't exist!");
90 | }
91 | } else {
92 | to_fmt = guessFormat(to_file);
93 | if (to_fmt == null) {
94 | throw new RuntimeException(
95 | "Couldn't guess format for file: "
96 | + to_file.getName()
97 | + "\nEnter it manually!");
98 | }
99 | }
100 |
101 | Log.info("Converting " + from_file.getName() + " ["
102 | + from_fmt.name() + "] -> " + to_file.getName() + " ["
103 | + to_fmt.name() + "] t=" + timebase);
104 |
105 | Segmentation from_seg = fromFmt(from_fmt, timebase);
106 | from_seg.read(from_file);
107 | Segmentation to_seg = fromFmt(to_fmt, timebase);
108 |
109 | int t = (Integer) po.getArgument("tier");
110 | if (t < 0)
111 | to_seg.tiers.addAll(from_seg.tiers);
112 | else
113 | to_seg.tiers.add(from_seg.tiers.get(t));
114 |
115 | to_seg.write(to_file);
116 |
117 | } catch (Exception e) {
118 | Log.error("Main error", e);
119 | }
120 |
121 | }
122 |
123 | private static Format guessFormat(File file) {
124 |
125 | String name = file.getName();
126 | int pos = name.lastIndexOf('.');
127 | if (pos < 0)
128 | return null;
129 |
130 | String ext = name.substring(pos + 1);
131 |
132 | if (ext.equals("TextGrid"))
133 | return Format.TextGrid;
134 |
135 | if (ext.toLowerCase().equals("lab"))
136 | return Format.LAB;
137 |
138 | if (ext.toLowerCase().equals("rttm"))
139 | return Format.RTTM;
140 |
141 | if (ext.toLowerCase().equals("ctm"))
142 | return Format.CTM;
143 |
144 | if (ext.toLowerCase().equals("eaf"))
145 | return Format.EAF;
146 |
147 | return null;
148 | }
149 |
150 | public static Segmentation fromFmt(Format fmt, double timebase)
151 | throws ParserConfigurationException {
152 | switch (fmt) {
153 | case CTM:
154 | return new CTM();
155 | case EAF:
156 | return new EAF();
157 | case LAB:
158 | return new LAB();
159 | case RTTM:
160 | return new RTTM(timebase);
161 | case TextGrid:
162 | return new TextGrid();
163 | default:
164 | return null;
165 | }
166 | }
167 | }
168 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/service/database/dbTasks.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.service.database;
2 |
3 | import java.sql.SQLException;
4 | import java.sql.Timestamp;
5 | import java.text.DateFormat;
6 |
7 | import pl.edu.pjwstk.kaldi.service.database.Database.Pair;
8 |
9 | public class dbTasks {
10 |
11 | public static enum dbStatus {
12 | queued, running, done, dead, copyof
13 | }
14 |
15 | private static DateFormat df = DateFormat.getDateTimeInstance();
16 |
17 | public static class Task {
18 |
19 | public int _id;
20 | public dbStatus status = dbStatus.queued;
21 | public String task_file;
22 | public int pid;
23 | public String hash;
24 | public Timestamp time;
25 | public int login_id;
26 | public String host;
27 | public int copyid;
28 |
29 | public String toString() {
30 | return "(" + _id + ") " + status + " -- " + task_file + " -- "
31 | + pid + " -- " + hash + " -- " + df.format(time) + " -- "
32 | + login_id + " -- " + host;
33 | }
34 | }
35 |
36 | public static Task getOldestQueued() throws RuntimeException {
37 |
38 | try {
39 |
40 | String options = Database.whereAnd(new Pair[] { new Pair("status",
41 | "queued") });
42 | options += " " + Database.order("time", true);
43 | options += " " + Database.limit(1);
44 |
45 | Object[] ret = Database.get(Task.class, options);
46 |
47 | if (ret.length == 0)
48 | return null;
49 | else
50 | return (Task) ret[0];
51 |
52 | } catch (InstantiationException | IllegalAccessException | SQLException
53 | | RuntimeException e) {
54 | throw new RuntimeException(e);
55 | }
56 | }
57 |
58 | public static Task[] getAllRunning() throws RuntimeException {
59 | try {
60 | String options = Database.whereAnd(new Pair[] { new Pair("status",
61 | "running") });
62 | options += " " + Database.order("time", true);
63 |
64 | Object[] obj = Database.get(Task.class, options);
65 |
66 | Task[] ret = new Task[obj.length];
67 | for (int i = 0; i < ret.length; i++)
68 | ret[i] = (Task) obj[i];
69 |
70 | return ret;
71 |
72 | } catch (InstantiationException | IllegalAccessException | SQLException
73 | | RuntimeException e) {
74 | throw new RuntimeException(e);
75 | }
76 | }
77 |
78 | public static void changeStatus(Task task, dbStatus status)
79 | throws RuntimeException {
80 | try {
81 | Database.update("Task", "status", status.name(), "_id", task._id);
82 | } catch (SQLException e) {
83 | throw new RuntimeException(e);
84 | }
85 | }
86 |
87 | public static void changePID(Task task, int pid) throws RuntimeException {
88 | try {
89 | Database.updateInt("Task", "pid", pid, "_id", task._id);
90 | } catch (SQLException e) {
91 | throw new RuntimeException(e);
92 | }
93 | }
94 |
95 | public static void setHash(Task task, String hash) throws RuntimeException {
96 | try {
97 | Database.update("Task", "hash", hash, "_id", task._id);
98 | } catch (SQLException e) {
99 | throw new RuntimeException(e);
100 | }
101 |
102 | }
103 |
104 | public static void setCopy(Task task, int copy) throws RuntimeException {
105 | try {
106 | Database.updateInt("Task", "copyid", copy, "_id", task._id);
107 | } catch (SQLException e) {
108 | throw new RuntimeException(e);
109 | }
110 |
111 | }
112 |
113 | public static Task getByHash(String hash) throws RuntimeException {
114 | try {
115 |
116 | String options = Database
117 | .whereAnd(new Pair[] { new Pair("status", "copyof", true),
118 | new Pair("status", "dead",true),
119 | new Pair("hash", hash) });
120 | options += " " + Database.order("time", true);
121 | options += " " + Database.limit(1);
122 |
123 | Object[] ret = Database.get(Task.class, options);
124 |
125 | if (ret.length == 0)
126 | return null;
127 | else
128 | return (Task) ret[0];
129 |
130 | } catch (InstantiationException | IllegalAccessException | SQLException
131 | | RuntimeException e) {
132 | throw new RuntimeException(e);
133 | }
134 | }
135 |
136 | public static Task getByID(int id) throws RuntimeException {
137 | try {
138 |
139 | String options = Database.whereAnd(new Pair[] { new Pair("_id", ""
140 | + id, false, false) });
141 |
142 | Object[] ret = Database.get(Task.class, options);
143 |
144 | if (ret.length == 0)
145 | return null;
146 | else
147 | return (Task) ret[0];
148 |
149 | } catch (InstantiationException | IllegalAccessException | SQLException
150 | | RuntimeException e) {
151 | throw new RuntimeException(e);
152 | }
153 | }
154 |
155 | public static void main(String[] args) {
156 |
157 | try {
158 | Task t = getOldestQueued();
159 | System.out.println("1>" + t);
160 |
161 | Task[] t2 = getAllRunning();
162 | for (Task t3 : t2) {
163 | System.out.println("2>" + t3);
164 | }
165 |
166 | } catch (Exception e) {
167 | e.printStackTrace();
168 | }
169 | }
170 | }
171 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/programs/Julius.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.programs;
2 |
3 | import java.io.File;
4 | import java.io.FileNotFoundException;
5 | import java.io.IOException;
6 | import java.util.Locale;
7 | import java.util.Vector;
8 |
9 | import pl.edu.pjwstk.kaldi.files.Segmentation;
10 | import pl.edu.pjwstk.kaldi.files.TextGrid;
11 | import pl.edu.pjwstk.kaldi.files.julius.JuliusOutput;
12 | import pl.edu.pjwstk.kaldi.utils.FileUtils;
13 | import pl.edu.pjwstk.kaldi.utils.Log;
14 | import pl.edu.pjwstk.kaldi.utils.ProgramLauncher;
15 | import pl.edu.pjwstk.kaldi.utils.Settings;
16 |
17 | public class Julius {
18 |
19 | public static void test() throws FileNotFoundException {
20 | if (!Settings.julius_bin.exists())
21 | throw new FileNotFoundException(Settings.julius_bin.getAbsolutePath());
22 | if (!Settings.julius_mklm_bin.exists())
23 | throw new FileNotFoundException(Settings.julius_mklm_bin.getAbsolutePath());
24 | // TODO: check config files, etc...
25 | }
26 |
27 | public static void julius(File conf, File filelist, File dic, File binlm) throws RuntimeException {
28 |
29 | String[] cmd = new String[] { Settings.julius_bin.getAbsolutePath(), "-C", conf.getAbsolutePath(), "-filelist",
30 | filelist.getAbsolutePath(), "-v", dic.getAbsolutePath(), "-d", binlm.getAbsolutePath() };
31 |
32 | ProgramLauncher launcher = new ProgramLauncher(cmd);
33 | launcher.setStdoutStream(new Log.Stream());
34 | launcher.setStderrStream(new Log.Stream("ERR>>"));
35 |
36 | Log.verbose("julius: " + filelist.getName());
37 | launcher.run();
38 | Log.verbose("Done.");
39 |
40 | if (launcher.getReturnValue() != 0)
41 | throw new RuntimeException("Retval: " + launcher.getReturnValue());
42 | }
43 |
44 | public static void mkbingram(File model_bkwd, File binlm) throws RuntimeException {
45 | String[] cmd = new String[] { Settings.julius_mklm_bin.getAbsolutePath(), "-nrl", model_bkwd.getAbsolutePath(),
46 | binlm.getAbsolutePath() };
47 |
48 | ProgramLauncher launcher = new ProgramLauncher(cmd);
49 | launcher.setStdoutStream(new Log.Stream());
50 | launcher.setStderrStream(new Log.Stream("ERR>>"));
51 |
52 | Log.verbose("mkbingram: " + model_bkwd.getName() + " -> " + binlm.getName());
53 | launcher.run();
54 | Log.verbose("Done.");
55 |
56 | if (launcher.getReturnValue() != 0)
57 | throw new RuntimeException("Retval: " + launcher.getReturnValue());
58 | }
59 |
60 | public static Segmentation align(File sound, File text) throws IOException, RuntimeException {
61 |
62 | File files[] = new File[] { sound };
63 | File conf = new File("julius_model/julius.jconf");
64 |
65 | File scp = new File(Settings.temp_dir, "julius.scp");
66 | File vocab = new File(Settings.temp_dir, "julius.voc");
67 | File dict = new File(Settings.temp_dir, "julius.dic");
68 | File model = new File(Settings.temp_dir, "julius.lm");
69 | File text_b = new File(Settings.temp_dir, "julius_rev.txt");
70 | File binlm = new File(Settings.temp_dir, "julius.jlm");
71 |
72 | // FileUtils.makeVocab(text, vocab);
73 |
74 | FileUtils.reverse(text, text_b);
75 |
76 | NGram.srilm_estimate(text_b, vocab, model, 3);
77 |
78 | mkbingram(model, binlm);
79 |
80 | Transcriber.transcribe(vocab, Settings.default_encoding, dict, Settings.default_encoding, true);
81 | FileUtils.makeSCPFile(scp, files, false);
82 |
83 | Log.verbose("Running julius...");
84 | julius(conf, scp, dict, binlm);
85 |
86 | Log.verbose("Parsing julius output...");
87 | String soundname = sound.getAbsolutePath();
88 | soundname = soundname.substring(0, soundname.lastIndexOf('.'));
89 | File outfile = new File(soundname + ".out");
90 | Vector julouts = null;
91 |
92 | julouts = JuliusOutput.loadFromJulius(outfile);
93 |
94 | if (julouts.isEmpty())
95 | throw new RuntimeException("Julius didn't provide any outputs!");
96 |
97 | Segmentation ret = julouts.get(0).aligned.toSegmentation(Settings.julius_win_offset);
98 |
99 | for (int i = 1; i < julouts.size(); i++) {
100 | double offset = ret.tiers.get(0).max();
101 | ret.appendSegmenation(julouts.get(i).aligned.toSegmentation(Settings.julius_win_offset), offset);
102 | }
103 |
104 | return ret;
105 | }
106 |
107 | /**
108 | * Unit tests.
109 | *
110 | * @param args
111 | */
112 | public static void main(String[] args) {
113 | try {
114 |
115 | Locale.setDefault(Locale.ENGLISH);
116 |
117 | Log.init("JuliusUnitTest", false);
118 |
119 | Transcriber.init();
120 | Transcriber.test();
121 |
122 | Segmentation seg = align(new File("/home/guest/Desktop/Respeaking/test/kopacz.wav"),
123 | new File("/home/guest/Desktop/Respeaking/test/kopacz.txt"));
124 |
125 | TextGrid grid = new TextGrid(seg);
126 |
127 | grid.write(new File("/home/guest/Desktop/Respeaking/test/out.TextGrid"));
128 |
129 | Log.info("Julius Test complete!");
130 |
131 | } catch (Exception e) {
132 | e.printStackTrace();
133 | }
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/service/tasks/Task.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.service.tasks;
2 |
3 | import java.io.File;
4 | import java.io.FileInputStream;
5 | import java.io.IOException;
6 | import java.math.BigInteger;
7 | import java.nio.ByteBuffer;
8 | import java.nio.channels.FileChannel;
9 | import java.security.MessageDigest;
10 | import java.security.NoSuchAlgorithmException;
11 |
12 | import javax.xml.parsers.DocumentBuilderFactory;
13 | import javax.xml.parsers.ParserConfigurationException;
14 | import javax.xml.xpath.XPath;
15 | import javax.xml.xpath.XPathConstants;
16 | import javax.xml.xpath.XPathExpressionException;
17 | import javax.xml.xpath.XPathFactory;
18 |
19 | import org.w3c.dom.Document;
20 | import org.w3c.dom.Element;
21 | import org.w3c.dom.NodeList;
22 | import org.xml.sax.SAXException;
23 |
24 | import pl.edu.pjwstk.kaldi.utils.Log;
25 | import pl.edu.pjwstk.kaldi.utils.Settings;
26 |
27 | public abstract class Task implements Runnable {
28 |
29 | public static enum State {
30 | INITIALIZED, RUNNING, FAILED, SUCCEEDED
31 | }
32 |
33 | public State state = State.INITIALIZED;
34 |
35 | public abstract void loadSettings(XPath xpath, Element node) throws XPathExpressionException;
36 |
37 | public abstract void updateHash(MessageDigest m) throws IOException;
38 |
39 | protected static Task getTask(String name) {
40 |
41 | if (name.equals("test")) {
42 | return new TestTask();
43 | }
44 |
45 | if (name.equals("decode")) {
46 | return new DecodeTask();
47 | }
48 |
49 | if (name.equals("align")) {
50 | return new AlignTask();
51 | }
52 |
53 | if (name.equals("speaker-diarization")) {
54 | return new SpeakerDiarizationTask();
55 | }
56 |
57 | if (name.equals("convert-encoding")) {
58 | return new ConvertEncodingTask();
59 | }
60 |
61 | if (name.equals("nser")) {
62 | return new NSERTask();
63 | }
64 |
65 | if (name.equals("kws")) {
66 | return new KeywordSpottingTask();
67 | }
68 |
69 | Log.error("Unknown task: " + name);
70 | return null;
71 | }
72 |
73 | public static void run(File task_config)
74 | throws SAXException, IOException, ParserConfigurationException, XPathExpressionException, RuntimeException {
75 |
76 | Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(task_config);
77 |
78 | XPath xpath = XPathFactory.newInstance().newXPath();
79 |
80 | NodeList tasks = (NodeList) xpath.evaluate("/tasks/task", doc, XPathConstants.NODESET);
81 |
82 | for (int i = 0; i < tasks.getLength(); i++) {
83 | Element elTask = (Element) tasks.item(i);
84 |
85 | String name = elTask.getAttribute("name");
86 |
87 | Task task = getTask(name);
88 |
89 | task.loadSettings(xpath, elTask);
90 |
91 | task.run();
92 |
93 | if (task.state != State.SUCCEEDED) {
94 | throw new RuntimeException("Failed to complete task!");
95 | }
96 | }
97 | }
98 |
99 | public static String getHash(File task_config) throws SAXException, IOException, ParserConfigurationException,
100 | XPathExpressionException, NoSuchAlgorithmException {
101 | Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(task_config);
102 |
103 | XPath xpath = XPathFactory.newInstance().newXPath();
104 |
105 | NodeList tasks = (NodeList) xpath.evaluate("/tasks/task", doc, XPathConstants.NODESET);
106 |
107 | MessageDigest m = MessageDigest.getInstance("MD5");
108 |
109 | for (int i = 0; i < tasks.getLength(); i++) {
110 | Element elTask = (Element) tasks.item(i);
111 |
112 | String name = elTask.getAttribute("name");
113 |
114 | Task task = getTask(name);
115 |
116 | if (task == null)
117 | continue;
118 |
119 | m.update(name.getBytes(Settings.default_encoding));
120 |
121 | task.loadSettings(xpath, elTask);
122 |
123 | try {
124 | task.updateHash(m);
125 | } catch (IOException e) {
126 | // IGNORE MISSING FILES IN TASKS THAT HAVEN'T CREATED THEM
127 | // YET...
128 | }
129 | }
130 |
131 | byte[] d = m.digest();
132 | BigInteger bigInt = new BigInteger(1, d);
133 | String hashstr = bigInt.toString(16);
134 | while (hashstr.length() < 32) {
135 | hashstr = "0" + hashstr;
136 | }
137 |
138 | return hashstr;
139 | }
140 |
141 | protected static void processFileHash(MessageDigest m, File f) throws IOException {
142 |
143 | FileInputStream stream = new FileInputStream(f);
144 | FileChannel chan = stream.getChannel();
145 |
146 | ByteBuffer bb = ByteBuffer.allocate(512);
147 |
148 | while (true) {
149 | int ret = chan.read(bb);
150 | if (ret < 0)
151 | break;
152 | m.update(bb);
153 | bb.rewind();
154 | }
155 |
156 | chan.close();
157 | stream.close();
158 | }
159 |
160 | public static void main(String[] args) {
161 | try {
162 | System.out.println(getHash(new File("/var/www/html/mowa/tasks/task_20150501_225120/config.xml")));
163 | } catch (XPathExpressionException | NoSuchAlgorithmException | SAXException | IOException
164 | | ParserConfigurationException e) {
165 | e.printStackTrace();
166 | }
167 | }
168 | }
169 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/programs/Praat.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.programs;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.File;
5 | import java.io.FileReader;
6 | import java.io.IOException;
7 | import java.io.PrintWriter;
8 | import java.util.Vector;
9 |
10 | import javax.xml.parsers.DocumentBuilderFactory;
11 | import javax.xml.parsers.ParserConfigurationException;
12 | import javax.xml.transform.OutputKeys;
13 | import javax.xml.transform.Result;
14 | import javax.xml.transform.Source;
15 | import javax.xml.transform.Transformer;
16 | import javax.xml.transform.TransformerException;
17 | import javax.xml.transform.TransformerFactory;
18 | import javax.xml.transform.TransformerFactoryConfigurationError;
19 | import javax.xml.transform.dom.DOMSource;
20 | import javax.xml.transform.stream.StreamResult;
21 |
22 | import org.w3c.dom.Document;
23 | import org.w3c.dom.Element;
24 |
25 | import pl.edu.pjwstk.kaldi.utils.Log;
26 | import pl.edu.pjwstk.kaldi.utils.ProgramLauncher;
27 | import pl.edu.pjwstk.kaldi.utils.Settings;
28 |
29 | public class Praat {
30 |
31 | public static class PitchMark {
32 | public double time;
33 | public double intensity;
34 | public double frequency;
35 | public double strength;
36 | }
37 |
38 | public static Vector pitch(File wav_file, File pitch_file,
39 | File pitch_wav) throws IOException {
40 |
41 | File script = new File("pitch.script");
42 | PrintWriter writer = new PrintWriter(script);
43 |
44 | writer.println("Read from file: \"" + wav_file.getAbsolutePath() + "\"");
45 | writer.println("To Pitch: 0, 75, 600");
46 | writer.println("Save as short text file: \""
47 | + pitch_file.getAbsolutePath() + "\"");
48 | writer.println("To Sound (hum)");
49 | writer.println("Save as WAV file: \"" + pitch_wav.getAbsolutePath()
50 | + "\"");
51 |
52 | writer.close();
53 |
54 | String[] cmd = new String[] { Settings.praat_bin.getAbsolutePath(),
55 | script.getAbsolutePath() };
56 |
57 | ProgramLauncher launcher = new ProgramLauncher(cmd);
58 |
59 | Log.verbose("Running Praat to compute pitch...");
60 | launcher.run();
61 | Log.verbose("Done.");
62 |
63 | Vector ret = new Vector();
64 |
65 | BufferedReader reader = new BufferedReader(new FileReader(pitch_file));
66 |
67 | int num, numc;
68 | double dx, x1;
69 |
70 | String line;
71 |
72 | reader.readLine();// header line #1
73 | reader.readLine();// header line #2
74 | reader.readLine();// empty line
75 | reader.readLine();// min time
76 | reader.readLine();// max time
77 |
78 | line = reader.readLine();// marks num
79 | num = Integer.parseInt(line);
80 |
81 | line = reader.readLine();// dx
82 | dx = Double.parseDouble(line);
83 |
84 | line = reader.readLine();// x1
85 | x1 = Double.parseDouble(line);
86 |
87 | reader.readLine();// max freq
88 | reader.readLine();// max n candidates
89 |
90 | for (int i = 0; i < num; i++) {
91 | PitchMark mark = new PitchMark();
92 |
93 | mark.time = i * dx + x1;
94 |
95 | line = reader.readLine();// intensity
96 |
97 | mark.intensity = Double.parseDouble(line);
98 |
99 | line = reader.readLine();// num candidates
100 | numc = Integer.parseInt(line);
101 |
102 | if (numc == 0)
103 | continue;
104 |
105 | line = reader.readLine();// frequency
106 | mark.frequency = Double.parseDouble(line);
107 |
108 | line = reader.readLine();// strength
109 | mark.strength = Double.parseDouble(line);
110 |
111 | for (int j = 1; j < numc; j++) {
112 | reader.readLine();// frequency
113 | reader.readLine();// strength
114 | }
115 |
116 | ret.add(mark);
117 | }
118 |
119 | reader.close();
120 |
121 | return ret;
122 | }
123 |
124 | public static void savePitchMarksToXML(String audio_id,
125 | Vector pitch, File xml)
126 | throws TransformerFactoryConfigurationError,
127 | ParserConfigurationException, TransformerException {
128 |
129 | Document doc = DocumentBuilderFactory.newInstance()
130 | .newDocumentBuilder().newDocument();
131 |
132 | Element elRoot = doc.createElement("audio-segment");
133 | elRoot.setAttribute("id", audio_id);
134 | doc.appendChild(elRoot);
135 |
136 | for (PitchMark p : pitch) {
137 | Element elPitch = doc.createElement("pitch");
138 | elPitch.setAttribute("t", String.format("%2.3f", p.time));
139 | elPitch.setAttribute("i", String.format("%2.3f", p.intensity));
140 | elPitch.setAttribute("c", String.format("%2.3f", p.strength));
141 | elPitch.setTextContent(String.format("%2.3f", p.frequency));
142 | elRoot.appendChild(elPitch);
143 | }
144 |
145 | Transformer trans = TransformerFactory.newInstance().newTransformer();
146 |
147 | trans.setOutputProperty("{http://xml.apache.org/xslt}indent-amount",
148 | "4");
149 | trans.setOutputProperty(OutputKeys.METHOD, "xml");
150 | trans.setOutputProperty(OutputKeys.INDENT, "yes");
151 |
152 | Source source = new DOMSource(doc);
153 | Result result = new StreamResult(xml);
154 | trans.transform(source, result);
155 | }
156 |
157 | }
158 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/service/tasks/DecodeTask.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.service.tasks;
2 |
3 | import java.io.File;
4 | import java.io.IOException;
5 | import java.security.MessageDigest;
6 |
7 | import javax.xml.xpath.XPath;
8 | import javax.xml.xpath.XPathConstants;
9 | import javax.xml.xpath.XPathExpressionException;
10 |
11 | import org.w3c.dom.Element;
12 |
13 | import pl.edu.pjwstk.kaldi.files.CTM;
14 | import pl.edu.pjwstk.kaldi.files.TextGrid;
15 | import pl.edu.pjwstk.kaldi.programs.KaldiUtils;
16 | import pl.edu.pjwstk.kaldi.utils.FileUtils;
17 | import pl.edu.pjwstk.kaldi.utils.Log;
18 | import pl.edu.pjwstk.kaldi.utils.Settings;
19 |
20 | public class DecodeTask extends Task {
21 |
22 | private File input_file;
23 | private File mfcc_config;
24 | private File mdl_file;
25 | private File hclg_file;
26 | private File words_table;
27 | private File phones_table;
28 | private File word_boundaries;
29 |
30 | private File lda_matrix = null;
31 |
32 | @Override
33 | public void run() {
34 |
35 | state = State.RUNNING;
36 |
37 | boolean fail = false;
38 | File files[] = { input_file, mfcc_config, mdl_file, hclg_file, words_table, phones_table, word_boundaries,
39 | lda_matrix };
40 | for (File f : files)
41 | if (f != null && !f.exists()) {
42 | Log.error("Missing file: " + f.getAbsolutePath());
43 | fail = true;
44 | }
45 |
46 | if (fail) {
47 | Log.error("Some files are missing!");
48 | state = State.FAILED;
49 | return;
50 | }
51 |
52 | File scp_file = new File(Settings.curr_task_dir, "wav.scp");
53 | File mfcc = new File(Settings.curr_task_dir, "mfcc");
54 | File cmvn_stats = new File(Settings.curr_task_dir, "cmvn_stats");
55 | File cmvn = new File(Settings.curr_task_dir, "cmvn");
56 | File deltas = new File(Settings.curr_task_dir, "deltas");
57 | File splice = new File(Settings.curr_task_dir, "splice");
58 | File trans = new File(Settings.curr_task_dir, "trans");
59 | File lattice = new File(Settings.curr_task_dir, "lattice");
60 | File words = new File(Settings.curr_task_dir, "words");
61 | File alignment = new File(Settings.curr_task_dir, "alignment");
62 | File words_int = new File(Settings.curr_task_dir, "words.int");
63 | File words_txt = new File(Settings.curr_task_dir, "words.txt");
64 | File aligned_lattice = new File(Settings.curr_task_dir, "aligned_lattice");
65 | File ctm_int = new File(Settings.curr_task_dir, "ctm.int");
66 | File ctm_txt = new File(Settings.curr_task_dir, "ctm.txt");
67 | File tg_out = new File(Settings.curr_task_dir, "out.TextGrid");
68 |
69 | try {
70 |
71 | FileUtils.makeSCPFile(scp_file, new File[] { input_file }, true);
72 |
73 | KaldiUtils.compute_mfcc_feats(mfcc_config, scp_file, mfcc);
74 |
75 | KaldiUtils.compute_cmvn_stats(mfcc, cmvn_stats);
76 |
77 | KaldiUtils.apply_cmvn(cmvn_stats, mfcc, cmvn);
78 |
79 | File data;
80 |
81 | if (lda_matrix != null) {
82 |
83 | KaldiUtils.splice_feats(cmvn, splice);
84 |
85 | KaldiUtils.transform_feats(lda_matrix, false, splice, trans);
86 |
87 | data = trans;
88 |
89 | } else {
90 |
91 | KaldiUtils.add_deltas(cmvn, deltas);
92 |
93 | data = deltas;
94 | }
95 |
96 | KaldiUtils.gmm_latgen_faster(mdl_file, hclg_file, data, lattice, words, alignment);
97 |
98 | KaldiUtils.copy_int_vector("ark", words, "ark,t", words_int);
99 |
100 | KaldiUtils.int2sym("2-", words_table, words_int, words_txt);
101 |
102 | KaldiUtils.lattice_align_words(word_boundaries, mdl_file, lattice, aligned_lattice);
103 |
104 | KaldiUtils.lattice_to_ctm_conf(aligned_lattice, ctm_int);
105 |
106 | KaldiUtils.int2sym("5", words_table, ctm_int, ctm_txt);
107 |
108 | CTM ctm = new CTM();
109 |
110 | ctm.read(ctm_txt);
111 |
112 | TextGrid tg = new TextGrid(ctm);
113 |
114 | tg.write(tg_out);
115 |
116 | state = State.SUCCEEDED;
117 |
118 | } catch (Exception e) {
119 | Log.error("Decoding task.", e);
120 | state = State.FAILED;
121 | }
122 | }
123 |
124 | @Override
125 | public void loadSettings(XPath xpath, Element node) throws XPathExpressionException {
126 |
127 | input_file = new File((String) xpath.evaluate("input-file", node, XPathConstants.STRING));
128 | mfcc_config = new File((String) xpath.evaluate("mfcc-config", node, XPathConstants.STRING));
129 | mdl_file = new File((String) xpath.evaluate("mdl", node, XPathConstants.STRING));
130 | hclg_file = new File((String) xpath.evaluate("hclg", node, XPathConstants.STRING));
131 | words_table = new File((String) xpath.evaluate("words-table", node, XPathConstants.STRING));
132 | phones_table = new File((String) xpath.evaluate("phones-table", node, XPathConstants.STRING));
133 | word_boundaries = new File((String) xpath.evaluate("word-boundaries", node, XPathConstants.STRING));
134 |
135 | String str = (String) xpath.evaluate("lda-matrix", node, XPathConstants.STRING);
136 | if (str != null && !str.isEmpty())
137 | lda_matrix = new File(str);
138 |
139 | }
140 |
141 | @Override
142 | public void updateHash(MessageDigest m) throws IOException {
143 | processFileHash(m, input_file);
144 | }
145 |
146 | }
147 |
--------------------------------------------------------------------------------
/src/main/java/pl/edu/pjwstk/kaldi/files/julius/WordGraph.java:
--------------------------------------------------------------------------------
1 | package pl.edu.pjwstk.kaldi.files.julius;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 | import java.util.Stack;
6 | import java.util.Vector;
7 |
8 | import pl.edu.pjwstk.kaldi.utils.Log;
9 |
10 | public class WordGraph {
11 |
12 | public Map lattice;
13 | public Map