mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 08:37:25 -05:00
* WIP - Adds support for aliasing P25 Phase 2 tones.Playlist editor - adds editor support for alias actions * Playlist editor implementation and integration into application is complete. Adds JavaFX window monitoring to persist window size/location across application runs. Co-authored-by: Denny <denny@denny-desktop>
This commit is contained in:
@@ -30,6 +30,10 @@ import io.github.dsheirer.protocol.Protocol;
|
||||
*/
|
||||
public class LTRTalkgroup extends TalkgroupIdentifier implements Comparable<LTRTalkgroup>
|
||||
{
|
||||
private static final int AREA_MASK = 0x2000;
|
||||
private static final int HOME_MASK = 0x1F00;
|
||||
private static final int GROUP_MASK = 0xFF;
|
||||
|
||||
public LTRTalkgroup(Integer talkgroup, Role role)
|
||||
{
|
||||
super(talkgroup, role);
|
||||
@@ -38,7 +42,7 @@ public class LTRTalkgroup extends TalkgroupIdentifier implements Comparable<LTRT
|
||||
@Override
|
||||
public Protocol getProtocol()
|
||||
{
|
||||
return Protocol.LTR_NET;
|
||||
return Protocol.LTR;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,12 +53,17 @@ public class LTRTalkgroup extends TalkgroupIdentifier implements Comparable<LTRT
|
||||
return String.format("%02d-%03d", getHomeChannel(), getTalkgroup());
|
||||
}
|
||||
|
||||
public int getArea()
|
||||
{
|
||||
return (getValue() & AREA_MASK) >> 13;
|
||||
}
|
||||
|
||||
/**
|
||||
* Home channel for the identifier
|
||||
*/
|
||||
public int getHomeChannel()
|
||||
{
|
||||
return (getValue() >> 8) & 0x1F;
|
||||
return (getValue() & HOME_MASK) >> 8;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,17 +71,26 @@ public class LTRTalkgroup extends TalkgroupIdentifier implements Comparable<LTRT
|
||||
*/
|
||||
public int getTalkgroup()
|
||||
{
|
||||
return getValue() & 0xFF;
|
||||
return getValue() & GROUP_MASK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an LTR-Net identifier from the integer value that contains both the fleet and the ident with a TO role
|
||||
* Creates an LTR identifier from the integer value that contains both the fleet and the ident with a TO role
|
||||
*/
|
||||
public static LTRTalkgroup create(int talkgroup)
|
||||
{
|
||||
return new LTRTalkgroup(talkgroup, Role.TO);
|
||||
}
|
||||
|
||||
public static int create(int area, int home, int group)
|
||||
{
|
||||
int value = (area << 13);
|
||||
value += (home << 8);
|
||||
value += group;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(LTRTalkgroup o)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2020 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
package io.github.dsheirer.identifier.talkgroup;
|
||||
|
||||
import io.github.dsheirer.identifier.Role;
|
||||
import io.github.dsheirer.protocol.Protocol;
|
||||
|
||||
/**
|
||||
* Unknown (protocol) talkgroup identifier
|
||||
*/
|
||||
public class UnknownTalkgroupIdentifier extends TalkgroupIdentifier
|
||||
{
|
||||
public UnknownTalkgroupIdentifier(Integer value)
|
||||
{
|
||||
super(value, Role.TO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Protocol getProtocol()
|
||||
{
|
||||
return Protocol.UNKNOWN;
|
||||
}
|
||||
|
||||
public static UnknownTalkgroupIdentifier create(int value)
|
||||
{
|
||||
return new UnknownTalkgroupIdentifier(value);
|
||||
}
|
||||
}
|
||||
296
src/main/java/io/github/dsheirer/identifier/tone/AmbeTone.java
Normal file
296
src/main/java/io/github/dsheirer/identifier/tone/AmbeTone.java
Normal file
@@ -0,0 +1,296 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2020 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
package io.github.dsheirer.identifier.tone;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* AMBE tones enumeration
|
||||
*
|
||||
* Note: this uses identical values as the Tone enumeraton in the JMBE library
|
||||
*/
|
||||
public enum AmbeTone
|
||||
{
|
||||
DTMF_0("0", "DTMF 0"),
|
||||
DTMF_1("1", "DTMF 1"),
|
||||
DTMF_2("2", "DTMF 2"),
|
||||
DTMF_3("3", "DTMF 3"),
|
||||
DTMF_4("4", "DTMF 4"),
|
||||
DTMF_5("5", "DTMF 5"),
|
||||
DTMF_6("6", "DTMF 6"),
|
||||
DTMF_7("7", "DTMF 7"),
|
||||
DTMF_8("8", "DTMF 8"),
|
||||
DTMF_9("9", "DTMF 9"),
|
||||
DTMF_A("A", "DTMF A"),
|
||||
DTMF_B("B", "DTMF B"),
|
||||
DTMF_C("C", "DTMF C"),
|
||||
DTMF_D("D", "DTMF D"),
|
||||
DTMF_STAR("*", "DTMF *"),
|
||||
DTMF_POUND("#", "DTMF #"),
|
||||
|
||||
KNOX_0("0", "KNOX 0"),
|
||||
KNOX_1("1", "KNOX 1"),
|
||||
KNOX_2("2", "KNOX 2"),
|
||||
KNOX_3("3", "KNOX 3"),
|
||||
KNOX_4("4", "KNOX 4"),
|
||||
KNOX_5("5", "KNOX 5"),
|
||||
KNOX_6("6", "KNOX 6"),
|
||||
KNOX_7("7", "KNOX 7"),
|
||||
KNOX_8("8", "KNOX 8"),
|
||||
KNOX_9("9", "KNOX 9"),
|
||||
KNOX_A("A", "KNOX A"),
|
||||
KNOX_B("B", "KNOX B"),
|
||||
KNOX_C("C", "KNOX C"),
|
||||
KNOX_D("D", "KNOX D"),
|
||||
KNOX_STAR("*", "KNOX "),
|
||||
KNOX_POUND("#", "KNOX #"),
|
||||
|
||||
BUSY_TONE("BUSY TONE", "BUSY TONE"),
|
||||
CALL_PROGRESS("CALL PROGRESS", "CALL PROGRESS TONE"),
|
||||
DIAL_TONE("DIAL TONE", "DIAL TONE"),
|
||||
RINGING_TONE("RINGING TONE", "RINGING TONE"),
|
||||
|
||||
HZ_156_25("156.25", "TONE 156.25"),
|
||||
HZ_187_50("187.50", "TONE 187.50"),
|
||||
HZ_218_75("218.75", "TONE 218.75"),
|
||||
HZ_250_00("250.00", "TONE 250.00"),
|
||||
HZ_281_25("281.25", "TONE 281.25"),
|
||||
HZ_312_50("312.50", "TONE 312.50"),
|
||||
HZ_343_75("343.75", "TONE 343.75"),
|
||||
HZ_375_00("375.00", "TONE 375.00"),
|
||||
HZ_406_25("406.25", "TONE 406.25"),
|
||||
HZ_437_50("437.50", "TONE 437.50"),
|
||||
HZ_468_75("468.75", "TONE 468.75"),
|
||||
HZ_500_00("500.00", "TONE 500.00"),
|
||||
HZ_531_25("531.25", "TONE 531.25"),
|
||||
HZ_562_50("562.50", "TONE 562.50"),
|
||||
HZ_593_75("593.75", "TONE 593.75"),
|
||||
HZ_625_00("625.00", "TONE 625.00"),
|
||||
HZ_656_25("656.25", "TONE 656.25"),
|
||||
HZ_687_50("687.5", "TONE 687.50"),
|
||||
HZ_718_75("718.75", "TONE 718.75"),
|
||||
HZ_750_00("750.00", "TONE 750.00"),
|
||||
HZ_781_25("781.25", "TONE 781.25"),
|
||||
HZ_812_50("812.50", "TONE 812.50"),
|
||||
HZ_843_75("843.75", "TONE 843.75"),
|
||||
HZ_875_00("875.00", "TONE 875.00"),
|
||||
HZ_906_25("906.25", "TONE 906.25"),
|
||||
HZ_937_50("937.50", "TONE 937.50"),
|
||||
HZ_968_75("968.75", "TONE 968.75"),
|
||||
HZ_1000_00("1000.00", "TONE 1000.00"),
|
||||
HZ_1031_25("1031.25", "TONE 1031.25"),
|
||||
HZ_1062_50("1062.50", "TONE 1062.50"),
|
||||
HZ_1093_75("1093.75", "TONE 1093.75"),
|
||||
HZ_1125_00("1125.00", "TONE 1125.00"),
|
||||
HZ_1156_25("1156.25", "TONE 1156.25"),
|
||||
HZ_1187_50("1187.50", "TONE 1187.50"),
|
||||
HZ_1218_75("1218.75", "TONE 1218.75"),
|
||||
HZ_1250_00("1250.00", "TONE 1250.00"),
|
||||
HZ_1281_25("1281.25", "TONE 1281.25"),
|
||||
HZ_1312_50("1312.50", "TONE 1312.50"),
|
||||
HZ_1343_75("1343.75", "TONE 1343.75"),
|
||||
HZ_1375_00("1375.00", "TONE 1375.00"),
|
||||
HZ_1406_25("1406.25", "TONE 1406.25"),
|
||||
HZ_1437_50("1437.50", "TONE 1437.50"),
|
||||
HZ_1468_75("1468.75", "TONE 1468.75"),
|
||||
HZ_1500_00("1500.00", "TONE 1500.00"),
|
||||
HZ_1531_25("1531.25", "TONE 1531.25"),
|
||||
HZ_1562_50("1562.50", "TONE 1562.50"),
|
||||
HZ_1593_75("1593.75", "TONE 1593.75"),
|
||||
HZ_1625_00("1625.00", "TONE 1625.00"),
|
||||
HZ_1656_25("1656.25", "TONE 1656.25"),
|
||||
HZ_1687_50("1687.50", "TONE 1687.50"),
|
||||
HZ_1718_75("1718.75", "TONE 1718.75"),
|
||||
HZ_1750_00("1750.00", "TONE 1750.00"),
|
||||
HZ_1781_25("1781.25", "TONE 1781.25"),
|
||||
HZ_1812_50("1812.50", "TONE 1812.50"),
|
||||
HZ_1843_75("1843.75", "TONE 1843.75"),
|
||||
HZ_1875_00("1875.00", "TONE 1875.00"),
|
||||
HZ_1906_25("1906.25", "TONE 1906.25"),
|
||||
HZ_1937_50("1937.50", "TONE 1937.50"),
|
||||
HZ_1968_75("1968.75", "TONE 1968.75"),
|
||||
HZ_2000_00("2000.00", "TONE 2000.00"),
|
||||
HZ_2031_25("2031.25", "TONE 2031.25"),
|
||||
HZ_2062_50("2062.50", "TONE 2062.50"),
|
||||
HZ_2093_75("2093.75", "TONE 2093.75"),
|
||||
HZ_2125_00("2125.00", "TONE 2125.00"),
|
||||
HZ_2156_25("2156.25", "TONE 2156.25"),
|
||||
HZ_2187_50("2187.50", "TONE 2187.50"),
|
||||
HZ_2218_75("2218.75", "TONE 2218.75"),
|
||||
HZ_2250_00("2250.00", "TONE 2250.00"),
|
||||
HZ_2281_25("2281.25", "TONE 2281.25"),
|
||||
HZ_2312_50("2312.50", "TONE 2312.50"),
|
||||
HZ_2343_75("2343.75", "TONE 2343.75"),
|
||||
HZ_2375_00("2375.00", "TONE 2375.00"),
|
||||
HZ_2406_25("2406.25", "TONE 2406.25"),
|
||||
HZ_2437_50("2437.50", "TONE 2437.50"),
|
||||
HZ_2468_75("2468.75", "TONE 2468.75"),
|
||||
HZ_2500_00("2500.00", "TONE 2500.00"),
|
||||
HZ_2531_25("2531.25", "TONE 2531.25"),
|
||||
HZ_2562_50("2562.50", "TONE 2562.50"),
|
||||
HZ_2593_75("2593.75", "TONE 2593.75"),
|
||||
HZ_2625_00("2625.00", "TONE 2625.00"),
|
||||
HZ_2656_25("2656.25", "TONE 2656.25"),
|
||||
HZ_2718_75("2718.75", "TONE 2718.75"),
|
||||
HZ_2687_50("2687.50", "TONE 2687.50"),
|
||||
HZ_2750_00("2750.00", "TONE 2750.00"),
|
||||
HZ_2781_25("2781.25", "TONE 2781.25"),
|
||||
HZ_2812_50("2812.50", "TONE 2812.50"),
|
||||
HZ_2843_75("2843.75", "TONE 2843.75"),
|
||||
HZ_2875_00("2875.00", "TONE 2875.00"),
|
||||
HZ_2906_25("2906.25", "TONE 2906.25"),
|
||||
HZ_2937_50("2937.50", "TONE 2937.50"),
|
||||
HZ_2968_75("2968.75", "TONE 2968.75"),
|
||||
HZ_3000_00("3000.00", "TONE 3000.00"),
|
||||
HZ_3031_25("3031.25", "TONE 3031.25"),
|
||||
HZ_3062_50("3062.50", "TONE 3062.50"),
|
||||
HZ_3093_75("3093.75", "TONE 3093.75"),
|
||||
HZ_3125_00("3125.00", "TONE 3125.00"),
|
||||
HZ_3156_25("3156.25", "TONE 3156.25"),
|
||||
HZ_3187_50("3187.50", "TONE 3187.50"),
|
||||
HZ_3218_75("3218.75", "TONE 3218.75"),
|
||||
HZ_3250_00("3250.00", "TONE 3250.00"),
|
||||
HZ_3281_25("3281.25", "TONE 3281.25"),
|
||||
HZ_3312_50("3312.50", "TONE 3312.50"),
|
||||
HZ_3343_75("3343.75", "TONE 3343.75"),
|
||||
HZ_3375_00("3375.00", "TONE 3375.00"),
|
||||
HZ_3406_25("3406.25", "TONE 3406.25"),
|
||||
HZ_3437_50("3437.50", "TONE 3437.50"),
|
||||
HZ_3468_75("3468.75", "TONE 3468.75"),
|
||||
HZ_3500_00("3500.00", "TONE 3500.00"),
|
||||
HZ_3531_25("3531.25", "TONE 3531.25"),
|
||||
HZ_3562_50("3562.50", "TONE 3562.50"),
|
||||
HZ_3593_75("3593.75", "TONE 3593.75"),
|
||||
HZ_3625_00("3625.00", "TONE 3625.00"),
|
||||
HZ_3656_25("3656.25", "TONE 3656.25"),
|
||||
HZ_3687_50("3687.50", "TONE 3687.50"),
|
||||
HZ_3718_75("3718.75", "TONE 3718.75"),
|
||||
HZ_3750_00("3750.00", "TONE 3750.00"),
|
||||
HZ_3781_25("3781.25", "TONE 3781.25"),
|
||||
HZ_3812_50("3812.50", "TONE 3812.50"),
|
||||
|
||||
INVALID("INVALID", "INVALID");
|
||||
|
||||
private String mValue;
|
||||
private String mLabel;
|
||||
|
||||
public static final EnumSet<AmbeTone> ALL_VALID_TONES = EnumSet.range(AmbeTone.DTMF_0, AmbeTone.HZ_3812_50);
|
||||
|
||||
public static final EnumSet<AmbeTone> CALL_PROGRESS_TONES = EnumSet.range(AmbeTone.BUSY_TONE, AmbeTone.RINGING_TONE);
|
||||
public static final EnumSet<AmbeTone> DISCRETE_TONES = EnumSet.range(AmbeTone.HZ_156_25, AmbeTone.HZ_3812_50);
|
||||
public static final EnumSet<AmbeTone> DTMF_TONES = EnumSet.range(AmbeTone.DTMF_0, AmbeTone.DTMF_POUND);
|
||||
public static final EnumSet<AmbeTone> KNOX_TONES = EnumSet.range(AmbeTone.KNOX_0, AmbeTone.KNOX_POUND);
|
||||
|
||||
private static final Map<String,AmbeTone> CALL_PROGRESS_LOOKUP_MAP = new TreeMap<>();
|
||||
private static final Map<String,AmbeTone> DTMF_LOOKUP_MAP = new TreeMap<>();
|
||||
private static final Map<String,AmbeTone> KNOX_LOOKUP_MAP = new TreeMap<>();
|
||||
private static final Map<String,AmbeTone> TONE_LOOKUP_MAP = new TreeMap<>();
|
||||
|
||||
static
|
||||
{
|
||||
for(AmbeTone tone : CALL_PROGRESS_TONES)
|
||||
{
|
||||
CALL_PROGRESS_LOOKUP_MAP.put(tone.getValue(), tone);
|
||||
}
|
||||
for(AmbeTone tone : DTMF_TONES)
|
||||
{
|
||||
DTMF_LOOKUP_MAP.put(tone.getValue(), tone);
|
||||
}
|
||||
for(AmbeTone tone : KNOX_TONES)
|
||||
{
|
||||
KNOX_LOOKUP_MAP.put(tone.getValue(), tone);
|
||||
}
|
||||
for(AmbeTone tone : DISCRETE_TONES)
|
||||
{
|
||||
TONE_LOOKUP_MAP.put(tone.getValue(), tone);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a tone entry
|
||||
*
|
||||
* @param value for the tone
|
||||
* @param label for display value
|
||||
*/
|
||||
AmbeTone(String value, String label)
|
||||
{
|
||||
mValue = value;
|
||||
mLabel = label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Value of the tone as produced by the JMBE library
|
||||
*/
|
||||
public String getValue()
|
||||
{
|
||||
return mValue;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return mLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup the tone entry from the type and value parameters.
|
||||
* @param type of tone, one of: CALL PROGRESS, DTMF, KNOX, or TONE
|
||||
* @param tone value with the tone type set
|
||||
* @return tone entry or INVALID
|
||||
*/
|
||||
public static AmbeTone fromValues(String type, String tone)
|
||||
{
|
||||
if(type != null && tone != null)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case "CALL PROGRESS":
|
||||
if(CALL_PROGRESS_LOOKUP_MAP.containsKey(tone))
|
||||
{
|
||||
return CALL_PROGRESS_LOOKUP_MAP.get(tone);
|
||||
}
|
||||
break;
|
||||
case "DTMF":
|
||||
if(DTMF_LOOKUP_MAP.containsKey(tone))
|
||||
{
|
||||
return DTMF_LOOKUP_MAP.get(tone);
|
||||
}
|
||||
break;
|
||||
case "KNOX":
|
||||
if(KNOX_LOOKUP_MAP.containsKey(tone))
|
||||
{
|
||||
return KNOX_LOOKUP_MAP.get(tone);
|
||||
}
|
||||
break;
|
||||
case "TONE":
|
||||
if(TONE_LOOKUP_MAP.containsKey(tone))
|
||||
{
|
||||
return TONE_LOOKUP_MAP.get(tone);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return INVALID;
|
||||
}
|
||||
}
|
||||
@@ -24,14 +24,12 @@ package io.github.dsheirer.identifier.tone;
|
||||
|
||||
import io.github.dsheirer.protocol.Protocol;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* P25 Phase II AMBE audio codec tone metadata
|
||||
*/
|
||||
public class P25ToneIdentifier extends ToneIdentifier
|
||||
{
|
||||
public P25ToneIdentifier(String value)
|
||||
public P25ToneIdentifier(ToneSequence value)
|
||||
{
|
||||
super(value);
|
||||
}
|
||||
@@ -42,7 +40,7 @@ public class P25ToneIdentifier extends ToneIdentifier
|
||||
return Protocol.APCO25;
|
||||
}
|
||||
|
||||
public static P25ToneIdentifier create(String value)
|
||||
public static P25ToneIdentifier create(ToneSequence value)
|
||||
{
|
||||
return new P25ToneIdentifier(value);
|
||||
}
|
||||
|
||||
162
src/main/java/io/github/dsheirer/identifier/tone/Tone.java
Normal file
162
src/main/java/io/github/dsheirer/identifier/tone/Tone.java
Normal file
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2020 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
package io.github.dsheirer.identifier.tone;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
|
||||
import javafx.beans.Observable;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.util.Callback;
|
||||
|
||||
/**
|
||||
* An AMBE tone with a duration in 20 millisecond units.
|
||||
*/
|
||||
public class Tone
|
||||
{
|
||||
private AmbeTone mAmbeTone;
|
||||
private int mDuration = 0;
|
||||
private StringProperty mValueProperty = new SimpleStringProperty();
|
||||
|
||||
/**
|
||||
* Constructs an instance for the specified tone and duration
|
||||
*/
|
||||
public Tone(AmbeTone tone, int duration)
|
||||
{
|
||||
mAmbeTone = tone;
|
||||
mDuration = duration;
|
||||
}
|
||||
|
||||
public Tone copyOf()
|
||||
{
|
||||
return new Tone(mAmbeTone, mDuration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance for the specified tone.
|
||||
*/
|
||||
public Tone(AmbeTone tone)
|
||||
{
|
||||
this(tone, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance
|
||||
*
|
||||
* Do not use. Used by Jackson for serialization.
|
||||
*/
|
||||
public Tone()
|
||||
{
|
||||
//Empty for jackson constructor
|
||||
|
||||
//Placeholder to ensure no null
|
||||
mAmbeTone = AmbeTone.INVALID;
|
||||
}
|
||||
|
||||
public StringProperty valueProperty()
|
||||
{
|
||||
return mValueProperty;
|
||||
}
|
||||
|
||||
private void updateValueProperty()
|
||||
{
|
||||
//The value property doesn't always fire, so this hack seems to get it to fire consistently
|
||||
mValueProperty.get();
|
||||
mValueProperty.set(toString());
|
||||
mValueProperty.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ambe tone for this sequence
|
||||
*/
|
||||
@JacksonXmlProperty(isAttribute = true, localName = "value")
|
||||
public AmbeTone getAmbeTone()
|
||||
{
|
||||
return mAmbeTone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the tone
|
||||
*/
|
||||
public void setAmbeTone(AmbeTone tone)
|
||||
{
|
||||
if(tone != null)
|
||||
{
|
||||
mAmbeTone = tone;
|
||||
updateValueProperty();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Count of 20 millisecond units of duration
|
||||
*/
|
||||
@JacksonXmlProperty(isAttribute = true, localName = "duration")
|
||||
public int getDuration()
|
||||
{
|
||||
return mDuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the duration in units of 20 milliseconds.
|
||||
*/
|
||||
public void setDuration(int duration)
|
||||
{
|
||||
mDuration = duration;
|
||||
updateValueProperty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments the duration count by 1 unit of 20 milliseconds.
|
||||
*/
|
||||
public void incrementDuration()
|
||||
{
|
||||
mDuration++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this tone sequence is contained in the other tone sequence, meaning that the specific tone for this
|
||||
* sequence matches the other sequence tone and this duration is less than or equal to the other duration.
|
||||
* @param other to check for contains
|
||||
* @return true if this sequence is contained in the other sequence.
|
||||
*/
|
||||
@JsonIgnore
|
||||
public boolean isContainedIn(Tone other)
|
||||
{
|
||||
return other != null && getAmbeTone() == other.getAmbeTone() && getDuration() <= other.getDuration();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(mAmbeTone.toString());
|
||||
sb.append(" (").append(mDuration * 20).append("ms)");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an observable property extractor for use with observable lists to detect changes internal to this object.
|
||||
*/
|
||||
public static Callback<Tone,Observable[]> extractor()
|
||||
{
|
||||
return (Tone tone) -> new Observable[] {tone.valueProperty()};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -23,16 +23,16 @@
|
||||
package io.github.dsheirer.identifier.tone;
|
||||
|
||||
import io.github.dsheirer.identifier.Form;
|
||||
import io.github.dsheirer.identifier.Identifier;
|
||||
import io.github.dsheirer.identifier.IdentifierClass;
|
||||
import io.github.dsheirer.identifier.Role;
|
||||
import io.github.dsheirer.identifier.string.StringIdentifier;
|
||||
|
||||
/**
|
||||
* Pass-band audio tones identifier
|
||||
*/
|
||||
public abstract class ToneIdentifier extends StringIdentifier
|
||||
public abstract class ToneIdentifier extends Identifier<ToneSequence>
|
||||
{
|
||||
public ToneIdentifier(String value)
|
||||
public ToneIdentifier(ToneSequence value)
|
||||
{
|
||||
super(value, IdentifierClass.USER, Form.TONE, Role.FROM);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2020 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
package io.github.dsheirer.identifier.tone;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
|
||||
import com.google.common.base.Joiner;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A sequentially ordered list of tones
|
||||
*/
|
||||
public class ToneSequence
|
||||
{
|
||||
private ObservableList<Tone> mTones = FXCollections.observableArrayList(Tone.extractor());
|
||||
|
||||
/**
|
||||
* Constructs an instance
|
||||
* @param tones for the instance
|
||||
*/
|
||||
public ToneSequence(List<Tone> tones)
|
||||
{
|
||||
mTones.setAll(tones);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance
|
||||
*/
|
||||
public ToneSequence()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a deep copy of this tone sequence
|
||||
*/
|
||||
public ToneSequence copyOf()
|
||||
{
|
||||
ToneSequence toneSequence = new ToneSequence();
|
||||
for(Tone tone: mTones)
|
||||
{
|
||||
toneSequence.addTone(tone.copyOf());
|
||||
}
|
||||
return toneSequence;
|
||||
}
|
||||
|
||||
public ObservableList<Tone> tonesProperty()
|
||||
{
|
||||
return mTones;
|
||||
}
|
||||
|
||||
/**
|
||||
* List of tones
|
||||
*/
|
||||
@JacksonXmlProperty(isAttribute = false, localName = "tone")
|
||||
public List<Tone> getTones()
|
||||
{
|
||||
return mTones;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the tones for this list
|
||||
*/
|
||||
public void setTones(List<Tone> tones)
|
||||
{
|
||||
if(tones != null)
|
||||
{
|
||||
mTones.setAll(tones);
|
||||
}
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public boolean hasTones()
|
||||
{
|
||||
return !mTones.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all tones from this sequence
|
||||
*/
|
||||
public void clear()
|
||||
{
|
||||
mTones.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a tone to this sequence
|
||||
*/
|
||||
public void addTone(Tone tone)
|
||||
{
|
||||
if(tone != null)
|
||||
{
|
||||
mTones.add(tone);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the tone from this sequence
|
||||
*/
|
||||
public void removeTone(Tone tone)
|
||||
{
|
||||
if(tone != null)
|
||||
{
|
||||
mTones.remove(tone);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
if(mTones.isEmpty())
|
||||
{
|
||||
return "Tones: (empty)";
|
||||
}
|
||||
|
||||
return Joiner.on(",").join(mTones);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this sequence of tones is contained in the argument tone sequence. This method is used for
|
||||
* matching this sequence to another sequence, where this sequence is either a full or partial sequence contained
|
||||
* in the argument sequence.
|
||||
*
|
||||
* @param other to check for containment
|
||||
* @return true if contained
|
||||
*/
|
||||
public boolean isContainedIn(ToneSequence other)
|
||||
{
|
||||
if(other == null || other.getTones().isEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
List<Tone> otherTones = other.getTones();
|
||||
|
||||
int pointer = 0;
|
||||
|
||||
for(Tone thisTone: mTones)
|
||||
{
|
||||
boolean matches = false;
|
||||
|
||||
for(int x = pointer; x < otherTones.size(); x++)
|
||||
{
|
||||
if(thisTone.isContainedIn(otherTones.get(x)))
|
||||
{
|
||||
pointer = x + 1;
|
||||
matches = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!matches)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user