Skip to content

Commit

Permalink
Adding a temporary mute button (the sneeze key).
Browse files Browse the repository at this point in the history
  • Loading branch information
tarehart committed Oct 8, 2013
1 parent c42f470 commit 2b8b120
Show file tree
Hide file tree
Showing 5 changed files with 182 additions and 29 deletions.
1 change: 1 addition & 0 deletions Alter.iml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="JNativeHook" level="project" />
</component>
</module>

Binary file added lib/JNativeHook.jar
Binary file not shown.
89 changes: 79 additions & 10 deletions src/tarehart/alter/AlterForm.form
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="tarehart.alter.AlterForm">
<grid id="27dc6" binding="rootPanel" layout-manager="GridLayoutManager" row-count="5" column-count="5" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="27dc6" binding="rootPanel" layout-manager="GridLayoutManager" row-count="7" column-count="5" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="10" left="10" bottom="10" right="10"/>
<constraints>
<xy x="20" y="20" width="446" height="247"/>
<xy x="20" y="20" width="446" height="370"/>
</constraints>
<properties/>
<border type="none"/>
Expand All @@ -19,7 +19,7 @@
<component id="683f1" class="javax.swing.JSpinner" binding="spinner1" default-binding="true">
<constraints>
<grid row="3" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="50" height="-1"/>
<preferred-size width="50" height="22"/>
</grid>
</constraints>
<properties>
Expand All @@ -37,26 +37,29 @@
<component id="dddcb" class="javax.swing.JButton" binding="button1" default-binding="true">
<constraints>
<grid row="3" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="152" height="24"/>
<preferred-size width="152" height="22"/>
</grid>
</constraints>
<properties>
<text value="Begin Key Select"/>
<text value="Select Talk Key"/>
<toolTipText value="Click here, then hit the key."/>
</properties>
</component>
<component id="9436c" class="javax.swing.JLabel">
<constraints>
<grid row="3" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="3" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false">
<preferred-size width="45" height="22"/>
</grid>
</constraints>
<properties>
<text value="Pressing?"/>
</properties>
</component>
<grid id="14553" binding="statusLight" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="14553" binding="pressingStatus" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="3" column="4" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
<preferred-size width="30" height="-1"/>
<preferred-size width="30" height="22"/>
</grid>
</constraints>
<properties>
Expand Down Expand Up @@ -98,7 +101,7 @@
<grid id="29754" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="5" left="0" bottom="0" right="0"/>
<constraints>
<grid row="4" column="0" row-span="1" col-span="5" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
<grid row="5" column="0" row-span="1" col-span="5" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
Expand All @@ -114,7 +117,73 @@
<editable value="false"/>
<enabled value="true"/>
<font swing-font="Label.font"/>
<text value="This app will take care of push-to-talk for you. By default, it holds down the left Alt key (code 18) when you speak. If you want to use a different key, click &quot;Begin Key Select&quot; and press your key to fill in the new code. Tested with Battlefield 4 Beta."/>
<text value="This app will take care of push-to-talk for you. By default, it holds down the left Alt key (code 18) when you speak. If you want to use a different key, click &quot;Select Talk Button&quot; and press your key to fill in the new code."/>
</properties>
</component>
</children>
</grid>
<component id="72831" class="javax.swing.JButton" binding="sneezeSelect">
<constraints>
<grid row="4" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="136" height="24"/>
</grid>
</constraints>
<properties>
<text value="Select Sneeze Key"/>
<toolTipText value="Click here, then hit the key."/>
</properties>
</component>
<component id="a597" class="javax.swing.JSpinner" binding="spinner2" default-binding="true">
<constraints>
<grid row="4" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="27" height="24"/>
</grid>
</constraints>
<properties/>
</component>
<component id="13be3" class="javax.swing.JLabel">
<constraints>
<grid row="4" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false">
<preferred-size width="35" height="24"/>
</grid>
</constraints>
<properties>
<text value="Muted?"/>
</properties>
</component>
<grid id="54300" binding="muteStatus" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="4" column="4" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
<preferred-size width="30" height="24"/>
</grid>
</constraints>
<properties>
<background color="-10788278"/>
</properties>
<border type="none"/>
<children/>
</grid>
<grid id="f8ab6" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="5" left="0" bottom="0" right="0"/>
<constraints>
<grid row="6" column="0" row-span="1" col-span="5" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="e0725" class="javax.swing.JTextPane" default-binding="true">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="6" anchor="0" fill="3" indent="0" use-parent-layout="false">
<preferred-size width="150" height="50"/>
</grid>
</constraints>
<properties>
<background color="-1"/>
<editable value="false"/>
<enabled value="true"/>
<font swing-font="Label.font"/>
<text value="The sneeze key is something you can hit manually if you're about to sneeze or yell at your dog. It will disable talk key until you've been quiet for 5 seconds."/>
</properties>
</component>
</children>
Expand Down
65 changes: 60 additions & 5 deletions src/tarehart/alter/AlterForm.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package tarehart.alter;

