#2521 JMBE comfort noise insertion default gain (#2530)

Updates to JMBE library 2.1.0
Cleanup AMBE/IMBE sections in each editor P25, NXDN and DMR

Co-authored-by: denny <dennis.sheirer@gmail.com>
This commit is contained in:
Denny Sheirer
2026-10-30 04:26:24 -04:00
committed by GitHub
parent d86fba6945
commit 33a2471338
11 changed files with 134 additions and 128 deletions

View File

@@ -78,7 +78,7 @@ dependencies {
//Jitpack imports
implementation 'com.github.dnault:libresample4j:master'
implementation 'com.github.DSheirer.jmbe:api:v2.0.0'
implementation 'com.github.DSheirer.jmbe:api:v2.1.0'
implementation 'com.github.nwaldispuehl:java-lame:v3.98.4'
//mavenCentral/jcenter imports

View File

@@ -29,6 +29,7 @@ import io.github.dsheirer.gui.preference.PreferenceEditorType;
import io.github.dsheirer.gui.preference.ViewUserPreferenceEditorRequest;
import io.github.dsheirer.module.decode.DecoderType;
import io.github.dsheirer.module.decode.config.AuxDecodeConfiguration;
import io.github.dsheirer.module.decode.config.DecodeConfigJMBE;
import io.github.dsheirer.module.decode.config.DecodeConfiguration;
import io.github.dsheirer.module.log.config.EventLogConfiguration;
import io.github.dsheirer.playlist.PlaylistManager;
@@ -41,6 +42,7 @@ import io.github.dsheirer.util.ThreadPool;
import java.util.Optional;
import java.util.function.Predicate;
import javafx.application.Platform;
import javafx.beans.binding.Bindings;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.transformation.FilteredList;
@@ -48,6 +50,7 @@ import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
@@ -55,14 +58,18 @@ import javafx.scene.control.CheckBox;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.Slider;
import javafx.scene.control.Spinner;
import javafx.scene.control.SpinnerValueFactory;
import javafx.scene.control.TextField;
import javafx.scene.control.TextFormatter;
import javafx.scene.control.TextInputDialog;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import jiconfont.icons.font_awesome.FontAwesome;
@@ -681,6 +688,83 @@ public abstract class ChannelConfigurationEditor extends Editor<Channel>
return mNewAliasListButton;
}
/**
* Adds the JMBE audio controls to the decoder grid as a nested grid so that they don't have to align with the
* columns of the decoder rows above them, and keeps column 3 of the decoder grid as the growing column.
* @param gridPane decoder grid
* @param row in the decoder grid
* @param title label for the audio controls
* @param noiseGainSlider for comfort noise insertion gain
* @param agcSwitch for automatic gain control
* @param toneGainSlider for tone generation gain
* @param legacyToneLevelsSwitch for legacy tone levels
*/
protected void addAudioControls(GridPane gridPane, int row, String title, Slider noiseGainSlider,
ToggleSwitch agcSwitch, Slider toneGainSlider, ToggleSwitch legacyToneLevelsSwitch)
{
GridPane audioPane = new GridPane();
audioPane.setHgap(10);
audioPane.setVgap(10);
audioPane.add(new Label(title), 0, 0);
Label noiseGainLabel = new Label("Comfort Noise Volume:");
GridPane.setHalignment(noiseGainLabel, HPos.RIGHT);
audioPane.add(noiseGainLabel, 1, 0);
audioPane.add(createSliderWithReset(noiseGainSlider, DecodeConfigJMBE.DEFAULT_COMFORT_NOISE_GAIN), 2, 0);
Label agcLabel = new Label("AGC:");
agcLabel.setTooltip(agcSwitch.getTooltip());
GridPane.setHalignment(agcLabel, HPos.RIGHT);
audioPane.add(agcLabel, 3, 0);
audioPane.add(agcSwitch, 4, 0);
Label toneGainLabel = new Label("Tone Volume:");
GridPane.setHalignment(toneGainLabel, HPos.RIGHT);
audioPane.add(toneGainLabel, 1, 1);
audioPane.add(createSliderWithReset(toneGainSlider, DecodeConfigJMBE.DEFAULT_TONE_GAIN), 2, 1);
Label legacyToneLevelsLabel = new Label("Use Legacy Tone Levels:");
legacyToneLevelsLabel.setTooltip(legacyToneLevelsSwitch.getTooltip());
GridPane.setHalignment(legacyToneLevelsLabel, HPos.RIGHT);
audioPane.add(legacyToneLevelsLabel, 3, 1);
audioPane.add(legacyToneLevelsSwitch, 4, 1);
ColumnConstraints growColumn = new ColumnConstraints();
growColumn.setHgrow(Priority.ALWAYS);
gridPane.getColumnConstraints().addAll(new ColumnConstraints(), new ColumnConstraints(), new ColumnConstraints(),
growColumn);
gridPane.add(audioPane, 0, row, 6, 1);
}
/**
* Creates a horizontally growing box containing the slider and, to the right of the slider, a label showing the
* current slider value and a small reset button. The label and button track the disabled state of the slider.
* @param slider to wrap
* @param defaultValue to apply to the slider when the reset button is clicked
* @return box containing the slider, the value label and the reset button
*/
private HBox createSliderWithReset(Slider slider, double defaultValue)
{
IconNode resetIcon = new IconNode(FontAwesome.UNDO);
resetIcon.setIconSize(10);
Button resetButton = new Button();
resetIcon.fillProperty().bind(resetButton.textFillProperty());
resetButton.setGraphic(resetIcon);
resetButton.setTooltip(new Tooltip("Reset to default value"));
resetButton.disableProperty().bind(slider.disableProperty());
resetButton.setOnAction(event -> slider.setValue(defaultValue));
Label valueLabel = new Label();
valueLabel.textProperty().bind(Bindings.format("%.2f", slider.valueProperty()));
valueLabel.disableProperty().bind(slider.disableProperty());
valueLabel.setMinWidth(Region.USE_PREF_SIZE);
HBox box = new HBox(5, slider, valueLabel, resetButton);
box.setAlignment(Pos.CENTER_LEFT);
HBox.setHgrow(slider, Priority.ALWAYS);
GridPane.setHgrow(box, Priority.ALWAYS);
return box;
}
private VBox getButtonBox()
{
if(mButtonBox == null)

View File

@@ -40,8 +40,6 @@ import io.github.dsheirer.source.config.SourceConfiguration;
import io.github.dsheirer.source.tuner.manager.TunerManager;
import java.util.ArrayList;
import java.util.List;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
@@ -62,9 +60,7 @@ import javafx.scene.control.Tooltip;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.util.Callback;
import org.controlsfx.control.ToggleSwitch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -210,25 +206,8 @@ public class DMRConfigurationEditor extends ChannelConfigurationEditor
gridPane.getChildren().add(editorBox);
row++;
Label jmbeLabel = new Label("AMBE Audio");
GridPane.setHalignment(jmbeLabel, HPos.LEFT);
gridPane.add(jmbeLabel, 0, row);
GridPane.setHalignment(getJmbeAGCButton(), HPos.LEFT);
gridPane.add(getJmbeAGCButton(), 1, row);
gridPane.add(new Label("Tone Volume:"), 2, row);
GridPane.setHgrow(getJmbeToneGainSlider(), Priority.ALWAYS);
gridPane.add(getJmbeToneGainSlider(), 3, row);
gridPane.add(new Label("Comfort Noise Volume:"), 4, row);
GridPane.setHgrow(getJmbeNoiseGainSlider(), Priority.ALWAYS);
gridPane.add(getJmbeNoiseGainSlider(), 5, row);
row++;
gridPane.add(getLegacyToneLevelsButton(), 0, row, 6, 1);
addAudioControls(gridPane, row, "AMBE Audio", getJmbeNoiseGainSlider(), getJmbeAGCButton(),
getJmbeToneGainSlider(), getLegacyToneLevelsButton());
mDecoderPane.setContent(gridPane);
}
@@ -584,7 +563,7 @@ public class DMRConfigurationEditor extends ChannelConfigurationEditor
{
if(mJmbeAGCButton == null)
{
mJmbeAGCButton = new ToggleSwitch("AGC:");
mJmbeAGCButton = new ToggleSwitch();
mJmbeAGCButton.setTooltip(new Tooltip("Automatic Gain Control to automatically adjust call audio volume"));
mJmbeAGCButton.setDisable(true);
mJmbeAGCButton.selectedProperty().addListener((o, old, n) -> modifiedProperty().set(true));
@@ -597,7 +576,7 @@ public class DMRConfigurationEditor extends ChannelConfigurationEditor
{
if(mLegacyToneLevelsButton == null)
{
mLegacyToneLevelsButton = new ToggleSwitch("Use legacy tone levels");
mLegacyToneLevelsButton = new ToggleSwitch();
mLegacyToneLevelsButton.setTooltip(new Tooltip(
"Restore JMBE 1.x AMBE tone levels. Requires a supporting JMBE library; " +
"stock libraries ignore this option. Tone Volume still adjusts the selected level."));
@@ -714,7 +693,7 @@ public class DMRConfigurationEditor extends ChannelConfigurationEditor
}
getJmbeAGCButton().setSelected(decodeConfig.isAGC());
getJmbeNoiseGainSlider().setValue(decodeConfig.getNoiseGain());
getJmbeNoiseGainSlider().setValue(decodeConfig.getComfortNoiseGain());
getJmbeToneGainSlider().setValue(decodeConfig.getToneGain());
getLegacyToneLevelsButton().setSelected(decodeConfig.isLegacyToneLevels());
}
@@ -752,7 +731,7 @@ public class DMRConfigurationEditor extends ChannelConfigurationEditor
config.setUseCompressedTalkgroups(getUseCompressedTalkgroupsToggle().isSelected());
config.setTimeslotMap(new ArrayList<>(getTimeslotTable().getItems()));
config.setAGC(getJmbeAGCButton().selectedProperty().getValue());
config.setNoiseGain((float)getJmbeNoiseGainSlider().getValue());
config.setComfortNoiseGain((float)getJmbeNoiseGainSlider().getValue());
config.setToneGain((float)getJmbeToneGainSlider().getValue());
config.setLegacyToneLevels(getLegacyToneLevelsButton().isSelected());
getItem().setDecodeConfiguration(config);

View File

@@ -64,7 +64,6 @@ import javafx.scene.control.ToggleButton;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import org.controlsfx.control.SegmentedButton;
import org.controlsfx.control.ToggleSwitch;
@@ -97,7 +96,7 @@ public class NXDNConfigurationEditor extends ChannelConfigurationEditor
private ToggleSwitch mIgnoreEncryptedCallsToggle;
private ToggleSwitch mJmbeAGCButton;
private Slider mJmbeToneGainSlider;
private ToggleSwitch mLegacyToneLevelsButton;
private ToggleSwitch mJmbeLegacyToneLevelsButton;
private Slider mJmbeNoiseGainSlider;
/**
@@ -216,25 +215,8 @@ public class NXDNConfigurationEditor extends ChannelConfigurationEditor
gridPane.getChildren().add(editorBox);
row++;
Label jmbeLabel = new Label("AMBE Audio");
GridPane.setHalignment(jmbeLabel, HPos.LEFT);
gridPane.add(jmbeLabel, 0, row);
GridPane.setHalignment(getJmbeAGCButton(), HPos.LEFT);
gridPane.add(getJmbeAGCButton(), 1, row);
gridPane.add(new Label("Tone Volume:"), 2, row);
GridPane.setHgrow(getJmbeToneGainSlider(), Priority.ALWAYS);
gridPane.add(getJmbeToneGainSlider(), 3, row);
gridPane.add(new Label("Comfort Noise Volume:"), 4, row);
GridPane.setHgrow(getJmbeNoiseGainSlider(), Priority.ALWAYS);
gridPane.add(getJmbeNoiseGainSlider(), 5, row);
row++;
gridPane.add(getLegacyToneLevelsButton(), 0, row, 6, 1);
addAudioControls(gridPane, row, "AMBE Audio", getJmbeNoiseGainSlider(), getJmbeAGCButton(),
getJmbeToneGainSlider(), getJmbeLegacyToneLevelsButton());
mDecoderPane.setContent(gridPane);
}
@@ -564,7 +546,7 @@ public class NXDNConfigurationEditor extends ChannelConfigurationEditor
{
if(mJmbeAGCButton == null)
{
mJmbeAGCButton = new ToggleSwitch("AGC:");
mJmbeAGCButton = new ToggleSwitch();
mJmbeAGCButton.setTooltip(new Tooltip("Automatic Gain Control to automatically adjust call audio volume"));
mJmbeAGCButton.setDisable(true);
mJmbeAGCButton.selectedProperty().addListener((o, old, n) -> modifiedProperty().set(true));
@@ -573,19 +555,19 @@ public class NXDNConfigurationEditor extends ChannelConfigurationEditor
return mJmbeAGCButton;
}
private ToggleSwitch getLegacyToneLevelsButton()
private ToggleSwitch getJmbeLegacyToneLevelsButton()
{
if(mLegacyToneLevelsButton == null)
if(mJmbeLegacyToneLevelsButton == null)
{
mLegacyToneLevelsButton = new ToggleSwitch("Use legacy tone levels");
mLegacyToneLevelsButton.setTooltip(new Tooltip(
mJmbeLegacyToneLevelsButton = new ToggleSwitch();
mJmbeLegacyToneLevelsButton.setTooltip(new Tooltip(
"Restore JMBE 1.x AMBE tone levels. Requires a supporting JMBE library; " +
"stock libraries ignore this option. Tone Volume still adjusts the selected level."));
mLegacyToneLevelsButton.setDisable(true);
mLegacyToneLevelsButton.selectedProperty().addListener(
mJmbeLegacyToneLevelsButton.setDisable(true);
mJmbeLegacyToneLevelsButton.selectedProperty().addListener(
(o, oldValue, newValue) -> modifiedProperty().set(true));
}
return mLegacyToneLevelsButton;
return mJmbeLegacyToneLevelsButton;
}
public Slider getJmbeToneGainSlider()
@@ -677,7 +659,7 @@ public class NXDNConfigurationEditor extends ChannelConfigurationEditor
getJmbeAGCButton().setDisable(disable);
getJmbeNoiseGainSlider().setDisable(disable);
getJmbeToneGainSlider().setDisable(disable);
getLegacyToneLevelsButton().setDisable(disable);
getJmbeLegacyToneLevelsButton().setDisable(disable);
if(config instanceof DecodeConfigNXDN configNXDN)
{
@@ -699,9 +681,9 @@ public class NXDNConfigurationEditor extends ChannelConfigurationEditor
getIgnoreDataCallsToggle().setSelected(configNXDN.isIgnoreDataCalls());
getIgnoreEncryptedCallsToggle().setSelected(configNXDN.isIgnoreEncryptedCalls());
getJmbeAGCButton().setSelected(configNXDN.isAGC());
getJmbeNoiseGainSlider().setValue(configNXDN.getNoiseGain());
getJmbeNoiseGainSlider().setValue(configNXDN.getComfortNoiseGain());
getJmbeToneGainSlider().setValue(configNXDN.getToneGain());
getLegacyToneLevelsButton().setSelected(configNXDN.isLegacyToneLevels());
getJmbeLegacyToneLevelsButton().setSelected(configNXDN.isLegacyToneLevels());
}
else
{
@@ -712,7 +694,7 @@ public class NXDNConfigurationEditor extends ChannelConfigurationEditor
getJmbeAGCButton().setSelected(false);
getJmbeNoiseGainSlider().setValue(0);
getJmbeToneGainSlider().setValue(0);
getLegacyToneLevelsButton().setSelected(false);
getJmbeLegacyToneLevelsButton().setSelected(false);
}
}
@@ -746,9 +728,9 @@ public class NXDNConfigurationEditor extends ChannelConfigurationEditor
config.setIgnoreDataCalls(getIgnoreDataCallsToggle().isSelected());
config.setIgnoreEncryptedCalls(getIgnoreEncryptedCallsToggle().isSelected());
config.setAGC(getJmbeAGCButton().selectedProperty().getValue());
config.setNoiseGain((float)getJmbeNoiseGainSlider().getValue());
config.setComfortNoiseGain((float)getJmbeNoiseGainSlider().getValue());
config.setToneGain((float)getJmbeToneGainSlider().getValue());
config.setLegacyToneLevels(getLegacyToneLevelsButton().isSelected());
config.setLegacyToneLevels(getJmbeLegacyToneLevelsButton().isSelected());
getItem().setDecodeConfiguration(config);
}

View File

@@ -51,7 +51,6 @@ import javafx.scene.control.Toggle;
import javafx.scene.control.ToggleButton;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import org.controlsfx.control.SegmentedButton;
import org.controlsfx.control.ToggleSwitch;
@@ -161,25 +160,8 @@ public class P25P1ConfigurationEditor extends ChannelConfigurationEditor
row++;
Label jmbeLabel = new Label("AMBE/IMBE Audio");
GridPane.setHalignment(jmbeLabel, HPos.LEFT);
gridPane.add(jmbeLabel, 0, row);
GridPane.setHalignment(getJmbeAGCButton(), HPos.LEFT);
gridPane.add(getJmbeAGCButton(), 1, row);
gridPane.add(new Label("Tone Volume:"), 2, row);
GridPane.setHgrow(getJmbeToneGainSlider(), Priority.ALWAYS);
gridPane.add(getJmbeToneGainSlider(), 3, row);
gridPane.add(new Label("Comfort Noise Volume:"), 4, row);
GridPane.setHgrow(getJmbeNoiseGainSlider(), Priority.ALWAYS);
gridPane.add(getJmbeNoiseGainSlider(), 5, row);
row++;
gridPane.add(getLegacyToneLevelsButton(), 0, row, 6, 1);
addAudioControls(gridPane, row, "AMBE/IMBE Audio", getJmbeNoiseGainSlider(), getJmbeAGCButton(),
getJmbeToneGainSlider(), getLegacyToneLevelsButton());
mDecoderPane.setContent(gridPane);
}
@@ -286,7 +268,7 @@ public class P25P1ConfigurationEditor extends ChannelConfigurationEditor
{
if(mJmbeAGCButton == null)
{
mJmbeAGCButton = new ToggleSwitch("AGC:");
mJmbeAGCButton = new ToggleSwitch();
mJmbeAGCButton.setTooltip(new Tooltip("Automatic Gain Control to automatically adjust call audio volume"));
mJmbeAGCButton.setDisable(true);
mJmbeAGCButton.selectedProperty().addListener((o, old, n) -> modifiedProperty().set(true));
@@ -299,7 +281,7 @@ public class P25P1ConfigurationEditor extends ChannelConfigurationEditor
{
if(mLegacyToneLevelsButton == null)
{
mLegacyToneLevelsButton = new ToggleSwitch("Use legacy tone levels");
mLegacyToneLevelsButton = new ToggleSwitch();
mLegacyToneLevelsButton.setTooltip(new Tooltip(
"Restore JMBE 1.x AMBE tone levels. Requires a supporting JMBE library; " +
"stock libraries ignore this option. Tone Volume still adjusts the selected level."));
@@ -432,7 +414,7 @@ public class P25P1ConfigurationEditor extends ChannelConfigurationEditor
getJmbeToneGainSlider().setDisable(false);
getLegacyToneLevelsButton().setDisable(false);
getJmbeAGCButton().setSelected(decodeConfig.isAGC());
getJmbeNoiseGainSlider().setValue(decodeConfig.getNoiseGain());
getJmbeNoiseGainSlider().setValue(decodeConfig.getComfortNoiseGain());
getJmbeToneGainSlider().setValue(decodeConfig.getToneGain());
getLegacyToneLevelsButton().setSelected(decodeConfig.isLegacyToneLevels());
@@ -470,7 +452,7 @@ public class P25P1ConfigurationEditor extends ChannelConfigurationEditor
config.setTrafficChannelPoolSize(getTrafficChannelPoolSizeSpinner().getValue());
config.setModulation(getC4FMToggleButton().isSelected() ? Modulation.C4FM : Modulation.CQPSK);
config.setAGC(getJmbeAGCButton().selectedProperty().getValue());
config.setNoiseGain((float)getJmbeNoiseGainSlider().getValue());
config.setComfortNoiseGain((float)getJmbeNoiseGainSlider().getValue());
config.setToneGain((float)getJmbeToneGainSlider().getValue());
config.setLegacyToneLevels(getLegacyToneLevelsButton().isSelected());
getItem().setDecodeConfiguration(config);

View File

@@ -48,7 +48,6 @@ import javafx.scene.control.SpinnerValueFactory;
import javafx.scene.control.TitledPane;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import org.controlsfx.control.ToggleSwitch;
import org.slf4j.Logger;
@@ -171,26 +170,8 @@ public class P25P2ConfigurationEditor extends ChannelConfigurationEditor
gridPane.getChildren().add(noteLabel);
row++;
Label jmbeLabel = new Label("AMBE Audio");
GridPane.setHalignment(jmbeLabel, HPos.LEFT);
gridPane.add(jmbeLabel, 0, row);
GridPane.setHalignment(getJmbeAGCButton(), HPos.LEFT);
gridPane.add(getJmbeAGCButton(), 1, row);
gridPane.add(new Label("Tone Volume:"), 2, row);
GridPane.setHgrow(getJmbeToneGainSlider(), Priority.ALWAYS);
gridPane.add(getJmbeToneGainSlider(), 3, row);
gridPane.add(new Label("Comfort Noise Volume:"), 4, row);
GridPane.setHgrow(getJmbeNoiseGainSlider(), Priority.ALWAYS);
gridPane.add(getJmbeNoiseGainSlider(), 5, row);
row++;
gridPane.add(getLegacyToneLevelsButton(), 0, row, 6, 1);
addAudioControls(gridPane, row, "AMBE Audio", getJmbeNoiseGainSlider(), getJmbeAGCButton(),
getJmbeToneGainSlider(), getLegacyToneLevelsButton());
mDecoderPane.setContent(gridPane);
}
@@ -202,7 +183,7 @@ public class P25P2ConfigurationEditor extends ChannelConfigurationEditor
{
if(mJmbeAGCButton == null)
{
mJmbeAGCButton = new ToggleSwitch("AGC:");
mJmbeAGCButton = new ToggleSwitch();
mJmbeAGCButton.setTooltip(new Tooltip("Automatic Gain Control to automatically adjust call audio volume"));
mJmbeAGCButton.setDisable(true);
mJmbeAGCButton.selectedProperty().addListener((o, old, n) -> modifiedProperty().set(true));
@@ -215,7 +196,7 @@ public class P25P2ConfigurationEditor extends ChannelConfigurationEditor
{
if(mLegacyToneLevelsButton == null)
{
mLegacyToneLevelsButton = new ToggleSwitch("Use legacy tone levels");
mLegacyToneLevelsButton = new ToggleSwitch();
mLegacyToneLevelsButton.setTooltip(new Tooltip(
"Restore JMBE 1.x AMBE tone levels. Requires a supporting JMBE library; " +
"stock libraries ignore this option. Tone Volume still adjusts the selected level."));
@@ -433,7 +414,7 @@ public class P25P2ConfigurationEditor extends ChannelConfigurationEditor
getTrafficChannelPoolSizeSpinner().setDisable(false);
getTrafficChannelPoolSizeSpinner().getValueFactory().setValue(decodeConfig.getTrafficChannelPoolSize());
getJmbeAGCButton().setSelected(decodeConfig.isAGC());
getJmbeNoiseGainSlider().setValue(decodeConfig.getNoiseGain());
getJmbeNoiseGainSlider().setValue(decodeConfig.getComfortNoiseGain());
getJmbeToneGainSlider().setValue(decodeConfig.getToneGain());
getLegacyToneLevelsButton().setSelected(decodeConfig.isLegacyToneLevels());
}
@@ -480,7 +461,7 @@ public class P25P2ConfigurationEditor extends ChannelConfigurationEditor
config.setIgnoreDataCalls(getIgnoreDataCallsButton().isSelected());
config.setTrafficChannelPoolSize(getTrafficChannelPoolSizeSpinner().getValue());
config.setAGC(getJmbeAGCButton().selectedProperty().getValue());
config.setNoiseGain((float)getJmbeNoiseGainSlider().getValue());
config.setComfortNoiseGain((float)getJmbeNoiseGainSlider().getValue());
config.setToneGain((float)getJmbeToneGainSlider().getValue());
config.setLegacyToneLevels(getLegacyToneLevelsButton().isSelected());
getItem().setDecodeConfiguration(config);

View File

@@ -571,10 +571,9 @@ public class DecoderFactory
{
List<String> features = audioModule.getFeatures();
String legacyToneFeature = "feature_legacy_tone_levels";
if(features.contains(legacyToneFeature))
if(features.contains(IAudioCodecV2.FEATURE_LEGACY_TONE_LEVELS))
{
audioModule.setFeature(legacyToneFeature, config.isLegacyToneLevels());
audioModule.setFeature(IAudioCodecV2.FEATURE_LEGACY_TONE_LEVELS, config.isLegacyToneLevels());
}
if(features.contains(IAudioCodecV2.FEATURE_AUTOMATIC_GAIN_CONTROL))
@@ -584,7 +583,7 @@ public class DecoderFactory
if(features.contains(IAudioCodecV2.FEATURE_NOISE_GENERATOR_GAIN))
{
audioModule.setFeature(IAudioCodecV2.FEATURE_NOISE_GENERATOR_GAIN, config.getNoiseGain());
audioModule.setFeature(IAudioCodecV2.FEATURE_NOISE_GENERATOR_GAIN, config.getComfortNoiseGain());
}
if(features.contains(IAudioCodecV2.FEATURE_TONE_GENERATOR_GAIN))
@@ -956,7 +955,7 @@ public class DecoderFactory
public static void transferJMBESettings(DecodeConfigJMBE from, DecodeConfigJMBE to)
{
to.setAGC(from.isAGC());
to.setNoiseGain(from.getNoiseGain());
to.setComfortNoiseGain(from.getComfortNoiseGain());
to.setToneGain(from.getToneGain());
to.setLegacyToneLevels(from.isLegacyToneLevels());
}

View File

@@ -4,6 +4,8 @@ import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
public abstract class DecodeConfigJMBE extends DecodeConfiguration
{
public static float DEFAULT_COMFORT_NOISE_GAIN = 0.05f;
public static float DEFAULT_TONE_GAIN = 1.0f;
private boolean mAGC = true;
private boolean mLegacyToneLevels;
@@ -21,8 +23,8 @@ public abstract class DecodeConfigJMBE extends DecodeConfiguration
{
mLegacyToneLevels = enabled;
}
private float mToneGain = 1.0f;
private float mNoiseGain = 1.0f;
private float mToneGain = DEFAULT_TONE_GAIN;
private float mComfortNoiseGain = DEFAULT_COMFORT_NOISE_GAIN;
/**
* Automatic Gain Control (AGC) for the JMBE audio codec
@@ -78,28 +80,28 @@ public abstract class DecodeConfigJMBE extends DecodeConfiguration
* @return noise gain in range 0.0 (no noise) to 1.0 (default noise)
*/
@JacksonXmlProperty(isAttribute = true, localName = "jmbeNoiseGain", namespace = "http://www.w3.org/2001/XMLSchema-instance")
public float getNoiseGain()
public float getComfortNoiseGain()
{
return mNoiseGain;
return mComfortNoiseGain;
}
/**
* Sets the comfort noise insertion gain for the JMBE audio codec
* @param gain noise gain in range 0.0 (no noise) to 1.0 (default noise)
*/
public void setNoiseGain(float gain)
public void setComfortNoiseGain(float gain)
{
if(gain > 1.0f)
{
mNoiseGain = 1.0f;
mComfortNoiseGain = 1.0f;
}
else if(gain < 0)
{
mNoiseGain = 0;
mComfortNoiseGain = 0;
}
else
{
mNoiseGain = gain;
mComfortNoiseGain = gain;
}
}
}

View File

@@ -22,7 +22,6 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import io.github.dsheirer.module.decode.DecoderType;
import io.github.dsheirer.module.decode.config.DecodeConfigJMBE;
import io.github.dsheirer.module.decode.config.DecodeConfiguration;
import io.github.dsheirer.module.decode.dmr.channel.TimeslotFrequency;
import io.github.dsheirer.module.decode.dmr.message.DMRMessage;
import io.github.dsheirer.module.decode.event.DecodeEvent;

View File

@@ -23,7 +23,6 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import io.github.dsheirer.module.decode.DecoderType;
import io.github.dsheirer.module.decode.config.DecodeConfigJMBE;
import io.github.dsheirer.module.decode.config.DecodeConfiguration;
import io.github.dsheirer.module.decode.nxdn.channel.ChannelFrequency;
import io.github.dsheirer.module.decode.nxdn.layer3.proprietary.Encoding;
import io.github.dsheirer.module.decode.nxdn.layer3.type.TransmissionMode;

View File

@@ -23,7 +23,6 @@ import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import io.github.dsheirer.module.decode.config.DecodeConfigJMBE;
import io.github.dsheirer.module.decode.config.DecodeConfiguration;
import io.github.dsheirer.module.decode.p25.phase2.DecodeConfigP25Phase2;
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")