Compare commits
4 Commits
59cad38f74
...
83e3c53ebc
| Author | SHA1 | Date |
|---|---|---|
|
|
83e3c53ebc | |
|
|
b8f64ad4ba | |
|
|
a9ba42d24c | |
|
|
4836e4c4c0 |
|
|
@ -0,0 +1,2 @@
|
|||
class MIA { //TODO: Semantic Kernel Class
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
import javax.sound.sampled.AudioFormat
|
||||
import javax.sound.sampled.AudioSystem
|
||||
import javax.sound.sampled.DataLine
|
||||
import javax.sound.sampled.TargetDataLine
|
||||
/**
|
||||
* TODO: Documentation
|
||||
*/
|
||||
class Microphone {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private val source = getSource()
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private val audioFormat = getFormat()
|
||||
/**
|
||||
*
|
||||
*/
|
||||
fun startCapture() {
|
||||
source.start()
|
||||
//TODO: Start processing loop in new coroutine and check if it could be moved into own file
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
fun stopCapture() {
|
||||
source.stop()
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
fun closeSource() {
|
||||
source.close()
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private fun getFormat(): AudioFormat {
|
||||
return AudioFormat( //TODO: Get format settings from user settings
|
||||
16000.0f, // 16000 Required
|
||||
16,
|
||||
2,
|
||||
true,
|
||||
true
|
||||
)
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private fun getSource(): TargetDataLine {
|
||||
val info = DataLine.Info(
|
||||
TargetDataLine::class.java,
|
||||
audioFormat
|
||||
)
|
||||
val source = AudioSystem.getLine(info) as TargetDataLine
|
||||
source.open(audioFormat)
|
||||
|
||||
return source
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
import org.vosk.Model
|
||||
import org.vosk.Recognizer
|
||||
import java.nio.file.Paths
|
||||
/**
|
||||
* TODO: Documentation
|
||||
*/
|
||||
class STT {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private val model = Model(getModelPath())
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private val recognizer = Recognizer(model, 16000.0f)
|
||||
/**
|
||||
*
|
||||
*/
|
||||
fun parseBuffer(buffer: ByteArray, audioBytes: Int): String? {
|
||||
return if (recognizer.acceptWaveForm(buffer, audioBytes)) {
|
||||
recognizer.result
|
||||
} else {
|
||||
recognizer.partialResult
|
||||
}
|
||||
}
|
||||
fun closeModel() {
|
||||
recognizer.close()
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private fun getModelPath(): String {
|
||||
return Paths.get(
|
||||
javaClass.getResource("STT-model")!!.toURI()
|
||||
).toFile().absolutePath
|
||||
}
|
||||
|
||||
//TODO: Install model into dir from resource link
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package window_control
|
||||
|
||||
enum class OS {
|
||||
Windows,
|
||||
Mac,
|
||||
Linux
|
||||
}
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
package window_control
|
||||
|
||||
import com.sun.jna.Library
|
||||
import com.sun.jna.Native
|
||||
import com.sun.jna.platform.win32.WinDef
|
||||
import com.sun.jna.win32.W32APIOptions
|
||||
import java.awt.Point
|
||||
import java.awt.Robot
|
||||
import java.awt.event.KeyEvent
|
||||
|
||||
class WindowController { //TODO: Class that controls program window
|
||||
private val os = OS.valueOf(System.getProperty("os.name"))
|
||||
private val inputController = Robot()
|
||||
|
||||
fun setActiveWindow(windowName: String) {
|
||||
when (os) {
|
||||
OS.Windows -> activateWindowsWindow(windowName)
|
||||
OS.Mac -> activateMacWindow(windowName)
|
||||
OS.Linux -> activateLinuxWindow(windowName)
|
||||
}
|
||||
}
|
||||
|
||||
fun sendKeyPresses(keyCodes: Array<Int>) {
|
||||
keyCodes.iterator().forEach { keyCode ->
|
||||
inputController.keyPress(keyCode)
|
||||
}
|
||||
}
|
||||
fun sendKeyReleases(keyCodes: Array<Int>) {
|
||||
keyCodes.iterator().forEach { keyCode ->
|
||||
inputController.keyRelease(keyCode)
|
||||
}
|
||||
}
|
||||
fun sendKeyStrokes(keyCodes: Array<Int>, delay: Int?) { //TODO: Create KeyList Class
|
||||
keyCodes.iterator().forEach { keyCode ->
|
||||
sendKeyPresses(arrayOf(keyCode))
|
||||
inputController.delay(delay!!)
|
||||
sendKeyReleases(arrayOf(keyCode))
|
||||
}
|
||||
}
|
||||
|
||||
fun sendMultiKeyStrokes(commands: Array<Array<Int>>, delay: Int?) { //TODO: Create MultiKeyList Class
|
||||
commands.iterator().forEach { command ->
|
||||
sendMousePresses(command)
|
||||
inputController.delay(delay!!)
|
||||
sendMouseReleases(command)
|
||||
}
|
||||
}
|
||||
|
||||
fun sendMousePresses(buttonCodes: Array<Int>) { //TODO: Create ButtonList Class
|
||||
buttonCodes.iterator().forEach { buttonCode ->
|
||||
inputController.mousePress(buttonCode)
|
||||
}
|
||||
}
|
||||
fun sendMouseReleases(buttonCodes: Array<Int>) {
|
||||
buttonCodes.iterator().forEach { buttonCode ->
|
||||
inputController.mouseRelease(buttonCode)
|
||||
}
|
||||
}
|
||||
fun sendMouseLocation(location: Point) {
|
||||
inputController.mouseMove(location.x, location.y)
|
||||
}
|
||||
fun sendMouseStrokes(buttonCodes: Array<Int>, delay: Int?) {
|
||||
buttonCodes.iterator().forEach { buttonCode ->
|
||||
sendMousePresses(arrayOf(buttonCode))
|
||||
inputController.delay(delay!!)
|
||||
sendMouseReleases(arrayOf(buttonCode))
|
||||
}
|
||||
}
|
||||
fun sendMouseStrokesAtLocation(buttonCodes: Array<Int>, delay: Int?, location: Point) {
|
||||
sendMouseLocation(location)
|
||||
buttonCodes.iterator().forEach { buttonCode ->
|
||||
sendMouseStrokes(arrayOf(buttonCode), delay)
|
||||
}
|
||||
}
|
||||
fun sendMouseStrokesAtLocations(commands: Array<Pair<Point,Array<Int>>>, delay: Int?) {
|
||||
commands.iterator().forEach { command ->
|
||||
sendMouseLocation(command.first)
|
||||
sendMouseStrokes(command.second, delay)
|
||||
}
|
||||
}
|
||||
|
||||
private fun activateWindowsWindow(windowName: String) {
|
||||
val window = User32.INSTANCE.findWindow(null, windowName)
|
||||
User32.INSTANCE.setActiveWindow(window)
|
||||
}
|
||||
private fun activateMacWindow(windowName: String) {
|
||||
val command = arrayOf("osascript", "-e", "tell application \"$windowName\" to activate") //TODO: double check how this command works to ensure it works
|
||||
Runtime.getRuntime().exec(command).waitFor()
|
||||
}
|
||||
private fun activateLinuxWindow(windowName: String) {
|
||||
val xorgFlag = System.getenv("DISPLAY")
|
||||
val hyprlandFlag = System.getenv("HYPRLAND_CMD") //TODO: User override of default checks, and add sway compatibility
|
||||
|
||||
if (hyprlandFlag != null) {
|
||||
val command = arrayOf("hyprctl", "dispatch", "focuswindow", windowName) //TODO: need to check both class regex and title regex (look at hyprland wiki)
|
||||
Runtime.getRuntime().exec(command).waitFor()
|
||||
}
|
||||
else if (xorgFlag != null) {
|
||||
val command = arrayOf("xdotool", "search", "--name", windowName, "windowactivate")
|
||||
Runtime.getRuntime().exec(command).waitFor()
|
||||
}
|
||||
}
|
||||
|
||||
interface User32: Library {
|
||||
companion object {
|
||||
val INSTANCE: User32 = Native.load("user32", User32::class.java, W32APIOptions.DEFAULT_OPTIONS)
|
||||
}
|
||||
|
||||
fun findWindow(className: String?, windowName: String?): WinDef.HWND
|
||||
fun setActiveWindow(window: WinDef.HWND): Boolean
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue