diff --git a/README.md b/README.md index b16a37a..a4ad8ca 100644 --- a/README.md +++ b/README.md @@ -49,20 +49,40 @@ application = Zen [fader 7] application = Last Epoch.exe:Warframe.x64.exe + +[knob 16] +application = Firefox ``` -Follow the same syntax to add the rest of the faders and applications to map to -the faders (Add an empty line in to the file, might fix at some point but it -requires one empty line after configurations.) +Follow the same syntax to add the rest of the faders, knobs and applications to +map to the faders or knobs. -The faders id's are from left to right 0 - 7 so to spotify to the leftmost fader -you would type +The faders IDs are from left to right 0 - 7 and the knob IDs are 16 - 23. To +map spotify to the leftmost fader you would type ```sh [fader 0] application = spotify ``` +To map Firefox to the leftmost knob you would type + +```sh +[knob 16] +application = Firefox +``` + +You can map any pipewire node to any fader or knob, i.e. not only applications, but +also for example output and devices: + +```sh +[fader 6] +application = alsa_output.usb-Beyerdynamic_FOX_5.00-00.analog-stereo + +[fader 22] +application = alsa_input.usb-Beyerdynamic_FOX_5.00-00.mono-fallback.3 +``` + You can force reconfiguration with `cycle` button from midiKONTROL2. This is required if you open up a application after starting midi-mixer diff --git a/src/main/java/io/github/katacc/AudioController.java b/src/main/java/io/github/katacc/AudioController.java index c44a6a7..c555a97 100644 --- a/src/main/java/io/github/katacc/AudioController.java +++ b/src/main/java/io/github/katacc/AudioController.java @@ -24,8 +24,24 @@ public class AudioController { private List id5; private List id6; private List id7; + private List id16; + private List id17; + private List id18; + private List id19; + private List id20; + private List id21; + private List id22; + private List id23; private Vector id7App; + private Vector id16App; + private Vector id17App; + private Vector id18App; + private Vector id19App; + private Vector id20App; + private Vector id21App; + private Vector id22App; + private Vector id23App; private Vector id5App; private Vector id6App; private Vector id4App; @@ -49,6 +65,14 @@ private AudioController() { id5 = new ArrayList<>(); id6 = new ArrayList<>(); id7 = new ArrayList<>(); + id16 = new ArrayList<>(); + id17 = new ArrayList<>(); + id18 = new ArrayList<>(); + id19 = new ArrayList<>(); + id20 = new ArrayList<>(); + id21 = new ArrayList<>(); + id22 = new ArrayList<>(); + id23 = new ArrayList<>(); id0App = new Vector<>(); @@ -59,6 +83,14 @@ private AudioController() { id5App = new Vector<>(); id6App = new Vector<>(); id7App = new Vector<>(); + id16App = new Vector<>(); + id17App = new Vector<>(); + id18App = new Vector<>(); + id19App = new Vector<>(); + id20App = new Vector<>(); + id21App = new Vector<>(); + id22App = new Vector<>(); + id23App = new Vector<>(); audioSetTimer = 0; } @@ -232,6 +264,142 @@ public void changeVolume(MidiMessage msg) { System.out.println("Error: " + e.getMessage()); } } + if (control == 16) { + if (id16.isEmpty()) { + System.out.println("id16 is empty... refreshing config..."); + getConfig(); + } + try { + for (int id : id16) { + String command = String.format("wpctl set-volume %s, %s", id, scaled_volume); + if (debug) { + System.out.println("Executing command: " + command); + } + Process process = Runtime.getRuntime().exec(command); + } + } catch (IOException e) { + System.out.println("Error: " + e.getMessage()); + } + } + if (control == 17) { + if (id17.isEmpty()) { + System.out.println("id17 is empty... refreshing config..."); + getConfig(); + } + try { + for (int id : id17) { + String command = String.format("wpctl set-volume %s, %s", id, scaled_volume); + if (debug) { + System.out.println("Executing command: " + command); + } + Process process = Runtime.getRuntime().exec(command); + } + } catch (IOException e) { + System.out.println("Error: " + e.getMessage()); + } + } + if (control == 18) { + if (id18.isEmpty()) { + System.out.println("id18 is empty... refreshing config..."); + getConfig(); + } + try { + for (int id : id18) { + String command = String.format("wpctl set-volume %s, %s", id, scaled_volume); + if (debug) { + System.out.println("Executing command: " + command); + } + Process process = Runtime.getRuntime().exec(command); + } + } catch (IOException e) { + System.out.println("Error: " + e.getMessage()); + } + } + if (control == 19) { + if (id19.isEmpty()) { + System.out.println("id19 is empty... refreshing config..."); + getConfig(); + } + try { + for (int id : id19) { + String command = String.format("wpctl set-volume %s, %s", id, scaled_volume); + if (debug) { + System.out.println("Executing command: " + command); + } + Process process = Runtime.getRuntime().exec(command); + } + } catch (IOException e) { + System.out.println("Error: " + e.getMessage()); + } + } + if (control == 20) { + if (id20.isEmpty()) { + System.out.println("id20 is empty... refreshing config..."); + getConfig(); + } + try { + for (int id : id20) { + String command = String.format("wpctl set-volume %s, %s", id, scaled_volume); + if (debug) { + System.out.println("Executing command: " + command); + } + Process process = Runtime.getRuntime().exec(command); + } + } catch (IOException e) { + System.out.println("Error: " + e.getMessage()); + } + } + if (control == 21) { + if (id21.isEmpty()) { + System.out.println("id21 is empty... refreshing config..."); + getConfig(); + } + try { + for (int id : id21) { + String command = String.format("wpctl set-volume %s, %s", id, scaled_volume); + if (debug) { + System.out.println("Executing command: " + command); + } + Process process = Runtime.getRuntime().exec(command); + } + } catch (IOException e) { + System.out.println("Error: " + e.getMessage()); + } + } + if (control == 22) { + if (id22.isEmpty()) { + System.out.println("id22 is empty... refreshing config..."); + getConfig(); + } + try { + for (int id : id22) { + String command = String.format("wpctl set-volume %s, %s", id, scaled_volume); + if (debug) { + System.out.println("Executing command: " + command); + } + Process process = Runtime.getRuntime().exec(command); + } + } catch (IOException e) { + System.out.println("Error: " + e.getMessage()); + } + } + if (control == 23) { + if (id23.isEmpty()) { + System.out.println("id23 is empty... refreshing config..."); + getConfig(); + } + try { + for (int id : id23) { + String command = String.format("wpctl set-volume %s, %s", id, scaled_volume); + if (debug) { + System.out.println("Executing command: " + command); + } + Process process = Runtime.getRuntime().exec(command); + } + } catch (IOException e) { + System.out.println("Error: " + e.getMessage()); + } + } } audioSetTimer++; if (control == 41) { @@ -356,6 +524,14 @@ public void getConfig() { id5.clear(); id6.clear(); id7.clear(); + id16.clear(); + id17.clear(); + id18.clear(); + id19.clear(); + id20.clear(); + id21.clear(); + id22.clear(); + id23.clear(); // Clear the application lists before grabbing new ones. id0App.clear(); @@ -366,6 +542,14 @@ public void getConfig() { id5App.clear(); id6App.clear(); id7App.clear(); + id16App.clear(); + id17App.clear(); + id18App.clear(); + id19App.clear(); + id20App.clear(); + id21App.clear(); + id22App.clear(); + id23App.clear(); // Defaults int faderConfig = 99; @@ -374,48 +558,25 @@ public void getConfig() { Vector appVector = new Vector<>(); // Read config file - var state = ReadingState.FADER; try (BufferedReader br = new BufferedReader(new FileReader(configPath))) { + String line; - do { - + while ((line = br.readLine()) != null) { String applicationConfig; - - String line = br.readLine(); - - if (line == null) { - state = ReadingState.DONE; + if (line.startsWith("[fader ")) { + faderConfig = Integer.parseInt(line.substring(7, line.length() - 1)); + } else if (line.startsWith("[knob ")) { + faderConfig = Integer.parseInt(line.substring(6, line.length() - 1)); + } else if (line.startsWith("application =")) { + applicationConfig = line.substring(14).trim(); + applicationArray = applicationConfig.split(":"); + appVector.addAll(Arrays.asList(applicationArray)); + System.out.println(faderConfig + " " + appVector); + constructConfig(faderConfig, new Vector<>(appVector)); + faderConfig = 99; + appVector.clear(); } - - // Parse config file with state machine - switch (state) { - case FADER: - faderConfig = Integer.parseInt(line.substring(7, 8)); - state = state.nextState(); - break; - - case APPLICATION: - applicationConfig = line.substring(14); - applicationArray = applicationConfig.split(":"); - appVector.addAll(Arrays.asList(applicationArray)); - state = state.nextState(); - break; - - case BLANK: - System.out.println(faderConfig + " " + Arrays.toString(applicationArray)); - constructConfig(faderConfig, appVector); - state = state.nextState(); - - faderConfig = 99; - appVector.clear(); - break; - - case DONE: - break; - } - - } while (state != ReadingState.DONE); - + } } catch (IOException IOE) { System.out.println("Error reading configs from file: " + IOE.getMessage()); } @@ -514,6 +675,94 @@ public void constructConfig(int fader, Vector applications) { } break; + case 16: + this.id16App = applications; + + for (String app : id16App) { + List temp_id = AudioController.getInstance().getId(app); + if (!temp_id.isEmpty()) { + this.id16.addAll(temp_id); + } + } + break; + + case 17: + this.id17App = applications; + + for (String app : id17App) { + List temp_id = AudioController.getInstance().getId(app); + if (!temp_id.isEmpty()) { + this.id17.addAll(temp_id); + } + } + break; + + case 18: + this.id18App = applications; + + for (String app : id18App) { + List temp_id = AudioController.getInstance().getId(app); + if (!temp_id.isEmpty()) { + this.id18.addAll(temp_id); + } + } + break; + + case 19: + this.id19App = applications; + + for (String app : id19App) { + List temp_id = AudioController.getInstance().getId(app); + if (!temp_id.isEmpty()) { + this.id19.addAll(temp_id); + } + } + break; + + case 20: + this.id20App = applications; + + for (String app : id20App) { + List temp_id = AudioController.getInstance().getId(app); + if (!temp_id.isEmpty()) { + this.id20.addAll(temp_id); + } + } + break; + + case 21: + this.id21App = applications; + + for (String app : id21App) { + List temp_id = AudioController.getInstance().getId(app); + if (!temp_id.isEmpty()) { + this.id21.addAll(temp_id); + } + } + break; + + case 22: + this.id22App = applications; + + for (String app : id22App) { + List temp_id = AudioController.getInstance().getId(app); + if (!temp_id.isEmpty()) { + this.id22.addAll(temp_id); + } + } + break; + + case 23: + this.id23App = applications; + + for (String app : id23App) { + List temp_id = AudioController.getInstance().getId(app); + if (!temp_id.isEmpty()) { + this.id23.addAll(temp_id); + } + } + break; + default: break; } diff --git a/src/main/java/io/github/katacc/ReadingState.java b/src/main/java/io/github/katacc/ReadingState.java deleted file mode 100644 index 754f68a..0000000 --- a/src/main/java/io/github/katacc/ReadingState.java +++ /dev/null @@ -1,29 +0,0 @@ -package io.github.katacc; - -public enum ReadingState { - FADER { - public ReadingState nextState() { - return APPLICATION; - } - }, - - APPLICATION { - public ReadingState nextState() { - return BLANK; - } - }, - - BLANK { - public ReadingState nextState() { - return FADER; - } - }, - - DONE { - public ReadingState nextState() { - return FADER; - } - }; - - public abstract ReadingState nextState(); -}