import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
import org.jnativehook.keyboard.NativeKeyEvent;
import org.jnativehook.keyboard.NativeKeyListener;

import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.Mixer;
import javax.swing.*;
Expand All @@ -15,11 +20,13 @@
public class AlterForm {

private static final int MAX_VOLUME = 400;
private static final int GRACE_PERIOD = 500; // 1000 milliseconds = 1 second
private static final int LINGER_PERIOD = 500; // 1000 milliseconds = 1 second
private static final int DEFAULT_THRESHOLD = 50;
private static final String CONFIG_THRESHOLD = "threshold";
private static final String CONFIG_KEY_CODE = "keyCode";
private static final String CONFIG_MIC_CHOICE = "microphoneChoice";
private static final int SNEEZE_PERIOD = 5000; // 5000 milliseconds = 5 seconds
private static final String CONFIG_MUTE_CODE = "sneezeCode";
private TalkingJudge judge;
private KeyPresser presser;
private MicrophoneAnalyzer microphoneAnalyzer;
Expand All @@ -31,7 +38,7 @@ public AlterForm() throws AWTException {

microphoneAnalyzer = new MicrophoneAnalyzer();
presser = new KeyPresser();
judge = new TalkingJudge(presser, GRACE_PERIOD);
judge = new TalkingJudge(presser, LINGER_PERIOD, SNEEZE_PERIOD);

progressBar1.setMaximum(MAX_VOLUME);
slider1.setMaximum(MAX_VOLUME);
Expand All @@ -42,6 +49,7 @@ public AlterForm() throws AWTException {
setKeyFromUI();

addUIListeners();
setSneezeHook();

microphoneAnalyzer.addListener(new AmplitudeUpdateListener() {
@Override
Expand All @@ -50,17 +58,52 @@ public void amplitudeUpdated(float newAmplitude) {
progressBar1.setValue(level);
if (level >= slider1.getValue()) {
judge.gainSound();
statusLight.setBackground(Color.green);
pressingStatus.setBackground(Color.green);
} else {
judge.loseSound();
}

if (!judge.hearsTalking()) {
statusLight.setBackground(Color.darkGray);
pressingStatus.setBackground(Color.darkGray);
}

if (!judge.isMuted()) {
muteStatus.setBackground(Color.darkGray);
}
}
});

}

private boolean setSneezeHook() {
try {
GlobalScreen.registerNativeHook();
}
catch (NativeHookException ex) {
System.err.println("There was a problem registering the sneeze hook.");
System.err.println(ex.getMessage());

return false;
}

//Construct the example object and initialze native hook.
GlobalScreen.getInstance().addNativeKeyListener(new NativeKeyListener() {
@Override
public void nativeKeyPressed(NativeKeyEvent nativeKeyEvent) {
if (nativeKeyEvent.getKeyCode() == (Integer) spinner2.getValue()) {
judge.sneezeIncoming();
muteStatus.setBackground(Color.green);
}
}

@Override
public void nativeKeyReleased(NativeKeyEvent nativeKeyEvent) { }

@Override
public void nativeKeyTyped(NativeKeyEvent nativeKeyEvent) { }
});

return true;
}

private void addUIListeners() {
Expand All @@ -86,6 +129,13 @@ public void actionPerformed(ActionEvent e) {
KeyGrabber.grabNextKey(spinner1);
}
});

sneezeSelect.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
KeyGrabber.grabNextKey(spinner2);
}
});
}

