-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #52 from pastore99/revert-51-merging-43-44-46
Revert "Merging 43 44 46"
- Loading branch information
Showing
9 changed files
with
516 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
package controller; | ||
|
||
import com.google.gson.Gson; | ||
import com.google.gson.reflect.TypeToken; | ||
import info.debatty.java.stringsimilarity.Levenshtein; | ||
import model.entity.ExerciseGlossary; | ||
import model.service.exercise.ExerciseManager; | ||
import model.service.exercise.SpeechRecognition; | ||
|
||
import javax.servlet.ServletException; | ||
import javax.servlet.annotation.MultipartConfig; | ||
import javax.servlet.annotation.WebServlet; | ||
import javax.servlet.http.*; | ||
import java.io.*; | ||
import java.lang.reflect.Type; | ||
import java.sql.Blob; | ||
import java.sql.Date; | ||
import java.sql.SQLException; | ||
import java.util.Map; | ||
import java.util.Set; | ||
import java.util.concurrent.ExecutionException; | ||
|
||
|
||
@WebServlet("/exerciseEvaluator") | ||
@MultipartConfig | ||
public class ExerciseEvaluator extends HttpServlet { | ||
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { | ||
HttpSession s = request.getSession(); | ||
String contentType = request.getContentType(); | ||
ExerciseManager em = new ExerciseManager(); | ||
|
||
int exerciseId = (int) s.getAttribute("exerciseID"); | ||
int userId = (int) s.getAttribute("id"); | ||
Date d = (Date) s.getAttribute("insertDate"); | ||
|
||
int score; | ||
|
||
if ("application/json".equals(contentType)) { | ||
score = evaluateNoAudio(exerciseId, userId, d); | ||
} else { | ||
try { | ||
score = evaluateAudio(exerciseId, userId, d); | ||
} catch (ExecutionException | InterruptedException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
em.saveEvaluation(userId, exerciseId, d, score); | ||
} | ||
|
||
|
||
private int evaluateNoAudio(int exerciseId, int userId, Date date){ | ||
Gson gson = new Gson(); | ||
|
||
ExerciseGlossary baseExercise = new ExerciseManager().getExercise(exerciseId); | ||
String executionJSON = getJSONfromBlob(exerciseId, userId, date); | ||
String type = baseExercise.getType(); | ||
|
||
int score; | ||
|
||
switch (type) { | ||
case "CROSSWORD" -> { | ||
String[][] solution = gson.fromJson(baseExercise.getSolution(), String[][].class); | ||
String[][] execution = gson.fromJson(executionJSON, String[][].class); | ||
|
||
score = evaluateCrossword(execution, solution); | ||
} | ||
case "IMAGESTOTEXT", "TEXTTOIMAGES" -> { | ||
Type solutionType = new TypeToken<Map<String, String>>() {}.getType(); | ||
Map<String, String> solution = gson.fromJson(baseExercise.getSolution(), solutionType); | ||
Map<String, String> execution = gson.fromJson(executionJSON, solutionType); | ||
|
||
score = evaluateITTnTTI(execution, solution); | ||
} | ||
case "RIGHTTEXT" -> { | ||
Type solutionType = new TypeToken<Set<String>>(){}.getType(); | ||
Set<String> solution = gson.fromJson(baseExercise.getSolution(), solutionType); | ||
Set<String> execution = gson.fromJson(executionJSON, solutionType); | ||
|
||
score = evaluateRightText(execution, solution); | ||
} | ||
default -> throw new IllegalStateException("Unexpected value: " + type); | ||
} | ||
|
||
return score; | ||
} | ||
|
||
private String getJSONfromBlob(int exerciseId, int userId, Date d){ | ||
Blob executionBlob = new ExerciseManager().getExecution(exerciseId, userId, d); | ||
StringBuilder stringBuilder = new StringBuilder(); | ||
|
||
try (InputStream binaryStream = executionBlob.getBinaryStream(); | ||
InputStreamReader inputStreamReader = new InputStreamReader(binaryStream); | ||
BufferedReader bufferedReader = new BufferedReader(inputStreamReader)) { | ||
|
||
String line; | ||
while ((line = bufferedReader.readLine()) != null) { | ||
stringBuilder.append(line); | ||
} | ||
|
||
} catch (SQLException | IOException e) { | ||
e.printStackTrace(); | ||
} | ||
|
||
return stringBuilder.toString(); | ||
} | ||
|
||
private int evaluateRightText(Set<String> execution, Set<String> solution) { | ||
double right = 0; | ||
int total = solution.size(); | ||
for (String s : solution) { | ||
if (execution.contains(s.toUpperCase())){ | ||
right++; | ||
} | ||
} | ||
return (int)((right /total)*100); | ||
} | ||
|
||
private int evaluateITTnTTI(Map<String, String> execution, Map<String, String> solution) { | ||
double right = 0; | ||
int total = solution.size(); | ||
|
||
for (Map.Entry<String, String> entry : execution.entrySet()) { | ||
String k = entry.getKey(); | ||
String executionValue = entry.getValue(); | ||
String solutionValue = solution.get(k); | ||
|
||
if (executionValue != null) { | ||
if (executionValue.equals(solutionValue.toUpperCase())) { | ||
right++; | ||
} | ||
} | ||
} | ||
return (int)((right /total)*100); | ||
} | ||
|
||
private int evaluateCrossword(String[][] execution, String[][] solution) { | ||
double right = 0; | ||
int total = 0; | ||
|
||
for (int i = 0; i < execution.length; i++) { | ||
for (int j = 0; j < execution[0].length; j++) { | ||
if (!execution[i][j].equals("#")){ | ||
if (execution[i][j].equals(solution[i][j].toUpperCase())) { | ||
right++; | ||
} | ||
total++; | ||
} | ||
} | ||
} | ||
return (int)((right /total)*100); | ||
} | ||
|
||
private int evaluateAudio(int exerciseId, int userId, Date d) throws IOException, ExecutionException, InterruptedException { | ||
SpeechRecognition s = new SpeechRecognition(); | ||
Levenshtein l = new Levenshtein(); | ||
Gson g = new Gson(); | ||
ExerciseGlossary baseExercise = new ExerciseManager().getExercise(exerciseId); | ||
String solution = g.fromJson(baseExercise.getInitialState(), String.class); | ||
|
||
InputStream audioExecution = getAudiofromBlob(exerciseId, userId, d); | ||
String audioText = null; | ||
if (audioExecution!=null){ | ||
audioText = s.azureSTT(audioExecution); | ||
} | ||
System.out.println(audioText); | ||
System.out.println("\n"+solution); | ||
|
||
if(audioText != null){ | ||
double distance = l.distance(solution, audioText); | ||
double result = ((solution.length()-distance)/solution.length())*100; | ||
return (int) Math.round(result); | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
private InputStream getAudiofromBlob(int exerciseId, int userId, Date d){ | ||
Blob executionBlob = new ExerciseManager().getExecution(exerciseId, userId, d); | ||
try (InputStream audioInputStream = executionBlob.getBinaryStream()) { | ||
return audioInputStream; | ||
} catch (SQLException | IOException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
package model.service.exercise; | ||
|
||
import com.microsoft.cognitiveservices.speech.*; | ||
import com.microsoft.cognitiveservices.speech.audio.AudioConfig; | ||
import java.io.*; | ||
import java.nio.file.*; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
import java.util.Properties; | ||
import java.util.concurrent.ExecutionException; | ||
import java.util.concurrent.Future; | ||
|
||
|
||
public class SpeechRecognition { | ||
private static final String AZURE_PROPERTIES = "/azure.properties"; | ||
private static String speechKey; | ||
private static String speechRegion; | ||
|
||
public SpeechRecognition(){ | ||
Properties azureProps = loadProps(); | ||
speechRegion = azureProps.getProperty("azure.region"); | ||
speechKey = azureProps.getProperty("azure.key"); | ||
} | ||
|
||
|
||
public String azureSTT(InputStream audio) throws InterruptedException, ExecutionException, IOException { | ||
SpeechConfig speechConfig = SpeechConfig.fromSubscription(speechKey, speechRegion); | ||
speechConfig.setSpeechRecognitionLanguage("it-It"); | ||
|
||
AudioConfig audioConfig = AudioConfig.fromWavFileInput(generateFile(audio)); | ||
SpeechRecognizer speechRecognizer = new SpeechRecognizer(speechConfig, audioConfig); | ||
|
||
Future<SpeechRecognitionResult> task = speechRecognizer.recognizeOnceAsync(); | ||
SpeechRecognitionResult speechRecognitionResult = task.get(); | ||
|
||
String result = null; | ||
|
||
if (speechRecognitionResult.getReason() == ResultReason.RecognizedSpeech) { | ||
result = ("RECOGNIZED: Text= " + speechRecognitionResult.getText()); | ||
} | ||
else if (speechRecognitionResult.getReason() == ResultReason.NoMatch) { | ||
result = ("NOMATCH: Speech could not be recognized."); | ||
} | ||
return result; | ||
} | ||
|
||
public String generateFile(InputStream inputAudio) throws IOException { | ||
//Crea temporaneamente il file creato dal DB | ||
File tempFile = File.createTempFile("tempAudio", ".opus"); | ||
try (FileOutputStream fos = new FileOutputStream(tempFile)) { | ||
byte[] buffer = new byte[1024]; | ||
int bytesRead; | ||
while ((bytesRead = inputAudio.read(buffer)) != -1) { | ||
fos.write(buffer, 0, bytesRead); | ||
} | ||
} | ||
//Ottieni il path dell'output basandoti sul file creato | ||
Path outputPath = Paths.get(tempFile.getPath()).getParent(); | ||
String path = outputPath.toString() + "\\outputJava.wav"; | ||
|
||
//Controlla che non esista già un file | ||
try { | ||
// Use the delete method from Files class to delete the file | ||
Files.delete(Paths.get(path)); | ||
} catch (IOException e) { | ||
System.err.println("Error deleting the file: " + e.getMessage()); | ||
} | ||
|
||
|
||
List<String> command = Arrays.asList( | ||
"ffmpeg", | ||
"-i", tempFile.getPath(), | ||
"-ar", "16000", | ||
"-ac", "1", | ||
"-acodec", "pcm_s16le", | ||
path | ||
); | ||
|
||
try { | ||
ProcessBuilder processBuilder = new ProcessBuilder(command); | ||
Process process = processBuilder.start(); | ||
|
||
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); | ||
String line; | ||
while ((line = reader.readLine()) != null) { | ||
System.out.println(line); | ||
} | ||
int exitCode = process.waitFor(); | ||
if(exitCode != 0){ | ||
System.err.println("\nExited with error code : " + exitCode); | ||
} | ||
} catch (IOException | InterruptedException e) { | ||
e.printStackTrace(); | ||
} | ||
|
||
return path; | ||
} | ||
|
||
private Properties loadProps() { | ||
Properties props = new Properties(); | ||
try (InputStream input = SpeechRecognition.class.getResourceAsStream(AZURE_PROPERTIES)) { | ||
props.load(input); | ||
} catch (IOException e) { | ||
System.out.println(e.getMessage()); | ||
} | ||
|
||
return props; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.