mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 08:37:25 -05:00
Compare commits
214 Commits
v0.3.0-bet
...
v0.3.4-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dfaf506e23 | ||
|
|
81c9a352a8 | ||
|
|
e6937764c3 | ||
|
|
5bfc5bf456 | ||
|
|
ce83273393 | ||
|
|
95aa9f8803 | ||
|
|
3619b480f8 | ||
|
|
830b2a2d34 | ||
|
|
78bb5ffe43 | ||
|
|
5dd1664844 | ||
|
|
8868c1f954 | ||
|
|
646bd78037 | ||
|
|
5af4cb8706 | ||
|
|
45a6c5a0b6 | ||
|
|
b563f2d11b | ||
|
|
148ddd0bd5 | ||
|
|
a0630102e6 | ||
|
|
3d1ac30646 | ||
|
|
dda37a1198 | ||
|
|
eaf7c7d11e | ||
|
|
80c5ad1bc8 | ||
|
|
956bf2d76a | ||
|
|
1406d5576a | ||
|
|
03e39f3343 | ||
|
|
28f351287c | ||
|
|
54227703a2 | ||
|
|
bb078de0a9 | ||
|
|
ec30cd6305 | ||
|
|
5a88ac0200 | ||
|
|
05eea44f7e | ||
|
|
030fc1617c | ||
|
|
594a77a9d0 | ||
|
|
c2fcc9e85d | ||
|
|
1c06c4382f | ||
|
|
3d9b38bef5 | ||
|
|
d5b377b1af | ||
|
|
69e9bed2af | ||
|
|
ddad4b6fb0 | ||
|
|
b65dd7e414 | ||
|
|
b076587f30 | ||
|
|
336669f1d5 | ||
|
|
46cf7f4193 | ||
|
|
e9aeb09011 | ||
|
|
c7f00ea124 | ||
|
|
1759f4a804 | ||
|
|
3d9044802e | ||
|
|
42aec490bd | ||
|
|
c3f5c1c70e | ||
|
|
188a521770 | ||
|
|
6e352143d2 | ||
|
|
7391265949 | ||
|
|
26b97f09b7 | ||
|
|
1d2d9e8630 | ||
|
|
ee6aeafa84 | ||
|
|
47cc194415 | ||
|
|
9316599dec | ||
|
|
a1535c4157 | ||
|
|
b478068475 | ||
|
|
7286c978da | ||
|
|
628d514462 | ||
|
|
3478702845 | ||
|
|
695d622603 | ||
|
|
e8e47bfb40 | ||
|
|
c1a4425969 | ||
|
|
4fa1a1aa81 | ||
|
|
4e1f9bcf97 | ||
|
|
50bb96b14a | ||
|
|
51ea70f279 | ||
|
|
e15f271a54 | ||
|
|
605475c98b | ||
|
|
86248c511a | ||
|
|
b1e07f762c | ||
|
|
f2d1ac7e48 | ||
|
|
d114282e4b | ||
|
|
0fd20655fa | ||
|
|
181527f54c | ||
|
|
910587bad7 | ||
|
|
1dc9a7fb0e | ||
|
|
eef29d28da | ||
|
|
a3ecb339be | ||
|
|
910a08f7bb | ||
|
|
5a76f31dea | ||
|
|
1b42e64f50 | ||
|
|
1ddc0a33a5 | ||
|
|
88580af436 | ||
|
|
64688a3c20 | ||
|
|
8be3399a6b | ||
|
|
28340809ca | ||
|
|
f3d3a8187a | ||
|
|
8484e837b8 | ||
|
|
01b188ea25 | ||
|
|
108691dc3c | ||
|
|
455aa97286 | ||
|
|
d608834214 | ||
|
|
41660e1881 | ||
|
|
110ccb158c | ||
|
|
64ccacf04a | ||
|
|
f00b9555fe | ||
|
|
85442a9648 | ||
|
|
c67a0b329d | ||
|
|
8035d64fcd | ||
|
|
df2a061a08 | ||
|
|
e430319937 | ||
|
|
724f769771 | ||
|
|
c196cfebed | ||
|
|
e80b5866d4 | ||
|
|
c8994d5593 | ||
|
|
99ef57c90f | ||
|
|
be62ae0459 | ||
|
|
b9be6f43e0 | ||
|
|
d5ad3f807d | ||
|
|
d85ebd018d | ||
|
|
ab4e31ae00 | ||
|
|
5efd89632e | ||
|
|
1dc3863489 | ||
|
|
441286ba13 | ||
|
|
e4323df347 | ||
|
|
a872e0d664 | ||
|
|
fbc92cfe31 | ||
|
|
1a432197ac | ||
|
|
fbc6e508bd | ||
|
|
f9b6e67b00 | ||
|
|
a628800a71 | ||
|
|
25f71a76c4 | ||
|
|
5fe8ccd478 | ||
|
|
069f951a86 | ||
|
|
dab6df7836 | ||
|
|
89da46b63c | ||
|
|
5f2ce2a9f2 | ||
|
|
7a0b377971 | ||
|
|
5dbe0ecce3 | ||
|
|
6647c581a6 | ||
|
|
a2ab5bfa95 | ||
|
|
ed486440b8 | ||
|
|
13464e01fc | ||
|
|
ea46a8b0e8 | ||
|
|
d510c34356 | ||
|
|
ae8a44caed | ||
|
|
1aa85a86ca | ||
|
|
17539d4d55 | ||
|
|
1db1d28390 | ||
|
|
37a941e904 | ||
|
|
57f6655824 | ||
|
|
4cd8f8209f | ||
|
|
61bfef5798 | ||
|
|
ef172a04c6 | ||
|
|
a877afcceb | ||
|
|
980ad72d4d | ||
|
|
9b746cc032 | ||
|
|
f51ae0b5da | ||
|
|
561078e9bf | ||
|
|
e052b01f9b | ||
|
|
09cf4fcfd7 | ||
|
|
5e731d0e9f | ||
|
|
670a02b0ba | ||
|
|
9ef156b061 | ||
|
|
d9cf1b19f3 | ||
|
|
a4a339b505 | ||
|
|
119370c46e | ||
|
|
4eb66e6045 | ||
|
|
8827ecd0e9 | ||
|
|
8660002f93 | ||
|
|
2058fcbc1d | ||
|
|
9515dfa380 | ||
|
|
9e9a604c6a | ||
|
|
234e313b7a | ||
|
|
e1e7169029 | ||
|
|
f3605db0ed | ||
|
|
c0a6d578c7 | ||
|
|
79b4b30ec7 | ||
|
|
17c7466c6b | ||
|
|
8162d6ffd6 | ||
|
|
cd60251337 | ||
|
|
5647879b37 | ||
|
|
6916d95cdf | ||
|
|
a0c32f6fe0 | ||
|
|
c3d60dc174 | ||
|
|
e55a2226a2 | ||
|
|
9f01678b00 | ||
|
|
46425e9cae | ||
|
|
3726401563 | ||
|
|
a3e50acfe3 | ||
|
|
cf0018e6ba | ||
|
|
e8055dcab0 | ||
|
|
fce3d5c4f3 | ||
|
|
9cc0d367a8 | ||
|
|
2ca9e5d5ce | ||
|
|
861203c3a0 | ||
|
|
7c930deefe | ||
|
|
0e0af932eb | ||
|
|
6ba5e91fcb | ||
|
|
34dd2161ef | ||
|
|
2543072e08 | ||
|
|
281be147f8 | ||
|
|
12ecca4555 | ||
|
|
4c27d04120 | ||
|
|
ece202315f | ||
|
|
6afe5dcec9 | ||
|
|
8db47c25bc | ||
|
|
6a340050c6 | ||
|
|
183eb2f7c7 | ||
|
|
6bc92e8b94 | ||
|
|
767b302ed7 | ||
|
|
952d930b5b | ||
|
|
26087c465f | ||
|
|
74c15d530b | ||
|
|
8621d1c8e2 | ||
|
|
1cd45a1b79 | ||
|
|
8215b78a43 | ||
|
|
f53519ad59 | ||
|
|
e6ab615931 | ||
|
|
0c84984fcc | ||
|
|
b3e493989e | ||
|
|
50e838749d |
34
.classpath
34
.classpath
@@ -1,34 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="lib" path="imports/commons-lang3-3.2.1.jar"/>
|
||||
<classpathentry kind="lib" path="imports/jide-oss-3.5.15.jar"/>
|
||||
<classpathentry kind="lib" path="imports/jsr80-1.0.1.jar"/>
|
||||
<classpathentry kind="lib" path="imports/libusb4java-1.2.0-linux-arm.jar"/>
|
||||
<classpathentry kind="lib" path="imports/libusb4java-1.2.0-linux-x86_64.jar"/>
|
||||
<classpathentry kind="lib" path="imports/libusb4java-1.2.0-linux-x86.jar"/>
|
||||
<classpathentry kind="lib" path="imports/libusb4java-1.2.0-osx-x86_64.jar"/>
|
||||
<classpathentry kind="lib" path="imports/libusb4java-1.2.0-osx-x86.jar"/>
|
||||
<classpathentry kind="lib" path="imports/libusb4java-1.2.0-windows-x86_64.jar"/>
|
||||
<classpathentry kind="lib" path="imports/libusb4java-1.2.0-windows-x86.jar"/>
|
||||
<classpathentry kind="lib" path="imports/miglayout-4.0-swing.jar"/>
|
||||
<classpathentry kind="lib" path="imports/usb-api-1.0.2.jar"/>
|
||||
<classpathentry kind="lib" path="imports/usb4java-1.2.0.jar"/>
|
||||
<classpathentry kind="lib" path="imports/usb4java-javax-1.2.0.jar"/>
|
||||
<classpathentry kind="lib" path="config"/>
|
||||
<classpathentry kind="lib" path="imports/JTransforms-3.0.jar" sourcepath="/home/denny/.m2/repository/com/github/wendykierp/JTransforms/3.0/JTransforms-3.0-sources.jar"/>
|
||||
<classpathentry kind="lib" path="imports/libusb4java-1.2.0-linux-ppc.jar"/>
|
||||
<classpathentry kind="lib" path="imports/JLargeArrays-1.2.jar"/>
|
||||
<classpathentry kind="lib" path="imports/slf4j-api-1.7.7.jar"/>
|
||||
<classpathentry kind="lib" path="imports/logback-classic-1.1.2.jar"/>
|
||||
<classpathentry kind="lib" path="imports/logback-core-1.1.2.jar"/>
|
||||
<classpathentry kind="lib" path="imports/commons-io-2.4.jar"/>
|
||||
<classpathentry kind="lib" path="imports/jmbe-interface-0.3.2.jar"/>
|
||||
<classpathentry kind="lib" path="imports/tablefilter-swing-5.2.1.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:file:/home/denny/Downloads/tablefilter-swing-5.2.1-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
@@ -1,4 +0,0 @@
|
||||
[Dolphin]
|
||||
Timestamp=2015,9,8,20,39,49
|
||||
Version=3
|
||||
ViewMode=1
|
||||
35
.gitignore
vendored
35
.gitignore
vendored
@@ -1,6 +1,35 @@
|
||||
*.class
|
||||
### JetBrains template
|
||||
.idea/
|
||||
/classes*
|
||||
/product*
|
||||
/bin*
|
||||
out/
|
||||
.directory
|
||||
.settings
|
||||
.settings
|
||||
|
||||
## File-based project format:
|
||||
*.iws
|
||||
*.iml
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
### Java template
|
||||
*.class
|
||||
*.log
|
||||
# Package Files #
|
||||
*.jar
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
### Gradle template
|
||||
.gradle
|
||||
/build/
|
||||
|
||||
# Ignore Gradle GUI config
|
||||
gradle-app.setting
|
||||
|
||||
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
|
||||
!gradle-wrapper.jar
|
||||
|
||||
# Cache of project
|
||||
.gradletasknamecache
|
||||
|
||||
9
.idea/codeStyleSettings.xml
generated
9
.idea/codeStyleSettings.xml
generated
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectCodeStyleSettingsManager">
|
||||
<option name="PER_PROJECT_SETTINGS">
|
||||
<value />
|
||||
</option>
|
||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default (1)" />
|
||||
</component>
|
||||
</project>
|
||||
21
.idea/compiler.xml
generated
21
.idea/compiler.xml
generated
@@ -1,22 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<resourceExtensions />
|
||||
<wildcardResourcePatterns>
|
||||
<entry name="!?*.java" />
|
||||
<entry name="!?*.form" />
|
||||
<entry name="!?*.class" />
|
||||
<entry name="!?*.groovy" />
|
||||
<entry name="!?*.scala" />
|
||||
<entry name="!?*.flex" />
|
||||
<entry name="!?*.kt" />
|
||||
<entry name="!?*.clj" />
|
||||
<entry name="!?*.aj" />
|
||||
</wildcardResourcePatterns>
|
||||
<annotationProcessing>
|
||||
<profile default="true" name="Default" enabled="false">
|
||||
<processorPath useClasspath="true" />
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
<bytecodeTargetLevel>
|
||||
<module name="sdr-trunk_main" target="1.8" />
|
||||
<module name="sdr-trunk_test" target="1.8" />
|
||||
</bytecodeTargetLevel>
|
||||
</component>
|
||||
</project>
|
||||
9
.idea/copyright/profiles_settings.xml
generated
9
.idea/copyright/profiles_settings.xml
generated
@@ -1,9 +0,0 @@
|
||||
<component name="CopyrightManager">
|
||||
<settings default="sdrtrunk">
|
||||
<LanguageOptions name="__TEMPLATE__">
|
||||
<option name="addBlankAfter" value="false" />
|
||||
<option name="separateBefore" value="true" />
|
||||
<option name="separateAfter" value="true" />
|
||||
</LanguageOptions>
|
||||
</settings>
|
||||
</component>
|
||||
6
.idea/copyright/sdrtrunk.xml
generated
6
.idea/copyright/sdrtrunk.xml
generated
@@ -1,6 +0,0 @@
|
||||
<component name="CopyrightManager">
|
||||
<copyright>
|
||||
<option name="myName" value="sdrtrunk" />
|
||||
<option name="notice" value="sdrtrunk Copyright (C) 2014-&#36;today.year 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/> " />
|
||||
</copyright>
|
||||
</component>
|
||||
23
.idea/dictionaries/denny.xml
generated
23
.idea/dictionaries/denny.xml
generated
@@ -1,23 +0,0 @@
|
||||
<component name="ProjectDictionaryState">
|
||||
<dictionary name="denny">
|
||||
<words>
|
||||
<w>bahroo</w>
|
||||
<w>broadcastify</w>
|
||||
<w>esnid</w>
|
||||
<w>fleetsync</w>
|
||||
<w>icecast</w>
|
||||
<w>ident</w>
|
||||
<w>polyphase</w>
|
||||
<w>remez</w>
|
||||
<w>samplerate</w>
|
||||
<w>sdrtrunk</w>
|
||||
<w>sheirer</w>
|
||||
<w>shoutcast</w>
|
||||
<w>streamable</w>
|
||||
<w>talkgroup</w>
|
||||
<w>tgid</w>
|
||||
<w>ultravox</w>
|
||||
<w>xtea</w>
|
||||
</words>
|
||||
</dictionary>
|
||||
</component>
|
||||
65
.idea/libraries/imports.xml
generated
65
.idea/libraries/imports.xml
generated
@@ -1,65 +0,0 @@
|
||||
<component name="libraryTable">
|
||||
<library name="imports">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/imports/logback-classic-1.1.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/usb-api-1.0.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/commons-io-2.4.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/commons-lang3-3.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/tablefilter-swing-5.2.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/libusb4java-1.2.0-linux-x86.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/JLargeArrays-1.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/libusb4java-1.2.0-linux-ppc.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/libusb4java-1.2.0-windows-x86.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/libusb4java-1.2.0-osx-x86.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/miglayout-4.0-swing.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/libusb4java-1.2.0-windows-x86_64.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/usb4java-1.2.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/jide-oss-3.5.15.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/libusb4java-1.2.0-linux-x86_64.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/logback-core-1.1.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/usb4java-javax-1.2.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/jsr80-1.0.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/libusb4java-1.2.0-linux-arm.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/libusb4java-1.2.0-osx-x86_64.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/JTransforms-3.0.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/jmbe-interface-0.3.3.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/java-lame-3.98.4.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/commons-codec-1.9.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/commons-logging-1.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/slf4j-api-1.7.21.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC>
|
||||
<root url="https://hc.apache.org/httpcomponents-core-ga/httpcore/apidocs/index.html" />
|
||||
</JAVADOC>
|
||||
<SOURCES>
|
||||
<root url="file://$USER_HOME$/Downloads/httpcomponents-client-4.5.2/examples" />
|
||||
<root url="file://$USER_HOME$/Downloads/httpcomponents-client-4.5.2/fluent-hc/src/examples" />
|
||||
<root url="file://$USER_HOME$/Downloads/httpcomponents-client-4.5.2/fluent-hc/src/main/java" />
|
||||
<root url="file://$USER_HOME$/Downloads/httpcomponents-client-4.5.2/fluent-hc/src/test/java" />
|
||||
<root url="file://$USER_HOME$/Downloads/httpcomponents-client-4.5.2/httpclient-cache/src/main/java" />
|
||||
<root url="file://$USER_HOME$/Downloads/httpcomponents-client-4.5.2/httpclient-cache/src/main/java-deprecated" />
|
||||
<root url="file://$USER_HOME$/Downloads/httpcomponents-client-4.5.2/httpclient-cache/src/test/java" />
|
||||
<root url="file://$USER_HOME$/Downloads/httpcomponents-client-4.5.2/httpclient-osgi/src/main/java" />
|
||||
<root url="file://$USER_HOME$/Downloads/httpcomponents-client-4.5.2/httpclient-osgi/src/test/java" />
|
||||
<root url="file://$USER_HOME$/Downloads/httpcomponents-client-4.5.2/httpclient-win/src/examples" />
|
||||
<root url="file://$USER_HOME$/Downloads/httpcomponents-client-4.5.2/httpclient-win/src/main/java" />
|
||||
<root url="file://$USER_HOME$/Downloads/httpcomponents-client-4.5.2/httpclient-win/src/test/java" />
|
||||
<root url="file://$USER_HOME$/Downloads/httpcomponents-client-4.5.2/httpclient/src/examples" />
|
||||
<root url="file://$USER_HOME$/Downloads/httpcomponents-client-4.5.2/httpclient/src/main/java" />
|
||||
<root url="file://$USER_HOME$/Downloads/httpcomponents-client-4.5.2/httpclient/src/main/java-deprecated" />
|
||||
<root url="file://$USER_HOME$/Downloads/httpcomponents-client-4.5.2/httpclient/src/test/java" />
|
||||
<root url="file://$USER_HOME$/Downloads/httpcomponents-client-4.5.2/httpmime/src/examples" />
|
||||
<root url="file://$USER_HOME$/Downloads/httpcomponents-client-4.5.2/httpmime/src/main/java" />
|
||||
<root url="file://$USER_HOME$/Downloads/httpcomponents-client-4.5.2/httpmime/src/main/java-deprecated" />
|
||||
<root url="file://$USER_HOME$/Downloads/httpcomponents-client-4.5.2/httpmime/src/test/java" />
|
||||
<root url="file://$USER_HOME$/Downloads/httpcomponents-asyncclient-4.1.2/httpasyncclient/src/examples" />
|
||||
<root url="file://$USER_HOME$/Downloads/httpcomponents-asyncclient-4.1.2/httpasyncclient/src/main/java" />
|
||||
<root url="file://$USER_HOME$/Downloads/httpcomponents-asyncclient-4.1.2/httpasyncclient/src/main/java-deprecated" />
|
||||
<root url="file://$USER_HOME$/Downloads/httpcomponents-asyncclient-4.1.2/httpasyncclient/src/test/java" />
|
||||
<root url="file://$USER_HOME$/Downloads/httpcomponents-client-4.5.2/httpclient/src/examples" />
|
||||
<root url="file://$USER_HOME$/Downloads/httpcomponents-client-4.5.2/httpclient/src/main/java" />
|
||||
<root url="file://$USER_HOME$/Downloads/httpcomponents-client-4.5.2/httpclient/src/main/java-deprecated" />
|
||||
<root url="file://$USER_HOME$/Downloads/httpcomponents-client-4.5.2/httpclient/src/test/java" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
@@ -1,20 +0,0 @@
|
||||
<component name="libraryTable">
|
||||
<library name="org.asynchttpclient:async-http-client:2.0.18" type="repository">
|
||||
<properties maven-id="org.asynchttpclient:async-http-client:2.0.18" />
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/imports/slf4j-api-1.7.21.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/javassist-3.20.0-GA.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/axis.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/jaxrpc.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/commons-discovery-0.2.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/activation-1.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/java-mail-1.4.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/wsdl4j-1.5.1.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/radioreference-14.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/mina-core-2.0.16.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/imports/mina-http-2.0.16.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
||||
38
.idea/misc.xml
generated
38
.idea/misc.xml
generated
@@ -1,43 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ClientPropertiesManager">
|
||||
<properties class="javax.swing.AbstractButton">
|
||||
<property name="hideActionText" class="java.lang.Boolean" />
|
||||
</properties>
|
||||
<properties class="javax.swing.JComponent">
|
||||
<property name="html.disable" class="java.lang.Boolean" />
|
||||
</properties>
|
||||
<properties class="javax.swing.JEditorPane">
|
||||
<property name="JEditorPane.w3cLengthUnits" class="java.lang.Boolean" />
|
||||
<property name="JEditorPane.honorDisplayProperties" class="java.lang.Boolean" />
|
||||
<property name="charset" class="java.lang.String" />
|
||||
</properties>
|
||||
<properties class="javax.swing.JList">
|
||||
<property name="List.isFileList" class="java.lang.Boolean" />
|
||||
</properties>
|
||||
<properties class="javax.swing.JPasswordField">
|
||||
<property name="JPasswordField.cutCopyAllowed" class="java.lang.Boolean" />
|
||||
</properties>
|
||||
<properties class="javax.swing.JSlider">
|
||||
<property name="Slider.paintThumbArrowShape" class="java.lang.Boolean" />
|
||||
<property name="JSlider.isFilled" class="java.lang.Boolean" />
|
||||
</properties>
|
||||
<properties class="javax.swing.JTable">
|
||||
<property name="Table.isFileList" class="java.lang.Boolean" />
|
||||
<property name="JTable.autoStartsEdit" class="java.lang.Boolean" />
|
||||
<property name="terminateEditOnFocusLost" class="java.lang.Boolean" />
|
||||
</properties>
|
||||
<properties class="javax.swing.JToolBar">
|
||||
<property name="JToolBar.isRollover" class="java.lang.Boolean" />
|
||||
</properties>
|
||||
<properties class="javax.swing.JTree">
|
||||
<property name="JTree.lineStyle" class="java.lang.String" />
|
||||
</properties>
|
||||
<properties class="javax.swing.text.JTextComponent">
|
||||
<property name="caretAspectRatio" class="java.lang.Double" />
|
||||
<property name="caretWidth" class="java.lang.Integer" />
|
||||
</properties>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
|
||||
4
.idea/modules.xml
generated
4
.idea/modules.xml
generated
@@ -2,7 +2,9 @@
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/sdrtrunk.iml" filepath="$PROJECT_DIR$/sdrtrunk.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/modules/sdr-trunk.iml" filepath="$PROJECT_DIR$/.idea/modules/sdr-trunk.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/modules/sdr-trunk_main.iml" filepath="$PROJECT_DIR$/.idea/modules/sdr-trunk_main.iml" group="sdr-trunk" />
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/modules/sdr-trunk_test.iml" filepath="$PROJECT_DIR$/.idea/modules/sdr-trunk_test.iml" group="sdr-trunk" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
124
.idea/uiDesigner.xml
generated
124
.idea/uiDesigner.xml
generated
@@ -1,124 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Palette2">
|
||||
<group name="Swing">
|
||||
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
|
||||
</item>
|
||||
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
|
||||
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
|
||||
<initial-values>
|
||||
<property name="text" value="Button" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="RadioButton" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="CheckBox" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="Label" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
|
||||
<preferred-size width="-1" height="20" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
|
||||
</item>
|
||||
</group>
|
||||
</component>
|
||||
</project>
|
||||
2
.idea/vcs.xml
generated
2
.idea/vcs.xml
generated
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
23
.project
23
.project
@@ -1,23 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>sdrtrunk</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -1,12 +0,0 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
33
CHANGELOG
33
CHANGELOG
@@ -1,11 +1,31 @@
|
||||
0.3.4 20180418
|
||||
- New P25 C4FM decoder that uses Differential QPSK decoder instead of FM demodulation with 4FSK.
|
||||
- Adds channel auto-start and ordering capability with startup dialog allowing user to invoke or bypass channel
|
||||
auto-start. Provides user with more control over startup configuration.
|
||||
- Adds preferred tuner attribute to channel configuration allowing user to select a preferred tuner for the channel
|
||||
|
||||
0.3.0 2017xxxx (work in progress)
|
||||
0.3.3 20171225
|
||||
- Changes build system from ant to gradle. Thanks to: Roman Tsypuk https://github.com/tsypuk
|
||||
- Adds LIST and ID3 metadata to wav audio recordings
|
||||
|
||||
0.3.2 20171105
|
||||
- Resolves issue with tuner frequency adjustments that was causing channel processing
|
||||
to lockup and show persistent 'overflow' state in each channel status
|
||||
- Resolves issue with broadcastify 'mountpoint-in-use' error handling and updates
|
||||
memory usage logging
|
||||
- Resolves issue with Shoutcast 2 login error
|
||||
|
||||
0.3.1 20171009
|
||||
- Resolves Java 9 incompatibility issues
|
||||
|
||||
0.3.0 20170922
|
||||
- REQUIRES: Java 8 (or newer) for compatibility and eventual changeover to JavaFX
|
||||
- FEATURE: audio streaming - adds capability to stream to multiple remote broadcast
|
||||
servers (Broadcastify, Icecast v2.3 and v2.4+, and Shoutcast V1 and V2). Each
|
||||
stream can be independently configured with a delay. Audio calls are directed
|
||||
to one or more streams by attaching one or more stream identifiers to each alias.
|
||||
- Requires Java 8 (or newer) for compatibility with eventual changeover to JavaFX
|
||||
- Extensive GUI updates for tuner, channel and alias management.
|
||||
- Extensive GUI updates for tuner, channel and alias management. Includes new
|
||||
'Now Playing' channel view and 'Detail' view.
|
||||
- Updated alias list management of alias id values and wildcards. Weighting is now
|
||||
applied to each wildcard so that they can be ordered from most specific to least
|
||||
specific for lookup value matching purposes.
|
||||
@@ -13,6 +33,11 @@
|
||||
patch group aliases that roll-up aliases from each patched talkgroup to support
|
||||
audio recording and streaming of patch calls according to the identifiers and
|
||||
actions defined for each of the patched talkgroups.
|
||||
- Implemented bounded queues for both tuner and individual channel IQ sample
|
||||
buffers. Bounded queues have ability to enter/exit overflow state when queue
|
||||
size reaches overflow threshold and reset when queue size falls below the reset
|
||||
threshold. Channel state will show OVERFLOW in red/yellow.
|
||||
- Improves handling of P25 TDMA channels (NO Phase 2 decoder support yet)
|
||||
- Updated airspy controller for airspy-mini specific sample rate handling.
|
||||
- New developer remez filter designer tool and internal usage
|
||||
|
||||
@@ -28,7 +53,7 @@
|
||||
- Updated Baseband (I/Q) recording at 48 kHz
|
||||
- Added Airspy tuner support
|
||||
- New traffic channel pool manager for trunked call following
|
||||
- P25 Decoder for C4FM and LSM with trunked call following and audio
|
||||
- P25 Decoder for C4FM and LSM with trunked call following and audio
|
||||
decoding via the JMBE library
|
||||
- Updated MPT1327 decoder and trunked call following.
|
||||
- Updated spectral and waterfall display with zoom (2-64x) and pan and automatic
|
||||
|
||||
@@ -631,8 +631,8 @@ to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
{one line to give the program's name and a brief idea of what it does.}
|
||||
Copyright (C) {year} {name of author}
|
||||
|
||||
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
|
||||
@@ -652,7 +652,7 @@ Also add information on how to contact you by electronic and paper mail.
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
{project} Copyright (C) {year} {fullname}
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
@@ -671,4 +671,4 @@ into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
81
README.md
81
README.md
@@ -1,19 +1,78 @@
|
||||
# sdrtrunk
|
||||
A cross-platform java application for decoding, monitoring, recording and streaming trunked mobile and related radio protocols using Software Defined Radios (SDR).
|
||||
|
||||
* [Getting Started](https://github.com/DSheirer/sdrtrunk/wiki/GettingStarted)
|
||||
* [User's Manual](https://github.com/DSheirer/sdrtrunk/wiki/UserManual)
|
||||
* [Getting Started](https://github.com/DSheirer/sdrtrunk/wiki/GettingStarted_V0.3.0)
|
||||
* [User's Manual Version 0.3.0](https://github.com/DSheirer/sdrtrunk/wiki/UserManual_V0.3.0)
|
||||
* [Download](https://github.com/DSheirer/sdrtrunk/releases)
|
||||
* [Support](https://groups.google.com/forum/#!forum/sdrtrunk)
|
||||
|
||||

|
||||
<script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||

|
||||
**Figure 1:** sdrtrunk **Version 0.3.0** Application Screenshot
|
||||
|
||||
ga('create', 'UA-67489234-1', 'auto');
|
||||
ga('send', 'pageview');
|
||||
# End User Instructions:
|
||||
|
||||
</script>
|
||||
If you simply want to download and run the program, please follow these instructions.
|
||||
|
||||
## Install Java 8 (or newer)
|
||||
|
||||
## Download the latest sdrtrunk release
|
||||
|
||||
All release versions of sdrtrunk are available from the [releases](https://github.com/DSheirer/sdrtrunk/releases) tab.
|
||||
|
||||
**(final)** These versions have been tested and are the current release version.
|
||||
|
||||
**(beta)** These versions are currently being tested for bugs and functionality.
|
||||
|
||||
## Run the application
|
||||
|
||||
Either double-click on the downloaded file (if supported on your operating system) or open a terminal/command window
|
||||
and change to the directory where you downloaded the release file and type:
|
||||
|
||||
```
|
||||
java -jar downloaded-jar-filename
|
||||
```
|
||||
|
||||
Note: replace _downloaded-jar-filename_ with the actual name of the sdrtrunk release version that you downloaded
|
||||
|
||||
## Optional - P25 Audio
|
||||
If you're using sdrtrunk with a P25 trunked radio system, the [JMBE](https://github.com/DSheirer/sdrtrunk/wiki/JMBE) wiki page contains instructions
|
||||
for downloading the JMBE audio library source code and compiling the JMBE library. Copy the resulting JMBE audio library
|
||||
jar file to the same folder containing the sdrtrunk application to use the library with sdrtrunk.
|
||||
|
||||
# Developer Instructions:
|
||||
|
||||
If you're interested in modifying and/or compiling the source code, please follow these instructions to use gradle to compile the code.
|
||||
|
||||
## Build the project
|
||||
sdrtrunk uses gradle as the build system. You can build it with locally installed gradle or if you do not have/want
|
||||
to install gradle you can use preconfigured linux/windows wrapper.
|
||||
|
||||
### Build with locally installed gradle 4.3.1
|
||||
```
|
||||
gradle clean buildSdr
|
||||
```
|
||||
### Build with preconfigured wrapper for linux/windows
|
||||
Linux
|
||||
```
|
||||
./gradlew clean buildSdr
|
||||
```
|
||||
Windows
|
||||
```
|
||||
gradle.bat clean buildSdr
|
||||
```
|
||||
This would add gradle, download all project dependencies and build JAR
|
||||
|
||||
## Development
|
||||
All dependencies/versions are controlled from build.gradle.
|
||||
To change the new release version tag of artifact - change property:
|
||||
```
|
||||
version = '0.3.2'
|
||||
```
|
||||
|
||||
## Run SDRTrunk
|
||||
SDRTrunk is packed into single uber-jar file. There is need to have folders with dependencies and
|
||||
adding them with classpath. Just run with java.
|
||||
### Use Java8
|
||||
```
|
||||
java -jar build/libs/sdr-trunk-all-0.3.2.jar
|
||||
```
|
||||
|
||||
75
build.gradle
Normal file
75
build.gradle
Normal file
@@ -0,0 +1,75 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'idea'
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
version = '0.3.4-beta.2'
|
||||
sourceCompatibility = 1.8
|
||||
|
||||
sourceSets {
|
||||
main.java.srcDirs 'src/main'
|
||||
test.java.srcDirs 'src/test'
|
||||
}
|
||||
|
||||
idea {
|
||||
module {
|
||||
downloadJavadoc = true
|
||||
downloadSources = true
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testCompile 'junit:junit:4.12'
|
||||
testCompile 'org.assertj:assertj-core:3.8.0'
|
||||
compile fileTree(dir: 'imports', include: '*.jar')
|
||||
compile 'org.apache.commons:commons-lang3:3.7'
|
||||
compile 'org.apache.commons:commons-io:1.3.2'
|
||||
compile 'org.slf4j:slf4j-api:1.7.25'
|
||||
compile 'ch.qos.logback:logback-core:1.2.3'
|
||||
compile 'ch.qos.logback:logback-classic:1.2.3'
|
||||
compile 'com.miglayout:miglayout-swing:5.0'
|
||||
|
||||
compile 'org.usb4java:usb4java-javax:1.2.0'
|
||||
compile 'org.usb4java:usb4java:1.2.0'
|
||||
compile 'org.usb4java:libusb4java:1.2.0'
|
||||
compile 'javax.usb:usb-api:1.0.2'
|
||||
compile 'com.github.wendykierp:JTransforms:3.1'
|
||||
compile 'pl.edu.icm:JLargeArrays:1.6'
|
||||
compile 'net.coderazzi:tablefilter-swing:5.3.1'
|
||||
compile 'com.jidesoft:jide-oss:3.4.3'
|
||||
compile 'org.apache.mina:mina-core:2.0.16'
|
||||
compile 'org.apache.mina:mina-http:2.0.16'
|
||||
compile 'org.apache.axis:axis-jaxrpc:1.4'
|
||||
compile 'org.apache.axis:axis:1.4'
|
||||
compile 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.9.3'
|
||||
compile 'org.kordamp.ikonli:ikonli-javafx:2.1.1'
|
||||
compile 'org.kordamp.ikonli:ikonli-fontawesome-pack:2.1.1'
|
||||
}
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
gradleVersion = '4.3.1'
|
||||
}
|
||||
|
||||
task buildSdr(type: Jar) {
|
||||
manifest {
|
||||
attributes 'Implementation-Title': 'SdrTrunk project',
|
||||
'Implementation-Version': version,
|
||||
'Main-Class': 'io.github.dsheirer.gui.SDRTrunk',
|
||||
'Class-Path': 'jmbe-0.3.2.jar jmbe-0.3.3.jar'
|
||||
}
|
||||
baseName = project.name + '-all'
|
||||
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
|
||||
with jar
|
||||
}
|
||||
121
build/build.xml
121
build/build.xml
@@ -1,121 +0,0 @@
|
||||
<project name="SDRTrunk" default="SDRTrunk" basedir=".">
|
||||
<description>
|
||||
Ant build script for SDRTrunk Decoder Application
|
||||
</description>
|
||||
|
||||
<!-- version properties -->
|
||||
<property name="major" value="0"/>
|
||||
<property name="minor" value="3"/>
|
||||
<property name="patch" value="0"/>
|
||||
<property name="release" value="-beta1"/>
|
||||
<property name="filename" value="sdrtrunk_${major}.${minor}.${patch}${release}"/>
|
||||
|
||||
<!-- Build properties -->
|
||||
<property name="repo" location=".."/>
|
||||
<property name="source.code" location="${repo}/src"/>
|
||||
<property name="source.configs" location="${repo}/config"/>
|
||||
<property name="source.images" location="${repo}/images"/>
|
||||
<property name="source.libs" location="${repo}/imports"/>
|
||||
<property name="source.license" location="${repo}/license"/>
|
||||
<property name="source.scripts" location="${repo}/scripts"/>
|
||||
|
||||
<property name="output" location="${repo}/product"/>
|
||||
<property name="output.classes" location="${repo}/classes"/>
|
||||
<property name="output.folder" location="${output}/sdrtrunk"/>
|
||||
<property name="output.config" location="${output.folder}/config"/>
|
||||
<property name="output.images" location="${output.folder}/images"/>
|
||||
<property name="output.libs" location="${output.folder}/libs"/>
|
||||
|
||||
<path id="classpath">
|
||||
<fileset dir="${source.libs}" includes="*.jar" />
|
||||
</path>
|
||||
|
||||
<target name="init">
|
||||
<!-- Create the classes folder to contain the compiled java classes -->
|
||||
<mkdir dir="${output.classes}"/>
|
||||
|
||||
<!-- Create version file -->
|
||||
<echo message="${major}.${minor}.${patch}-${release}" file="${output.classes}/sdrtrunk-version"/>
|
||||
</target>
|
||||
|
||||
<target name="compile" depends="clean,init" description="Compile java classes" >
|
||||
<javac srcdir="${source.code}" destdir="${output.classes}" classpathref="classpath" includeantruntime="false" />
|
||||
</target>
|
||||
|
||||
<target name="SDRTrunk" depends="compile" description="Create SDRTrunk application" >
|
||||
<!-- Create the distribution directory -->
|
||||
<mkdir dir="${output.folder}"/>
|
||||
|
||||
<!-- Create jar file -->
|
||||
<jar jarfile="${output.folder}/sdrtrunk.jar" basedir="${output.classes}">
|
||||
<manifest>
|
||||
<attribute name="Title" value="sdrtrunk"/>
|
||||
<attribute name="Main-Class" value="gui.SDRTrunk"/>
|
||||
<attribute name="Version" value="${major}.${minor}.${patch}-${release}"/>
|
||||
</manifest>
|
||||
<fileset dir="${source.configs}">
|
||||
<exclude name="*.rules"/>
|
||||
</fileset>
|
||||
|
||||
<fileset dir="${source.license}">
|
||||
<include name="license.txt"/>
|
||||
</fileset>
|
||||
</jar>
|
||||
|
||||
<!-- Copy third-party libraries -->
|
||||
<mkdir dir="${output.libs}"/>
|
||||
<copy todir="${output.libs}">
|
||||
<fileset dir="${source.libs}" includes="*.jar" />
|
||||
</copy>
|
||||
|
||||
<!-- Copy config files -->
|
||||
<mkdir dir="${output.config}"/>
|
||||
|
||||
<copy todir="${output.config}">
|
||||
<fileset dir="${source.configs}">
|
||||
<include name="*.rules"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
|
||||
<!-- Copy image files -->
|
||||
<mkdir dir="${output.images}"/>
|
||||
<copy todir="${output.images}">
|
||||
<fileset dir="${source.images}" />
|
||||
</copy>
|
||||
|
||||
<!-- Copy license file -->
|
||||
<copy todir="${output.folder}">
|
||||
<fileset dir="${source.license}">
|
||||
<include name="license.txt"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
|
||||
<!-- Copy program scripts -->
|
||||
<copy todir="${output.folder}">
|
||||
<fileset dir="${source.scripts}" />
|
||||
</copy>
|
||||
|
||||
|
||||
<!-- Bundle the files into .zip -->
|
||||
<zip destfile="${output}/${filename}.zip" basedir="${output}" />
|
||||
|
||||
<!-- Remove linux start script before tar task -->
|
||||
<delete file="${output.folder}/run_sdrtrunk_linux.sh"/>
|
||||
|
||||
<!-- Bundle files into .tar.gz and copy/set permissions on linux start script -->
|
||||
<tar destfile="${output}/${filename}.tar.gz" compression="gzip">
|
||||
<tarfileset dir="${output.folder}" prefix="sdrtrunk" />
|
||||
<tarfileset dir="${source.scripts}" prefix="sdrtrunk" filemode="777">
|
||||
<include name="run_sdrtrunk_linux.sh"/>
|
||||
</tarfileset>
|
||||
</tar>
|
||||
|
||||
<delete dir="${output.folder}"/>
|
||||
</target>
|
||||
|
||||
<target name="clean" description="Clean previous build artifacts" >
|
||||
<delete dir="${output.classes}"/>
|
||||
<delete dir="${output}"/>
|
||||
</target>
|
||||
|
||||
</project>
|
||||
@@ -1,33 +0,0 @@
|
||||
<configuration>
|
||||
<timestamp key="appstart" datePattern="HHmmss"/>
|
||||
|
||||
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${user.home}/SDRTrunk/logs/sdrtrunk_app.log</file>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- daily log rollover -->
|
||||
<fileNamePattern>${user.home}/SDRTrunk/logs/%d{yyyyMMdd}_sdrtrunk_app.log</fileNamePattern>
|
||||
<maxHistory>10</maxHistory>
|
||||
</rollingPolicy>
|
||||
<encoder>
|
||||
<pattern>%-25(%d{yyyyMMdd HHmmss.SSS} [%thread]) %-5level %logger{30} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="DEBUG">
|
||||
<appender-ref ref="FILE" />
|
||||
</root>
|
||||
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%-12(%d{HH:mm:ss.SSS}) %-5level %logger{25} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="DEBUG">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
|
||||
<!-- Apache Mina TCP/HTTP library -->
|
||||
<logger name="org.apache.mina" level="INFO" />
|
||||
|
||||
</configuration>
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
5
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
5
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.3.1-bin.zip
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStorePath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
172
gradlew
vendored
Executable file
172
gradlew
vendored
Executable file
@@ -0,0 +1,172 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
84
gradlew.bat
vendored
Normal file
84
gradlew.bat
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@@ -1,4 +0,0 @@
|
||||
[Dolphin]
|
||||
PreviewsShown=true
|
||||
Timestamp=2013,9,20,8,54,21
|
||||
Version=3
|
||||
@@ -1,4 +0,0 @@
|
||||
[Dolphin]
|
||||
Timestamp=2013,4,7,10,12,39
|
||||
Version=3
|
||||
ViewMode=1
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
imports/axis.jar
BIN
imports/axis.jar
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,2 +0,0 @@
|
||||
#!/bin/bash
|
||||
java -XX:+UseG1GC -cp "*:libs/*" gui.SDRTrunk
|
||||
@@ -1 +0,0 @@
|
||||
java -XX:+UseG1GC -cp "SDRTrunk.jar;*;libs/*;config/*;images/*" gui.SDRTrunk
|
||||
104
sdr-trunk.ipr
Normal file
104
sdr-trunk.ipr
Normal file
@@ -0,0 +1,104 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<option name="DEFAULT_COMPILER" value="Javac"/>
|
||||
<resourceExtensions>
|
||||
<entry name=".+\.(properties|xml|html|dtd|tld)"/>
|
||||
<entry name=".+\.(gif|png|jpeg|jpg)"/>
|
||||
</resourceExtensions>
|
||||
<wildcardResourcePatterns>
|
||||
<entry name="!?*.class"/>
|
||||
<entry name="!?*.scala"/>
|
||||
<entry name="!?*.java"/>
|
||||
<entry name="!?*.groovy"/>
|
||||
</wildcardResourcePatterns>
|
||||
<annotationProcessing enabled="false" useClasspath="true"/>
|
||||
<bytecodeTargetLevel target="1.8"/>
|
||||
</component>
|
||||
<component name="CopyrightManager" default="">
|
||||
<module2copyright/>
|
||||
</component>
|
||||
<component name="DependencyValidationManager">
|
||||
<option name="SKIP_IMPORT_STATEMENTS" value="false"/>
|
||||
</component>
|
||||
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false"/>
|
||||
<component name="GradleUISettings">
|
||||
<setting name="root"/>
|
||||
</component>
|
||||
<component name="GradleUISettings2">
|
||||
<setting name="root"/>
|
||||
</component>
|
||||
<component name="IdProvider" IDEtalkID="11DA1DB66DD62DDA1ED602B7079FE97C"/>
|
||||
<component name="JavadocGenerationManager">
|
||||
<option name="OUTPUT_DIRECTORY"/>
|
||||
<option name="OPTION_SCOPE" value="protected"/>
|
||||
<option name="OPTION_HIERARCHY" value="true"/>
|
||||
<option name="OPTION_NAVIGATOR" value="true"/>
|
||||
<option name="OPTION_INDEX" value="true"/>
|
||||
<option name="OPTION_SEPARATE_INDEX" value="true"/>
|
||||
<option name="OPTION_DOCUMENT_TAG_USE" value="false"/>
|
||||
<option name="OPTION_DOCUMENT_TAG_AUTHOR" value="false"/>
|
||||
<option name="OPTION_DOCUMENT_TAG_VERSION" value="false"/>
|
||||
<option name="OPTION_DOCUMENT_TAG_DEPRECATED" value="true"/>
|
||||
<option name="OPTION_DEPRECATED_LIST" value="true"/>
|
||||
<option name="OTHER_OPTIONS" value=""/>
|
||||
<option name="HEAP_SIZE"/>
|
||||
<option name="LOCALE"/>
|
||||
<option name="OPEN_IN_BROWSER" value="true"/>
|
||||
</component>
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module filepath="$PROJECT_DIR$/sdr-trunk.iml" fileurl="file://$PROJECT_DIR$/sdr-trunk.iml"/>
|
||||
</modules>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" assert-keyword="true" jdk-15="true" project-jdk-type="JavaSDK" assert-jdk-15="true" project-jdk-name="1.8">
|
||||
<output url="file://$PROJECT_DIR$/out"/>
|
||||
</component>
|
||||
<component name="SvnBranchConfigurationManager">
|
||||
<option name="mySupportsUserInfoFilter" value="true"/>
|
||||
</component>
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs=""/>
|
||||
</component>
|
||||
<component name="masterDetails">
|
||||
<states>
|
||||
<state key="ArtifactsStructureConfigurable.UI">
|
||||
<UIState>
|
||||
<splitter-proportions>
|
||||
<SplitterProportionsDataImpl/>
|
||||
</splitter-proportions>
|
||||
<settings/>
|
||||
</UIState>
|
||||
</state>
|
||||
<state key="Copyright.UI">
|
||||
<UIState>
|
||||
<splitter-proportions>
|
||||
<SplitterProportionsDataImpl/>
|
||||
</splitter-proportions>
|
||||
</UIState>
|
||||
</state>
|
||||
<state key="ProjectJDKs.UI">
|
||||
<UIState>
|
||||
<splitter-proportions>
|
||||
<SplitterProportionsDataImpl>
|
||||
<option name="proportions">
|
||||
<list>
|
||||
<option value="0.2"/>
|
||||
</list>
|
||||
</option>
|
||||
</SplitterProportionsDataImpl>
|
||||
</splitter-proportions>
|
||||
<last-edited>1.6</last-edited>
|
||||
</UIState>
|
||||
</state>
|
||||
<state key="ScopeChooserConfigurable.UI">
|
||||
<UIState>
|
||||
<splitter-proportions>
|
||||
<SplitterProportionsDataImpl/>
|
||||
</splitter-proportions>
|
||||
<settings/>
|
||||
</UIState>
|
||||
</state>
|
||||
</states>
|
||||
</component>
|
||||
</project>
|
||||
25
sdrtrunk.iml
25
sdrtrunk.iml
@@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/images" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/config" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$" type="java-resource" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="imports" level="project" />
|
||||
<orderEntry type="module-library">
|
||||
<library>
|
||||
<CLASSES>
|
||||
<root url="jar://$MODULE_DIR$/../jmbe/jmbe/library/jmbe-0.3.3.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</orderEntry>
|
||||
<orderEntry type="library" name="org.asynchttpclient:async-http-client:2.0.18" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
1
settings.gradle
Normal file
1
settings.gradle
Normal file
@@ -0,0 +1 @@
|
||||
rootProject.name = 'sdr-trunk'
|
||||
@@ -1,4 +0,0 @@
|
||||
[Dolphin]
|
||||
Timestamp=2015,9,1,6,42,59
|
||||
Version=3
|
||||
ViewMode=1
|
||||
@@ -1,375 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014-2016 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 alias;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlSeeAlso;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
|
||||
import alias.action.AliasAction;
|
||||
import alias.id.AliasID;
|
||||
import alias.id.AliasIDType;
|
||||
import alias.id.broadcast.BroadcastChannel;
|
||||
import alias.id.nonrecordable.NonRecordable;
|
||||
import alias.id.priority.Priority;
|
||||
|
||||
@XmlSeeAlso( { AliasID.class, AliasAction.class } )
|
||||
@XmlRootElement( name = "alias" )
|
||||
public class Alias
|
||||
{
|
||||
private String mList;
|
||||
private String mGroup;
|
||||
private String mName;
|
||||
private int mColor;
|
||||
private String mIconName;
|
||||
private List<AliasID> mAliasIDs = new ArrayList<AliasID>();
|
||||
private List<AliasAction> mAliasActions = new ArrayList<AliasAction>();
|
||||
|
||||
public Alias()
|
||||
{
|
||||
}
|
||||
|
||||
public Alias( String name )
|
||||
{
|
||||
mName = name;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return getName();
|
||||
}
|
||||
|
||||
@XmlAttribute( name="name" )
|
||||
public String getName()
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
|
||||
public void setName( String name )
|
||||
{
|
||||
mName = name;
|
||||
}
|
||||
|
||||
@XmlAttribute( name="list" )
|
||||
public String getList()
|
||||
{
|
||||
return mList;
|
||||
}
|
||||
|
||||
public void setList( String list )
|
||||
{
|
||||
mList = list;
|
||||
}
|
||||
|
||||
public boolean hasList()
|
||||
{
|
||||
return mList != null;
|
||||
}
|
||||
|
||||
@XmlAttribute( name="group" )
|
||||
public String getGroup()
|
||||
{
|
||||
return mGroup;
|
||||
}
|
||||
|
||||
public void setGroup( String group )
|
||||
{
|
||||
mGroup = group;
|
||||
}
|
||||
|
||||
public boolean hasGroup()
|
||||
{
|
||||
return mGroup != null;
|
||||
}
|
||||
|
||||
@XmlAttribute
|
||||
public int getColor()
|
||||
{
|
||||
return mColor;
|
||||
}
|
||||
|
||||
public void setColor( int color )
|
||||
{
|
||||
mColor = color;
|
||||
}
|
||||
|
||||
public Color getDisplayColor()
|
||||
{
|
||||
return new Color( getColor() );
|
||||
}
|
||||
|
||||
@XmlAttribute
|
||||
public String getIconName()
|
||||
{
|
||||
return mIconName;
|
||||
}
|
||||
|
||||
public void setIconName( String iconName )
|
||||
{
|
||||
mIconName = iconName;
|
||||
}
|
||||
|
||||
@XmlElement( name="id" )
|
||||
public List<AliasID> getId()
|
||||
{
|
||||
return mAliasIDs;
|
||||
}
|
||||
|
||||
public void setId( ArrayList<AliasID> id )
|
||||
{
|
||||
mAliasIDs = id;
|
||||
}
|
||||
|
||||
public void addAliasID( AliasID id )
|
||||
{
|
||||
mAliasIDs.add( id );
|
||||
}
|
||||
|
||||
public void removeAliasID( AliasID id )
|
||||
{
|
||||
mAliasIDs.remove( id );
|
||||
}
|
||||
|
||||
@XmlElement( name="action" )
|
||||
public List<AliasAction> getAction()
|
||||
{
|
||||
return mAliasActions;
|
||||
}
|
||||
|
||||
public void setAction( List<AliasAction> actions )
|
||||
{
|
||||
mAliasActions = actions;
|
||||
}
|
||||
|
||||
public void addAliasAction( AliasAction action )
|
||||
{
|
||||
mAliasActions.add( action );
|
||||
}
|
||||
|
||||
public void removeAliasAction( AliasAction action )
|
||||
{
|
||||
mAliasActions.remove( action );
|
||||
}
|
||||
|
||||
public boolean hasActions()
|
||||
{
|
||||
return !mAliasActions.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform any validation/cleanup actions on this alias.
|
||||
*/
|
||||
public void validate()
|
||||
{
|
||||
//Check for duplicate broadcast channels
|
||||
List<BroadcastChannel> broadcastChannels = getBroadcastChannels();
|
||||
|
||||
if(broadcastChannels.size() > 0)
|
||||
{
|
||||
Set<String> channelNames = new TreeSet<>();
|
||||
|
||||
for(BroadcastChannel broadcastChannel: broadcastChannels)
|
||||
{
|
||||
String channelName = broadcastChannel.getChannelName();
|
||||
|
||||
if(channelName == null || channelName.isEmpty() || channelNames.contains(channelName))
|
||||
{
|
||||
removeAliasID(broadcastChannel);
|
||||
}
|
||||
else
|
||||
{
|
||||
channelNames.add(channelName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Returns the priority level of this alias, if defined, or the default priority
|
||||
*/
|
||||
@XmlTransient
|
||||
public int getCallPriority()
|
||||
{
|
||||
for( AliasID id: mAliasIDs )
|
||||
{
|
||||
if( id.getType() == AliasIDType.PRIORITY)
|
||||
{
|
||||
return ((Priority)id).getPriority();
|
||||
}
|
||||
}
|
||||
|
||||
return Priority.DEFAULT_PRIORITY;
|
||||
}
|
||||
|
||||
public boolean hasCallPriority()
|
||||
{
|
||||
for( AliasID id: mAliasIDs )
|
||||
{
|
||||
if( id.getType() == AliasIDType.PRIORITY)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets or updates the call priority
|
||||
*/
|
||||
public void setCallPriority( int priority )
|
||||
{
|
||||
if( priority == Priority.DO_NOT_MONITOR ||
|
||||
( Priority.MIN_PRIORITY <= priority && priority <= Priority.MAX_PRIORITY ) )
|
||||
{
|
||||
for( AliasID id: mAliasIDs )
|
||||
{
|
||||
if( id.getType() == AliasIDType.PRIORITY)
|
||||
{
|
||||
((Priority)id).setPriority( priority );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//If we don't find a priority id, create one
|
||||
Priority p = new Priority();
|
||||
p.setPriority( priority );
|
||||
addAliasID( p );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inspects the alias for a non-recordable alias id. Default is true;
|
||||
*/
|
||||
@XmlTransient
|
||||
public boolean isRecordable()
|
||||
{
|
||||
for( AliasID id: getId() )
|
||||
{
|
||||
if( id.getType() == AliasIDType.NON_RECORDABLE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets or removes the non-recordable alias ID for this alias.
|
||||
*/
|
||||
public void setRecordable( boolean recordable )
|
||||
{
|
||||
if( recordable )
|
||||
{
|
||||
AliasID toRemove = null;
|
||||
|
||||
for( AliasID id: getId() )
|
||||
{
|
||||
if( id.getType() == AliasIDType.NON_RECORDABLE)
|
||||
{
|
||||
toRemove = id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( toRemove != null )
|
||||
{
|
||||
removeAliasID( toRemove );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( AliasID id: getId() )
|
||||
{
|
||||
if( id.getType() == AliasIDType.NON_RECORDABLE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
addAliasID( new NonRecordable() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inspects the alias for broadcast channel/streamable alias ids. Default is false;
|
||||
*/
|
||||
@XmlTransient
|
||||
public boolean isStreamable()
|
||||
{
|
||||
for( AliasID id: getId() )
|
||||
{
|
||||
if( id.getType() == AliasIDType.BROADCAST_CHANNEL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* List of broadcast channels specified for this alias.
|
||||
*/
|
||||
@XmlTransient
|
||||
public List<BroadcastChannel> getBroadcastChannels()
|
||||
{
|
||||
List<BroadcastChannel> broadcastChannels = new ArrayList<>();
|
||||
|
||||
for(AliasID id: getId())
|
||||
{
|
||||
if(id.getType() == AliasIDType.BROADCAST_CHANNEL)
|
||||
{
|
||||
broadcastChannels.add((BroadcastChannel)id);
|
||||
}
|
||||
}
|
||||
|
||||
return broadcastChannels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this alias contains a broadcast channel alias id with the channel name.
|
||||
*/
|
||||
public boolean hasBroadcastChannel(String channel)
|
||||
{
|
||||
if(channel == null || channel.isEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for(AliasID id: getId())
|
||||
{
|
||||
if(id.getType() == AliasIDType.BROADCAST_CHANNEL &&
|
||||
((BroadcastChannel)id).getChannelName().contentEquals(channel))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,347 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014-2016 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 alias;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
|
||||
import alias.id.broadcast.BroadcastChannel;
|
||||
import sample.Broadcaster;
|
||||
import sample.Listener;
|
||||
import alias.AliasEvent.Event;
|
||||
|
||||
/**
|
||||
* Alias Model
|
||||
*/
|
||||
public class AliasModel extends AbstractTableModel
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final int COLUMN_LIST = 0;
|
||||
public static final int COLUMN_GROUP = 1;
|
||||
public static final int COLUMN_NAME = 2;
|
||||
public static final int COLUMN_ICON = 3;
|
||||
public static final int COLUMN_COLOR = 4;
|
||||
|
||||
private List<Alias> mAliases = new CopyOnWriteArrayList<>();
|
||||
private Broadcaster<AliasEvent> mAliasEventBroadcaster = new Broadcaster<>();
|
||||
private Map<String,AliasList> mAliasListMap = new HashMap<>();
|
||||
|
||||
public AliasModel()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmodifiable list of all aliases currently in the model
|
||||
*/
|
||||
public List<Alias> getAliases()
|
||||
{
|
||||
return Collections.unmodifiableList( mAliases );
|
||||
}
|
||||
|
||||
public Alias getAliasAtIndex( int row )
|
||||
{
|
||||
if( mAliases.size() >= row )
|
||||
{
|
||||
return mAliases.get( row );
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public AliasList getAliasList( String name )
|
||||
{
|
||||
if( mAliasListMap.containsKey( name ) )
|
||||
{
|
||||
return mAliasListMap.get( name );
|
||||
}
|
||||
|
||||
AliasList aliasList = new AliasList( name );
|
||||
|
||||
for( Alias alias: mAliases )
|
||||
{
|
||||
if( alias.getList().equalsIgnoreCase( name ) )
|
||||
{
|
||||
aliasList.addAlias( alias );
|
||||
}
|
||||
}
|
||||
|
||||
mAliasListMap.put( name, aliasList );
|
||||
|
||||
//Register the new alias list to receive updates from this model
|
||||
addListener( aliasList );
|
||||
|
||||
return aliasList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of unique alias list names from across the alias set
|
||||
*/
|
||||
public List<String> getListNames()
|
||||
{
|
||||
List<String> listNames = new ArrayList<>();
|
||||
|
||||
for( Alias alias: mAliases )
|
||||
{
|
||||
if( alias.hasList() && !listNames.contains( alias.getList() ) )
|
||||
{
|
||||
listNames.add( alias.getList() );
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort( listNames );
|
||||
|
||||
return listNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of alias group names for all aliases
|
||||
*/
|
||||
public List<String> getGroupNames()
|
||||
{
|
||||
List<String> groupNames = new ArrayList<>();
|
||||
|
||||
for( Alias alias: mAliases )
|
||||
{
|
||||
if( alias.hasGroup() && !groupNames.contains( alias.getGroup() ) )
|
||||
{
|
||||
groupNames.add( alias.getGroup() );
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort( groupNames );
|
||||
|
||||
return groupNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of alias group names for all aliases that have a matching
|
||||
* list name value
|
||||
*/
|
||||
public List<String> getGroupNames( String listName )
|
||||
{
|
||||
List<String> groupNames = new ArrayList<>();
|
||||
|
||||
if( listName != null )
|
||||
{
|
||||
for( Alias alias: mAliases )
|
||||
{
|
||||
if( alias.hasList() &&
|
||||
alias.hasGroup() &&
|
||||
listName.equals( alias.getList() ) &&
|
||||
!groupNames.contains( alias.getGroup() ) )
|
||||
{
|
||||
groupNames.add( alias.getGroup() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort( groupNames );
|
||||
|
||||
return groupNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bulk loading of aliases
|
||||
*/
|
||||
public void addAliases( List<Alias> aliases )
|
||||
{
|
||||
for( Alias alias: aliases )
|
||||
{
|
||||
addAlias( alias );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the alias to the model
|
||||
*/
|
||||
public int addAlias( Alias alias )
|
||||
{
|
||||
if( alias != null )
|
||||
{
|
||||
mAliases.add( alias );
|
||||
|
||||
int index = mAliases.size() - 1;
|
||||
|
||||
fireTableRowsInserted( index, index );
|
||||
|
||||
broadcast( new AliasEvent( alias, Event.ADD ) );
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the channel from the model and broadcasts a channel remove event
|
||||
*/
|
||||
public void removeAlias( Alias alias )
|
||||
{
|
||||
if( alias != null )
|
||||
{
|
||||
int index = mAliases.indexOf( alias );
|
||||
|
||||
mAliases.remove( alias );
|
||||
|
||||
fireTableRowsDeleted( index, index );
|
||||
|
||||
broadcast( new AliasEvent( alias, Event.DELETE ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renames any broadcast channels that have the previous name.
|
||||
* @param previousName to rename
|
||||
* @param newName to assign to the broadcast channel
|
||||
*/
|
||||
public void renameBroadcastChannel(String previousName, String newName)
|
||||
{
|
||||
if(previousName == null || previousName.isEmpty() || newName == null || newName.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for(Alias alias: mAliases)
|
||||
{
|
||||
if(alias.hasBroadcastChannel(previousName))
|
||||
{
|
||||
for(BroadcastChannel broadcastChannel: alias.getBroadcastChannels())
|
||||
{
|
||||
if(broadcastChannel.getChannelName().contentEquals(previousName))
|
||||
{
|
||||
broadcastChannel.setChannelName(newName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRowCount()
|
||||
{
|
||||
return mAliases.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnCount()
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnName( int columnIndex )
|
||||
{
|
||||
switch( columnIndex )
|
||||
{
|
||||
case COLUMN_LIST:
|
||||
return "List";
|
||||
case COLUMN_GROUP:
|
||||
return "Group";
|
||||
case COLUMN_NAME:
|
||||
return "Name";
|
||||
case COLUMN_ICON:
|
||||
return "Icon";
|
||||
case COLUMN_COLOR:
|
||||
return "Color";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getColumnClass( int columnIndex )
|
||||
{
|
||||
if( columnIndex == COLUMN_COLOR )
|
||||
{
|
||||
return Integer.class;
|
||||
}
|
||||
|
||||
return String.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCellEditable( int rowIndex, int columnIndex )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValueAt( int rowIndex, int columnIndex )
|
||||
{
|
||||
Alias alias = mAliases.get( rowIndex );
|
||||
|
||||
switch( columnIndex )
|
||||
{
|
||||
case COLUMN_LIST:
|
||||
return alias.getList();
|
||||
case COLUMN_GROUP:
|
||||
return alias.getGroup();
|
||||
case COLUMN_NAME:
|
||||
return alias.getName();
|
||||
case COLUMN_ICON:
|
||||
return alias.getIconName();
|
||||
case COLUMN_COLOR:
|
||||
return alias.getColor();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValueAt( Object aValue, int rowIndex, int columnIndex )
|
||||
{
|
||||
throw new IllegalArgumentException( "Not yet implemented" );
|
||||
}
|
||||
|
||||
public void broadcast( AliasEvent event )
|
||||
{
|
||||
Alias alias = event.getAlias();
|
||||
|
||||
//Validate the alias following a user action that changed the alias or any alias IDs
|
||||
if(alias != null)
|
||||
{
|
||||
alias.validate();
|
||||
}
|
||||
|
||||
if( event.getEvent() == Event.CHANGE )
|
||||
{
|
||||
int index = mAliases.indexOf( event.getAlias() );
|
||||
|
||||
fireTableRowsUpdated( index, index );
|
||||
}
|
||||
|
||||
mAliasEventBroadcaster.broadcast( event );
|
||||
}
|
||||
|
||||
public void addListener( Listener<AliasEvent> listener )
|
||||
{
|
||||
mAliasEventBroadcaster.addListener( listener );
|
||||
}
|
||||
|
||||
public void removeListener( Listener<AliasEvent> listener )
|
||||
{
|
||||
mAliasEventBroadcaster.removeListener( listener );
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* sdrtrunk
|
||||
* Copyright (C) 2014-2017 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 alias.action;
|
||||
|
||||
import alias.Alias;
|
||||
import alias.action.beep.BeepAction;
|
||||
import alias.action.clip.ClipAction;
|
||||
import alias.action.script.ScriptAction;
|
||||
import message.Message;
|
||||
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlSeeAlso;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
/**
|
||||
* Alias action defines an action to execute when an alias is detected active.
|
||||
*/
|
||||
@XmlSeeAlso( { BeepAction.class, ClipAction.class, ScriptAction.class } )
|
||||
@XmlRootElement( name = "action" )
|
||||
public abstract class AliasAction
|
||||
{
|
||||
public AliasAction()
|
||||
{
|
||||
}
|
||||
|
||||
@XmlTransient
|
||||
public abstract AliasActionType getType();
|
||||
|
||||
/**
|
||||
* Task to execute when an alias action is defined. The message argument is
|
||||
* the original message containing one or more aliases that have an alias
|
||||
* action attached. The alias argument is the parent alias containing the
|
||||
* alias action.
|
||||
*/
|
||||
public abstract void execute( ScheduledExecutorService scheduledExecutorService, Alias alias, Message message );
|
||||
|
||||
/**
|
||||
* Dismiss a persistent alias action
|
||||
*/
|
||||
public abstract void dismiss( boolean reset );
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package alias.action.beep;
|
||||
|
||||
import message.Message;
|
||||
import alias.Alias;
|
||||
import alias.action.AliasActionType;
|
||||
import alias.action.RecurringAction;
|
||||
|
||||
public class BeepAction extends RecurringAction
|
||||
{
|
||||
|
||||
@Override
|
||||
public AliasActionType getType()
|
||||
{
|
||||
return AliasActionType.BEEP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performAction( Alias alias, Message message )
|
||||
{
|
||||
System.out.println( "\007" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "Beep";
|
||||
}
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
package alias.action.clip;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import javax.sound.sampled.AudioInputStream;
|
||||
import javax.sound.sampled.AudioSystem;
|
||||
import javax.sound.sampled.Clip;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
|
||||
import message.Message;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import alias.Alias;
|
||||
import alias.action.AliasActionType;
|
||||
import alias.action.RecurringAction;
|
||||
|
||||
public class ClipAction extends RecurringAction
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger( ClipAction.class );
|
||||
|
||||
private String mFilePath;
|
||||
|
||||
@XmlTransient
|
||||
private Clip mClip;
|
||||
|
||||
public ClipAction()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public AliasActionType getType()
|
||||
{
|
||||
return AliasActionType.CLIP;
|
||||
}
|
||||
|
||||
public String getPath()
|
||||
{
|
||||
return mFilePath;
|
||||
}
|
||||
|
||||
public void setPath( String path )
|
||||
{
|
||||
mFilePath = path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performAction( Alias alias, Message message )
|
||||
{
|
||||
try
|
||||
{
|
||||
play();
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
mLog.error( "Couldn't play audio clip", e );
|
||||
}
|
||||
}
|
||||
|
||||
public void play() throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
if( mFilePath != null )
|
||||
{
|
||||
if( mClip == null )
|
||||
{
|
||||
mClip = AudioSystem.getClip();
|
||||
|
||||
AudioInputStream ais =
|
||||
AudioSystem.getAudioInputStream( new File( mFilePath ) );
|
||||
|
||||
mClip.open( ais );
|
||||
}
|
||||
|
||||
if( mClip.isRunning() )
|
||||
{
|
||||
mClip.stop();
|
||||
}
|
||||
|
||||
mClip.setFramePosition( 0 );
|
||||
|
||||
mClip.start();
|
||||
}
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
mClip = null;
|
||||
|
||||
mLog.error( "Error playing sound clip [" + mFilePath + "] - " + e.getMessage() );
|
||||
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
if( mFilePath == null )
|
||||
{
|
||||
return "Play Clip";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "Play Clip: " + mFilePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
package alias.action.script;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
import message.Message;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import alias.Alias;
|
||||
import alias.action.AliasActionType;
|
||||
import alias.action.RecurringAction;
|
||||
|
||||
public class ScriptAction extends RecurringAction
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger( ScriptAction.class );
|
||||
|
||||
private String mScript;
|
||||
|
||||
public ScriptAction()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public AliasActionType getType()
|
||||
{
|
||||
return AliasActionType.SCRIPT;
|
||||
}
|
||||
|
||||
public String getScript()
|
||||
{
|
||||
return mScript;
|
||||
}
|
||||
|
||||
public void setScript( String script )
|
||||
{
|
||||
mScript = script;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performAction( Alias alias, Message message )
|
||||
{
|
||||
try
|
||||
{
|
||||
play();
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
mLog.error( "Couldn't execute script [" + mScript + "]", e );
|
||||
}
|
||||
}
|
||||
|
||||
public void play() throws Exception
|
||||
{
|
||||
if( mScript != null )
|
||||
{
|
||||
ProcessBuilder pb = new ProcessBuilder( mScript );
|
||||
|
||||
pb.redirectErrorStream( true );
|
||||
|
||||
Process p = pb.start();
|
||||
|
||||
int exitCode = p.waitFor();
|
||||
|
||||
BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader( p.getInputStream() ) );
|
||||
|
||||
String line = "";
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
while( ( line = reader.readLine() ) != null )
|
||||
{
|
||||
sb.append(line + "\n");
|
||||
}
|
||||
|
||||
if( exitCode != 0 )
|
||||
{
|
||||
throw new RuntimeException( "Exit Code: " + exitCode +
|
||||
" Console:" + sb.toString() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
if( mScript == null )
|
||||
{
|
||||
return "Run Script";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "Run Script: " + mScript;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014-2016 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 alias.id;
|
||||
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlSeeAlso;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
|
||||
import alias.id.broadcast.BroadcastChannel;
|
||||
import playlist.version1.Group;
|
||||
import alias.id.esn.Esn;
|
||||
import alias.id.fleetsync.FleetsyncID;
|
||||
import alias.id.lojack.LoJackFunctionAndID;
|
||||
import alias.id.mdc.MDC1200ID;
|
||||
import alias.id.mobileID.Min;
|
||||
import alias.id.mpt1327.MPT1327ID;
|
||||
import alias.id.nonrecordable.NonRecordable;
|
||||
import alias.id.priority.Priority;
|
||||
import alias.id.siteID.SiteID;
|
||||
import alias.id.status.StatusID;
|
||||
import alias.id.talkgroup.TalkgroupID;
|
||||
import alias.id.uniqueID.UniqueID;
|
||||
|
||||
@SuppressWarnings( "deprecation" )
|
||||
@XmlSeeAlso( {BroadcastChannel.class, Esn.class, FleetsyncID.class, Group.class, LoJackFunctionAndID.class,
|
||||
MDC1200ID.class, Min.class, MPT1327ID.class, NonRecordable.class,
|
||||
Priority.class, SiteID.class, StatusID.class, TalkgroupID.class,
|
||||
UniqueID.class } )
|
||||
@XmlRootElement( name = "id" )
|
||||
public abstract class AliasID
|
||||
{
|
||||
public AliasID()
|
||||
{
|
||||
}
|
||||
|
||||
public abstract AliasIDType getType();
|
||||
|
||||
public abstract boolean matches( AliasID id );
|
||||
|
||||
@XmlTransient
|
||||
public abstract boolean isValid();
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* sdrtrunk
|
||||
* Copyright (C) 2014-2016 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 alias.id.broadcast;
|
||||
|
||||
import alias.id.AliasID;
|
||||
import alias.id.AliasIDType;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
|
||||
public class BroadcastChannel extends AliasID implements Comparable<BroadcastChannel>
|
||||
{
|
||||
private String mChannelName;
|
||||
|
||||
public BroadcastChannel()
|
||||
{
|
||||
//JAXB Constructor
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(BroadcastChannel other)
|
||||
{
|
||||
if(mChannelName != null && other.getChannelName() != null)
|
||||
{
|
||||
return mChannelName.compareTo(other.getChannelName());
|
||||
}
|
||||
else if(mChannelName != null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a named broadcast channel
|
||||
*/
|
||||
public BroadcastChannel(String channelName)
|
||||
{
|
||||
mChannelName = channelName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Name of the broadcastAudio channel configuration
|
||||
*/
|
||||
@XmlAttribute(name="channel")
|
||||
public String getChannelName()
|
||||
{
|
||||
return mChannelName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of the broadcastAudio channel configuration
|
||||
*/
|
||||
public void setChannelName(String channel)
|
||||
{
|
||||
mChannelName = channel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AliasIDType getType()
|
||||
{
|
||||
return AliasIDType.BROADCAST_CHANNEL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid()
|
||||
{
|
||||
return mChannelName != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches( AliasID id )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
if(isValid())
|
||||
{
|
||||
return "Broadcast Channel: " + mChannelName;
|
||||
}
|
||||
else
|
||||
{
|
||||
return "Broadcast Channel: None Selected";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2015 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 alias.id.lojack;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
|
||||
import module.decode.lj1200.LJ1200Message;
|
||||
import module.decode.lj1200.LJ1200Message.Function;
|
||||
import alias.id.AliasID;
|
||||
import alias.id.AliasIDType;
|
||||
|
||||
public class LoJackFunctionAndID extends AliasID
|
||||
{
|
||||
private LJ1200Message.Function mFunction = Function.F0_UNKNOWN;
|
||||
private String mID = "*****";
|
||||
|
||||
public LoJackFunctionAndID()
|
||||
{
|
||||
}
|
||||
|
||||
@XmlAttribute( name="id" )
|
||||
public String getID()
|
||||
{
|
||||
return mID;
|
||||
}
|
||||
|
||||
public void setID( String id )
|
||||
{
|
||||
mID = id;
|
||||
}
|
||||
|
||||
@XmlAttribute( name="function" )
|
||||
public Function getFunction()
|
||||
{
|
||||
return mFunction;
|
||||
}
|
||||
|
||||
public void setFunction( Function function )
|
||||
{
|
||||
mFunction = function;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid()
|
||||
{
|
||||
return mFunction != null && mID != null;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "LoJack FUNC: " + mFunction.getLabel() + " ID:" + ( mID == null ? "" : mID );
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if the function and id combination match this alias id
|
||||
*/
|
||||
public boolean matches( Function function, String id )
|
||||
{
|
||||
return mFunction == function &&
|
||||
mID != null &&
|
||||
id != null &&
|
||||
id.matches( mID.replace( "*", ".?" ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches( AliasID id )
|
||||
{
|
||||
boolean retVal = false;
|
||||
|
||||
if( mID != null && id instanceof LoJackFunctionAndID )
|
||||
{
|
||||
LoJackFunctionAndID otherLojack = (LoJackFunctionAndID)id;
|
||||
|
||||
if( otherLojack.getFunction() == mFunction )
|
||||
{
|
||||
//Create a pattern - replace * wildcards with regex single-char wildcard
|
||||
String pattern = mID.replace( "*", ".?" );
|
||||
|
||||
retVal = otherLojack.getID().matches( pattern );
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AliasIDType getType()
|
||||
{
|
||||
return AliasIDType.LOJACK;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result
|
||||
+ ( ( mFunction == null ) ? 0 : mFunction.hashCode() );
|
||||
result = prime * result + ( ( mID == null ) ? 0 : mID.hashCode() );
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals( Object obj )
|
||||
{
|
||||
if ( this == obj )
|
||||
return true;
|
||||
if ( obj == null )
|
||||
return false;
|
||||
if ( getClass() != obj.getClass() )
|
||||
return false;
|
||||
LoJackFunctionAndID other = (LoJackFunctionAndID) obj;
|
||||
if ( mFunction != other.mFunction )
|
||||
return false;
|
||||
if ( mID == null )
|
||||
{
|
||||
if ( other.mID != null )
|
||||
return false;
|
||||
} else if ( !mID.equals( other.mID ) )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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 alias.id.mdc;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
|
||||
import alias.id.AliasID;
|
||||
import alias.id.AliasIDType;
|
||||
|
||||
|
||||
public class MDC1200ID extends AliasID
|
||||
{
|
||||
private String mID;
|
||||
|
||||
public MDC1200ID()
|
||||
{
|
||||
}
|
||||
|
||||
@XmlAttribute
|
||||
public String getIdent()
|
||||
{
|
||||
return mID;
|
||||
}
|
||||
|
||||
public void setIdent( String ident )
|
||||
{
|
||||
mID = ident;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid()
|
||||
{
|
||||
return mID != null;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "MDC-1200: " + mID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches( AliasID id )
|
||||
{
|
||||
boolean retVal = false;
|
||||
|
||||
if( mID != null && id instanceof MDC1200ID )
|
||||
{
|
||||
MDC1200ID tgid = (MDC1200ID)id;
|
||||
|
||||
//Create a pattern - replace * wildcards with regex single-char wildcard
|
||||
String pattern = mID.replace( "*", ".?" );
|
||||
|
||||
retVal = tgid.getIdent().matches( pattern );
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AliasIDType getType()
|
||||
{
|
||||
return AliasIDType.MDC1200;
|
||||
}
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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 alias.id.mobileID;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
|
||||
import alias.id.AliasID;
|
||||
import alias.id.AliasIDType;
|
||||
|
||||
/**
|
||||
* Mobile ID Number
|
||||
*/
|
||||
public class Min extends AliasID
|
||||
{
|
||||
private String mMin;
|
||||
|
||||
public Min()
|
||||
{
|
||||
}
|
||||
|
||||
@XmlAttribute
|
||||
public String getMin()
|
||||
{
|
||||
return mMin;
|
||||
}
|
||||
|
||||
public void setMin( String min )
|
||||
{
|
||||
mMin = min;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid()
|
||||
{
|
||||
return mMin != null;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "MIN: " + mMin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches( AliasID id )
|
||||
{
|
||||
boolean retVal = false;
|
||||
|
||||
if( mMin != null && id instanceof Min )
|
||||
{
|
||||
Min min = (Min)id;
|
||||
|
||||
//Create a pattern - replace * wildcards with regex single-char wildcard
|
||||
String pattern = mMin.replace( "*", ".?" );
|
||||
|
||||
retVal = min.getMin().matches( pattern );
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AliasIDType getType()
|
||||
{
|
||||
return AliasIDType.MIN;
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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 alias.id.mpt1327;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
|
||||
import alias.id.AliasID;
|
||||
import alias.id.AliasIDType;
|
||||
|
||||
public class MPT1327ID extends AliasID
|
||||
{
|
||||
private String mID;
|
||||
|
||||
public MPT1327ID()
|
||||
{
|
||||
}
|
||||
|
||||
@XmlAttribute
|
||||
public String getIdent()
|
||||
{
|
||||
return mID;
|
||||
}
|
||||
|
||||
public void setIdent( String ident )
|
||||
{
|
||||
mID = ident;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid()
|
||||
{
|
||||
return mID != null;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "MPT-1327: " + mID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches( AliasID id )
|
||||
{
|
||||
boolean retVal = false;
|
||||
|
||||
if( mID != null && id instanceof MPT1327ID )
|
||||
{
|
||||
MPT1327ID tgid = (MPT1327ID)id;
|
||||
|
||||
//Create a pattern - replace * wildcards with regex single-char wildcard
|
||||
String pattern = mID.replace( "*", ".?" );
|
||||
|
||||
retVal = tgid.getIdent().matches( pattern );
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AliasIDType getType()
|
||||
{
|
||||
return AliasIDType.MPT1327;
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package alias.id.nonrecordable;
|
||||
|
||||
import alias.id.AliasID;
|
||||
import alias.id.AliasIDType;
|
||||
|
||||
public class NonRecordable extends AliasID
|
||||
{
|
||||
@Override
|
||||
public AliasIDType getType()
|
||||
{
|
||||
return AliasIDType.NON_RECORDABLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches( AliasID id )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "Audio Non-Recordable";
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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 alias.id.priority;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
|
||||
import alias.id.AliasID;
|
||||
import alias.id.AliasIDType;
|
||||
|
||||
/**
|
||||
* Specifies an (audio) priority level for this alias.
|
||||
*/
|
||||
public class Priority extends AliasID
|
||||
{
|
||||
public static final int DO_NOT_MONITOR = -1;
|
||||
public static final int SELECTED_PRIORITY = 0;
|
||||
public static final int MIN_PRIORITY = 1;
|
||||
public static final int MAX_PRIORITY = 100;
|
||||
public static final int DEFAULT_PRIORITY = 100;
|
||||
|
||||
private int mPriority = DEFAULT_PRIORITY;
|
||||
|
||||
public Priority()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the associated alias should not be monitored or tracked.
|
||||
*/
|
||||
public boolean isDoNotMonitor()
|
||||
{
|
||||
return mPriority == DO_NOT_MONITOR;
|
||||
}
|
||||
|
||||
@XmlAttribute
|
||||
public int getPriority()
|
||||
{
|
||||
return mPriority;
|
||||
}
|
||||
|
||||
public void setPriority( int priority )
|
||||
{
|
||||
mPriority = priority;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "Audio Priority: " + ( isDoNotMonitor() ? "Do Not Monitor" : mPriority );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches( AliasID id )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AliasIDType getType()
|
||||
{
|
||||
return AliasIDType.PRIORITY;
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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 alias.id.siteID;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
|
||||
import alias.id.AliasID;
|
||||
import alias.id.AliasIDType;
|
||||
|
||||
public class SiteID extends AliasID
|
||||
{
|
||||
private String mSite;
|
||||
|
||||
public SiteID()
|
||||
{
|
||||
}
|
||||
|
||||
@XmlAttribute
|
||||
public String getSite()
|
||||
{
|
||||
return mSite;
|
||||
}
|
||||
|
||||
public void setSite( String site )
|
||||
{
|
||||
mSite = site;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid()
|
||||
{
|
||||
return mSite != null;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "Site: " + mSite;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches( AliasID otherID )
|
||||
{
|
||||
return otherID != null &&
|
||||
otherID instanceof SiteID &&
|
||||
getSite().contentEquals( ( (SiteID)otherID).getSite() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public AliasIDType getType()
|
||||
{
|
||||
return AliasIDType.SITE;
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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 alias.id.status;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
|
||||
import alias.id.AliasID;
|
||||
import alias.id.AliasIDType;
|
||||
|
||||
public class StatusID extends AliasID
|
||||
{
|
||||
private int mStatus;
|
||||
|
||||
public StatusID()
|
||||
{
|
||||
}
|
||||
|
||||
@XmlAttribute
|
||||
public int getStatus()
|
||||
{
|
||||
return mStatus;
|
||||
}
|
||||
|
||||
public void setStatus( int status )
|
||||
{
|
||||
this.mStatus = status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "Status: " + String.format( "%03d", mStatus );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches( AliasID id )
|
||||
{
|
||||
boolean retVal = false;
|
||||
|
||||
if( id instanceof StatusID )
|
||||
{
|
||||
StatusID statusId = (StatusID)id;
|
||||
|
||||
retVal = ( mStatus == statusId.getStatus() );
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AliasIDType getType()
|
||||
{
|
||||
return AliasIDType.STATUS;
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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 alias.id.uniqueID;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
|
||||
import alias.id.AliasID;
|
||||
import alias.id.AliasIDType;
|
||||
|
||||
public class UniqueID extends AliasID
|
||||
{
|
||||
private int mUid;
|
||||
|
||||
public UniqueID()
|
||||
{
|
||||
}
|
||||
|
||||
@XmlAttribute
|
||||
public int getUid()
|
||||
{
|
||||
return mUid;
|
||||
}
|
||||
|
||||
public void setUid( int uid )
|
||||
{
|
||||
this.mUid = uid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "UniqueID: " + mUid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches( AliasID id )
|
||||
{
|
||||
boolean retVal = false;
|
||||
|
||||
if( id instanceof UniqueID )
|
||||
{
|
||||
UniqueID uid = (UniqueID)id;
|
||||
|
||||
retVal = mUid == uid.getUid();
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AliasIDType getType()
|
||||
{
|
||||
return AliasIDType.LTR_NET_UID;
|
||||
}
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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 buffer;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import sample.complex.Complex;
|
||||
|
||||
/**
|
||||
* Circular sample buffer - allocates a buffer and stores samples in a circular
|
||||
* fashion, overwriting older samples with newly arrived samples. Initially
|
||||
* fills buffer with 0-valued samples
|
||||
*
|
||||
* Can be used as a delay-type buffer, to delay samples by the 'size' amount
|
||||
*/
|
||||
public class ComplexCircularBuffer
|
||||
{
|
||||
Complex[] mBuffer;
|
||||
int mBufferPointer = 0;
|
||||
|
||||
public ComplexCircularBuffer( int size )
|
||||
{
|
||||
mBuffer = new Complex[ size ];
|
||||
|
||||
Arrays.fill( mBuffer, new Complex( 1.0f, 1.0f ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sample currently pointed to in the buffer and stores the
|
||||
* new sample in its place
|
||||
* @param sample
|
||||
* @return
|
||||
*/
|
||||
public Complex get( Complex sample )
|
||||
{
|
||||
Complex retVal = mBuffer[ mBufferPointer ];
|
||||
|
||||
put( sample );
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public void put( Complex sample )
|
||||
{
|
||||
mBuffer[ mBufferPointer ] = sample;
|
||||
|
||||
mBufferPointer++;
|
||||
|
||||
if( mBufferPointer >= mBuffer.length )
|
||||
{
|
||||
mBufferPointer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public Complex[] get( int count )
|
||||
{
|
||||
Complex[] samples = new Complex[ count ];
|
||||
|
||||
int tempCounter = mBufferPointer;
|
||||
|
||||
for( int x = 0; x < count; x++ )
|
||||
{
|
||||
samples[ x ] = mBuffer[ tempCounter ];
|
||||
|
||||
tempCounter++;
|
||||
|
||||
if( tempCounter > mBuffer.length - 1 )
|
||||
{
|
||||
tempCounter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return samples;
|
||||
}
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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 buffer;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Circular sample buffer - allocates a buffer and stores samples in a circular
|
||||
* fashion, overwriting older samples with newly arrived samples. Initially
|
||||
* fills buffer with 0-valued samples
|
||||
*
|
||||
* Can be used as a delay-type buffer, to delay samples by the 'size' amount
|
||||
*/
|
||||
public class DoubleCircularBuffer
|
||||
{
|
||||
double[] mBuffer;
|
||||
int mBufferPointer = 0;
|
||||
|
||||
public DoubleCircularBuffer( int size )
|
||||
{
|
||||
mBuffer = new double[ size ];
|
||||
|
||||
Arrays.fill( mBuffer, 0.0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts the new value into the buffer and returns the oldest buffer value
|
||||
* that it replaced
|
||||
* @param newValue
|
||||
* @return
|
||||
*/
|
||||
public double get( double newValue )
|
||||
{
|
||||
double oldestSample = mBuffer[ mBufferPointer ];
|
||||
|
||||
mBuffer[ mBufferPointer ] = newValue;
|
||||
|
||||
mBufferPointer++;
|
||||
|
||||
if( mBufferPointer >= mBuffer.length )
|
||||
{
|
||||
mBufferPointer = 0;
|
||||
}
|
||||
|
||||
return oldestSample;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum from the values currently in the buffer
|
||||
*/
|
||||
public double max()
|
||||
{
|
||||
double max = 0.0d;
|
||||
|
||||
for( int x = 0; x < mBuffer.length; x++ )
|
||||
{
|
||||
if( mBuffer[ x ] > max )
|
||||
{
|
||||
max = mBuffer[ x ];
|
||||
}
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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 buffer;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Circular sample buffer - allocates a buffer and stores samples in a circular
|
||||
* fashion, overwriting older samples with newly arrived samples. Initially
|
||||
* fills buffer with 0-valued samples
|
||||
*
|
||||
* Can be used as a delay-type buffer, to delay samples by the 'size' amount
|
||||
* @author denny
|
||||
*
|
||||
*/
|
||||
public class FloatCircularBuffer
|
||||
{
|
||||
float[] mBuffer;
|
||||
int mBufferPointer = 0;
|
||||
|
||||
public FloatCircularBuffer( int size )
|
||||
{
|
||||
mBuffer = new float[ size ];
|
||||
|
||||
Arrays.fill( mBuffer, (float)0.0 );
|
||||
}
|
||||
|
||||
public int getSize()
|
||||
{
|
||||
return mBuffer.length;
|
||||
}
|
||||
|
||||
public float[] getBuffer()
|
||||
{
|
||||
return mBuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts the new value into the buffer and returns the oldest buffer value
|
||||
* that it replaced
|
||||
* @param newValue
|
||||
* @return
|
||||
*/
|
||||
public float get( float newValue )
|
||||
{
|
||||
float oldestSample = mBuffer[ mBufferPointer ];
|
||||
|
||||
mBuffer[ mBufferPointer ] = newValue;
|
||||
|
||||
mBufferPointer++;
|
||||
|
||||
if( mBufferPointer >= mBuffer.length )
|
||||
{
|
||||
mBufferPointer = 0;
|
||||
}
|
||||
|
||||
return oldestSample;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to put a new value in the buffer, while discarding
|
||||
* the old value
|
||||
*/
|
||||
public void put( float newValue )
|
||||
{
|
||||
get( newValue );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of arraySize, loaded with sampleCount of the
|
||||
* oldest samples, loaded into the array starting at index 0.
|
||||
*
|
||||
* This is useful for fetching an array filled half way with samples to
|
||||
* use in FFT processing.
|
||||
* @param arraySize - size of the array (must be larger than sampleCount)
|
||||
* @param sampleCount - number of the oldest samples in the buffer to load
|
||||
* @return
|
||||
*/
|
||||
public float[] get( int arraySize, int sampleCount )
|
||||
{
|
||||
float[] samples = new float[ arraySize ];
|
||||
|
||||
if( arraySize > sampleCount )
|
||||
{
|
||||
int tempCounter = mBufferPointer;
|
||||
|
||||
for( int x = 0; x < sampleCount; x++ )
|
||||
{
|
||||
samples[ x ] = mBuffer[ tempCounter ];
|
||||
|
||||
tempCounter++;
|
||||
|
||||
if( tempCounter > mBuffer.length )
|
||||
{
|
||||
tempCounter = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return samples;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014-2016 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 channel.state;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
/**
|
||||
* Details the set of states for a channel and the allowable transition states
|
||||
*/
|
||||
public enum State
|
||||
{
|
||||
IDLE( "IDLE" )
|
||||
{
|
||||
@Override
|
||||
public boolean canChangeTo( State state )
|
||||
{
|
||||
return state != TEARDOWN &&
|
||||
state != RESET;
|
||||
}
|
||||
},
|
||||
CALL( "CALL" )
|
||||
{
|
||||
@Override
|
||||
public boolean canChangeTo( State state )
|
||||
{
|
||||
return state == CONTROL ||
|
||||
state == DATA ||
|
||||
state == ENCRYPTED ||
|
||||
state == FADE ||
|
||||
state == TEARDOWN;
|
||||
}
|
||||
},
|
||||
DATA( "DATA" )
|
||||
{
|
||||
@Override
|
||||
public boolean canChangeTo( State state )
|
||||
{
|
||||
return state == CALL ||
|
||||
state == CONTROL ||
|
||||
state == ENCRYPTED ||
|
||||
state == FADE ||
|
||||
state == TEARDOWN;
|
||||
}
|
||||
},
|
||||
ENCRYPTED( "ENCRYPTED" )
|
||||
{
|
||||
@Override
|
||||
public boolean canChangeTo( State state )
|
||||
{
|
||||
return state == FADE || state == TEARDOWN;
|
||||
}
|
||||
},
|
||||
CONTROL( "CONTROL" )
|
||||
{
|
||||
@Override
|
||||
public boolean canChangeTo( State state )
|
||||
{
|
||||
return state == IDLE ||
|
||||
state == FADE;
|
||||
}
|
||||
},
|
||||
FADE( "FADE" )
|
||||
{
|
||||
@Override
|
||||
public boolean canChangeTo( State state )
|
||||
{
|
||||
return state != FADE &&
|
||||
state != RESET;
|
||||
}
|
||||
},
|
||||
RESET( "RESET" )
|
||||
{
|
||||
@Override
|
||||
public boolean canChangeTo(State state)
|
||||
{
|
||||
return state == IDLE;
|
||||
}
|
||||
},
|
||||
|
||||
TEARDOWN( "TEARDOWN" )
|
||||
{
|
||||
@Override
|
||||
public boolean canChangeTo(State state)
|
||||
{
|
||||
return state == RESET;
|
||||
}
|
||||
};
|
||||
|
||||
private String mDisplayValue;
|
||||
|
||||
public static final EnumSet<State> CALL_STATES = EnumSet.of( CALL, CONTROL, DATA, ENCRYPTED );
|
||||
public static final EnumSet<State> IDLE_STATES = EnumSet.of( IDLE, FADE );
|
||||
|
||||
private State( String displayValue )
|
||||
{
|
||||
mDisplayValue = displayValue;
|
||||
}
|
||||
|
||||
public abstract boolean canChangeTo( State state );
|
||||
|
||||
public String getDisplayValue()
|
||||
{
|
||||
return mDisplayValue;
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
package controller;
|
||||
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* Thread factory that applies custom names to threads
|
||||
*/
|
||||
public class NamingThreadFactory implements ThreadFactory
|
||||
{
|
||||
static final AtomicInteger poolNumber = new AtomicInteger(1);
|
||||
|
||||
final ThreadGroup mThreadGroup;
|
||||
|
||||
final AtomicInteger mThreadNumber = new AtomicInteger(1);
|
||||
|
||||
final String mNamePrefix;
|
||||
|
||||
public NamingThreadFactory( String prefix )
|
||||
{
|
||||
SecurityManager s = System.getSecurityManager();
|
||||
|
||||
mThreadGroup = (s != null)? s.getThreadGroup() :
|
||||
Thread.currentThread().getThreadGroup();
|
||||
|
||||
mNamePrefix = prefix + " pool-" +
|
||||
poolNumber.getAndIncrement() +
|
||||
"-thread-";
|
||||
}
|
||||
|
||||
public Thread newThread( Runnable runnable )
|
||||
{
|
||||
Thread thread = new Thread(mThreadGroup, runnable,
|
||||
mNamePrefix + mThreadNumber.getAndIncrement(), 0 );
|
||||
|
||||
if( thread.isDaemon() )
|
||||
{
|
||||
thread.setDaemon( false );
|
||||
}
|
||||
|
||||
if( thread.getPriority() != Thread.NORM_PRIORITY )
|
||||
{
|
||||
thread.setPriority( Thread.NORM_PRIORITY );
|
||||
}
|
||||
|
||||
return thread;
|
||||
}
|
||||
}
|
||||
@@ -1,463 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014-2016 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 controller.channel;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlSeeAlso;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
|
||||
import module.decode.DecoderFactory;
|
||||
import module.decode.DecoderType;
|
||||
import module.decode.config.AuxDecodeConfiguration;
|
||||
import module.decode.config.DecodeConfiguration;
|
||||
import module.log.EventLogType;
|
||||
import module.log.config.EventLogConfiguration;
|
||||
import record.RecorderType;
|
||||
import record.config.RecordConfiguration;
|
||||
import source.SourceType;
|
||||
import source.config.SourceConfigFactory;
|
||||
import source.config.SourceConfigRecording;
|
||||
import source.config.SourceConfigTuner;
|
||||
import source.config.SourceConfiguration;
|
||||
import source.tuner.TunerChannel;
|
||||
import source.tuner.TunerChannel.Type;
|
||||
import source.tuner.frequency.FrequencyChangeEvent;
|
||||
import source.tuner.frequency.FrequencyChangeEvent.Event;
|
||||
import source.tuner.frequency.IFrequencyChangeProcessor;
|
||||
import controller.config.Configuration;
|
||||
|
||||
@XmlSeeAlso( { Configuration.class } )
|
||||
@XmlRootElement( name = "channel" )
|
||||
public class Channel extends Configuration implements IFrequencyChangeProcessor
|
||||
{
|
||||
// Standard channels are persisted and traffic channels are temporary
|
||||
public enum ChannelType { STANDARD, TRAFFIC };
|
||||
|
||||
|
||||
// Static unique channel identifier tracking
|
||||
private static int UNIQUE_ID = 0;
|
||||
|
||||
private DecodeConfiguration mDecodeConfiguration = DecoderFactory.getDefaultDecodeConfiguration();
|
||||
private AuxDecodeConfiguration mAuxDecodeConfiguration =
|
||||
new AuxDecodeConfiguration();
|
||||
private SourceConfiguration mSourceConfiguration =
|
||||
SourceConfigFactory.getDefaultSourceConfiguration();
|
||||
private EventLogConfiguration mEventLogConfiguration =
|
||||
new EventLogConfiguration();
|
||||
private RecordConfiguration mRecordConfiguration = new RecordConfiguration();
|
||||
|
||||
private String mAliasListName;
|
||||
private String mSystem = "System";
|
||||
private String mSite = "Site";
|
||||
private String mName = "Channel";
|
||||
|
||||
private boolean mEnabled;
|
||||
private boolean mSelected;
|
||||
private TunerChannel mTunerChannel = null;
|
||||
|
||||
private ChannelType mChannelType = ChannelType.STANDARD;
|
||||
|
||||
private int mChannelID;
|
||||
private int mChannelFrequencyCorrection = 0;
|
||||
|
||||
/**
|
||||
* Channel represents a complete set of configurations needed to setup and
|
||||
* manage a processing chain and/or manage as a set of business objects that
|
||||
* can be displayed in graphical components.
|
||||
*
|
||||
* @param channelName
|
||||
* @param channelType
|
||||
*/
|
||||
public Channel( String channelName, ChannelType channelType )
|
||||
{
|
||||
this( channelName );
|
||||
mChannelType = channelType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new standard channel with the specified channel name
|
||||
*/
|
||||
public Channel( String channelName )
|
||||
{
|
||||
this();
|
||||
mName = channelName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new standard channel with a default name of "Channel"
|
||||
*/
|
||||
public Channel()
|
||||
{
|
||||
mChannelID = UNIQUE_ID++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a (new) deep copy of this channel
|
||||
*/
|
||||
public Channel copyOf()
|
||||
{
|
||||
Channel channel = new Channel( mName );
|
||||
channel.setSystem( mSystem );
|
||||
channel.setSite( mSite );
|
||||
channel.setAliasListName( mAliasListName );
|
||||
|
||||
AuxDecodeConfiguration aux = new AuxDecodeConfiguration();
|
||||
|
||||
for( DecoderType auxType: aux.getAuxDecoders() )
|
||||
{
|
||||
aux.addAuxDecoder( auxType );
|
||||
}
|
||||
|
||||
channel.setAuxDecodeConfiguration( aux );
|
||||
|
||||
channel.setDecodeConfiguration( DecoderFactory.copy( mDecodeConfiguration ) );
|
||||
|
||||
EventLogConfiguration log = new EventLogConfiguration();
|
||||
|
||||
for( EventLogType logType: mEventLogConfiguration.getLoggers() )
|
||||
{
|
||||
log.addLogger( logType );
|
||||
}
|
||||
|
||||
channel.setEventLogConfiguration( log );
|
||||
|
||||
RecordConfiguration record = new RecordConfiguration();
|
||||
|
||||
for( RecorderType recordType: mRecordConfiguration.getRecorders() )
|
||||
{
|
||||
record.addRecorder( recordType );
|
||||
}
|
||||
|
||||
channel.setRecordConfiguration( record );
|
||||
|
||||
channel.setSourceConfiguration( SourceConfigFactory.copy( mSourceConfiguration ) );
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unique identifier for this channel. Value is transient (not persisted).
|
||||
*/
|
||||
@XmlTransient
|
||||
public int getChannelID()
|
||||
{
|
||||
return mChannelID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this channel has been selected for prioritized audio output
|
||||
* and display of processing chain products
|
||||
*/
|
||||
@XmlTransient
|
||||
public boolean isSelected()
|
||||
{
|
||||
return mSelected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets selection status of the channel.
|
||||
*
|
||||
* NOTE: this method is package private so that only the ChannelSelectionManager
|
||||
* can toggle the selection state. Use the channel model to broadcast a
|
||||
* request select/deselect channel event.
|
||||
*
|
||||
* @param selected
|
||||
*/
|
||||
void setSelected( boolean selected )
|
||||
{
|
||||
mSelected = selected;
|
||||
}
|
||||
|
||||
@XmlTransient
|
||||
public ChannelType getChannelType()
|
||||
{
|
||||
return mChannelType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the owning system for this channel.
|
||||
*/
|
||||
@XmlAttribute( name = "system" )
|
||||
public String getSystem()
|
||||
{
|
||||
return mSystem;
|
||||
}
|
||||
|
||||
public void setSystem( String system )
|
||||
{
|
||||
mSystem = system;
|
||||
}
|
||||
|
||||
public boolean hasSystem()
|
||||
{
|
||||
return mSystem != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the owning site for this channel.
|
||||
*/
|
||||
@XmlAttribute( name = "site" )
|
||||
public String getSite()
|
||||
{
|
||||
return mSite;
|
||||
}
|
||||
|
||||
public void setSite( String site )
|
||||
{
|
||||
mSite = site;
|
||||
}
|
||||
|
||||
public boolean hasSite()
|
||||
{
|
||||
return mSite != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this channel.
|
||||
*/
|
||||
@XmlAttribute( name = "name" )
|
||||
public String getName()
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of this channel.
|
||||
*/
|
||||
public void setName( String name )
|
||||
{
|
||||
mName = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default display string for this channel: SYSTEM_SITE_NAME
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append( hasSystem() ? getSystem() : "SYSTEM" );
|
||||
sb.append( "_" );
|
||||
sb.append( hasSite() ? getSite() : "SITE" );
|
||||
sb.append( "_" );
|
||||
sb.append( getName() );
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this channel is enabled for processing.
|
||||
*/
|
||||
@XmlAttribute( name = "enabled" )
|
||||
public boolean getEnabled()
|
||||
{
|
||||
return mEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this channel will automatically start processing on
|
||||
* application startup or if this channel is currently processing after
|
||||
* application startup.
|
||||
*
|
||||
* Note: this method is package private and is intended to be managed
|
||||
* by a co-package central processing manager
|
||||
*
|
||||
* @see controller.ChannelProcessingManager
|
||||
*/
|
||||
void setEnabled( boolean enabled )
|
||||
{
|
||||
mEnabled = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the alias list that is used by this channel for looking up alias
|
||||
* values for the various identifiers produced by the decoder(s).
|
||||
*/
|
||||
@XmlElement( name = "alias_list_name" )
|
||||
public String getAliasListName()
|
||||
{
|
||||
return mAliasListName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the alias list to be used for looking up the alias values for the
|
||||
* various identifiers produced by the decoder
|
||||
*/
|
||||
public void setAliasListName( String name )
|
||||
{
|
||||
mAliasListName = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the primary decoder configuration used by this channel
|
||||
*/
|
||||
@XmlElement( name = "decode_configuration" )
|
||||
public DecodeConfiguration getDecodeConfiguration()
|
||||
{
|
||||
return mDecodeConfiguration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the primary decoder configuration used by this channel
|
||||
*/
|
||||
public void setDecodeConfiguration( DecodeConfiguration config )
|
||||
{
|
||||
mDecodeConfiguration = config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the aux decoder configuration used by this channel. Aux decoders
|
||||
* operate on demodulated audio
|
||||
*/
|
||||
@XmlElement( name = "aux_decode_configuration" )
|
||||
public AuxDecodeConfiguration getAuxDecodeConfiguration()
|
||||
{
|
||||
return mAuxDecodeConfiguration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the decoder configuration used by this channel
|
||||
*/
|
||||
public void setAuxDecodeConfiguration( AuxDecodeConfiguration config )
|
||||
{
|
||||
mAuxDecodeConfiguration = config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the source configuration for this channel. A channel source
|
||||
* identifies where the processing chain will get source sample data from.
|
||||
*/
|
||||
@XmlElement( name = "source_configuration" )
|
||||
public SourceConfiguration getSourceConfiguration()
|
||||
{
|
||||
return mSourceConfiguration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the source configuration for this channel.
|
||||
*/
|
||||
public void setSourceConfiguration( SourceConfiguration config )
|
||||
{
|
||||
mSourceConfiguration = config;
|
||||
|
||||
//Clear the tune channel object so that it can be recreated if the
|
||||
//source configuration changes
|
||||
mTunerChannel = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the event logger configuration for this channel.
|
||||
*/
|
||||
@XmlElement( name = "event_log_configuration" )
|
||||
public EventLogConfiguration getEventLogConfiguration()
|
||||
{
|
||||
return mEventLogConfiguration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the event logger configuration for this channel.
|
||||
*/
|
||||
public void setEventLogConfiguration( EventLogConfiguration config )
|
||||
{
|
||||
mEventLogConfiguration = config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the recorder configuration for this channel.
|
||||
*/
|
||||
@XmlElement( name = "record_configuration" )
|
||||
public RecordConfiguration getRecordConfiguration()
|
||||
{
|
||||
return mRecordConfiguration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the recorder configuration for this channel.
|
||||
*/
|
||||
public void setRecordConfiguration( RecordConfiguration config )
|
||||
{
|
||||
mRecordConfiguration = config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to construct a tuner channel object representing a
|
||||
* tuner or recording source frequency and bandwidth that can be used by
|
||||
* application components for graphically representing this channel.
|
||||
*
|
||||
* If the source configuration is not a tuner or recording, this method
|
||||
* returns null.
|
||||
*/
|
||||
@XmlTransient
|
||||
public TunerChannel getTunerChannel()
|
||||
{
|
||||
if( mTunerChannel == null )
|
||||
{
|
||||
if( mSourceConfiguration.getSourceType() == SourceType.TUNER )
|
||||
{
|
||||
SourceConfigTuner config = (SourceConfigTuner)mSourceConfiguration;
|
||||
|
||||
mTunerChannel = new TunerChannel( Type.LOCKED, config.getFrequency(),
|
||||
mDecodeConfiguration.getDecoderType().getChannelBandwidth() );
|
||||
}
|
||||
else if( mSourceConfiguration.getSourceType() == SourceType.RECORDING )
|
||||
{
|
||||
SourceConfigRecording config =
|
||||
(SourceConfigRecording)mSourceConfiguration;
|
||||
|
||||
mTunerChannel = new TunerChannel( Type.LOCKED, config.getFrequency(),
|
||||
mDecodeConfiguration.getDecoderType().getChannelBandwidth() );
|
||||
}
|
||||
}
|
||||
|
||||
return mTunerChannel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to indicate if any part of this channel is contained
|
||||
* within the minimum and maximum frequency values.
|
||||
*/
|
||||
public boolean isWithin( long minimum, long maximum )
|
||||
{
|
||||
TunerChannel tunerChannel = getTunerChannel();
|
||||
|
||||
return tunerChannel != null &&
|
||||
tunerChannel.overlaps( minimum, maximum );
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to make the current channel frequency correction value
|
||||
* available for use outside of a constructed processing chain while maintaining
|
||||
* linkage to the source channel. This hack allows the correction value to
|
||||
* be used to visually show in the spectral display.
|
||||
*/
|
||||
@Override
|
||||
public void frequencyChanged( FrequencyChangeEvent event )
|
||||
{
|
||||
if( event.getEvent() == Event.NOTIFICATION_CHANNEL_FREQUENCY_CORRECTION_CHANGE )
|
||||
{
|
||||
mChannelFrequencyCorrection = event.getValue().intValue();
|
||||
}
|
||||
}
|
||||
|
||||
@XmlTransient
|
||||
public int getChannelFrequencyCorrection()
|
||||
{
|
||||
return mChannelFrequencyCorrection;
|
||||
}
|
||||
}
|
||||
@@ -1,257 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014-2016 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 controller.channel;
|
||||
|
||||
import gui.editor.Editor;
|
||||
import gui.editor.EditorValidationException;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
import module.decode.AuxDecodeConfigurationEditor;
|
||||
import module.decode.DecodeConfigurationEditor;
|
||||
import module.log.EventLogConfigurationEditor;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import record.RecordConfigurationEditor;
|
||||
import source.SourceConfigurationEditor;
|
||||
import source.SourceManager;
|
||||
import alias.AliasModel;
|
||||
|
||||
import com.jidesoft.swing.JideTabbedPane;
|
||||
|
||||
import controller.channel.ChannelEvent.Event;
|
||||
import controller.channel.map.ChannelMapModel;
|
||||
|
||||
public class ChannelEditor extends Editor<Channel> implements ActionListener, ChannelEventListener
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private NameConfigurationEditor mNameConfigurationEditor;
|
||||
private SourceConfigurationEditor mSourceConfigurationEditor;
|
||||
private DecodeConfigurationEditor mDecodeConfigurationEditor;
|
||||
private AuxDecodeConfigurationEditor mAuxDecodeConfigurationEditor;
|
||||
private EventLogConfigurationEditor mEventLogConfigurationEditor;
|
||||
private RecordConfigurationEditor mRecordConfigurationEditor;
|
||||
|
||||
private JButton mEnableButton = new JButton( "Enable" );
|
||||
private JLabel mChannelName = new JLabel( "Channel:" );
|
||||
|
||||
private ChannelModel mChannelModel;
|
||||
private ChannelMapModel mChannelMapModel;
|
||||
private SourceManager mSourceManager;
|
||||
|
||||
private boolean mChannelEnableRequested = false;
|
||||
|
||||
public ChannelEditor( ChannelModel channelModel,
|
||||
ChannelMapModel channelMapModel,
|
||||
SourceManager sourceManager,
|
||||
AliasModel aliasModel )
|
||||
{
|
||||
mChannelModel = channelModel;
|
||||
mChannelMapModel = channelMapModel;
|
||||
mSourceManager = sourceManager;
|
||||
mNameConfigurationEditor = new NameConfigurationEditor( aliasModel, mChannelModel );
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
setLayout( new MigLayout( "fill,wrap 3", "[grow,fill][grow,fill][grow,fill]", "[grow,fill][]" ) );
|
||||
|
||||
JideTabbedPane tabs = new JideTabbedPane();
|
||||
tabs.setFont( this.getFont() );
|
||||
tabs.setForeground( Color.BLACK );
|
||||
|
||||
tabs.setTabTrailingComponent( mChannelName );
|
||||
|
||||
mNameConfigurationEditor.setSaveRequestListener( this );
|
||||
tabs.addTab( "Name/Alias", mNameConfigurationEditor );
|
||||
|
||||
mSourceConfigurationEditor = new SourceConfigurationEditor( mSourceManager );
|
||||
mSourceConfigurationEditor.setSaveRequestListener( this );
|
||||
tabs.addTab( "Source", mSourceConfigurationEditor );
|
||||
|
||||
mDecodeConfigurationEditor = new DecodeConfigurationEditor( mChannelMapModel );
|
||||
mDecodeConfigurationEditor.setSaveRequestListener( this );
|
||||
tabs.addTab( "Decoder", mDecodeConfigurationEditor );
|
||||
|
||||
mAuxDecodeConfigurationEditor = new AuxDecodeConfigurationEditor();
|
||||
mAuxDecodeConfigurationEditor.setSaveRequestListener( this );
|
||||
tabs.addTab( "Aux Decoders", mAuxDecodeConfigurationEditor );
|
||||
|
||||
mEventLogConfigurationEditor = new EventLogConfigurationEditor();
|
||||
mEventLogConfigurationEditor.setSaveRequestListener( this );
|
||||
tabs.addTab( "Logging", mEventLogConfigurationEditor );
|
||||
|
||||
mRecordConfigurationEditor = new RecordConfigurationEditor();
|
||||
mRecordConfigurationEditor.setSaveRequestListener( this );
|
||||
tabs.addTab( "Recording", mRecordConfigurationEditor );
|
||||
|
||||
add( tabs, "span" );
|
||||
|
||||
mEnableButton.addActionListener( this );
|
||||
mEnableButton.setEnabled( false );
|
||||
mEnableButton.setToolTipText( "Start the currently selected channel running/decoding" );
|
||||
add( mEnableButton );
|
||||
|
||||
JButton btnSave = new JButton( "Save" );
|
||||
btnSave.setToolTipText( "Save changes to the currently selected channel" );
|
||||
btnSave.addActionListener( ChannelEditor.this );
|
||||
add( btnSave );
|
||||
|
||||
JButton btnReset = new JButton( "Reset" );
|
||||
btnReset.setToolTipText( "Reload the currently selected channel" );
|
||||
btnReset.addActionListener( ChannelEditor.this );
|
||||
add( btnReset );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelChanged( ChannelEvent event )
|
||||
{
|
||||
if( hasItem() && getItem() == event.getChannel() )
|
||||
{
|
||||
switch( event.getEvent() )
|
||||
{
|
||||
case NOTIFICATION_CONFIGURATION_CHANGE:
|
||||
case NOTIFICATION_PROCESSING_START:
|
||||
case NOTIFICATION_PROCESSING_STOP:
|
||||
setItem( getItem() );
|
||||
mChannelEnableRequested = false;
|
||||
break;
|
||||
case NOTIFICATION_DELETE:
|
||||
setItem( null );
|
||||
break;
|
||||
case NOTIFICATION_ENABLE_REJECTED:
|
||||
if( mChannelEnableRequested )
|
||||
{
|
||||
JOptionPane.showMessageDialog( ChannelEditor.this, "Channel could not be "
|
||||
+ "enabled. This is likely because there are no tuner channels "
|
||||
+ "available", "Couldn't enable channel", JOptionPane.INFORMATION_MESSAGE );
|
||||
|
||||
mChannelEnableRequested = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
String command = e.getActionCommand();
|
||||
|
||||
if( command.contentEquals( "Enable" ) )
|
||||
{
|
||||
if( hasItem() )
|
||||
{
|
||||
save();
|
||||
|
||||
mChannelEnableRequested = true;
|
||||
mChannelModel.broadcast( new ChannelEvent( getItem(), Event.REQUEST_ENABLE ) );
|
||||
}
|
||||
}
|
||||
else if( command.contentEquals( "Disable" ) )
|
||||
{
|
||||
if( hasItem() )
|
||||
{
|
||||
mChannelModel.broadcast( new ChannelEvent( getItem(), Event.REQUEST_DISABLE ) );
|
||||
}
|
||||
}
|
||||
else if( command.contentEquals( "Save" ) )
|
||||
{
|
||||
save();
|
||||
}
|
||||
else if( command.contentEquals( "Reset" ) )
|
||||
{
|
||||
setItem( getItem() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the channel configuration in each of the channel editor components
|
||||
* Note: this method must be invoked on the swing event dispatch thread
|
||||
*/
|
||||
public void setItem( final Channel channel )
|
||||
{
|
||||
super.setItem( channel );
|
||||
|
||||
mNameConfigurationEditor.setItem( channel );
|
||||
mSourceConfigurationEditor.setItem( channel );
|
||||
mDecodeConfigurationEditor.setItem( channel );
|
||||
mAuxDecodeConfigurationEditor.setItem( channel );
|
||||
mEventLogConfigurationEditor.setItem( channel );
|
||||
mRecordConfigurationEditor.setItem( channel );
|
||||
|
||||
if( channel != null )
|
||||
{
|
||||
mChannelName.setText( "Channel: " + channel.getName() );
|
||||
mEnableButton.setText( channel.getEnabled() ? "Disable" : "Enable" );
|
||||
mEnableButton.setEnabled( true );
|
||||
mEnableButton.setBackground( channel.getEnabled() ? Color.GREEN : getBackground() );
|
||||
}
|
||||
else
|
||||
{
|
||||
mChannelName.setText( "Channel: " );
|
||||
mEnableButton.setText( "Enable" );
|
||||
mEnableButton.setEnabled( false );
|
||||
mEnableButton.setBackground( getBackground() );
|
||||
}
|
||||
}
|
||||
|
||||
public void save()
|
||||
{
|
||||
if( hasItem() )
|
||||
{
|
||||
mNameConfigurationEditor.save();
|
||||
mSourceConfigurationEditor.save();
|
||||
mDecodeConfigurationEditor.save();
|
||||
mAuxDecodeConfigurationEditor.save();
|
||||
mEventLogConfigurationEditor.save();
|
||||
mRecordConfigurationEditor.save();
|
||||
|
||||
try
|
||||
{
|
||||
mDecodeConfigurationEditor.validate( mSourceConfigurationEditor );
|
||||
mDecodeConfigurationEditor.validate( mAuxDecodeConfigurationEditor );
|
||||
}
|
||||
catch( EditorValidationException e )
|
||||
{
|
||||
e.getEditor().requestFocus();
|
||||
|
||||
JOptionPane.showMessageDialog( e.getEditor(), e.getReason(),
|
||||
"Configuration Error", JOptionPane.ERROR_MESSAGE );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
mChannelModel.broadcast( new ChannelEvent( getItem(),
|
||||
Event.NOTIFICATION_CONFIGURATION_CHANGE ) );
|
||||
}
|
||||
|
||||
setModified( false );
|
||||
}
|
||||
}
|
||||
@@ -1,269 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014-2016 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 controller.channel;
|
||||
|
||||
import gui.editor.Editor;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.ComboBoxModel;
|
||||
import javax.swing.DefaultComboBoxModel;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import alias.AliasModel;
|
||||
|
||||
public class NameConfigurationEditor extends Editor<Channel> implements DocumentListener
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final static Logger mLog = LoggerFactory.getLogger( NameConfigurationEditor.class );
|
||||
|
||||
private static ComboBoxModel<String> EMPTY_MODEL = new DefaultComboBoxModel<>();
|
||||
|
||||
private AliasModel mAliasModel;
|
||||
private ChannelModel mChannelModel;
|
||||
|
||||
private JTextField mChannelName;
|
||||
private JComboBox<String> mSystemNameCombo;
|
||||
private JComboBox<String> mSiteNameCombo;
|
||||
private JComboBox<String> mAliasListCombo;
|
||||
|
||||
public NameConfigurationEditor( AliasModel aliasModel, ChannelModel model )
|
||||
{
|
||||
mAliasModel = aliasModel;
|
||||
mChannelModel = model;
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
setLayout( new MigLayout( "fill,wrap 4", "[right][grow,fill][right][grow,fill]", "[][][grow]" ) );
|
||||
|
||||
mChannelName = new JTextField( "" );
|
||||
mChannelName.getDocument().addDocumentListener( this );
|
||||
mChannelName.setEnabled( false );
|
||||
|
||||
add( new JLabel( "Name:" ) );
|
||||
add( mChannelName );
|
||||
|
||||
mSystemNameCombo = new JComboBox<>( EMPTY_MODEL );
|
||||
mSystemNameCombo.setEnabled( false );
|
||||
mSystemNameCombo.setEditable( true );
|
||||
mSystemNameCombo.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
Object selected = mSystemNameCombo.getSelectedItem();
|
||||
|
||||
if( selected != null )
|
||||
{
|
||||
String system = (String)selected;
|
||||
|
||||
List<String> sites = mChannelModel.getSites( system );
|
||||
|
||||
if( !sites.contains( getItem().getSite() ) )
|
||||
{
|
||||
sites.add( getItem().getSite() );
|
||||
}
|
||||
|
||||
if( sites.isEmpty() )
|
||||
{
|
||||
mSiteNameCombo.setModel( EMPTY_MODEL );
|
||||
}
|
||||
else
|
||||
{
|
||||
mSiteNameCombo.setModel( new DefaultComboBoxModel<String>(
|
||||
sites.toArray( new String[ sites.size() ] ) ) );;
|
||||
}
|
||||
|
||||
mSiteNameCombo.setSelectedItem( getItem().getSite() );
|
||||
}
|
||||
|
||||
setModified( true );
|
||||
}
|
||||
} );
|
||||
|
||||
add( new JLabel( "System:" ) );
|
||||
add( mSystemNameCombo );
|
||||
|
||||
mAliasListCombo = new JComboBox<String>();
|
||||
mAliasListCombo.setEnabled( false );
|
||||
mAliasListCombo.setEditable( true );
|
||||
mAliasListCombo.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
setModified( true );
|
||||
}
|
||||
} );
|
||||
|
||||
add( new JLabel( "Alias List:" ) );
|
||||
add( mAliasListCombo );
|
||||
|
||||
mSiteNameCombo = new JComboBox<>( EMPTY_MODEL );
|
||||
mSiteNameCombo.setEnabled( false );
|
||||
mSiteNameCombo.setEditable( true );
|
||||
mSiteNameCombo.addActionListener( new ActionListener()
|
||||
{
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e )
|
||||
{
|
||||
setModified( true );
|
||||
}
|
||||
} );
|
||||
|
||||
add( new JLabel( "Site:" ) );
|
||||
add( mSiteNameCombo );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save()
|
||||
{
|
||||
if( hasItem() && isModified() )
|
||||
{
|
||||
getItem().setName( mChannelName.getText() );
|
||||
|
||||
Object system = mSystemNameCombo.getSelectedItem();
|
||||
getItem().setSystem( ( system == null ? null : (String)system ) );
|
||||
|
||||
Object site = mSiteNameCombo.getSelectedItem();
|
||||
getItem().setSite( ( site == null ? null : (String)site ) );
|
||||
|
||||
Object aliasList = mAliasListCombo.getSelectedItem();
|
||||
getItem().setAliasListName( aliasList == null ? null : (String)aliasList );
|
||||
}
|
||||
|
||||
setModified( false );
|
||||
}
|
||||
|
||||
private void setControlsEnabled( boolean enabled )
|
||||
{
|
||||
if( mChannelName.isEnabled() != enabled )
|
||||
{
|
||||
mChannelName.setEnabled( enabled );
|
||||
}
|
||||
|
||||
if( mAliasListCombo.isEnabled() != enabled )
|
||||
{
|
||||
mAliasListCombo.setEnabled( enabled );
|
||||
}
|
||||
|
||||
if( mSystemNameCombo.isEnabled() != enabled )
|
||||
{
|
||||
mSystemNameCombo.setEnabled( enabled );
|
||||
}
|
||||
|
||||
if( mSiteNameCombo.isEnabled() != enabled )
|
||||
{
|
||||
mSiteNameCombo.setEnabled( enabled );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItem( Channel channel )
|
||||
{
|
||||
super.setItem( channel );
|
||||
|
||||
if( hasItem() )
|
||||
{
|
||||
setControlsEnabled( true );
|
||||
|
||||
mChannelName.setText( channel.getName() );
|
||||
|
||||
List<String> systems = mChannelModel.getSystems();
|
||||
|
||||
if( systems.isEmpty() )
|
||||
{
|
||||
mSystemNameCombo.setModel( EMPTY_MODEL );
|
||||
}
|
||||
else
|
||||
{
|
||||
mSystemNameCombo.setModel( new DefaultComboBoxModel<String>(
|
||||
systems.toArray( new String[ systems.size() ] ) ) );;
|
||||
}
|
||||
|
||||
mSystemNameCombo.setSelectedItem( channel.getSystem() );
|
||||
|
||||
List<String> sites = mChannelModel.getSites( channel.getSystem() );
|
||||
|
||||
if( sites.isEmpty() )
|
||||
{
|
||||
mSiteNameCombo.setModel( EMPTY_MODEL );
|
||||
}
|
||||
else
|
||||
{
|
||||
mSiteNameCombo.setModel( new DefaultComboBoxModel<String>(
|
||||
sites.toArray( new String[ sites.size() ] ) ) );;
|
||||
}
|
||||
|
||||
if( channel.getSite() != null )
|
||||
{
|
||||
mSiteNameCombo.setSelectedItem( channel.getSite() );
|
||||
}
|
||||
|
||||
List<String> lists = mAliasModel.getListNames();
|
||||
Collections.sort( lists );
|
||||
mAliasListCombo.setModel( new DefaultComboBoxModel<String>(
|
||||
lists.toArray( new String[ lists.size() ] ) ) );
|
||||
|
||||
if( channel.getAliasListName() != null )
|
||||
{
|
||||
mAliasListCombo.setSelectedItem( channel.getAliasListName() );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
setControlsEnabled( false );
|
||||
mChannelName.setText( null );
|
||||
}
|
||||
|
||||
setModified( false );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertUpdate( DocumentEvent e )
|
||||
{
|
||||
setModified( true );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changedUpdate( DocumentEvent e )
|
||||
{
|
||||
setModified( true );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeUpdate( DocumentEvent e )
|
||||
{
|
||||
setModified( true );
|
||||
}
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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 controller.channel.map;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlSeeAlso;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
|
||||
@XmlSeeAlso( { ChannelRange.class } )
|
||||
public class ChannelMap
|
||||
{
|
||||
private String mName;
|
||||
private boolean mInvalid = false;
|
||||
|
||||
private List<ChannelRange> mRanges = new ArrayList<ChannelRange>();
|
||||
|
||||
public ChannelMap()
|
||||
{
|
||||
this( "New Channel Map" );
|
||||
}
|
||||
|
||||
public ChannelMap( String name )
|
||||
{
|
||||
mName = name;
|
||||
}
|
||||
|
||||
public ChannelMap copyOf()
|
||||
{
|
||||
ChannelMap map = new ChannelMap( new String( mName ) );
|
||||
|
||||
for( ChannelRange range: mRanges )
|
||||
{
|
||||
map.addRange( range.copyOf() );
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
@XmlTransient
|
||||
public boolean isInvalid()
|
||||
{
|
||||
return mInvalid;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return mName + ( mInvalid ? " - Error" : "" );
|
||||
}
|
||||
|
||||
@XmlElement( name = "range" )
|
||||
public List<ChannelRange> getRanges()
|
||||
{
|
||||
return mRanges;
|
||||
}
|
||||
|
||||
public void setRanges( List<ChannelRange> ranges )
|
||||
{
|
||||
mRanges = ranges;
|
||||
|
||||
validate();
|
||||
}
|
||||
|
||||
@XmlAttribute
|
||||
public String getName()
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
|
||||
public void setName( String name )
|
||||
{
|
||||
mName = name;
|
||||
}
|
||||
|
||||
public long getFrequency( int channelNumber )
|
||||
{
|
||||
for( ChannelRange range: mRanges )
|
||||
{
|
||||
if( range.hasChannel( channelNumber ) )
|
||||
{
|
||||
return range.getFrequency( channelNumber );
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates each of the channel ranges for overlap
|
||||
*/
|
||||
private void validate()
|
||||
{
|
||||
mInvalid = false;
|
||||
|
||||
for( int x = 0; x < mRanges.size(); x++ )
|
||||
{
|
||||
if( !mRanges.get( x ).isValid() )
|
||||
{
|
||||
mInvalid = true;
|
||||
}
|
||||
|
||||
for( int y = x + 1; y < mRanges.size(); y++ )
|
||||
{
|
||||
if( mRanges.get( x ).overlaps( mRanges.get( y ) ) )
|
||||
{
|
||||
mInvalid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void addRange( ChannelRange range )
|
||||
{
|
||||
mRanges.add( range );
|
||||
|
||||
validate();
|
||||
}
|
||||
|
||||
public void removeRange( ChannelRange range )
|
||||
{
|
||||
mRanges.remove( range );
|
||||
|
||||
validate();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,186 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014-2016 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 controller.channel.map;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
|
||||
@XmlRootElement
|
||||
@XmlType( name = "range" )
|
||||
public class ChannelRange
|
||||
{
|
||||
private static final DecimalFormat FREQUENCY_FORMATTER = new DecimalFormat( "#.0000" );
|
||||
|
||||
private int mFirst = 1;
|
||||
private int mLast = 1023;
|
||||
private int mBase = 450000000;
|
||||
private int mSize = 12500;
|
||||
|
||||
private boolean mOverlapping = false;
|
||||
|
||||
public ChannelRange()
|
||||
{
|
||||
}
|
||||
|
||||
public ChannelRange( int first, int last, int base, int size )
|
||||
{
|
||||
mFirst = first;
|
||||
mLast = last;
|
||||
mBase = base;
|
||||
mSize = size;
|
||||
}
|
||||
|
||||
public ChannelRange copyOf()
|
||||
{
|
||||
return new ChannelRange( mFirst, mLast, mBase, mSize );
|
||||
}
|
||||
|
||||
public String getDescription()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
if( isValid() )
|
||||
{
|
||||
sb.append( "First: " );
|
||||
sb.append( mFirst + "=" );
|
||||
|
||||
long frequency = getFrequency( mFirst );
|
||||
|
||||
sb.append( FREQUENCY_FORMATTER.format( (double)frequency / 1E6D ) );
|
||||
sb.append( " Last: " );
|
||||
sb.append( mLast + "=" );
|
||||
|
||||
frequency = getFrequency( mLast );
|
||||
sb.append( FREQUENCY_FORMATTER.format( (double)frequency / 1E6D ) );
|
||||
sb.append( " MHz" );
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.append( "First channel must be smaller than last channel" );
|
||||
}
|
||||
|
||||
if( isOverlapping() )
|
||||
{
|
||||
if( sb.length() > 0 )
|
||||
{
|
||||
sb.append( ", " );
|
||||
}
|
||||
|
||||
sb.append( "Overlap!" );
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public boolean isValid()
|
||||
{
|
||||
return mFirst < mLast;
|
||||
}
|
||||
|
||||
public boolean overlaps( ChannelRange other )
|
||||
{
|
||||
return ( mFirst <= other.mFirst && other.mFirst <= mLast ) ||
|
||||
( mFirst <= other.mLast && other.mLast <= mLast ) ||
|
||||
( mFirst <= other.mFirst && other.mLast <= mLast ) ||
|
||||
( other.mFirst <= mFirst && mLast <= other.mLast );
|
||||
}
|
||||
|
||||
@XmlTransient
|
||||
public boolean isOverlapping()
|
||||
{
|
||||
return mOverlapping;
|
||||
}
|
||||
|
||||
public void setOverlapping( boolean overlapping )
|
||||
{
|
||||
mOverlapping = overlapping;
|
||||
}
|
||||
|
||||
public boolean hasChannel( int channel )
|
||||
{
|
||||
return mFirst <= channel && channel <= mLast;
|
||||
}
|
||||
|
||||
public long getFrequency( int channel )
|
||||
{
|
||||
if( hasChannel( channel ) )
|
||||
{
|
||||
return mBase + ( ( channel - mFirst ) * mSize );
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@XmlAttribute( name = "first" )
|
||||
public int getFirstChannelNumber()
|
||||
{
|
||||
return mFirst;
|
||||
}
|
||||
|
||||
public void setFirstChannelNumber( int first )
|
||||
{
|
||||
mFirst = first;
|
||||
}
|
||||
|
||||
@XmlAttribute( name = "last" )
|
||||
public void setLastChannelNumber( int last )
|
||||
{
|
||||
mLast = last;
|
||||
}
|
||||
|
||||
public int getLastChannelNumber()
|
||||
{
|
||||
return mLast;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the base frequency
|
||||
* @param base frequency in hertz
|
||||
*/
|
||||
@XmlAttribute( name = "base" )
|
||||
public void setBase( int base )
|
||||
{
|
||||
mBase = base;
|
||||
}
|
||||
|
||||
public int getBase()
|
||||
{
|
||||
return mBase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the channel size
|
||||
* @param size in hertz
|
||||
*/
|
||||
@XmlAttribute( name = "size" )
|
||||
public void setSize( int size )
|
||||
{
|
||||
mSize = size;
|
||||
}
|
||||
|
||||
public int getSize()
|
||||
{
|
||||
return mSize;
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 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 controller.config;
|
||||
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
import javax.xml.bind.annotation.XmlSeeAlso;
|
||||
|
||||
import module.decode.config.AuxDecodeConfiguration;
|
||||
import module.decode.config.DecodeConfiguration;
|
||||
import module.log.config.EventLogConfiguration;
|
||||
import record.config.RecordConfiguration;
|
||||
import source.config.SourceConfiguration;
|
||||
|
||||
@XmlSeeAlso( { AuxDecodeConfiguration.class,
|
||||
DecodeConfiguration.class,
|
||||
EventLogConfiguration.class,
|
||||
RecordConfiguration.class,
|
||||
SourceConfiguration.class } )
|
||||
@XmlRootElement( name = "configuration" )
|
||||
public abstract class Configuration
|
||||
{
|
||||
public Configuration()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,407 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2015 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 dsp.filter.cic;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import sample.Listener;
|
||||
import sample.complex.ComplexBuffer;
|
||||
import sample.complex.ComplexSampleListener;
|
||||
import sample.complex.ComplexToComplexBufferAssembler;
|
||||
import sample.decimator.ComplexDecimator;
|
||||
import dsp.filter.FilterFactory;
|
||||
import dsp.filter.Filters;
|
||||
import dsp.filter.Window.WindowType;
|
||||
import dsp.filter.fir.complex.ComplexFIRFilter_CB_CB;
|
||||
import dsp.filter.halfband.complex.HalfBandFilter_CB_CB;
|
||||
|
||||
public class ComplexPrimeCICDecimate implements Listener<ComplexBuffer>
|
||||
{
|
||||
public static int[] PRIMES = { 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,
|
||||
59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,
|
||||
157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,
|
||||
257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,
|
||||
367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,
|
||||
467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,
|
||||
599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691 };
|
||||
|
||||
private ArrayList<DecimatingStage> mDecimatingStages =
|
||||
new ArrayList<DecimatingStage>();
|
||||
|
||||
private DecimatingStage mFirstDecimatingStage;
|
||||
|
||||
private Output mOutput;
|
||||
|
||||
/**
|
||||
* Non-Recursive Prime-Factor CIC Filter with float sample array inputs and
|
||||
* decimated, single paired i/q float sample output.
|
||||
*
|
||||
* Implements the CIC filter described in Understanding Digital Signal
|
||||
* Processing, 3e, Lyons, on page 769. This filter is comprised of multiple
|
||||
* decimating stages each with a prime factor decimation rate. Multiple
|
||||
* stages are cascaded to achieve the overall decimation rate.
|
||||
*
|
||||
* This filter supports a maximum decimation rate of 700. This filter can
|
||||
* be adapted to higher decimation rates by adding additional prime factors
|
||||
* to the PRIMES array.
|
||||
*
|
||||
* @param decimation - overall decimation rate
|
||||
* @param order - filter order
|
||||
*/
|
||||
public ComplexPrimeCICDecimate( int decimation, int order,
|
||||
int passFrequency, int attenuation, WindowType windowType )
|
||||
{
|
||||
assert( decimation <= 700 );
|
||||
|
||||
|
||||
List<Integer> stageSizes = getPrimeFactors( decimation );
|
||||
|
||||
for( int x = 0; x < stageSizes.size(); x++ )
|
||||
{
|
||||
DecimatingStage stage = new DecimatingStage( stageSizes.get( x ), order );
|
||||
|
||||
mDecimatingStages.add( stage );
|
||||
|
||||
if( x == 0 )
|
||||
{
|
||||
/* Reference to first stage -- will receive all samples */
|
||||
mFirstDecimatingStage = stage;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Wire the current stage to the previous stage */
|
||||
mDecimatingStages.get( x - 1 ).setListener( stage );
|
||||
}
|
||||
}
|
||||
|
||||
mOutput = new Output( 48000, passFrequency, attenuation, windowType );
|
||||
|
||||
mDecimatingStages.get( mDecimatingStages.size() - 1 )
|
||||
.setListener( mOutput );
|
||||
}
|
||||
|
||||
public void dispose()
|
||||
{
|
||||
for( DecimatingStage stage: mDecimatingStages )
|
||||
{
|
||||
stage.dispose();
|
||||
}
|
||||
|
||||
mDecimatingStages.clear();
|
||||
mDecimatingStages = null;
|
||||
mFirstDecimatingStage = null;
|
||||
|
||||
mOutput.dispose();
|
||||
mOutput = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a listener to receive the output of this CIC decimation filter
|
||||
*/
|
||||
public void setListener( Listener<ComplexBuffer> listener )
|
||||
{
|
||||
mOutput.setListener( listener );
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes listener from output of this CIC decimation filter
|
||||
*/
|
||||
public void removeListener()
|
||||
{
|
||||
mOutput.removeListener();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the prime factors of the decimation rate up to a maximum
|
||||
* decimation rate of 700. If you wish to have decimation rates higher
|
||||
* than 700, then add additional prime factors to the PRIMES array.
|
||||
*
|
||||
* @param decimation - integral decimation rate
|
||||
* @return - ordered list (smallest to largest) of prime factors
|
||||
*/
|
||||
public static List<Integer> getPrimeFactors( int decimation )
|
||||
{
|
||||
ArrayList<Integer> stages = new ArrayList<Integer>();
|
||||
|
||||
int pointer = 0;
|
||||
|
||||
while( decimation > 0 && pointer < PRIMES.length )
|
||||
{
|
||||
int prime = PRIMES[ pointer ];
|
||||
|
||||
if( decimation % prime == 0 )
|
||||
{
|
||||
stages.add( prime );
|
||||
|
||||
decimation /= prime;
|
||||
}
|
||||
else
|
||||
{
|
||||
pointer++;
|
||||
}
|
||||
}
|
||||
|
||||
return stages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Primary input method for receiving sample arrays composed as I,Q,I,Q, etc.
|
||||
*/
|
||||
@Override
|
||||
public void receive( ComplexBuffer buffer )
|
||||
{
|
||||
if( mFirstDecimatingStage != null )
|
||||
{
|
||||
float[] samples = buffer.getSamples();
|
||||
|
||||
for( int x = 0; x < samples.length; x += 2 )
|
||||
{
|
||||
mFirstDecimatingStage.receive( samples[ x ], samples[ x + 1 ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decimating stage combines multiple CIC stages with a decimator. The
|
||||
* number of stages is indicated by the order value and the size indicates
|
||||
* the decimation rate of this stage.
|
||||
*/
|
||||
public class DecimatingStage implements ComplexSampleListener
|
||||
{
|
||||
private ArrayList<Stage> mStages = new ArrayList<Stage>();
|
||||
private Stage mFirstStage;
|
||||
private ComplexDecimator mDecimator;
|
||||
|
||||
public DecimatingStage( int size, int order )
|
||||
{
|
||||
for( int x = 0; x < order; x++ )
|
||||
{
|
||||
Stage stage;
|
||||
|
||||
if( size == 2 )
|
||||
{
|
||||
stage = new TwoStage();
|
||||
}
|
||||
else
|
||||
{
|
||||
stage = new Stage( size );
|
||||
}
|
||||
|
||||
mStages.add( stage );
|
||||
|
||||
if( x == 0 )
|
||||
{
|
||||
mFirstStage = stage;
|
||||
}
|
||||
else
|
||||
{
|
||||
mStages.get( x - 1 ).setListener( stage );
|
||||
}
|
||||
}
|
||||
|
||||
mDecimator = new ComplexDecimator( size );
|
||||
|
||||
mStages.get( mStages.size() - 1 ).setListener( mDecimator );
|
||||
}
|
||||
|
||||
public void dispose()
|
||||
{
|
||||
for( Stage stage: mStages )
|
||||
{
|
||||
stage.dispose();
|
||||
}
|
||||
|
||||
mStages.clear();
|
||||
mDecimator.dispose();
|
||||
mDecimator = null;
|
||||
mFirstStage = null;
|
||||
mStages = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void receive( float i, float q )
|
||||
{
|
||||
mFirstStage.receive( i, q );
|
||||
}
|
||||
|
||||
public void setListener( ComplexSampleListener listener )
|
||||
{
|
||||
mDecimator.setListener( listener );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Single non-decimating CIC stage component. Uses a circular buffer and a
|
||||
* running average internally to implement the stage so that stage size has
|
||||
* essentially no impact on the computational requirements of the stage
|
||||
*/
|
||||
public class Stage implements ComplexSampleListener
|
||||
{
|
||||
protected ComplexSampleListener mListener;
|
||||
|
||||
private float[] mISamples;
|
||||
private float[] mQSamples;
|
||||
|
||||
protected float mISum;
|
||||
protected float mQSum;
|
||||
|
||||
private int mSamplePointer = 0;
|
||||
private int mSize;
|
||||
|
||||
protected float mGain;
|
||||
|
||||
public Stage()
|
||||
{
|
||||
}
|
||||
|
||||
public Stage( int size )
|
||||
{
|
||||
mSize = size - 1;
|
||||
|
||||
mISamples = new float[ mSize ];
|
||||
mQSamples = new float[ mSize ];
|
||||
|
||||
mGain = 1.0f / (float)size;
|
||||
}
|
||||
|
||||
public void dispose()
|
||||
{
|
||||
mListener = null;
|
||||
}
|
||||
|
||||
public void receive( float i, float q )
|
||||
{
|
||||
/* Subtract the oldest sample and add back in the newest */
|
||||
mISum = mISum - mISamples[ mSamplePointer ] + i;
|
||||
mQSum = mQSum - mQSamples[ mSamplePointer ] + q;
|
||||
|
||||
/* Overwrite the oldest sample with the newest */
|
||||
mISamples[ mSamplePointer ] = i;
|
||||
mQSamples[ mSamplePointer ] = q;
|
||||
|
||||
mSamplePointer++;
|
||||
|
||||
if( mSamplePointer >= mSize )
|
||||
{
|
||||
mSamplePointer = 0;
|
||||
}
|
||||
|
||||
if( mListener != null )
|
||||
{
|
||||
mListener.receive( ( mISum * mGain ), ( mQSum * mGain ) );
|
||||
}
|
||||
}
|
||||
|
||||
public void setListener( ComplexSampleListener listener )
|
||||
{
|
||||
mListener = listener;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Size 2 stage that removes the unnecessary circular buffer management for
|
||||
* a two-stage.
|
||||
*/
|
||||
public class TwoStage extends Stage
|
||||
{
|
||||
public TwoStage()
|
||||
{
|
||||
super();
|
||||
|
||||
mGain = 0.5f;
|
||||
}
|
||||
|
||||
public void receive( float i, float q )
|
||||
{
|
||||
float iSum = mISum + i;
|
||||
float qSum = mQSum + q;
|
||||
|
||||
mISum = i;
|
||||
mQSum = q;
|
||||
|
||||
if( mListener != null )
|
||||
{
|
||||
mListener.receive( ( iSum * mGain ), ( qSum * mGain ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Output adapter - applies gain correction and cleanup filter and broadcast
|
||||
* to registered listener.
|
||||
*/
|
||||
public class Output implements ComplexSampleListener
|
||||
{
|
||||
/* Decimated output buffers will contain 1024 samples */
|
||||
private ComplexToComplexBufferAssembler mAssembler =
|
||||
new ComplexToComplexBufferAssembler( 2048 );
|
||||
|
||||
private ComplexFIRFilter_CB_CB mCleanupFilter;
|
||||
private HalfBandFilter_CB_CB mHalfBandFilter = new HalfBandFilter_CB_CB(
|
||||
Filters.FIR_HALF_BAND_31T_ONE_EIGHTH_FCO.getCoefficients(), 0.4f, false );
|
||||
|
||||
public Output( int outputSampleRate, int passFrequency, int attenuation,
|
||||
WindowType windowType )
|
||||
{
|
||||
mCleanupFilter = new ComplexFIRFilter_CB_CB( FilterFactory
|
||||
.getCICCleanupFilter( outputSampleRate,
|
||||
passFrequency,
|
||||
attenuation,
|
||||
windowType ), 0.4f );
|
||||
|
||||
mAssembler.setListener( mCleanupFilter );
|
||||
mCleanupFilter.setListener( mHalfBandFilter );
|
||||
}
|
||||
|
||||
public void dispose()
|
||||
{
|
||||
mAssembler.dispose();
|
||||
mCleanupFilter.dispose();
|
||||
mHalfBandFilter.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Receiver method for the output adapter to receive a filtered,
|
||||
* decimated sample, apply gain correction, apply cleanup filtering
|
||||
* and output the sample values as a complex sample.
|
||||
*/
|
||||
@Override
|
||||
public void receive( float inphase, float quadrature )
|
||||
{
|
||||
mAssembler.receive( inphase, quadrature );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a listener to receive output samples
|
||||
*/
|
||||
public void setListener( Listener<ComplexBuffer> listener )
|
||||
{
|
||||
mHalfBandFilter.setListener( listener );
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the listener from receiving output samples
|
||||
*/
|
||||
public void removeListener()
|
||||
{
|
||||
mHalfBandFilter.removeListener();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,171 +0,0 @@
|
||||
package dsp.filter.design;
|
||||
|
||||
import org.jtransforms.fft.FloatFFT_1D;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import dsp.filter.FilterFactory;
|
||||
import dsp.filter.Window.WindowType;
|
||||
import dsp.filter.fir.FIRFilterSpecification;
|
||||
import dsp.filter.fir.remez.RemezFIRFilterDesigner;
|
||||
import gui.control.CurveFittedAreaChart;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.scene.chart.NumberAxis;
|
||||
import javafx.scene.chart.XYChart;
|
||||
import javafx.scene.chart.XYChart.Series;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
|
||||
public class FilterView extends BorderPane
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger( FilterView.class );
|
||||
|
||||
private CurveFittedAreaChart mImpulseChart;
|
||||
private NumberAxis mImpulseXAxis;
|
||||
private NumberAxis mImpulseYAxis;
|
||||
private CurveFittedAreaChart mDFTChart;
|
||||
private NumberAxis mDFTXAxis;
|
||||
private NumberAxis mDFTYAxis;
|
||||
private static final int FFT_SIZE = 4096;
|
||||
private FloatFFT_1D mFFT = new FloatFFT_1D( FFT_SIZE );
|
||||
|
||||
public FilterView( float[] taps )
|
||||
{
|
||||
init();
|
||||
|
||||
if( taps != null )
|
||||
{
|
||||
setImpulseTaps( taps );
|
||||
|
||||
float[] dft = new float[ FFT_SIZE ];
|
||||
System.arraycopy( taps, 0, dft, 0, taps.length );
|
||||
|
||||
mFFT.realForward( dft );
|
||||
|
||||
setDFTTaps( convertDFTToDecibel( dft, taps.length ) );
|
||||
}
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
HBox hbox = new HBox();
|
||||
|
||||
mImpulseXAxis = new NumberAxis( 0.0, 0.5, 1.0 );
|
||||
mImpulseYAxis = new NumberAxis( -0.2, 1.2, .1 );
|
||||
|
||||
mImpulseChart = new CurveFittedAreaChart( mImpulseXAxis, mImpulseYAxis );
|
||||
mImpulseChart.setLegendVisible( false );
|
||||
mImpulseChart.setHorizontalGridLinesVisible( false );
|
||||
mImpulseChart.setVerticalGridLinesVisible(false);
|
||||
mImpulseChart.setAlternativeColumnFillVisible(false);
|
||||
mImpulseChart.setAlternativeRowFillVisible(false);
|
||||
|
||||
String css = FilterView.class.getResource( "FilterView.css" ).toExternalForm();
|
||||
mImpulseChart.getStylesheets().add( css );
|
||||
|
||||
hbox.getChildren().add( mImpulseChart );
|
||||
HBox.setHgrow( mImpulseChart, Priority.ALWAYS );
|
||||
|
||||
mDFTXAxis = new NumberAxis( 0.0, FFT_SIZE / 2, FFT_SIZE / 8 );
|
||||
mDFTYAxis = new NumberAxis( -200.0, 10.0, 10.0 );
|
||||
|
||||
mDFTChart = new CurveFittedAreaChart( mDFTXAxis, mDFTYAxis );
|
||||
mDFTChart.setLegendVisible( false );
|
||||
mDFTChart.setHorizontalGridLinesVisible( false );
|
||||
mDFTChart.setVerticalGridLinesVisible(false);
|
||||
mDFTChart.setAlternativeColumnFillVisible(false);
|
||||
mDFTChart.setAlternativeRowFillVisible(false);
|
||||
mDFTChart.getStylesheets().add( css );
|
||||
|
||||
hbox.getChildren().add( mDFTChart );
|
||||
HBox.setHgrow( mDFTChart, Priority.ALWAYS );
|
||||
|
||||
setCenter( hbox );
|
||||
}
|
||||
|
||||
public void setImpulseTaps( double[] taps )
|
||||
{
|
||||
float[] convertedTaps = new float[ taps.length ];
|
||||
|
||||
for( int x = 0; x < taps.length; x++ )
|
||||
{
|
||||
convertedTaps[ x ] = (float)taps[ x ];
|
||||
}
|
||||
|
||||
setImpulseTaps( convertedTaps );
|
||||
}
|
||||
|
||||
public void setImpulseTaps( float[] taps )
|
||||
{
|
||||
double smallest = 0.0;
|
||||
double largest = 0.0;
|
||||
|
||||
final XYChart.Series<Number, Number> series = new XYChart.Series<>();
|
||||
|
||||
for( int x = 0; x < taps.length; x++ )
|
||||
{
|
||||
if( taps[ x ] < smallest )
|
||||
{
|
||||
smallest = taps[ x ];
|
||||
}
|
||||
|
||||
if( taps[ x ] > largest )
|
||||
{
|
||||
largest = taps[ x ];
|
||||
}
|
||||
|
||||
series.getData().add( new XYChart.Data<Number, Number>( x, taps[ x ] ) );
|
||||
}
|
||||
|
||||
mImpulseXAxis.setLowerBound( 0.0 );
|
||||
mImpulseXAxis.setUpperBound( taps.length - 1 );
|
||||
mImpulseXAxis.setTickUnit( 1.0 );
|
||||
|
||||
double padding = Math.abs( largest - smallest ) * .1;
|
||||
|
||||
mImpulseYAxis.setLowerBound( smallest - padding );
|
||||
mImpulseYAxis.setUpperBound( largest + padding );
|
||||
mImpulseYAxis.setTickUnit( padding );
|
||||
|
||||
ObservableList<Series<Number,Number>> list = mImpulseChart.getData();
|
||||
list.add( series );
|
||||
}
|
||||
|
||||
public void setDFTTaps( float[] taps )
|
||||
{
|
||||
double smallest = 0.0;
|
||||
|
||||
final XYChart.Series<Number, Number> series = new XYChart.Series<>();
|
||||
|
||||
for( int x = 0; x < taps.length; x++ )
|
||||
{
|
||||
if( taps[ x ] < smallest )
|
||||
{
|
||||
smallest = taps[ x ];
|
||||
}
|
||||
|
||||
series.getData().add( new XYChart.Data<Number, Number>( x, taps[ x ] ) );
|
||||
}
|
||||
|
||||
ObservableList<Series<Number,Number>> list = mDFTChart.getData();
|
||||
list.add( series );
|
||||
}
|
||||
|
||||
public float[] convertDFTToDecibel( float[] dft, int tapLength )
|
||||
{
|
||||
float[] decibels = new float[ dft.length / 2 ];
|
||||
|
||||
int index = 0;
|
||||
|
||||
for( int x = 0; x < decibels.length; x ++ )
|
||||
{
|
||||
index = x * 2;
|
||||
|
||||
decibels[ x ] = 20.0f * (float)Math.log10( ( ( dft[ index ] * dft[ index ] ) +
|
||||
( dft[ index + 1 ] * dft[ index + 1 ] ) ) );
|
||||
}
|
||||
|
||||
return decibels;
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
package dsp.filter.design;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import dsp.filter.fir.FIRFilterSpecification;
|
||||
import dsp.filter.fir.remez.RemezFIRFilterDesigner;
|
||||
import javafx.application.Application;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
public class FilterViewer extends Application
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger( FilterViewer.class );
|
||||
|
||||
/**
|
||||
* Developer tool to visualize filter designs
|
||||
*/
|
||||
public FilterViewer()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start( Stage primaryStage ) throws Exception
|
||||
{
|
||||
Scene scene = new Scene( new FilterView( getFilter() ) );
|
||||
|
||||
primaryStage.setTitle( "Filter Viewer" );
|
||||
primaryStage.setScene( scene );
|
||||
primaryStage.show();
|
||||
}
|
||||
|
||||
public static void main( String[] args )
|
||||
{
|
||||
launch( args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the filter to visualize. Modify this method to visualize your filter design.
|
||||
*/
|
||||
private float[] getFilter()
|
||||
{
|
||||
// FIRFilterSpecification specification = FIRFilterSpecification.lowPassBuilder()
|
||||
// .sampleRate( 48000 )
|
||||
// .gridDensity( 16 )
|
||||
// .passBandCutoff( 3200 )
|
||||
// .passBandAmplitude( 1.0 )
|
||||
// .passBandRipple( 0.02 )
|
||||
// .stopBandStart( 4000 )
|
||||
// .stopBandAmplitude( 0.0 )
|
||||
// .stopBandRipple( 0.03 )
|
||||
// .build();
|
||||
|
||||
FIRFilterSpecification specification = FIRFilterSpecification.highPassBuilder()
|
||||
.sampleRate( 24000 )
|
||||
.stopBandCutoff( 800 )
|
||||
.stopBandAmplitude( 0.0 )
|
||||
.stopBandRipple( 0.03 )
|
||||
.passBandStart( 1000 )
|
||||
.passBandAmplitude( 1.0 )
|
||||
.passBandRipple( 0.08 )
|
||||
.build();
|
||||
|
||||
// FIRFilterSpecification specification = FIRFilterSpecification.bandPassBuilder()
|
||||
// .sampleRate( 48000 )
|
||||
// .stopFrequency1( 200 )
|
||||
// .passFrequencyBegin( 400 )
|
||||
// .passFrequencyEnd( 3200 )
|
||||
// .stopFrequency2( 3400 )
|
||||
// .stopRipple( 0.0003 )
|
||||
// .passRipple( 0.008)
|
||||
// .build();
|
||||
|
||||
float[] taps = null;
|
||||
|
||||
// taps = FilterFactory.getLowPass( 16000, 2400, 73, WindowType.HANNING );
|
||||
|
||||
try
|
||||
{
|
||||
RemezFIRFilterDesigner designer = new RemezFIRFilterDesigner( specification );
|
||||
|
||||
if( designer.isValid() )
|
||||
{
|
||||
taps = designer.getImpulseResponse();
|
||||
}
|
||||
}
|
||||
catch( FilterDesignException fde )
|
||||
{
|
||||
mLog.error( "Filter design error", fde );
|
||||
}
|
||||
|
||||
return taps;
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
package dsp.filter.fir.complex;
|
||||
|
||||
import sample.complex.Complex;
|
||||
import dsp.filter.fir.FIRFilter;
|
||||
import dsp.filter.fir.real.RealFIRFilter;
|
||||
|
||||
public class ComplexFIRFilter extends FIRFilter
|
||||
{
|
||||
private RealFIRFilter mIFilter;
|
||||
private RealFIRFilter mQFilter;
|
||||
|
||||
/**
|
||||
* Complex FIR Filter for processing complex sample pairs. Wraps two real
|
||||
* FIR filters for processing each of the inphase and quadrature samples.
|
||||
*
|
||||
* @param coefficients - filter taps
|
||||
* @param gain - gain to apply to filtered outputs - use 1.0f for no gain
|
||||
*/
|
||||
public ComplexFIRFilter( float[] coefficients, float gain )
|
||||
{
|
||||
mIFilter = new RealFIRFilter( coefficients, gain );
|
||||
mQFilter = new RealFIRFilter( coefficients, gain );
|
||||
}
|
||||
|
||||
public float[] getCoefficients()
|
||||
{
|
||||
return mIFilter.getCoefficients();
|
||||
}
|
||||
|
||||
public float filterInphase( float sample )
|
||||
{
|
||||
return mIFilter.filter( sample );
|
||||
}
|
||||
|
||||
public float filterQuadrature( float sample )
|
||||
{
|
||||
return mQFilter.filter( sample );
|
||||
}
|
||||
|
||||
public Complex filter( Complex sample )
|
||||
{
|
||||
float i = filterInphase( sample.inphase() );
|
||||
float q = filterQuadrature( sample.quadrature() );
|
||||
|
||||
return new Complex( i, q );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose()
|
||||
{
|
||||
mIFilter.dispose();
|
||||
mQFilter.dispose();
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
package dsp.filter.interpolator;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import sample.complex.Complex;
|
||||
|
||||
public class RealInterpolator extends Interpolator
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger( RealInterpolator.class );
|
||||
|
||||
private float mGain;
|
||||
|
||||
public RealInterpolator( float gain )
|
||||
{
|
||||
mGain = gain;
|
||||
}
|
||||
/**
|
||||
* Calculates an interpolated value from the 8 samples beginning at the
|
||||
* offset index. Uses the mu value to determine which of 128 filter kernels
|
||||
* to use in order to closely approximate the ideal frequency response for
|
||||
* the value of mu, ranging from 0.0 to 1.0, indicating the interpolated
|
||||
* position in the sample set ranging from offset to offset + 7.
|
||||
*
|
||||
* @param samples - sample array of length at least offset + 7
|
||||
*
|
||||
* @param mu - interpolated sample position between 0 and 1.0
|
||||
*
|
||||
* @return - interpolated sample value
|
||||
*/
|
||||
public float filter( float[] samples, int offset, float mu )
|
||||
{
|
||||
/* Ensure we have enough samples in the array */
|
||||
assert( samples.length >= offset + 7 );
|
||||
|
||||
/* Identify the filter bank that corresponds to mu */
|
||||
int index = (int)( NSTEPS * mu );
|
||||
|
||||
float accumulator = ( TAPS[ index ][ 7 ] * samples[ offset ] );
|
||||
accumulator += ( TAPS[ index ][ 6 ] * samples[ offset + 1 ] );
|
||||
accumulator += ( TAPS[ index ][ 5 ] * samples[ offset + 2 ] );
|
||||
accumulator += ( TAPS[ index ][ 4 ] * samples[ offset + 3 ] );
|
||||
accumulator += ( TAPS[ index ][ 3 ] * samples[ offset + 4 ] );
|
||||
accumulator += ( TAPS[ index ][ 2 ] * samples[ offset + 5 ] );
|
||||
accumulator += ( TAPS[ index ][ 1 ] * samples[ offset + 6 ] );
|
||||
accumulator += ( TAPS[ index ][ 0 ] * samples[ offset + 7 ] );
|
||||
|
||||
return accumulator * mGain;
|
||||
}
|
||||
|
||||
public Complex filter( float[] iSamples, float[] qSamples, int offset, float mu )
|
||||
{
|
||||
float i = filter( iSamples, offset, mu );
|
||||
float q = filter( qSamples, offset, mu );
|
||||
|
||||
return new Complex( i, q );
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user