private void setKeyFromUI() {
Expand All @@ -104,12 +154,14 @@ private void setUIFromPreferences() {

slider1.setValue(preferences.getInt(CONFIG_THRESHOLD, DEFAULT_THRESHOLD));
spinner1.setValue(preferences.getInt(CONFIG_KEY_CODE, KeyEvent.VK_ALT));
spinner2.setValue(preferences.getInt(CONFIG_MUTE_CODE, KeyEvent.VK_F5));
comboBox1.setSelectedIndex(preferences.getInt(CONFIG_MIC_CHOICE, 0));

}

private void savePreferences() {
preferences.putInt(CONFIG_KEY_CODE, (Integer) spinner1.getValue());
preferences.putInt(CONFIG_MUTE_CODE, (Integer) spinner2.getValue());
preferences.putInt(CONFIG_THRESHOLD, slider1.getValue());
preferences.putInt(CONFIG_MIC_CHOICE, comboBox1.getSelectedIndex());
}
Expand Down Expand Up @@ -198,7 +250,10 @@ public static void main(String[] args) {
private JPanel rootPanel;
private JButton button1;
private JSpinner spinner1;
private JPanel statusLight;
private JPanel pressingStatus;
private JComboBox<Mixer.Info> comboBox1;
private JTextPane thisAppWillTakeTextPane;
private JButton sneezeSelect;
private JSpinner spinner2;
private JPanel muteStatus;
}
56 changes: 42 additions & 14 deletions src/tarehart/alter/TalkingJudge.java
Original file line number Diff line number Diff line change
@@ -1,40 +1,55 @@
package tarehart.alter;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class TalkingJudge {

private int gracePeriod;
private int lingerTime;
private int sneezeTime;
private KeyPresser presser;
private Timer timer;
private Timer lingerTimer;
private Timer sneezeTimer;
private boolean mutedForSneeze;

public TalkingJudge(KeyPresser presser, int gracePeriod) {
this.gracePeriod = gracePeriod;
public TalkingJudge(KeyPresser presser, int lingerTime, int sneezeTime) {
this.lingerTime = lingerTime;
this.presser = presser;
this.sneezeTime = sneezeTime;

setupTimer();
setupTimers();

}

private void setupTimer() {
timer = new Timer(gracePeriod, new ActionListener() {
private void setupTimers() {
lingerTimer = new Timer(lingerTime, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
presser.release();
}
});
lingerTimer.setRepeats(false);

timer.setRepeats(false);
sneezeTimer = new Timer(sneezeTime, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
mutedForSneeze = false;
}
});
sneezeTimer.setRepeats(false);
}

public void gainSound() {
if (timer.isRunning()) {
timer.stop();

if (mutedForSneeze) {
sneezeTimer.restart();
} else {
presser.beginHold();
if (lingerTimer.isRunning()) {
lingerTimer.stop();
} else {
presser.beginHold();
}
}
}

Expand All @@ -44,13 +59,26 @@ public void loseSound() {
return;
}

if (!timer.isRunning()) {
timer.restart();
if (!lingerTimer.isRunning()) {
lingerTimer.restart();
}
}

public boolean hearsTalking() {
return presser.isPressing();
}

public void sneezeIncoming() {
if (sneezeTimer.isRunning()) {
sneezeTimer.restart();
} else {
presser.release();
mutedForSneeze = true;
sneezeTimer.start();
}
}

public boolean isMuted() {
return mutedForSneeze;
}
}

0 comments on commit 2b8b120

Please sign in to comment.