mirror of
https://github.com/PAMGuard/PAMGuard.git
synced 2024-11-21 22:52:22 +00:00
commit
3e717bd207
@ -6,8 +6,9 @@
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/Java 17">
|
||||
<attributes>
|
||||
<attribute name="module" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
@ -16,6 +17,5 @@
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="lib" path="/X3/src/org"/>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
|
203
README.html
203
README.html
@ -372,9 +372,9 @@ size for the JVM being used to run Pamguard i.e. how much memory it gets to use.
|
||||
The default max size usually being too low.</p>
|
||||
|
||||
<p class=MsoNormal>The -Djava.library.path=lib64 tells the JVM that it should
|
||||
look in the folder called "lib64" for the required shared libraries
|
||||
(change to <em><span style='font-family:"Calibri",sans-serif'>lib</span></em>
|
||||
for the 32 bit version).</p>
|
||||
look in the folder called "lib64" for the required shared libraries (change
|
||||
to <em><span style='font-family:"Calibri",sans-serif'>lib</span></em> for the
|
||||
32 bit version).</p>
|
||||
|
||||
<p class=MsoNormal>For "Mixed" and "Viewer" modes just add
|
||||
a "-m" or "-v" to the list of java arguments. On Windows
|
||||
@ -452,7 +452,6 @@ lang=EN-US>Latest Version 2.02.05 October 2022</span></h1>
|
||||
|
||||
<p class=MsoNormal><span lang=EN-US>Changes to GUI to make dialog shorter for
|
||||
low DPI screens. </span></p>
|
||||
|
||||
<p class=MsoNormal><span lang=EN-US>Complete rewrite of the classification
|
||||
system to have nested classifiers which can be enabled or disabled. </span></p>
|
||||
|
||||
@ -500,7 +499,7 @@ audio files. </span></p>
|
||||
<h2><span lang=EN-US>Bug Fixes</span></h2>
|
||||
|
||||
<p class=MsoNormal><span lang=EN-US>Soundtrap DWV import. Will now generate binary
|
||||
files even if DWV file doesn’t exist (which is correct behavior in quiet
|
||||
files even if DWV file doesnt exist (which is correct behavior in quiet
|
||||
conditions when no clicks were detected). </span></p>
|
||||
|
||||
<p class=MsoNormal><span lang=EN-US>Spectrogram. Changes to stop occasional
|
||||
@ -511,6 +510,10 @@ monitors so that data fields are sized correctly. </span></p>
|
||||
|
||||
<p class=MsoNormal><span lang=EN-US>Fixed a memory leak in ROCCA</span></p>
|
||||
|
||||
<p class=MsoNormal><span lang=EN-US>Fixed issues with options in Click Detector
|
||||
bearing time display which (when using planar and 3D arrays) allow you to plot
|
||||
relative to the array, the vessel, or North. </span></p>
|
||||
|
||||
<h1><a name="_Latest_Version_2.02.03_2"></a><span lang=EN-US>Version 2.02.03
|
||||
February 2022</span></h1>
|
||||
|
||||
@ -531,7 +534,7 @@ running in real time. Added template names based on file names. </p>
|
||||
<p class=MsoNormal>#13 Merging files when offline processing file folders: Had
|
||||
an error introduced in last release which caused it to fail to recognise gaps
|
||||
between files, meaning that some output data (i.e. after a gap) would have an
|
||||
incorrect time stamp. This did not affect data if the ‘merge contiguous files’
|
||||
incorrect time stamp. This did not affect data if the Âmerge contiguous filesÂ
|
||||
option was not selected. </p>
|
||||
|
||||
<p class=MsoNormal>#14 Logger forms data were not plotting correctly. This was
|
||||
@ -605,7 +608,7 @@ href="http://www.pamguard.org/downloads.php?cat_id=3">here</a>.</p>
|
||||
<p class=MsoNormal><b><span lang=EN-US>Detection Group Localiser</span></b><span
|
||||
lang=EN-US> </span></p>
|
||||
|
||||
<p class=MsoNormal>This module has been renamed “Detection Grouper”, so as to
|
||||
<p class=MsoNormal>This module has been renamed ÂDetection GrouperÂ, so as to
|
||||
avoid confusion with the Group 3D localizer. This is because the Detection
|
||||
Grouper is more for organizing data into groups to be localized than it is for
|
||||
doing localization.</p>
|
||||
@ -709,16 +712,16 @@ lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> &nb
|
||||
new CPOD features </p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>15. </span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> </span>
|
||||
Better interpolation of data by the Decimator when decimating/upsampling by a
|
||||
non-integer amount </p>
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> </span><span
|
||||
lang=EN-US> </span>Better interpolation of data by the Decimator when
|
||||
decimating/upsampling by a non-integer amount </p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>16. </span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> </span>
|
||||
Noise Level Outputs - as an aid to performance diagnosis, some detectors
|
||||
(currently the GPL, Click Detector and Whistle and Moan Detector) are
|
||||
outputting additional noise metrics to their binary output files. These can be
|
||||
read with the <a href="https://sourceforge.net/projects/pamguard/files/Matlab/">PAMGuard
|
||||
(currently the GPL, Click Detector and Whistle and Moan Detector) are outputting
|
||||
additional noise metrics to their binary output files. These can be read with
|
||||
the <a href="https://sourceforge.net/projects/pamguard/files/Matlab/">PAMGuard
|
||||
Matlab library</a> and used to diagnose system performance in varying noise
|
||||
conditions. Improved displays within PAMGuard for these noise metrics will be
|
||||
included in a future release. </p>
|
||||
@ -726,10 +729,10 @@ included in a future release. </p>
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>17. </span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> </span>
|
||||
An implementation of the Generalized Power Law Detector, developed by Tyler
|
||||
Helble ([Helble et al., ‘A generalized power-law detection algorithm for
|
||||
humpback whale vocalizations’, The Journal of the Acoustical Society of
|
||||
America, vol. 131, no. 4, pp. 2682–2699, 2012) is now available. For details,
|
||||
see the online help </p>
|
||||
Helble ([Helble et al., ÂA generalized power-law detection algorithm for humpback
|
||||
whale vocalizationsÂ, The Journal of the Acoustical Society of America, vol.
|
||||
131, no. 4, pp. 2682Â2699, 2012) is now available. For details, see the online
|
||||
help </p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>18. </span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> </span>
|
||||
@ -816,8 +819,8 @@ Measurement module. </p>
|
||||
<p class=MsoNormal><b><span lang=EN-US>Upgrades</span></b></p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>1. </span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> </span>
|
||||
Speed up adding subdetections to superdetections. </p>
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> </span><span
|
||||
lang=EN-US> </span>Speed up adding subdetections to superdetections. </p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>2. </span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> </span><span
|
||||
@ -969,15 +972,15 @@ lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> &nb
|
||||
Add functionality for bluetooth headsets. </p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>2. </span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> </span>
|
||||
Add user-facing option to adjust the startup delay for the time-correction
|
||||
(Global Time module). This provides a workaround to speed up analysis of
|
||||
thousands of wav files (i.e. by setting startup delay to 0 instead of default
|
||||
value of 2000 ms). </p>
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> </span><span
|
||||
lang=EN-US> </span>Add user-facing option to adjust the startup delay for the
|
||||
time-correction (Global Time module). This provides a workaround to speed up
|
||||
analysis of thousands of wav files (i.e. by setting startup delay to 0 instead
|
||||
of default value of 2000 ms). </p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>3. </span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> </span>
|
||||
Add support for RS Aqua time format. </p>
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> </span><span
|
||||
lang=EN-US> </span>Add support for RS Aqua time format. </p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>4. </span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> </span>
|
||||
@ -1055,9 +1058,9 @@ lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> &nb
|
||||
Bug 433. Custom storage options were being lost when Pamguard restarted.</p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>2. </span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> </span>
|
||||
Bug 434. Pamguard Viewer mode was having problems importing settings from psfx
|
||||
file.</p>
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> </span><span
|
||||
lang=EN-US> </span>Bug 434. Pamguard Viewer mode was having problems importing
|
||||
settings from psfx file.</p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>3. </span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> </span>
|
||||
@ -1105,8 +1108,8 @@ files.</p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>13. </span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> </span>
|
||||
Bug 445. Overlay data in FX spectrogram display gets out of sync with
|
||||
underlying spectrogram image.</p>
|
||||
Bug 445. Overlay data in FX spectrogram display gets out of sync with underlying
|
||||
spectrogram image.</p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>14. </span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> </span>
|
||||
@ -1194,10 +1197,10 @@ Detector display. </p>
|
||||
<p class=MsoNormal><b><span lang=EN-US>Upgrades</span></b></p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>1. </span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> </span>
|
||||
This version of PAMGuard has been upgraded to make it compatible with Java 12.
|
||||
psfx files generated in previous beta releases should be compatible with this
|
||||
version, and vice-versa.</p>
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> </span><span
|
||||
lang=EN-US> </span>This version of PAMGuard has been upgraded to make it
|
||||
compatible with Java 12. psfx files generated in previous beta releases should
|
||||
be compatible with this version, and vice-versa.</p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>2. </span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> </span>
|
||||
@ -1352,8 +1355,8 @@ lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> &nb
|
||||
lang=EN-US> </span>Better display of microseconds in dialogs.</p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>4. </span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> </span>
|
||||
Added adaptive noise filter to Ishmael Detectors.</p>
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> </span><span
|
||||
lang=EN-US> </span>Added adaptive noise filter to Ishmael Detectors.</p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>5. </span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> </span><span
|
||||
@ -1478,8 +1481,8 @@ session, but not forever.</p>
|
||||
|
||||
<!-- ************************************************************************************************************************** --><!-- ************************************************************************************************************************** -->
|
||||
|
||||
<h1><a name="_Latest_Beta_Version_2.00.14c"></a><span lang=EN-US>Beta Version
|
||||
2.00.14c October 2018</span></h1>
|
||||
<h1><a name="_Latest_Beta_Version_2.00.14c"></a><span lang=EN-US>Beta Version 2.00.14c
|
||||
October 2018</span></h1>
|
||||
|
||||
<p class=MsoNormal><span lang=EN-US>PAMGuard Version 2 contains major updates.
|
||||
You should read and understand the notes listed for <a
|
||||
@ -1586,8 +1589,7 @@ Annotation module which has now been given two text type annotations.</p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>9. </span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>
|
||||
</span>Bug 391. Click Detector not registering change in multi-threading
|
||||
option.</p>
|
||||
</span>Bug 391. Click Detector not registering change in multi-threading option.</p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>10. </span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>
|
||||
@ -1611,9 +1613,9 @@ position for hydrophone 0.</p>
|
||||
<p class=MsoNormal><b><span lang=EN-US>Upgrades</span></b></p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>1. </span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> </span>
|
||||
Better way of coupling scrollers in User Display panels - see new options in
|
||||
main menu.</p>
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> </span><span
|
||||
lang=EN-US> </span>Better way of coupling scrollers in User Display panels -
|
||||
see new options in main menu.</p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>2. </span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> </span>
|
||||
@ -1743,8 +1745,7 @@ will be converted.</p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>4. </span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> </span>
|
||||
Many updates to the Video Range module. Will currently only work with
|
||||
landmarks.</p>
|
||||
Many updates to the Video Range module. Will currently only work with landmarks.</p>
|
||||
|
||||
<!-- ************************************************************************************************************************** -->
|
||||
|
||||
@ -1807,8 +1808,8 @@ Beta versions</p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>11. </span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>
|
||||
</span>Bug 366. Rocca manual whistle contour extraction throws error when
|
||||
trying to classify a boxed whistle</p>
|
||||
</span>Bug 366. Rocca manual whistle contour extraction throws error when trying
|
||||
to classify a boxed whistle</p>
|
||||
|
||||
<p class=MsoNormal><b><span lang=EN-US>Upgrades</span></b></p>
|
||||
|
||||
@ -1877,8 +1878,8 @@ lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> &nb
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>10.</span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>
|
||||
</span>Bug 354. Whistle Classifier was crashing if user accidentally entered
|
||||
invalid parameters. Have added diagnostics to prevent this.</p>
|
||||
</span>Bug 354. Whistle Classifier was crashing if user accidentally entered invalid
|
||||
parameters. Have added diagnostics to prevent this.</p>
|
||||
|
||||
<p class=MsoNormal><b><span lang=EN-US>Upgrades</span></b></p>
|
||||
|
||||
@ -1994,7 +1995,7 @@ file format is the addition of a Unique Data Identifier (UID) to each unit of
|
||||
data. This is intended to aid in offline analysis by making it easier for the
|
||||
user to link what they are seeing on different PAMGuard displays and also to
|
||||
link with any data post processed in Matlab or other custom analysis software.
|
||||
UID’s are also added to PAMGuard database tables. </span></p>
|
||||
UIDÂs are also added to PAMGuard database tables. </span></p>
|
||||
|
||||
<h4><span lang=EN-US>Converting Old Data</span></h4>
|
||||
|
||||
@ -2002,13 +2003,13 @@ UID
|
||||
viewer they will automatically be converted. For safety, the original binary
|
||||
files will not be overwritten and the new data will be placed in a new folder
|
||||
on your computer with the same path as the old data, but suffixed with
|
||||
‘_WithUID’, e.g. if your binary data were previously stored in the folder
|
||||
Â_WithUIDÂ, e.g. if your binary data were previously stored in the folder
|
||||
C:\MySurvey\binarydata the new data will be written to
|
||||
C:\MySurvey\binarydata_WithUID. </span></p>
|
||||
|
||||
<p class=MsoNormal><span lang=EN-US>The additional UID column will be added to
|
||||
all database tables and populated with unique values. For data which are stored
|
||||
in both the binary files and in database tables, the same UID’s will be used in
|
||||
in both the binary files and in database tables, the same UIDÂs will be used in
|
||||
both data stores. </span></p>
|
||||
|
||||
<h3><span lang=EN-US>New Displays</span></h3>
|
||||
@ -2023,11 +2024,11 @@ Note that this display is only available if you are running Java 8 or later. </s
|
||||
|
||||
<h3><span lang=EN-US>Event Marking and the Detection Group Localiser</span></h3>
|
||||
|
||||
<p class=MsoNormal><span lang=EN-US>A new system of event marking which can be
|
||||
used both online and offline has been added to PAMGuard. Details are in the
|
||||
PAMGuard help file (Displays/Display Marking). Data can be selected on the Map,
|
||||
the Spectrogram Display and the new Time Display FX in a similar way and sent
|
||||
to other PAMGuard modules. The new marking and data selection system works with
|
||||
<p class=MsoNormal><span lang=EN-US>A new system of event marking which can be used
|
||||
both online and offline has been added to PAMGuard. Details are in the PAMGuard
|
||||
help file (Displays/Display Marking). Data can be selected on the Map, the
|
||||
Spectrogram Display and the new Time Display FX in a similar way and sent to
|
||||
other PAMGuard modules. The new marking and data selection system works with
|
||||
the new Detection Group Localiser. The Detection Group Localiser extends the
|
||||
functionality which always existed in the click detector to other types of data
|
||||
(e.g. Whistles) so that they can be grouped and tracked using target motion
|
||||
@ -2152,8 +2153,8 @@ happens when the user selects save as new configuration. This has been fixed.</p
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>
|
||||
</span>Bug 315. code searched for file in working folder, which is the
|
||||
installation folder when starting PAMGuard using a shortcut link. But when
|
||||
double-clicking on a psf, the working folder is the location of the psf. This
|
||||
has been fixed.</p>
|
||||
double-clicking on a psf, the working folder is the location of the psf. This has
|
||||
been fixed.</p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>7.</span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'> </span><span
|
||||
@ -2182,8 +2183,8 @@ jar file will be required rather than a new bespoke PAMGuard installation.</span
|
||||
|
||||
<p class=MsoNormal><span lang=EN-US>Module code development remains largely
|
||||
unchanged, in most cases simply requiring the addition of an interface class.
|
||||
Instructions for the development of new modules utilizing the plug-in
|
||||
scheme can be found <a href="http://www.pamguard.org/16_HowtomakePlug-Ins.html"
|
||||
Instructions for the development of new modules utilizing the plug-in scheme
|
||||
can be found <a href="http://www.pamguard.org/16_HowtomakePlug-Ins.html"
|
||||
target="_blank">here</a>. Plug-in modules can be downloaded from the
|
||||
PAMGuard website here, but developers are encouraged to host and maintain their
|
||||
own modules.</span></p>
|
||||
@ -2191,8 +2192,8 @@ own modules.</span></p>
|
||||
<p class=MsoNormal><span lang=EN-US>Modules of interest to the general PAM
|
||||
community will remain as part of the core PAMGuard installation. However,
|
||||
specialized modules which are useful to only a small number of users have been
|
||||
removed and are available as a separate download. The following modules have
|
||||
been removed:</span></p>
|
||||
removed and are available as a separate download. The following modules have been
|
||||
removed:</span></p>
|
||||
|
||||
<p class=MsoListParagraph style='margin-left:43.5pt;text-indent:-25.5pt'>1.<span
|
||||
style='font-size:7.0pt;font-family:"Times New Roman",serif'>
|
||||
@ -2243,7 +2244,7 @@ November 2016</span></h1>
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>1.
|
||||
Bug 303. Some ASIO sound cards not working with either ASIO system in PAMGuard.
|
||||
For the PAMGuard ASIO system, this was due to a data format used by some sound
|
||||
cards never being properly implemented. For the “New ASIO system” which is
|
||||
cards never being properly implemented. For the ÂNew ASIO system which is
|
||||
based on jAsioHost, the unpacking of that format contained a bug which returned
|
||||
incorrect numbers, so data were swamped with noise. Both systems are now fixed.
|
||||
By preference, users should use the PAMGuard ASIO system since the JAsioHost
|
||||
@ -2374,9 +2375,9 @@ the database. </span></p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>2.</span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>
|
||||
</span><span lang=EN-US>The number of data streams associated with the click
|
||||
detector has been tidied up so that there are a) All Click, b) Tracked Clicks
|
||||
(those which are part of an event) and c) Events. </span></p>
|
||||
</span><span lang=EN-US>The number of data streams associated with the click detector
|
||||
has been tidied up so that there are a) All Click, b) Tracked Clicks (those
|
||||
which are part of an event) and c) Events. </span></p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>3.</span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>
|
||||
@ -2637,12 +2638,12 @@ boundaries when file durations are set to a maximum fixed value. </p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span lang=EN-US>5.</span><span
|
||||
lang=EN-US style='font-size:7.0pt;font-family:"Times New Roman",serif'>
|
||||
</span>Bug 262. Access to SQLite database conversion. This would fail when
|
||||
tables were present which were not created by PAMGuard. Fixes have been
|
||||
put in place for spaces in the table name or for not having an 'Id' column.
|
||||
Fixes have not been implemented for spaces in a column name or use of a
|
||||
reserved word as a column name, however if either of these problems do exist it
|
||||
will no longer crash but issue a clear warning and carry onto the next table.</p>
|
||||
</span>Bug 262. Access to SQLite database conversion. This would fail when tables
|
||||
were present which were not created by PAMGuard. Fixes have been put in
|
||||
place for spaces in the table name or for not having an 'Id' column. Fixes have
|
||||
not been implemented for spaces in a column name or use of a reserved word as a
|
||||
column name, however if either of these problems do exist it will no longer
|
||||
crash but issue a clear warning and carry onto the next table.</p>
|
||||
|
||||
<p class=MsoNormal style='margin-left:18.0pt'><span lang=EN-US> </span></p>
|
||||
|
||||
@ -3071,12 +3072,12 @@ marine mammal survey package. See online help for details. </p>
|
||||
|
||||
<p class=MsoNormal><i>Alarms</i> (Utilities Group)</p>
|
||||
|
||||
<p class=MsoNormal>This is a general system of visual and audio alarms
|
||||
developed by Doug Gillespie for use on a variety of projects. The alarms can be
|
||||
coupled to any module or detector in PAMGuard. Where appropriate, modules can
|
||||
control which of their data will cause an alarm action (e.g. in the Click
|
||||
detector you can set which types of classified click will fire the alarm). See
|
||||
online help for details. </p>
|
||||
<p class=MsoNormal>This is a general system of visual and audio alarms developed
|
||||
by Doug Gillespie for use on a variety of projects. The alarms can be coupled
|
||||
to any module or detector in PAMGuard. Where appropriate, modules can control
|
||||
which of their data will cause an alarm action (e.g. in the Click detector you
|
||||
can set which types of classified click will fire the alarm). See online help
|
||||
for details. </p>
|
||||
|
||||
<p class=MsoNormal><i>Noise Band Monitor</i> (Sound Processing Group)</p>
|
||||
|
||||
@ -3140,8 +3141,8 @@ Millisecond time is also now included in the output file names. </p>
|
||||
|
||||
<p class=MsoNormal>Datagram options in Viewer have been improved so that the
|
||||
user has to verify the time binning for datagrams the first time the viewer is
|
||||
run and can also change the time bins from the File menu (See the
|
||||
File/BinaryStore/Datagram options menu. </p>
|
||||
run and can also change the time bins from the File menu (See the File/BinaryStore/Datagram
|
||||
options menu. </p>
|
||||
|
||||
<p class=MsoNormal><i>Viewer Configuration</i></p>
|
||||
|
||||
@ -3577,8 +3578,8 @@ the correct data stream. This has been fixed. </p>
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span style='font-family:
|
||||
Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif'>
|
||||
</span>Whistle classifier has some new features in the classifier training
|
||||
panel. It is also now possible to export training data files directly from
|
||||
binary data files. </p>
|
||||
panel. It is also now possible to export training data files directly from binary
|
||||
data files. </p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span style='font-family:
|
||||
Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif'>
|
||||
@ -3831,10 +3832,10 @@ port is closed. Might prevent a few problems when using a GPS. </p>
|
||||
<p class=MsoNormal>Crashes caused in real time or Mixed Mode if the number of
|
||||
software channels exceeds the number of hydrophones configured in the array
|
||||
manager. It is of course illogical to have software channels which are not
|
||||
assigned to a hydrophone, so rather than entirely prevent PAMGUARD from
|
||||
crashing I have inserted additional checks into the hydrophone array dialog
|
||||
which will prevent the user from closing that dialog unless all software
|
||||
channels are assigned to a hydrophone. </p>
|
||||
assigned to a hydrophone, so rather than entirely prevent PAMGUARD from crashing
|
||||
I have inserted additional checks into the hydrophone array dialog which will
|
||||
prevent the user from closing that dialog unless all software channels are
|
||||
assigned to a hydrophone. </p>
|
||||
|
||||
<h2><span style='font-weight:normal'>Version 1.8.01 Beta February 2010</span></h2>
|
||||
|
||||
@ -3929,17 +3930,17 @@ classifier is still available). </p>
|
||||
|
||||
<p class=MsoListParagraph style='text-indent:-18.0pt'><span style='font-family:
|
||||
Symbol'>'</span><span style='font-size:7.0pt;font-family:"Times New Roman",serif'>
|
||||
</span>Bearing ambiguity resolution for planar and volumetric arrays. New features
|
||||
in array dialog for estimations of errors on array location. These feed into to
|
||||
a maximum likelihood estimate of angles from small 2D or 3D sub arrays to give
|
||||
two polar angle coordinates. this can be used to resolve left right ambiguity
|
||||
and is implemented for both the click and the whistle/moan detectors. As a
|
||||
result, the click detector bearing time display can now be set to go from -180
|
||||
to 180 degrees rather than 0 - 180 degrees. In this case, clicks in the upper
|
||||
half of the bearing display will be to port and clicks in the right half will
|
||||
be to starboard. As you pass a whale which is to port, the clicks will move UP
|
||||
the display. In the long term, I hope to turn this display around so that time
|
||||
is up the screen rather than across. </p>
|
||||
</span>Bearing ambiguity resolution for planar and volumetric arrays. New
|
||||
features in array dialog for estimations of errors on array location. These
|
||||
feed into to a maximum likelihood estimate of angles from small 2D or 3D sub arrays
|
||||
to give two polar angle coordinates. this can be used to resolve left right
|
||||
ambiguity and is implemented for both the click and the whistle/moan detectors.
|
||||
As a result, the click detector bearing time display can now be set to go from
|
||||
-180 to 180 degrees rather than 0 - 180 degrees. In this case, clicks in the
|
||||
upper half of the bearing display will be to port and clicks in the right half
|
||||
will be to starboard. As you pass a whale which is to port, the clicks will
|
||||
move UP the display. In the long term, I hope to turn this display around so
|
||||
that time is up the screen rather than across. </p>
|
||||
|
||||
<p class=MsoNormal><b>Small features and bug fixes</b></p>
|
||||
|
||||
@ -4228,8 +4229,8 @@ acquisition. </p>
|
||||
|
||||
<p class=MsoNormal><b>Bug fixes</b></p>
|
||||
|
||||
<p class=MsoNormal>Speed up of graphics, particularly regarding large
|
||||
quantities of gps track data</p>
|
||||
<p class=MsoNormal>Speed up of graphics, particularly regarding large quantities
|
||||
of gps track data</p>
|
||||
|
||||
<p class=MsoNormal>National Instruments cards with names > 20 characters
|
||||
long are now correctly recognised. </p>
|
||||
|
@ -1,21 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="org.eclipse.m2e.Maven2LaunchConfigurationType">
|
||||
<booleanAttribute key="M2_DEBUG_OUTPUT" value="false"/>
|
||||
<stringAttribute key="M2_GOALS" value="package shade:shade"/>
|
||||
<booleanAttribute key="M2_NON_RECURSIVE" value="false"/>
|
||||
<booleanAttribute key="M2_OFFLINE" value="false"/>
|
||||
<stringAttribute key="M2_PROFILES" value=""/>
|
||||
<listAttribute key="M2_PROPERTIES"/>
|
||||
<stringAttribute key="M2_RUNTIME" value="EMBEDDED"/>
|
||||
<booleanAttribute key="M2_SKIP_TESTS" value="true"/>
|
||||
<intAttribute key="M2_THREADS" value="1"/>
|
||||
<booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="false"/>
|
||||
<stringAttribute key="M2_USER_SETTINGS" value=""/>
|
||||
<booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_ATTR_USE_ARGFILE" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_SHOW_CODEDETAILS_IN_EXCEPTION_MESSAGES" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_CLASSPATH_ONLY_JAR" value="false"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-13/"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-mx6000m -Djava.library.path=lib64"/>
|
||||
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc:/PamGuard Main DG}"/>
|
||||
</launchConfiguration>
|
@ -74,9 +74,9 @@
|
||||
<artifactId>javafx-maven-plugin</artifactId>
|
||||
<version>0.0.6</version>
|
||||
<configuration>
|
||||
<source>16</source>
|
||||
<target>16</target>
|
||||
<release>16</release>
|
||||
<source>17</source>
|
||||
<target>17</target>
|
||||
<release>17</release>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
|
24
pom.xml
24
pom.xml
@ -4,7 +4,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.pamguard</groupId>
|
||||
<artifactId>Pamguard</artifactId>
|
||||
<version>2.02.04ac</version>
|
||||
<version>2.02.05</version>
|
||||
<name>Pamguard Java12+</name>
|
||||
<description>Pamguard for Java 12+, using Maven to control dependcies</description>
|
||||
<url>www.pamguard.org</url>
|
||||
@ -76,9 +76,9 @@
|
||||
<artifactId>javafx-maven-plugin</artifactId>
|
||||
<version>0.0.6</version>
|
||||
<configuration>
|
||||
<source>16</source>
|
||||
<target>16</target>
|
||||
<release>16</release>
|
||||
<source>17</source>
|
||||
<target>17</target>
|
||||
<release>17</release>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
@ -391,6 +391,13 @@
|
||||
<version>${javafx.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Decorates JavaFX components-->
|
||||
<dependency>
|
||||
<groupId>net.synedra</groupId>
|
||||
<artifactId>validatorfx</artifactId>
|
||||
<version>0.4.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-compress -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
@ -777,7 +784,7 @@
|
||||
<dependency>
|
||||
<groupId>pamguard.org</groupId>
|
||||
<artifactId>x3</artifactId>
|
||||
<version>2.0.0</version>
|
||||
<version>2.1.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/it.sauronsoftware/jave -->
|
||||
@ -825,6 +832,13 @@
|
||||
<artifactId>swingx-all</artifactId>
|
||||
<version>1.6.5-1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Theme for JavaFX -->
|
||||
<dependency>
|
||||
<groupId>io.github.mkpaz</groupId>
|
||||
<artifactId>atlantafx-base</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
4
repo/pamguard/org/x3/1.0.0/_remote.repositories
Normal file
4
repo/pamguard/org/x3/1.0.0/_remote.repositories
Normal file
@ -0,0 +1,4 @@
|
||||
#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice.
|
||||
#Fri Aug 14 15:49:24 CEST 2020
|
||||
x3-1.0.0.pom>=
|
||||
x3-1.0.0.jar>=
|
BIN
repo/pamguard/org/x3/1.0.0/x3-1.0.0.jar
Normal file
BIN
repo/pamguard/org/x3/1.0.0/x3-1.0.0.jar
Normal file
Binary file not shown.
9
repo/pamguard/org/x3/1.0.0/x3-1.0.0.pom
Normal file
9
repo/pamguard/org/x3/1.0.0/x3-1.0.0.pom
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>pamguard.org</groupId>
|
||||
<artifactId>x3</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<description>POM was created from install:install-file</description>
|
||||
</project>
|
4
repo/pamguard/org/x3/2.0.0/_remote.repositories
Normal file
4
repo/pamguard/org/x3/2.0.0/_remote.repositories
Normal file
@ -0,0 +1,4 @@
|
||||
#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice.
|
||||
#Fri Sep 25 10:46:11 CEST 2020
|
||||
x3-2.0.0.pom>=
|
||||
x3-2.0.0.jar>=
|
39
repo/pamguard/org/x3/2.0.0/m2e-lastUpdated.properties
Normal file
39
repo/pamguard/org/x3/2.0.0/m2e-lastUpdated.properties
Normal file
@ -0,0 +1,39 @@
|
||||
#Fri Jan 14 08:14:25 GMT 2022
|
||||
repo|file\:///Users/au671271/pamguard/PAMGuard/repo|sources=1632311094649
|
||||
central|https\://jmachund.jfrog.io/artifactory/jpam2|javadoc=1641807924466
|
||||
repo|file\:///Users/au671271/git/PAMGuard/repo|javadoc=1642148065400
|
||||
github|https\://maven.pkg.github.com/macster110/jpam|sources=1642147913185
|
||||
repo|file\:///Users/au671271/pamguard/PAMGuard_16_mvn/repo|sources=1625576160247
|
||||
icm|http\://maven.icm.edu.pl/artifactory/repo|javadoc=1600971368390
|
||||
talan|https\://nexus.talanlabs.com/content/repositories/releases/|sources=1642147913185
|
||||
geomajas|http\://maven.geomajas.org/|javadoc=1642148065400
|
||||
central|https\://repo.maven.apache.org/maven2|javadoc=1642065819015
|
||||
bedatadriven|https\://nexus.bedatadriven.com/content/groups/public/|sources=1642147913185
|
||||
repo|file\:///Users/au671271/pamguard/PAMGuard_12_mvn/repo|sources=1602589977893
|
||||
jpamutils|https\://raw.github.com/macster110/jpam/mvn-repo/|javadoc=1642065819015
|
||||
icm|http\://maven.icm.edu.pl/artifactory/repo|sources=1600971300139
|
||||
geomajas|http\://maven.geomajas.org/|sources=1642147913185
|
||||
central|https\://repo1.maven.org/maven2|sources=1642147913185
|
||||
central|https\://repo.maven.apache.org/maven2|sources=1642065813019
|
||||
github|https\://maven.pkg.github.com/macster110/jpam|javadoc=1642148065400
|
||||
bintray-jerady-maven|https\://dl.bintray.com/jerady/maven|sources=1602589977893
|
||||
bedatadriven|https\://nexus.bedatadriven.com/content/groups/public/|javadoc=1642148065400
|
||||
jpamutils|https\://raw.github.com/macster110/jpam/mvn-repo/|sources=1642065813019
|
||||
my-local-repo|file\:///Users/au671271/pamguard/PAMGuard_12_mvn/src/jars|sources=1600949483388
|
||||
repo|file\:///Users/au671271/git/PAMGuard/repo|sources=1642147913185
|
||||
bintray-macster110-jtorch4pam|macster110|https\://dl.bintray.com/macster110/jtorch4pam|javadoc=1642148065400
|
||||
jdl4pam|https\://raw.github.com/macster110/jpam/mvn-repo/|javadoc=1642065819015
|
||||
unidata-all|https\://artifacts.unidata.ucar.edu/repository/unidata-all/|sources=1642147913185
|
||||
icm|https\://maven.averbis.com/m2/|sources=1601026887474
|
||||
bintray-jerady-maven|https\://dl.bintray.com/jerady/maven|javadoc=1602590126606
|
||||
talan|https\://nexus.talanlabs.com/content/repositories/releases/|javadoc=1642148065400
|
||||
central|https\://jmachund.jfrog.io/artifactory/jpam2|sources=1641807658592
|
||||
my-local-repo|file\:///Users/au671271/pamguard/PAMGuard_12_mvn/src/jars|javadoc=1600949605299
|
||||
unidata-all|https\://artifacts.unidata.ucar.edu/repository/unidata-all/|javadoc=1642148065400
|
||||
icm|https\://maven.averbis.com/m2/|javadoc=1601027283465
|
||||
repo|file\:///Users/au671271/pamguard/PAMGuard_12_mvn/repo|javadoc=1602590126606
|
||||
jdl4pam|https\://raw.github.com/macster110/jpam/mvn-repo/|sources=1642065813019
|
||||
bintray-macster110-jtorch4pam|macster110|https\://dl.bintray.com/macster110/jtorch4pam|sources=1642147913185
|
||||
repo|file\:///Users/au671271/pamguard/PAMGuard_16_mvn/repo|javadoc=1625576167973
|
||||
repo|file\:///Users/au671271/pamguard/PAMGuard/repo|javadoc=1632313121603
|
||||
central|https\://repo1.maven.org/maven2|javadoc=1642148065400
|
38
repo/pamguard/org/x3/2.0.0/x3-2.0.0-javadoc.jar.lastUpdated
Normal file
38
repo/pamguard/org/x3/2.0.0/x3-2.0.0-javadoc.jar.lastUpdated
Normal file
@ -0,0 +1,38 @@
|
||||
#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice.
|
||||
#Fri Jan 14 08:14:25 GMT 2022
|
||||
https\://dl.bintray.com/macster110/jtorch4pam/.error=
|
||||
file\:///Users/au671271/pamguard/PAMGuard_12_mvn/src/jars/.error=
|
||||
https\://jmachund.jfrog.io/artifactory/jpam2/.lastUpdated=1625576167971
|
||||
file\:///Users/au671271/pamguard/PAMGuard/repo/.error=
|
||||
file\:///Users/au671271/pamguard/PAMGuard_16_mvn/repo/.lastUpdated=1622023729745
|
||||
https\://dl.bintray.com/macster110/jtorch4pam/.lastUpdated=1600949601867
|
||||
file\:///Users/au671271/git/PAMGuard/repo/.error=
|
||||
https\://nexus.bedatadriven.com/content/groups/public/.error=
|
||||
https\://artifacts.unidata.ucar.edu/repository/unidata-all/.error=
|
||||
https\://artifacts.unidata.ucar.edu/repository/unidata-all/.lastUpdated=1600949603273
|
||||
https\://maven.averbis.com/m2/.lastUpdated=1601027283464
|
||||
file\:///Users/au671271/git/PAMGuard/repo/.lastUpdated=1641807924465
|
||||
https\://raw.github.com/macster110/jpam/mvn-repo/.lastUpdated=1642065819012
|
||||
file\:///Users/au671271/pamguard/PAMGuard_16_mvn/repo/.error=
|
||||
http\://maven.icm.edu.pl/artifactory/repo/.lastUpdated=1600971368389
|
||||
https\://nexus.bedatadriven.com/content/groups/public/.lastUpdated=1600949604396
|
||||
http\://maven.icm.edu.pl/artifactory/repo/.error=
|
||||
https\://repo1.maven.org/maven2/.error=
|
||||
@default-github-https\://maven.pkg.github.com/macster110/jpam/.lastUpdated=1642148065399
|
||||
file\:///Users/au671271/pamguard/PAMGuard/repo/.lastUpdated=1632313121601
|
||||
https\://repo1.maven.org/maven2/.lastUpdated=1642148065192
|
||||
https\://dl.bintray.com/jerady/maven/.lastUpdated=1600949602327
|
||||
http\://maven.geomajas.org/.lastUpdated=1600949604068
|
||||
https\://nexus.talanlabs.com/content/repositories/releases/.error=
|
||||
file\:///Users/au671271/pamguard/PAMGuard_12_mvn/repo/.error=
|
||||
file\:///Users/au671271/pamguard/PAMGuard_12_mvn/src/jars/.lastUpdated=1600949601869
|
||||
https\://repo.maven.apache.org/maven2/.lastUpdated=1600949605299
|
||||
http\://maven.geomajas.org/.error=
|
||||
https\://jmachund.jfrog.io/artifactory/jpam2/.error=
|
||||
https\://nexus.talanlabs.com/content/repositories/releases/.lastUpdated=1600949604877
|
||||
https\://maven.averbis.com/m2/.error=
|
||||
https\://repo.maven.apache.org/maven2/.error=
|
||||
file\:///Users/au671271/pamguard/PAMGuard_12_mvn/repo/.lastUpdated=1602590126603
|
||||
https\://maven.pkg.github.com/macster110/jpam/.error=Could not transfer artifact pamguard.org\:x3\:jar\:javadoc\:2.0.0 from/to github (https\://maven.pkg.github.com/macster110/jpam)\: Access denied to https\://maven.pkg.github.com/macster110/jpam/pamguard/org/x3/2.0.0/x3-2.0.0-javadoc.jar. Error code 401,
|
||||
https\://dl.bintray.com/jerady/maven/.error=
|
||||
https\://raw.github.com/macster110/jpam/mvn-repo/.error=
|
38
repo/pamguard/org/x3/2.0.0/x3-2.0.0-sources.jar.lastUpdated
Normal file
38
repo/pamguard/org/x3/2.0.0/x3-2.0.0-sources.jar.lastUpdated
Normal file
@ -0,0 +1,38 @@
|
||||
#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice.
|
||||
#Fri Jan 14 08:11:53 GMT 2022
|
||||
https\://dl.bintray.com/macster110/jtorch4pam/.error=
|
||||
file\:///Users/au671271/pamguard/PAMGuard_12_mvn/src/jars/.error=
|
||||
https\://jmachund.jfrog.io/artifactory/jpam2/.lastUpdated=1625576160246
|
||||
file\:///Users/au671271/pamguard/PAMGuard/repo/.error=
|
||||
file\:///Users/au671271/pamguard/PAMGuard_16_mvn/repo/.lastUpdated=1622023729649
|
||||
https\://dl.bintray.com/macster110/jtorch4pam/.lastUpdated=1600949479758
|
||||
file\:///Users/au671271/git/PAMGuard/repo/.error=
|
||||
https\://nexus.bedatadriven.com/content/groups/public/.error=
|
||||
https\://artifacts.unidata.ucar.edu/repository/unidata-all/.error=
|
||||
https\://artifacts.unidata.ucar.edu/repository/unidata-all/.lastUpdated=1600949481209
|
||||
https\://maven.averbis.com/m2/.lastUpdated=1601026887474
|
||||
file\:///Users/au671271/git/PAMGuard/repo/.lastUpdated=1641807658590
|
||||
https\://raw.github.com/macster110/jpam/mvn-repo/.lastUpdated=1642065813017
|
||||
file\:///Users/au671271/pamguard/PAMGuard_16_mvn/repo/.error=
|
||||
http\://maven.icm.edu.pl/artifactory/repo/.lastUpdated=1600971300137
|
||||
https\://nexus.bedatadriven.com/content/groups/public/.lastUpdated=1600949482388
|
||||
http\://maven.icm.edu.pl/artifactory/repo/.error=
|
||||
https\://repo1.maven.org/maven2/.error=
|
||||
@default-github-https\://maven.pkg.github.com/macster110/jpam/.lastUpdated=1642147913184
|
||||
file\:///Users/au671271/pamguard/PAMGuard/repo/.lastUpdated=1632311094646
|
||||
https\://repo1.maven.org/maven2/.lastUpdated=1642147912977
|
||||
https\://dl.bintray.com/jerady/maven/.lastUpdated=1600949480238
|
||||
http\://maven.geomajas.org/.lastUpdated=1600949482017
|
||||
https\://nexus.talanlabs.com/content/repositories/releases/.error=
|
||||
file\:///Users/au671271/pamguard/PAMGuard_12_mvn/repo/.error=
|
||||
file\:///Users/au671271/pamguard/PAMGuard_12_mvn/src/jars/.lastUpdated=1600949479759
|
||||
https\://repo.maven.apache.org/maven2/.lastUpdated=1600949483387
|
||||
http\://maven.geomajas.org/.error=
|
||||
https\://jmachund.jfrog.io/artifactory/jpam2/.error=
|
||||
https\://nexus.talanlabs.com/content/repositories/releases/.lastUpdated=1600949482866
|
||||
https\://maven.averbis.com/m2/.error=
|
||||
https\://repo.maven.apache.org/maven2/.error=
|
||||
file\:///Users/au671271/pamguard/PAMGuard_12_mvn/repo/.lastUpdated=1602589977891
|
||||
https\://maven.pkg.github.com/macster110/jpam/.error=Could not transfer artifact pamguard.org\:x3\:jar\:sources\:2.0.0 from/to github (https\://maven.pkg.github.com/macster110/jpam)\: Access denied to https\://maven.pkg.github.com/macster110/jpam/pamguard/org/x3/2.0.0/x3-2.0.0-sources.jar. Error code 401,
|
||||
https\://dl.bintray.com/jerady/maven/.error=
|
||||
https\://raw.github.com/macster110/jpam/mvn-repo/.error=
|
18
repo/pamguard/org/x3/2.0.0/x3-2.0.0.jar.lastUpdated
Normal file
18
repo/pamguard/org/x3/2.0.0/x3-2.0.0.jar.lastUpdated
Normal file
@ -0,0 +1,18 @@
|
||||
#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice.
|
||||
#Thu Sep 24 13:58:55 CEST 2020
|
||||
https\://dl.bintray.com/macster110/jtorch4pam/.error=
|
||||
file\:///Users/au671271/pamguard/PAMGuard_12_mvn/src/jars/.error=
|
||||
https\://dl.bintray.com/macster110/jtorch4pam/.lastUpdated=1600948677455
|
||||
https\://artifacts.unidata.ucar.edu/repository/unidata-all/.error=
|
||||
https\://nexus.bedatadriven.com/content/groups/public/.error=
|
||||
https\://artifacts.unidata.ucar.edu/repository/unidata-all/.lastUpdated=1600948714963
|
||||
https\://dl.bintray.com/jerady/maven/.lastUpdated=1600948680041
|
||||
http\://maven.geomajas.org/.lastUpdated=1600948729479
|
||||
https\://nexus.talanlabs.com/content/repositories/releases/.error=
|
||||
file\:///Users/au671271/pamguard/PAMGuard_12_mvn/src/jars/.lastUpdated=1600948677498
|
||||
https\://repo.maven.apache.org/maven2/.lastUpdated=1600948686447
|
||||
http\://maven.geomajas.org/.error=
|
||||
https\://nexus.talanlabs.com/content/repositories/releases/.lastUpdated=1600948735430
|
||||
https\://repo.maven.apache.org/maven2/.error=
|
||||
https\://dl.bintray.com/jerady/maven/.error=
|
||||
https\://nexus.bedatadriven.com/content/groups/public/.lastUpdated=1600948734692
|
@ -1 +0,0 @@
|
||||
851e2c9b153f1686858523e69d78da20
|
@ -1 +0,0 @@
|
||||
4d89dd98cf0188bb3bfe4afd74dc427ce23d3a41
|
18
repo/pamguard/org/x3/2.0.0/x3-2.0.0.pom.lastUpdated
Normal file
18
repo/pamguard/org/x3/2.0.0/x3-2.0.0.pom.lastUpdated
Normal file
@ -0,0 +1,18 @@
|
||||
#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice.
|
||||
#Thu Sep 24 13:57:29 CEST 2020
|
||||
https\://dl.bintray.com/macster110/jtorch4pam/.error=
|
||||
file\:///Users/au671271/pamguard/PAMGuard_12_mvn/src/jars/.error=
|
||||
https\://dl.bintray.com/macster110/jtorch4pam/.lastUpdated=1600948647604
|
||||
https\://artifacts.unidata.ucar.edu/repository/unidata-all/.error=
|
||||
https\://nexus.bedatadriven.com/content/groups/public/.error=
|
||||
https\://artifacts.unidata.ucar.edu/repository/unidata-all/.lastUpdated=1600948648002
|
||||
https\://dl.bintray.com/jerady/maven/.lastUpdated=1600948647670
|
||||
http\://maven.geomajas.org/.lastUpdated=1600948648672
|
||||
https\://nexus.talanlabs.com/content/repositories/releases/.error=
|
||||
file\:///Users/au671271/pamguard/PAMGuard_12_mvn/src/jars/.lastUpdated=1600948647606
|
||||
https\://repo.maven.apache.org/maven2/.lastUpdated=1600948649503
|
||||
http\://maven.geomajas.org/.error=
|
||||
https\://nexus.talanlabs.com/content/repositories/releases/.lastUpdated=1600948649324
|
||||
https\://repo.maven.apache.org/maven2/.error=
|
||||
https\://dl.bintray.com/jerady/maven/.error=
|
||||
https\://nexus.bedatadriven.com/content/groups/public/.lastUpdated=1600948648816
|
@ -1 +0,0 @@
|
||||
e09a0e45701b683f485aedf1349cab24
|
@ -1 +0,0 @@
|
||||
45129eae7b4f9c502cceffe8358fdc7e19ceaa39
|
4
repo/pamguard/org/x3/2.1.0/_remote.repositories
Normal file
4
repo/pamguard/org/x3/2.1.0/_remote.repositories
Normal file
@ -0,0 +1,4 @@
|
||||
#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice.
|
||||
#Tue Oct 11 15:59:57 BST 2022
|
||||
x3-2.1.0.jar>=
|
||||
x3-2.1.0.pom>=
|
13
repo/pamguard/org/x3/2.1.0/m2e-lastUpdated.properties
Normal file
13
repo/pamguard/org/x3/2.1.0/m2e-lastUpdated.properties
Normal file
@ -0,0 +1,13 @@
|
||||
#Thu Oct 06 15:38:43 BST 2022
|
||||
bedatadriven|https\://nexus.bedatadriven.com/content/groups/public/|javadoc=1665067123455
|
||||
repo|file\:///Users/au671271/git/PAMGuard/repo|javadoc=1665067123455
|
||||
repo|file\:///Users/au671271/git/PAMGuard/repo|sources=1665067040129
|
||||
talan|https\://nexus.talanlabs.com/content/repositories/releases/|sources=1665067040129
|
||||
bintray-macster110-jtorch4pam|macster110|https\://dl.bintray.com/macster110/jtorch4pam|javadoc=1665067123455
|
||||
bedatadriven|https\://nexus.bedatadriven.com/content/groups/public/|sources=1665067040129
|
||||
unidata-all|https\://artifacts.unidata.ucar.edu/repository/unidata-all/|sources=1665067040129
|
||||
talan|https\://nexus.talanlabs.com/content/repositories/releases/|javadoc=1665067123455
|
||||
central|https\://repo1.maven.org/maven2|sources=1665067040129
|
||||
unidata-all|https\://artifacts.unidata.ucar.edu/repository/unidata-all/|javadoc=1665067123455
|
||||
bintray-macster110-jtorch4pam|macster110|https\://dl.bintray.com/macster110/jtorch4pam|sources=1665067040129
|
||||
central|https\://repo1.maven.org/maven2|javadoc=1665067123455
|
14
repo/pamguard/org/x3/2.1.0/x3-2.1.0-javadoc.jar.lastUpdated
Normal file
14
repo/pamguard/org/x3/2.1.0/x3-2.1.0-javadoc.jar.lastUpdated
Normal file
@ -0,0 +1,14 @@
|
||||
#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice.
|
||||
#Thu Oct 06 15:38:43 BST 2022
|
||||
@default-talan-https\://nexus.talanlabs.com/content/repositories/releases/.lastUpdated=1665067122194
|
||||
https\://dl.bintray.com/macster110/jtorch4pam/.error=Could not transfer artifact pamguard.org\:x3\:jar\:javadoc\:2.1.0 from/to bintray-macster110-jtorch4pam (https\://dl.bintray.com/macster110/jtorch4pam)\: Remote host terminated the handshake
|
||||
https\://repo1.maven.org/maven2/.error=
|
||||
file\:///Users/au671271/git/PAMGuard/repo/.error=
|
||||
https\://nexus.bedatadriven.com/content/groups/public/.error=
|
||||
https\://artifacts.unidata.ucar.edu/repository/unidata-all/.error=
|
||||
https\://artifacts.unidata.ucar.edu/repository/unidata-all/.lastUpdated=1665067121806
|
||||
https\://repo1.maven.org/maven2/.lastUpdated=1665067123455
|
||||
https\://nexus.talanlabs.com/content/repositories/releases/.error=Could not transfer artifact pamguard.org\:x3\:jar\:javadoc\:2.1.0 from/to talan (https\://nexus.talanlabs.com/content/repositories/releases/)\: Access denied to https\://nexus.talanlabs.com/content/repositories/releases/pamguard/org/x3/2.1.0/x3-2.1.0-javadoc.jar. Error code 401, Unauthorized
|
||||
file\:///Users/au671271/git/PAMGuard/repo/.lastUpdated=1665067120886
|
||||
4d1f727a0c17e3b21ef2f6654eed0b3113a4db97@default-bintray-macster110-jtorch4pam-https\://dl.bintray.com/macster110/jtorch4pam/.lastUpdated=1665067120883
|
||||
https\://nexus.bedatadriven.com/content/groups/public/.lastUpdated=1665067122025
|
14
repo/pamguard/org/x3/2.1.0/x3-2.1.0-sources.jar.lastUpdated
Normal file
14
repo/pamguard/org/x3/2.1.0/x3-2.1.0-sources.jar.lastUpdated
Normal file
@ -0,0 +1,14 @@
|
||||
#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice.
|
||||
#Thu Oct 06 15:37:20 BST 2022
|
||||
@default-talan-https\://nexus.talanlabs.com/content/repositories/releases/.lastUpdated=1665067039941
|
||||
https\://dl.bintray.com/macster110/jtorch4pam/.error=Could not transfer artifact pamguard.org\:x3\:jar\:sources\:2.1.0 from/to bintray-macster110-jtorch4pam (https\://dl.bintray.com/macster110/jtorch4pam)\: Remote host terminated the handshake
|
||||
https\://repo1.maven.org/maven2/.error=
|
||||
file\:///Users/au671271/git/PAMGuard/repo/.error=
|
||||
https\://nexus.bedatadriven.com/content/groups/public/.error=
|
||||
https\://artifacts.unidata.ucar.edu/repository/unidata-all/.error=
|
||||
https\://artifacts.unidata.ucar.edu/repository/unidata-all/.lastUpdated=1665067039627
|
||||
https\://repo1.maven.org/maven2/.lastUpdated=1665067040128
|
||||
https\://nexus.talanlabs.com/content/repositories/releases/.error=Could not transfer artifact pamguard.org\:x3\:jar\:sources\:2.1.0 from/to talan (https\://nexus.talanlabs.com/content/repositories/releases/)\: Access denied to https\://nexus.talanlabs.com/content/repositories/releases/pamguard/org/x3/2.1.0/x3-2.1.0-sources.jar. Error code 401, Unauthorized
|
||||
file\:///Users/au671271/git/PAMGuard/repo/.lastUpdated=1665067038933
|
||||
4d1f727a0c17e3b21ef2f6654eed0b3113a4db97@default-bintray-macster110-jtorch4pam-https\://dl.bintray.com/macster110/jtorch4pam/.lastUpdated=1665067038929
|
||||
https\://nexus.bedatadriven.com/content/groups/public/.lastUpdated=1665067039782
|
BIN
repo/pamguard/org/x3/2.1.0/x3-2.1.0.jar
Normal file
BIN
repo/pamguard/org/x3/2.1.0/x3-2.1.0.jar
Normal file
Binary file not shown.
9
repo/pamguard/org/x3/2.1.0/x3-2.1.0.pom
Normal file
9
repo/pamguard/org/x3/2.1.0/x3-2.1.0.pom
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>pamguard.org</groupId>
|
||||
<artifactId>x3</artifactId>
|
||||
<version>2.1.0</version>
|
||||
<description>POM was created from install:install-file</description>
|
||||
</project>
|
16
repo/pamguard/org/x3/2.1.0/x3-2.1.0.pom.lastUpdated
Normal file
16
repo/pamguard/org/x3/2.1.0/x3-2.1.0.pom.lastUpdated
Normal file
@ -0,0 +1,16 @@
|
||||
#NOTE: This is a Maven Resolver internal implementation file, its format can be changed without prior notice.
|
||||
#Thu Oct 06 15:51:34 BST 2022
|
||||
@default-talan-https\://nexus.talanlabs.com/content/repositories/releases/.lastUpdated=1665067894494
|
||||
https\://dl.bintray.com/macster110/jtorch4pam/.error=Could not transfer artifact pamguard.org\:x3\:pom\:2.1.0 from/to bintray-macster110-jtorch4pam (https\://dl.bintray.com/macster110/jtorch4pam)\: Remote host terminated the handshake
|
||||
@default-repo-file\://${project.basedir}/repo/.lastUpdated=1665067029837
|
||||
https\://repo1.maven.org/maven2/.error=
|
||||
file\:///Users/au671271/git/PAMGuard/repo/.error=
|
||||
https\://nexus.bedatadriven.com/content/groups/public/.error=
|
||||
https\://artifacts.unidata.ucar.edu/repository/unidata-all/.error=
|
||||
https\://artifacts.unidata.ucar.edu/repository/unidata-all/.lastUpdated=1665067032579
|
||||
https\://repo1.maven.org/maven2/.lastUpdated=1665067036872
|
||||
https\://nexus.talanlabs.com/content/repositories/releases/.error=Could not transfer artifact pamguard.org\:x3\:pom\:2.1.0 from/to talan (https\://nexus.talanlabs.com/content/repositories/releases/)\: Access denied to https\://nexus.talanlabs.com/content/repositories/releases/pamguard/org/x3/2.1.0/x3-2.1.0.pom. Error code 401, Unauthorized
|
||||
file\://${project.basedir}/repo/.error=Could not transfer artifact pamguard.org\:x3\:pom\:2.1.0 from/to repo (file\://${project.basedir}/repo)\: Repository path /repo does not exist, and cannot be created.
|
||||
file\:///Users/au671271/git/PAMGuard/repo/.lastUpdated=1665067033714
|
||||
4d1f727a0c17e3b21ef2f6654eed0b3113a4db97@default-bintray-macster110-jtorch4pam-https\://dl.bintray.com/macster110/jtorch4pam/.lastUpdated=1665067894257
|
||||
https\://nexus.bedatadriven.com/content/groups/public/.lastUpdated=1665067034011
|
@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<metadata>
|
||||
<groupId>pamguard.org</groupId>
|
||||
<artifactId>x3</artifactId>
|
||||
<versioning>
|
||||
<release>2.0.0</release>
|
||||
<versions>
|
||||
<version>2.0.0</version>
|
||||
</versions>
|
||||
<lastUpdated>20200929205724</lastUpdated>
|
||||
</versioning>
|
||||
</metadata>
|
@ -1 +0,0 @@
|
||||
47ffb77b88155d037480604e508371ff
|
@ -1 +0,0 @@
|
||||
9c238e70383b552aaaf3161eaeee8ed238d90ff8
|
@ -15,7 +15,7 @@ import javax.swing.JTextArea;
|
||||
import javax.swing.SwingWorker;
|
||||
import javax.swing.border.TitledBorder;
|
||||
|
||||
import PamUtils.PamAudioFileFilter;
|
||||
import Acquisition.pamAudio.PamAudioFileFilter;
|
||||
import PamView.dialog.PamDialog;
|
||||
|
||||
public class CheckWavFileHeaders extends PamDialog {
|
||||
|
@ -47,6 +47,8 @@ import wavFiles.ByteConverter;
|
||||
import Acquisition.filedate.FileDate;
|
||||
import Acquisition.filedate.FileDateDialogStrip;
|
||||
import Acquisition.filedate.FileDateObserver;
|
||||
import Acquisition.pamAudio.PamAudioFileManager;
|
||||
import Acquisition.pamAudio.PamAudioFileFilter;
|
||||
import Acquisition.pamAudio.PamAudioSystem;
|
||||
import PamController.PamControlledUnitSettings;
|
||||
import PamController.PamController;
|
||||
@ -54,7 +56,6 @@ import PamController.PamSettingManager;
|
||||
import PamController.PamSettings;
|
||||
import PamDetection.RawDataUnit;
|
||||
import PamModel.SMRUEnable;
|
||||
import PamUtils.PamAudioFileFilter;
|
||||
import PamUtils.PamCalendar;
|
||||
import PamUtils.PamFileChooser;
|
||||
import PamView.dialog.PamLabel;
|
||||
@ -408,7 +409,7 @@ public class FileInputSystem extends DaqSystem implements ActionListener, PamSe
|
||||
// acquisitionDialog.NotifyChange();
|
||||
if (file.isFile() && !file.isHidden() && acquisitionDialog != null) {
|
||||
try {
|
||||
AudioInputStream audioStream = PamAudioSystem.getAudioInputStream(file);
|
||||
AudioInputStream audioStream = PamAudioFileManager.getInstance().getAudioInputStream(file);
|
||||
|
||||
// // Get additional information from the header if it's a wav file.
|
||||
// if (WavFileInputStream.class.isAssignableFrom(audioStream.getClass())) {
|
||||
@ -537,6 +538,7 @@ public class FileInputSystem extends DaqSystem implements ActionListener, PamSe
|
||||
}
|
||||
|
||||
public File getCurrentFile() {
|
||||
System.out.println("fileInputParameters: " + fileInputParameters);
|
||||
if (fileInputParameters.recentFiles == null) return null;
|
||||
if (fileInputParameters.recentFiles.size() < 1) return null;
|
||||
String fileName = fileInputParameters.recentFiles.get(0);
|
||||
@ -559,8 +561,11 @@ public class FileInputSystem extends DaqSystem implements ActionListener, PamSe
|
||||
public boolean prepareInputFile() {
|
||||
|
||||
File currentFile = getCurrentFile();
|
||||
// System.out.printf("*********************************** Opening file %s\n", currentFile.getName());
|
||||
if (currentFile == null) return false;
|
||||
if (currentFile == null) {
|
||||
System.out.println("The current file was null");
|
||||
return false;
|
||||
}
|
||||
System.out.printf("*********************************** Opening file %s\n", currentFile.getName());
|
||||
|
||||
try {
|
||||
|
||||
@ -568,7 +573,7 @@ public class FileInputSystem extends DaqSystem implements ActionListener, PamSe
|
||||
audioStream.close();
|
||||
}
|
||||
|
||||
audioStream = PamAudioSystem.getAudioInputStream(currentFile);
|
||||
audioStream = PamAudioFileManager.getInstance().getAudioInputStream(currentFile);
|
||||
|
||||
if (audioStream == null) {
|
||||
return false;
|
||||
@ -645,7 +650,8 @@ public class FileInputSystem extends DaqSystem implements ActionListener, PamSe
|
||||
|
||||
String audioFileStr = getCurrentFile()==null? "Null File": getCurrentFile().getAbsolutePath();
|
||||
|
||||
System.err.println("FileInputSystem: runFileAnalysis: AudioFilr format is null: " + audioFileStr);
|
||||
System.err.println("FileInputSystem: runFileAnalysis: AudioFile format is null: " + audioFileStr);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -28,11 +28,12 @@ import Acquisition.layoutFX.DAQSettingsPane;
|
||||
import Acquisition.layoutFX.FolderInputPane;
|
||||
import javafx.application.Platform;
|
||||
import pamguard.GlobalArguments;
|
||||
import Acquisition.pamAudio.PamAudioFileManager;
|
||||
import Acquisition.pamAudio.PamAudioFileFilter;
|
||||
import Acquisition.pamAudio.PamAudioSystem;
|
||||
import PamController.PamControlledUnitSettings;
|
||||
import PamController.PamController;
|
||||
import PamController.PamSettings;
|
||||
import PamUtils.PamAudioFileFilter;
|
||||
import PamUtils.PamCalendar;
|
||||
import PamUtils.PamFileChooser;
|
||||
import PamUtils.PamFileFilter;
|
||||
@ -429,6 +430,8 @@ public class FolderInputSystem extends FileInputSystem implements PamSettings{
|
||||
File aFile = files[0];
|
||||
setNewFile(aFile.getAbsolutePath());
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The file chooser is returning sub classes of File which are not
|
||||
* serialisable, so we can't use them. We need to convert their
|
||||
@ -505,7 +508,7 @@ public class FolderInputSystem extends FileInputSystem implements PamSettings{
|
||||
if (file.isFile() && !file.isHidden() && acquisitionDialog != null) {
|
||||
//Hidden files should not be used in analysis...
|
||||
try {
|
||||
audioStream = PamAudioSystem.getAudioInputStream(file);
|
||||
audioStream = PamAudioFileManager.getInstance().getAudioInputStream(file);
|
||||
AudioFormat audioFormat = audioStream.getFormat();
|
||||
fileSamples = audioStream.getFrameLength();
|
||||
acquisitionDialog.setSampleRate(audioFormat.getSampleRate());
|
||||
@ -568,6 +571,7 @@ public class FolderInputSystem extends FileInputSystem implements PamSettings{
|
||||
|
||||
@Override
|
||||
public File getCurrentFile() {
|
||||
//System.out.println("All files: " + allFiles);
|
||||
if (allFiles != null && allFiles.size() > currentFile) {
|
||||
return allFiles.get(currentFile);
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.sound.sampled.AudioFormat;
|
||||
import javax.sound.sampled.AudioInputStream;
|
||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
||||
import javax.sound.sampled.AudioFormat.Encoding;
|
||||
@ -25,10 +26,11 @@ import org.jflac.metadata.StreamInfo;
|
||||
import org.jflac.util.ByteData;
|
||||
|
||||
import wavFiles.ByteConverter;
|
||||
import Acquisition.pamAudio.PamAudioFileManager;
|
||||
import Acquisition.pamAudio.PamAudioFileFilter;
|
||||
import Acquisition.pamAudio.PamAudioSystem;
|
||||
import PamDetection.RawDataUnit;
|
||||
import PamUtils.FileParts;
|
||||
import PamUtils.PamAudioFileFilter;
|
||||
import PamUtils.PamCalendar;
|
||||
import PamUtils.PamFileFilter;
|
||||
import PamUtils.PamUtils;
|
||||
@ -150,7 +152,7 @@ public class RonaInputSystem extends FolderInputSystem {
|
||||
audioStreams[i].close();
|
||||
}
|
||||
|
||||
audioStreams[i] = PamAudioSystem.getAudioInputStream(findChannelFile(currentFile, i, 2));
|
||||
audioStreams[i] = PamAudioFileManager.getInstance().getAudioInputStream(findChannelFile(currentFile, i, 2));
|
||||
|
||||
audioFormat = audioStreams[i].getFormat();
|
||||
|
||||
|
@ -5,7 +5,7 @@ import java.util.ArrayList;
|
||||
import Acquisition.AudioFileFuncs;
|
||||
import Acquisition.FolderInputSystem;
|
||||
import Acquisition.WavFileFuncs;
|
||||
import PamUtils.PamAudioFileFilter;
|
||||
import Acquisition.pamAudio.PamAudioFileFilter;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.SimpleDoubleProperty;
|
||||
|
@ -11,10 +11,9 @@ import org.controlsfx.glyphfont.Glyph;
|
||||
import Acquisition.FileInputParameters;
|
||||
import Acquisition.FolderInputParameters;
|
||||
import Acquisition.FolderInputSystem;
|
||||
import Acquisition.pamAudio.PamAudioFileFilter;
|
||||
import PamController.PamController;
|
||||
import PamController.PamFolders;
|
||||
import PamController.SettingsPane;
|
||||
import PamUtils.PamAudioFileFilter;
|
||||
import PamUtils.PamCalendar;
|
||||
import PamUtils.worker.PamWorker;
|
||||
import PamUtils.worker.filelist.FileListData;
|
||||
@ -24,7 +23,6 @@ import javafx.beans.property.SimpleIntegerProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.CheckBox;
|
||||
@ -48,7 +46,6 @@ import pamViewFX.fxNodes.PamComboBox;
|
||||
import pamViewFX.fxNodes.PamHBox;
|
||||
import pamViewFX.fxNodes.PamProgressBar;
|
||||
import pamViewFX.fxNodes.PamVBox;
|
||||
import pamViewFX.fxNodes.utilityPanes.PamToggleSwitch;
|
||||
|
||||
/**
|
||||
* Pane for the folder input of the sound acquisition.
|
||||
@ -413,7 +410,7 @@ public class FolderInputPane extends DAQSettingsPane<FolderInputParameters>{
|
||||
for (int i=0; i<filesArr.length; i++) {
|
||||
filesArr[i] = files.get(i);
|
||||
}
|
||||
|
||||
|
||||
folderInputSystem.getFolderInputParameters().setSelectedFiles(filesArr);
|
||||
folderInputSystem.makeSelFileList();
|
||||
// folderInputSystem.makeSelFileList(folderInputSystem.getFolderInputParameters().getSelectedFiles());
|
||||
@ -626,7 +623,7 @@ public class FolderInputPane extends DAQSettingsPane<FolderInputParameters>{
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.println("File list worker: " + worker );
|
||||
//System.out.println("File list worker: " + worker );
|
||||
//must ensure this is on the FX thread
|
||||
//Platform.runLater(()->{
|
||||
this.progressBar.progressProperty().bind(worker.getPamWorkProgress().getProgressProperty());
|
||||
|
@ -2,31 +2,22 @@ package Acquisition.offlineFuncs;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.sound.sampled.AudioFormat;
|
||||
import javax.sound.sampled.AudioInputStream;
|
||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
||||
import javax.sound.sampled.AudioFormat.Encoding;
|
||||
|
||||
import org.jflac.FLACDecoder;
|
||||
import org.jflac.PCMProcessor;
|
||||
import org.jflac.metadata.Metadata;
|
||||
import org.jflac.metadata.StreamInfo;
|
||||
import org.jflac.sound.spi.FlacAudioFileReader;
|
||||
import org.jflac.util.ByteData;
|
||||
|
||||
import Acquisition.filedate.FileDate;
|
||||
import Acquisition.pamAudio.PamAudioSystem;
|
||||
import Acquisition.pamAudio.PamAudioFileManager;
|
||||
import Acquisition.pamAudio.PamAudioFileLoader;
|
||||
import Acquisition.pamAudio.PamAudioFileFilter;
|
||||
import PamController.OfflineFileDataStore;
|
||||
import PamDetection.RawDataUnit;
|
||||
import PamUtils.PamAudioFileFilter;
|
||||
import PamUtils.PamCalendar;
|
||||
import PamguardMVC.PamDataBlock;
|
||||
import PamguardMVC.PamRawDataBlock;
|
||||
import PamguardMVC.dataOffline.OfflineDataLoadInfo;
|
||||
import dataMap.OfflineDataMap;
|
||||
import dataMap.filemaps.FileDataMapPoint;
|
||||
@ -37,18 +28,13 @@ import wavFiles.ByteConverter;
|
||||
/**
|
||||
* This has been split off from OfflineFileServer so that OfflineFileServer can be used with
|
||||
* other file types.
|
||||
* @author dg50
|
||||
* @author Doug Gillespie
|
||||
*
|
||||
*/
|
||||
public class OfflineWavFileServer extends OfflineFileServer<FileDataMapPoint> {
|
||||
|
||||
private FileDate fileDate;
|
||||
|
||||
private ByteConverter byteConverter;
|
||||
|
||||
private AudioInputStream audioInputStream;
|
||||
private AudioFormat audioFormat;
|
||||
|
||||
public OfflineWavFileServer(OfflineFileDataStore offlineRawDataStore, FileDate fileDate) {
|
||||
super(offlineRawDataStore);
|
||||
this.fileDate = fileDate;
|
||||
@ -109,7 +95,10 @@ public class OfflineWavFileServer extends OfflineFileServer<FileDataMapPoint> {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
file = mapPoint.getSoundFile();/*
|
||||
file = mapPoint.getSoundFile();
|
||||
|
||||
//TODO - this should be integrated into the PamAudioFileManager.
|
||||
/*
|
||||
* Now need to open file file as an input stream (what a bore !)
|
||||
*/
|
||||
AudioInputStream audioStream;
|
||||
@ -139,7 +128,7 @@ public class OfflineWavFileServer extends OfflineFileServer<FileDataMapPoint> {
|
||||
}
|
||||
else {
|
||||
try {
|
||||
audioStream = PamAudioSystem.getAudioInputStream(file);
|
||||
audioStream = PamAudioFileManager.getInstance().getAudioInputStream(file);
|
||||
if (audioStream == null) {
|
||||
it.remove();
|
||||
continue;
|
||||
@ -166,302 +155,7 @@ public class OfflineWavFileServer extends OfflineFileServer<FileDataMapPoint> {
|
||||
|
||||
}
|
||||
|
||||
private boolean loadWavData(PamDataBlock dataBlock, OfflineDataLoadInfo offlineDataLoadInfo,
|
||||
ViewLoadObserver loadObserver) {
|
||||
|
||||
// Debug.out.println("OfflineFileServer: Load Wav Data: " + offlineDataLoadInfo.getCurrentObserver().getObserverName() );
|
||||
OfflineDataMap<FileDataMapPoint> dataMap = getDataMap();
|
||||
Iterator<FileDataMapPoint> mapIt = dataMap.getListIterator();
|
||||
FileDataMapPoint mapPoint = findFirstMapPoint(mapIt, offlineDataLoadInfo.getStartMillis(), offlineDataLoadInfo.getEndMillis());
|
||||
if (openSoundFile(mapPoint.getSoundFile()) == false) {
|
||||
System.out.println("Could not open .wav sound file " + mapPoint.getSoundFile().getAbsolutePath());
|
||||
return false;
|
||||
}
|
||||
File soundFile;
|
||||
|
||||
byteConverter = ByteConverter.createByteConverter(audioFormat);
|
||||
long currentTime = mapPoint.getStartTime();
|
||||
long prevFileEnd = mapPoint.getEndTime();
|
||||
boolean fileGap = false;
|
||||
int newSamples;
|
||||
double[][] doubleData;
|
||||
int nChannels = audioFormat.getChannels();
|
||||
int blockSamples = Math.max((int) audioFormat.getSampleRate() / 10, 1000);
|
||||
int frameSize = audioFormat.getFrameSize();
|
||||
if (frameSize < 0) {
|
||||
frameSize = audioFormat.getChannels()*audioFormat.getSampleSizeInBits()/8;
|
||||
}
|
||||
if (frameSize <= 0) {
|
||||
System.out.println("The frame size is less than zero " + mapPoint.getSoundFile().getAbsolutePath());
|
||||
return false;
|
||||
}
|
||||
byte[] inputBuffer = new byte[blockSamples * frameSize];
|
||||
int bytesRead = 0;
|
||||
long totalSamples = 0;
|
||||
// long fileSamples = 0;
|
||||
long millisecondsGaps = 0;
|
||||
long ms;
|
||||
|
||||
RawDataUnit newDataUnit;
|
||||
long skipped = 0;
|
||||
if (currentTime < offlineDataLoadInfo.getStartMillis()) {
|
||||
// need to fast forward in current file.
|
||||
long skipBytes = (long) (((offlineDataLoadInfo.getStartMillis()-currentTime)*audioFormat.getSampleRate()*audioFormat.getFrameSize())/1000.);
|
||||
try {
|
||||
skipped = audioInputStream.skip(skipBytes);
|
||||
// Debug.out.println("Skipped " + skipped);
|
||||
} catch (IOException e) {
|
||||
/**
|
||||
* The datamap point may be longer than the actual file here ? In any case, with the
|
||||
* NEMO data which is 5 mins per hour, this get's hit for the file before the
|
||||
* file we want every time !
|
||||
*/
|
||||
// System.out.println("End of audio file " + mapPoint.getSoundFile().getName());
|
||||
e.printStackTrace();
|
||||
}
|
||||
currentTime = offlineDataLoadInfo.getStartMillis();
|
||||
}
|
||||
ms = currentTime;
|
||||
while (ms < offlineDataLoadInfo.getEndMillis() && currentTime < offlineDataLoadInfo.getEndMillis()) {
|
||||
if (offlineDataLoadInfo.cancel) {
|
||||
//add the position we got to
|
||||
offlineDataLoadInfo.setLastLoadInfo(new AquisitionLoadPoint(ms, bytesRead));
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
try {
|
||||
bytesRead = audioInputStream.read(inputBuffer);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (bytesRead <= 0) {
|
||||
skipped = 0 ; //reset ot zero because were not skipping anyu bytes here.
|
||||
/*
|
||||
* that's the end of that file, so get the next one if there
|
||||
* is one, if not then break.
|
||||
*/
|
||||
if (mapIt.hasNext() == false) {
|
||||
break;
|
||||
}
|
||||
mapPoint = mapIt.next();
|
||||
fileGap = (mapPoint.getStartTime() - prevFileEnd) > 1000;
|
||||
// if (fileGap) {
|
||||
// System.out.println(String.format("Sound file gap %3.3fs from %s to %s",
|
||||
// (double) (mapPoint.getStartTime()-prevFileEnd) / 1000.,
|
||||
// PamCalendar.formatTime(prevFileEnd), PamCalendar.formatTime(mapPoint.getStartTime())));
|
||||
// }
|
||||
prevFileEnd = mapPoint.getEndTime();
|
||||
if (!fileGap) { // don't carry on if there is a file gap
|
||||
if (openSoundFile(mapPoint.getSoundFile()) == false) {
|
||||
break;
|
||||
}
|
||||
// try again to read data.
|
||||
try {
|
||||
bytesRead = audioInputStream.read(inputBuffer);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (bytesRead <= 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
newSamples = bytesRead / frameSize;
|
||||
doubleData = new double[nChannels][newSamples];
|
||||
int convertedSamples = byteConverter.bytesToDouble(inputBuffer, doubleData, bytesRead);
|
||||
ms = getOfflineRawDataStore().getParentProcess().absSamplesToMilliseconds(totalSamples);
|
||||
ms = currentTime + (long)(totalSamples * 1000 / (double) audioFormat.getSampleRate());
|
||||
|
||||
for (int ichan = 0; ichan < nChannels; ichan++) {
|
||||
|
||||
newDataUnit = new RawDataUnit(ms, 1 << ichan, totalSamples, newSamples);
|
||||
newDataUnit.setFileSamples(totalSamples + skipped / frameSize); //set the number samples into the wav file.
|
||||
newDataUnit.setRawData(doubleData[ichan], true);
|
||||
|
||||
//System.out.println("New wav data: " + PamCalendar.formatDateTime(newDataUnit.getTimeMilliseconds()));
|
||||
getRawDataBlock().addPamData(newDataUnit);
|
||||
}
|
||||
if (fileGap) {
|
||||
currentTime = mapPoint.getStartTime();
|
||||
totalSamples = 0;
|
||||
// fileSamples = 0;
|
||||
}
|
||||
|
||||
totalSamples += newSamples;
|
||||
// fileSamples += newSamples;
|
||||
}
|
||||
|
||||
// System.out.println("Finished loading wav: " + offlineDataLoadInfo.getCurrentObserver().getObserverName() );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean loadFlacData(PamDataBlock dataBlock, OfflineDataLoadInfo offlineDataLoadInfo,
|
||||
ViewLoadObserver loadObserver) {
|
||||
// System.out.println(String.format("Load flac data from "));
|
||||
/*
|
||||
* Only seem able to read whole flac files - so read the whole file
|
||||
* and just output samples of interest to data units. A bit crude,
|
||||
* but will probably not be too slow.
|
||||
*/
|
||||
OfflineDataMap<FileDataMapPoint> dataMap = this.getDataMap();
|
||||
Iterator<FileDataMapPoint> mapIt = dataMap.getListIterator();
|
||||
FileDataMapPoint mapPoint;
|
||||
File soundFile;
|
||||
mapPoint = findFirstMapPoint(mapIt, offlineDataLoadInfo.getStartMillis(), offlineDataLoadInfo.getEndMillis());
|
||||
if (mapPoint == null) {
|
||||
return false;
|
||||
}
|
||||
while (mapPoint != null) {
|
||||
|
||||
// AudioInputStream inputStream;
|
||||
// try {
|
||||
// inputStream = new FlacAudioFileReader().getAudioInputStream(mapPoint.getSoundFile());
|
||||
// } catch (UnsupportedAudioFileException | IOException e1) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e1.printStackTrace();
|
||||
// }
|
||||
FileInputStream fileStream;
|
||||
try {
|
||||
fileStream = new FileInputStream(mapPoint.getSoundFile());
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
FLACDecoder flacDecoder = new FLACDecoder(fileStream);
|
||||
// Metadata metaData[] = null;
|
||||
// try {
|
||||
// metaData = flacDecoder.readMetadata();
|
||||
// } catch (IOException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
flacDecoder.addPCMProcessor(new FlacPCM(mapPoint, dataBlock, fileStream,
|
||||
offlineDataLoadInfo, loadObserver));
|
||||
// StreamInfo streamInfo = flacDecoder.getStreamInfo(); // returns null !
|
||||
try {
|
||||
flacDecoder.decode();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
if (mapIt.hasNext() == false) {
|
||||
break;
|
||||
}
|
||||
mapPoint = mapIt.next();
|
||||
if (mapPoint.getStartTime() > offlineDataLoadInfo.getEndMillis()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only seem to be able to
|
||||
* @author doug
|
||||
*
|
||||
*/
|
||||
private class FlacPCM implements PCMProcessor {
|
||||
|
||||
private FileInputStream fileStream;
|
||||
private int frameSize;
|
||||
private long fileSamples;
|
||||
private int nChannels;
|
||||
private FileDataMapPoint mapPoint;
|
||||
private int totalSamples;
|
||||
private int sampleRate;
|
||||
private ViewLoadObserver loadObserver;
|
||||
private PamRawDataBlock dataBlock;
|
||||
private OfflineDataLoadInfo offlineDataLoadInfo;
|
||||
|
||||
|
||||
long ms=-1;
|
||||
|
||||
public FlacPCM(FileDataMapPoint mapPoint, PamDataBlock dataBlock, FileInputStream fileStream, OfflineDataLoadInfo offlineDataLoadInfo, ViewLoadObserver loadObserver) {
|
||||
this.mapPoint = mapPoint;
|
||||
this.dataBlock = (PamRawDataBlock) dataBlock;
|
||||
this.fileStream = fileStream;
|
||||
this.loadObserver = loadObserver;
|
||||
this.offlineDataLoadInfo=offlineDataLoadInfo;
|
||||
// System.out.printf("New FLAC decoder %s working from %s to %s\n", offlineDataLoadInfo.toString(),
|
||||
// PamCalendar.formatDBDateTime(offlineDataLoadInfo.getStartMillis()),
|
||||
// PamCalendar.formatDBDateTime(offlineDataLoadInfo.getEndMillis()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processPCM(ByteData byteData) {
|
||||
if (offlineDataLoadInfo.cancel) {
|
||||
|
||||
try {
|
||||
fileStream.close();
|
||||
ms = Math.max(offlineDataLoadInfo.getStartMillis(), ms);
|
||||
offlineDataLoadInfo.setLastLoadInfo(new AquisitionLoadPoint(ms, -1));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
ms = mapPoint.getStartTime() + (long)totalSamples * 1000L / (long)sampleRate;
|
||||
// System.out.println(String.format("PCM data at %s samps %d (load %s - %s)", PamCalendar.formatTime2(ms, 3), totalSamples,
|
||||
// PamCalendar.formatTime2(dataStart, 3), PamCalendar.formatTime2(dataEnd, 3)));
|
||||
if (ms > offlineDataLoadInfo.getEndMillis()) {
|
||||
try {
|
||||
fileStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return;
|
||||
}
|
||||
int newSamples = byteData.getLen() / frameSize;
|
||||
if (ms >= offlineDataLoadInfo.getStartMillis()) {
|
||||
double[][] doubleData = new double[nChannels][newSamples];
|
||||
byteConverter.bytesToDouble(byteData.getData(), doubleData, byteData.getLen());
|
||||
RawDataUnit newDataUnit = null;
|
||||
for (int ichan = 0; ichan < nChannels; ichan++) {
|
||||
|
||||
newDataUnit = new RawDataUnit(ms, 1 << ichan, totalSamples, newSamples);
|
||||
newDataUnit.setRawData(doubleData[ichan]);
|
||||
|
||||
dataBlock.addPamData(newDataUnit);
|
||||
|
||||
// GetOutputDataBlock().addPamData(pamDataUnit);
|
||||
}
|
||||
}
|
||||
// System.out.println(String.format("new samps %d at %s", newSamples, PamCalendar.formatTime(ms, 3)));
|
||||
|
||||
totalSamples += newSamples;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processStreamInfo(StreamInfo streamInfo) {
|
||||
frameSize = streamInfo.getChannels() * streamInfo.getBitsPerSample() / 8;
|
||||
byteConverter = ByteConverter.createByteConverter(streamInfo.getBitsPerSample() / 8, false, Encoding.PCM_SIGNED);
|
||||
fileSamples = streamInfo.getTotalSamples();
|
||||
nChannels = streamInfo.getChannels();
|
||||
sampleRate = streamInfo.getSampleRate();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean openSoundFile(File soundFile) {
|
||||
|
||||
try {
|
||||
audioInputStream = PamAudioSystem.getAudioInputStream(soundFile);
|
||||
if (audioInputStream == null) return false;
|
||||
audioFormat = audioInputStream.getFormat();
|
||||
} catch (UnsupportedAudioFileException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean loadData(PamDataBlock dataBlock, OfflineDataLoadInfo offlineLoadDataInfo, ViewLoadObserver loadObserver) {
|
||||
@ -482,34 +176,17 @@ public class OfflineWavFileServer extends OfflineFileServer<FileDataMapPoint> {
|
||||
if (mapPoint == null) {
|
||||
return false;
|
||||
}
|
||||
if (mapPoint.getSoundFile().getName().toLowerCase().endsWith(".flac")) {
|
||||
return loadFlacData(dataBlock, offlineLoadDataInfo, loadObserver);
|
||||
|
||||
PamAudioFileLoader audioFile = PamAudioFileManager.getInstance().getAudioLoader(mapPoint.getSoundFile());
|
||||
|
||||
if (audioFile==null) {
|
||||
System.err.println("OfflineWavFileServer: could not find audio loader for mapped sound file: " + mapPoint.getSoundFile());
|
||||
return false;
|
||||
}
|
||||
// if (mapPoint.getSoundFile().getName().toLowerCase().endsWith(".wav")) {
|
||||
if (isStandardAudio(mapPoint.getSoundFile().getName())) {
|
||||
return loadWavData(dataBlock, offlineLoadDataInfo, loadObserver);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
return audioFile.loadAudioData(this, dataBlock, offlineLoadDataInfo, loadObserver);
|
||||
|
||||
}
|
||||
|
||||
private String[] standardAudioTypes = {".wav", ".aif", ".aiff"};
|
||||
|
||||
/**
|
||||
* Is it a standard aif or wav audio file which can be opened with the standard reader ?
|
||||
* @param fileName
|
||||
* @return
|
||||
*/
|
||||
private boolean isStandardAudio(String fileName) {
|
||||
if (fileName == null) {
|
||||
return false;
|
||||
}
|
||||
fileName = fileName.toLowerCase();
|
||||
for (int i = 0; i < standardAudioTypes.length; i++) {
|
||||
if (fileName.endsWith(standardAudioTypes[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
236
src/Acquisition/pamAudio/FlacAudioFile.java
Normal file
236
src/Acquisition/pamAudio/FlacAudioFile.java
Normal file
@ -0,0 +1,236 @@
|
||||
package Acquisition.pamAudio;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.sound.sampled.AudioInputStream;
|
||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
||||
import javax.sound.sampled.AudioFormat.Encoding;
|
||||
|
||||
import org.jflac.FLACDecoder;
|
||||
import org.jflac.PCMProcessor;
|
||||
import org.jflac.metadata.StreamInfo;
|
||||
import org.jflac.sound.spi.FlacAudioFileReader;
|
||||
import org.jflac.util.ByteData;
|
||||
|
||||
import Acquisition.offlineFuncs.AquisitionLoadPoint;
|
||||
import PamDetection.RawDataUnit;
|
||||
import PamguardMVC.PamDataBlock;
|
||||
import PamguardMVC.PamRawDataBlock;
|
||||
import PamguardMVC.dataOffline.OfflineDataLoadInfo;
|
||||
import dataMap.OfflineDataMap;
|
||||
import dataMap.filemaps.FileDataMapPoint;
|
||||
import dataMap.filemaps.OfflineFileServer;
|
||||
import pamScrollSystem.ViewLoadObserver;
|
||||
import wavFiles.ByteConverter;
|
||||
|
||||
|
||||
/**
|
||||
* Opens a Flac compressed audio files.
|
||||
*
|
||||
* @author Jamie Macaulay, Doug Gillespie
|
||||
*
|
||||
*/
|
||||
public class FlacAudioFile implements PamAudioFileLoader {
|
||||
|
||||
|
||||
/**
|
||||
* Get the file extensions associated with loading these data.
|
||||
*/
|
||||
private ArrayList<String> fileExtensions;
|
||||
|
||||
public FlacAudioFile() {
|
||||
fileExtensions = new ArrayList<String>(Arrays.asList(new String[]{".flac"}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayList<String> getFileExtensions() {
|
||||
return fileExtensions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "FLAC";
|
||||
}
|
||||
|
||||
@Override
|
||||
public AudioInputStream getAudioStream(File soundFile) {
|
||||
if (soundFile != null && isFlacFile(soundFile)) {
|
||||
try {
|
||||
return new FlacAudioFileReader().getAudioInputStream(soundFile);
|
||||
}
|
||||
catch (UnsupportedAudioFileException | IOException e) {
|
||||
System.err.println("Could not open flac file: " + soundFile.getName());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadAudioData(OfflineFileServer offlineFileServer, PamDataBlock dataBlock, OfflineDataLoadInfo offlineDataLoadInfo,
|
||||
ViewLoadObserver loadObserver) {
|
||||
// System.out.println(String.format("Load flac data from "));
|
||||
/*
|
||||
* Only seem able to read whole flac files - so read the whole file
|
||||
* and just output samples of interest to data units. A bit crude,
|
||||
* but will probably not be too slow.
|
||||
*/
|
||||
OfflineDataMap<FileDataMapPoint> dataMap = offlineFileServer.getDataMap();
|
||||
Iterator<FileDataMapPoint> mapIt = dataMap.getListIterator();
|
||||
FileDataMapPoint mapPoint;
|
||||
File soundFile;
|
||||
mapPoint = offlineFileServer.findFirstMapPoint(mapIt, offlineDataLoadInfo.getStartMillis(), offlineDataLoadInfo.getEndMillis());
|
||||
if (mapPoint == null) {
|
||||
return false;
|
||||
}
|
||||
while (mapPoint != null) {
|
||||
|
||||
// AudioInputStream inputStream;
|
||||
// try {
|
||||
// inputStream = new FlacAudioFileReader().getAudioInputStream(mapPoint.getSoundFile());
|
||||
// } catch (UnsupportedAudioFileException | IOException e1) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e1.printStackTrace();
|
||||
// }
|
||||
FileInputStream fileStream;
|
||||
try {
|
||||
fileStream = new FileInputStream(mapPoint.getSoundFile());
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
FLACDecoder flacDecoder = new FLACDecoder(fileStream);
|
||||
// Metadata metaData[] = null;
|
||||
// try {
|
||||
// metaData = flacDecoder.readMetadata();
|
||||
// } catch (IOException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
flacDecoder.addPCMProcessor(new FlacPCM(mapPoint, dataBlock, fileStream,
|
||||
offlineDataLoadInfo, loadObserver));
|
||||
// StreamInfo streamInfo = flacDecoder.getStreamInfo(); // returns null !
|
||||
try {
|
||||
flacDecoder.decode();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
if (mapIt.hasNext() == false) {
|
||||
break;
|
||||
}
|
||||
mapPoint = mapIt.next();
|
||||
if (mapPoint.getStartTime() > offlineDataLoadInfo.getEndMillis()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only seem to be able to
|
||||
* @author doug
|
||||
*
|
||||
*/
|
||||
private class FlacPCM implements PCMProcessor {
|
||||
|
||||
private FileInputStream fileStream;
|
||||
private int frameSize;
|
||||
private long fileSamples;
|
||||
private int nChannels;
|
||||
private FileDataMapPoint mapPoint;
|
||||
private int totalSamples;
|
||||
private int sampleRate;
|
||||
private ViewLoadObserver loadObserver;
|
||||
private PamRawDataBlock dataBlock;
|
||||
private OfflineDataLoadInfo offlineDataLoadInfo;
|
||||
|
||||
|
||||
long ms=-1;
|
||||
private ByteConverter byteConverter;
|
||||
|
||||
public FlacPCM(FileDataMapPoint mapPoint, PamDataBlock dataBlock, FileInputStream fileStream, OfflineDataLoadInfo offlineDataLoadInfo, ViewLoadObserver loadObserver) {
|
||||
this.mapPoint = mapPoint;
|
||||
this.dataBlock = (PamRawDataBlock) dataBlock;
|
||||
this.fileStream = fileStream;
|
||||
this.loadObserver = loadObserver;
|
||||
this.offlineDataLoadInfo=offlineDataLoadInfo;
|
||||
// System.out.printf("New FLAC decoder %s working from %s to %s\n", offlineDataLoadInfo.toString(),
|
||||
// PamCalendar.formatDBDateTime(offlineDataLoadInfo.getStartMillis()),
|
||||
// PamCalendar.formatDBDateTime(offlineDataLoadInfo.getEndMillis()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processPCM(ByteData byteData) {
|
||||
if (offlineDataLoadInfo.cancel) {
|
||||
|
||||
try {
|
||||
fileStream.close();
|
||||
ms = Math.max(offlineDataLoadInfo.getStartMillis(), ms);
|
||||
offlineDataLoadInfo.setLastLoadInfo(new AquisitionLoadPoint(ms, -1));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
ms = mapPoint.getStartTime() + (long)totalSamples * 1000L / (long)sampleRate;
|
||||
// System.out.println(String.format("PCM data at %s samps %d (load %s - %s)", PamCalendar.formatTime2(ms, 3), totalSamples,
|
||||
// PamCalendar.formatTime2(dataStart, 3), PamCalendar.formatTime2(dataEnd, 3)));
|
||||
if (ms > offlineDataLoadInfo.getEndMillis()) {
|
||||
try {
|
||||
fileStream.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return;
|
||||
}
|
||||
int newSamples = byteData.getLen() / frameSize;
|
||||
if (ms >= offlineDataLoadInfo.getStartMillis()) {
|
||||
double[][] doubleData = new double[nChannels][newSamples];
|
||||
byteConverter.bytesToDouble(byteData.getData(), doubleData, byteData.getLen());
|
||||
RawDataUnit newDataUnit = null;
|
||||
for (int ichan = 0; ichan < nChannels; ichan++) {
|
||||
|
||||
newDataUnit = new RawDataUnit(ms, 1 << ichan, totalSamples, newSamples);
|
||||
newDataUnit.setRawData(doubleData[ichan]);
|
||||
|
||||
dataBlock.addPamData(newDataUnit);
|
||||
|
||||
// GetOutputDataBlock().addPamData(pamDataUnit);
|
||||
}
|
||||
}
|
||||
// System.out.println(String.format("new samps %d at %s", newSamples, PamCalendar.formatTime(ms, 3)));
|
||||
|
||||
totalSamples += newSamples;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processStreamInfo(StreamInfo streamInfo) {
|
||||
frameSize = streamInfo.getChannels() * streamInfo.getBitsPerSample() / 8;
|
||||
byteConverter = ByteConverter.createByteConverter(streamInfo.getBitsPerSample() / 8, false, Encoding.PCM_SIGNED);
|
||||
fileSamples = streamInfo.getTotalSamples();
|
||||
nChannels = streamInfo.getChannels();
|
||||
sampleRate = streamInfo.getSampleRate();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static boolean isFlacFile(File file) {
|
||||
String name = file.getName();
|
||||
if (name.length() < 5) {
|
||||
return false;
|
||||
}
|
||||
String end = name.substring(name.length()-5).toLowerCase();
|
||||
return (end.equals(".flac"));
|
||||
}
|
||||
|
||||
}
|
52
src/Acquisition/pamAudio/PamAudioFile.java
Normal file
52
src/Acquisition/pamAudio/PamAudioFile.java
Normal file
@ -0,0 +1,52 @@
|
||||
package Acquisition.pamAudio;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.sound.sampled.AudioInputStream;
|
||||
|
||||
import PamguardMVC.PamDataBlock;
|
||||
import PamguardMVC.dataOffline.OfflineDataLoadInfo;
|
||||
import dataMap.filemaps.OfflineFileServer;
|
||||
import pamScrollSystem.ViewLoadObserver;
|
||||
|
||||
/**
|
||||
* Interface for PAMGuard opening a sound file.
|
||||
*
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
public interface PamAudioFile {
|
||||
|
||||
/**
|
||||
* Get file extensions associated with the file type
|
||||
* @return a list of the file extensions (e.g.".wav")
|
||||
*/
|
||||
public ArrayList<String> getFileExtensions();
|
||||
|
||||
|
||||
/**
|
||||
* Get the name of the file.
|
||||
* @return the name of the file
|
||||
*/
|
||||
public String getName();
|
||||
|
||||
|
||||
/**
|
||||
* Get the audio stream for the file
|
||||
* @return the audio input stream.
|
||||
*/
|
||||
public AudioInputStream getAudioStream(File soundFile);
|
||||
|
||||
/**
|
||||
* Load a section of audio data.
|
||||
* @param dataBlock - the data block.
|
||||
* @param offlineFileServer - the offline file server.
|
||||
* @param offlineDataLoadInfo - the offline data load info.
|
||||
* @return true if the file has been loaded
|
||||
*/
|
||||
boolean loadAudioData(OfflineFileServer offlineFileServer, PamDataBlock dataBlock,
|
||||
OfflineDataLoadInfo offlineDataLoadInfo, ViewLoadObserver loadObserver);
|
||||
|
||||
|
||||
}
|
87
src/Acquisition/pamAudio/PamAudioFileFilter.java
Normal file
87
src/Acquisition/pamAudio/PamAudioFileFilter.java
Normal file
@ -0,0 +1,87 @@
|
||||
package Acquisition.pamAudio;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
|
||||
import PamUtils.PamFileFilter;
|
||||
|
||||
/**
|
||||
* The file filter for audio files compatible with PAMGuard.
|
||||
* <p>
|
||||
* All file extensions from all PamAudioFileLoaders in PamAudioManager are
|
||||
* accepted by the file filter. The file filter will aslo discard compressed
|
||||
* audio files if there exists a raw audio file of the same name.
|
||||
*
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
public class PamAudioFileFilter extends PamFileFilter {
|
||||
|
||||
private PamAudioFileManager pamAudioFileManager;
|
||||
|
||||
public PamAudioFileFilter(PamAudioFileManager pamAudioFileManager) {
|
||||
|
||||
/**
|
||||
* PamfileFilter converts everything to lower case, so no need to have upper and lower versions of
|
||||
* each ending.
|
||||
*/
|
||||
super("Audio Files", ".wav");
|
||||
|
||||
this.pamAudioFileManager = pamAudioFileManager;
|
||||
|
||||
//add all the file types.
|
||||
for (int i=0; i<pamAudioFileManager.getAudioFileLoaders().size(); i++) {
|
||||
for (int j=0; j<pamAudioFileManager.getAudioFileLoaders().get(i).getFileExtensions().size(); j++) {
|
||||
if (!pamAudioFileManager.getAudioFileLoaders().get(i).getFileExtensions().get(j).equals(".wav")){
|
||||
// already added .wav but add all other file extensions.
|
||||
addFileType(pamAudioFileManager.getAudioFileLoaders().get(i).getFileExtensions().get(j));
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public PamAudioFileFilter() {
|
||||
this(PamAudioFileManager.getInstance());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(File f) {
|
||||
//System.out.println("Accept?: " + super.accept(f) + " " + f.getName() );
|
||||
if (super.accept(f)) {
|
||||
//need to do an extra check here. Is there a .wav file or other raw wav file
|
||||
//that has the same name as another file type? If so we do not want both a compressed
|
||||
//and uncompressed file to be read - instead ignore the compressed file and only accept
|
||||
//the wav file.
|
||||
|
||||
if (pamAudioFileManager.isExtension(f, pamAudioFileManager.getRawFileLoader()) || f.isDirectory()) {
|
||||
//if a raw file then all OK.
|
||||
//System.out.println("Accepted file 1: " + f.getName());
|
||||
return true;
|
||||
}
|
||||
|
||||
String blankFileName = FilenameUtils.removeExtension(f.getAbsolutePath());
|
||||
//System.out.println("Blank file 1: " + blankFileName);
|
||||
|
||||
|
||||
File rawfile;
|
||||
for (int i=0; i<pamAudioFileManager.getRawFileLoader().getFileExtensions().size(); i++) {
|
||||
rawfile = new File(blankFileName + pamAudioFileManager.getRawFileLoader().getFileExtensions().get(i));
|
||||
//System.out.println("Raw file 1: " + blankFileName);
|
||||
|
||||
if (rawfile.exists()) {
|
||||
//the raw file will have been picked up by the file filter already or subsequently. So do not
|
||||
//use the other file.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//System.out.println("Accepted file 2: " + f.getName());
|
||||
return true;
|
||||
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
52
src/Acquisition/pamAudio/PamAudioFileLoader.java
Normal file
52
src/Acquisition/pamAudio/PamAudioFileLoader.java
Normal file
@ -0,0 +1,52 @@
|
||||
package Acquisition.pamAudio;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.sound.sampled.AudioInputStream;
|
||||
|
||||
import PamguardMVC.PamDataBlock;
|
||||
import PamguardMVC.dataOffline.OfflineDataLoadInfo;
|
||||
import dataMap.filemaps.OfflineFileServer;
|
||||
import pamScrollSystem.ViewLoadObserver;
|
||||
|
||||
/**
|
||||
* Interface for PAMGuard opening a sound file.
|
||||
*
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
public interface PamAudioFileLoader {
|
||||
|
||||
/**
|
||||
* Get file extensions associated with the file type
|
||||
* @return a list of the file extensions (e.g.".wav")
|
||||
*/
|
||||
public ArrayList<String> getFileExtensions();
|
||||
|
||||
|
||||
/**
|
||||
* Get the name of the file.
|
||||
* @return the name of the file
|
||||
*/
|
||||
public String getName();
|
||||
|
||||
|
||||
/**
|
||||
* Get the audio stream for the file
|
||||
* @return the audio input stream.
|
||||
*/
|
||||
public AudioInputStream getAudioStream(File soundFile);
|
||||
|
||||
/**
|
||||
* Load a section of audio data.
|
||||
* @param dataBlock - the data block.
|
||||
* @param offlineFileServer - the offline file server.
|
||||
* @param offlineDataLoadInfo - the offline data load info.
|
||||
* @return true if the file has been loaded
|
||||
*/
|
||||
public boolean loadAudioData(OfflineFileServer offlineFileServer, PamDataBlock dataBlock,
|
||||
OfflineDataLoadInfo offlineDataLoadInfo, ViewLoadObserver loadObserver);
|
||||
|
||||
|
||||
}
|
173
src/Acquisition/pamAudio/PamAudioFileManager.java
Normal file
173
src/Acquisition/pamAudio/PamAudioFileManager.java
Normal file
@ -0,0 +1,173 @@
|
||||
package Acquisition.pamAudio;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.sound.sampled.AudioInputStream;
|
||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
||||
|
||||
import org.codehaus.plexus.util.FileUtils;
|
||||
|
||||
/**
|
||||
* Central class for opening sound files.
|
||||
* <p>
|
||||
* PamAudioFieManager holds a list of PamAudioFile classes. Each PamAudioFile
|
||||
* can open a certain type of sound file e.g. flac or raw wav files.
|
||||
* PamAudioFieManager provides fucntions around the list to open files, provide
|
||||
* file filters etc.
|
||||
*
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
public class PamAudioFileManager {
|
||||
|
||||
/**
|
||||
* Instance of the PamAudioFieManager.
|
||||
*/
|
||||
private static PamAudioFileManager pamAudioFileManager;
|
||||
|
||||
/**
|
||||
* The pam audio file types.
|
||||
*/
|
||||
private ArrayList<PamAudioFileLoader> pamAudioFileTypes;
|
||||
|
||||
/**
|
||||
* The default file loader for raw files. A reference to this is kept so that
|
||||
* file loaders can preferentially select raw files over compressed file if they
|
||||
* have the same name e.g. if using a folder of uncompressed SoundTrap data that
|
||||
* contains both .sud and .wav files then only .wav files should be read.
|
||||
*/
|
||||
private WavAudioFile rawFileLoader;
|
||||
|
||||
public PamAudioFileManager() {
|
||||
pamAudioFileTypes = new ArrayList<PamAudioFileLoader>();
|
||||
|
||||
/***** Add new audio file types here *****/
|
||||
pamAudioFileTypes.add(rawFileLoader = new WavAudioFile());
|
||||
pamAudioFileTypes.add(new FlacAudioFile());
|
||||
pamAudioFileTypes.add(new SudAudioFile());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the audio file loader for a file.
|
||||
*
|
||||
* @param soundFile - the sound file
|
||||
* @return the audio file loader.
|
||||
*/
|
||||
public PamAudioFileLoader getAudioLoader(File soundFile) {
|
||||
for (int i = 0; i < pamAudioFileTypes.size(); i++) {
|
||||
if (isExtension(soundFile, pamAudioFileTypes.get(i))) {
|
||||
return pamAudioFileTypes.get(i);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a file has an extension supported by a PamAudioFile.
|
||||
*
|
||||
* @param file
|
||||
* @param pamAudioFile
|
||||
*/
|
||||
public boolean isExtension(File file, PamAudioFileLoader pamAudioFile) {
|
||||
for (int i = 0; i < pamAudioFile.getFileExtensions().size(); i++) {
|
||||
if (isSoundFile(file, pamAudioFile.getFileExtensions().get(i))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isSoundFile(File soundFile, String soundExtension) {
|
||||
String extension = FileUtils.getExtension(soundFile.getName());
|
||||
|
||||
//System.out.println("Sound Extension: " + soundExtension + " File extension: " + extension);
|
||||
return (soundExtension.equals(extension) || soundExtension.equals("." + extension));
|
||||
}
|
||||
|
||||
/**
|
||||
* Open an audio input stream. If the file is a Wav file, then it will attempt
|
||||
* to read the file with PAMGuards bespoke audio stream reader. This includes
|
||||
* support for wav files which are > 2GByte in size and also works for floating
|
||||
* point 32 bit files (which the Java one doesn't). If that fails, or if its not
|
||||
* a wav file, then the standard java AudioInputStream is used.
|
||||
*
|
||||
* @param file file to open
|
||||
* @return a new audio input stream
|
||||
* @throws UnsupportedAudioFileException thrown if it can't understand the audio
|
||||
* format.
|
||||
* @throws IOException
|
||||
*/
|
||||
public AudioInputStream getAudioInputStream(File file) throws UnsupportedAudioFileException, IOException {
|
||||
// if (file != null && isWavFile(file) && file.length() > largeFileSize) {
|
||||
if (file.exists() == false) {
|
||||
System.err.println("PamAudioFileManager: the input file was null");
|
||||
return null;
|
||||
}
|
||||
|
||||
AudioInputStream stream = null;
|
||||
for (int i = 0; i < pamAudioFileTypes.size(); i++) {
|
||||
System.out.println(file.getName() + " " + pamAudioFileTypes.get(i).getName());
|
||||
if (isExtension(file, pamAudioFileTypes.get(i))) {
|
||||
//System.out.println("Get stream for: " +pamAudioFileTypes.get(i).getName());
|
||||
stream = pamAudioFileTypes.get(i).getAudioStream(file);
|
||||
if (pamAudioFileTypes != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (stream == null) {
|
||||
// have a punt at opening as a default audiostream
|
||||
//System.out.println("Try default stream for: " +file.getName() );
|
||||
|
||||
stream = new WavAudioFile().getAudioStream(file);
|
||||
}
|
||||
|
||||
if (stream == null) {
|
||||
System.err.println("PamAudioFileManager: unable to open an AudioStream for " + file.getName());
|
||||
}
|
||||
|
||||
return stream;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the instance of the PamAudioManager
|
||||
*/
|
||||
public static PamAudioFileManager getInstance() {
|
||||
if (pamAudioFileManager == null) {
|
||||
pamAudioFileManager = new PamAudioFileManager();
|
||||
}
|
||||
return pamAudioFileManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the audio file filter
|
||||
*
|
||||
* @return the audio file filter.
|
||||
*/
|
||||
public PamAudioFileFilter getAudioFileFilter() {
|
||||
return new PamAudioFileFilter(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current audio file
|
||||
*
|
||||
* @return a list oif the current audio loaders.
|
||||
*/
|
||||
public ArrayList<PamAudioFileLoader> getAudioFileLoaders() {
|
||||
return this.pamAudioFileTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default file loader for raw files.
|
||||
* @return the default file loader for raw files.
|
||||
*/
|
||||
public WavAudioFile getRawFileLoader() {
|
||||
return rawFileLoader;
|
||||
}
|
||||
|
||||
}
|
@ -10,7 +10,13 @@ import javax.sound.sampled.UnsupportedAudioFileException;
|
||||
//import org.kc7bfi.jflac.sound.spi.FlacAudioFileReader;
|
||||
import org.jflac.sound.spi.FlacAudioFileReader;
|
||||
|
||||
|
||||
/**
|
||||
* Now replaced with PamAudioFileManager.
|
||||
*
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
@Deprecated
|
||||
public class PamAudioSystem {
|
||||
|
||||
private static final long largeFileSize = 01L<<31;
|
||||
@ -42,7 +48,7 @@ public class PamAudioSystem {
|
||||
return new FlacAudioFileReader().getAudioInputStream(file);
|
||||
}
|
||||
catch (UnsupportedAudioFileException e) {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
else if (file != null && isSudFile(file)) {
|
||||
@ -50,14 +56,15 @@ public class PamAudioSystem {
|
||||
return new SudAudioFileReader().getAudioInputStream(file);
|
||||
}
|
||||
catch (UnsupportedAudioFileException e) {
|
||||
|
||||
//e.printStackTrace();
|
||||
}
|
||||
}
|
||||
try {
|
||||
return AudioSystem.getAudioInputStream(file);
|
||||
return AudioSystem.getAudioInputStream(file);
|
||||
}
|
||||
catch (Exception e) {
|
||||
System.out.println("Error in audio file " + file.getName() + ": " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -93,10 +100,10 @@ public class PamAudioSystem {
|
||||
*/
|
||||
private static boolean isSudFile(File file) {
|
||||
String name = file.getName();
|
||||
if (name.length() < 5) {
|
||||
if (name.length() < 4) {
|
||||
return false;
|
||||
}
|
||||
String end = name.substring(name.length()-5).toLowerCase();
|
||||
String end = name.substring(name.length()-4).toLowerCase();
|
||||
return (end.equals(".sud"));
|
||||
}
|
||||
|
||||
|
63
src/Acquisition/pamAudio/SudAudioFile.java
Normal file
63
src/Acquisition/pamAudio/SudAudioFile.java
Normal file
@ -0,0 +1,63 @@
|
||||
package Acquisition.pamAudio;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.sound.sampled.AudioInputStream;
|
||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
||||
|
||||
/**
|
||||
* Opens a .sud audio file.
|
||||
* <p>
|
||||
* Sud files contain X3 compressed audio data. The sud
|
||||
* file reader opens files, creating a map of the file and saving
|
||||
* the map as a.sudx file so it can be read more rapidly when the file
|
||||
* is next accessed.
|
||||
* <p>
|
||||
* The SudioAudioInput stream fully implements AudioInputStream and so
|
||||
* sud files can be accessed using much of the same code as .wav files.
|
||||
*
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
public class SudAudioFile extends WavAudioFile {
|
||||
|
||||
|
||||
public SudAudioFile() {
|
||||
super();
|
||||
fileExtensions = new ArrayList<String>(Arrays.asList(new String[]{".sud"}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "SUD";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AudioInputStream getAudioStream(File soundFile) {
|
||||
if (soundFile.exists() == false) {
|
||||
System.err.println("The sud file does not exist: " + soundFile);
|
||||
return null;
|
||||
}
|
||||
if (soundFile != null) {
|
||||
try {
|
||||
return new SudAudioFileReader().getAudioInputStream(soundFile);
|
||||
}
|
||||
// don't do anything and it will try the built in Audiosystem
|
||||
catch (UnsupportedAudioFileException e) {
|
||||
System.err.println("Could not open sud file: not a supported file " + soundFile.getName());
|
||||
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
System.err.println("Could not open sud file: IO Exception: " + soundFile.getName());
|
||||
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -2,6 +2,7 @@ package Acquisition.pamAudio;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import org.pamguard.x3.sud.*;
|
||||
|
||||
import javax.sound.sampled.AudioInputStream;
|
||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
||||
@ -13,11 +14,41 @@ import javax.sound.sampled.UnsupportedAudioFileException;
|
||||
*
|
||||
*/
|
||||
public class SudAudioFileReader {
|
||||
|
||||
|
||||
/**
|
||||
* The current sud audio input stream
|
||||
*/
|
||||
SudAudioInputStream sudAudioInputStream;
|
||||
|
||||
/**
|
||||
* Parameters for opening .sud files.
|
||||
*/
|
||||
SudParams sudParams;
|
||||
|
||||
|
||||
public SudAudioFileReader() {
|
||||
sudParams = new SudParams();
|
||||
//set up the sud params for default. i.e. just read files and
|
||||
//don't save any decompressed or meta data.
|
||||
sudParams.saveWav = false;
|
||||
sudParams.saveMeta = false;
|
||||
sudParams.zeroPad = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the audio input streamn.
|
||||
* @param file - the .sud file to open.
|
||||
* @return the sud AudioStream.
|
||||
* @throws UnsupportedAudioFileException
|
||||
* @throws IOException
|
||||
*/
|
||||
public AudioInputStream getAudioInputStream(File file) throws UnsupportedAudioFileException, IOException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
try {
|
||||
sudAudioInputStream = SudAudioInputStream.openInputStream(file, sudParams, false);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return sudAudioInputStream;
|
||||
}
|
||||
|
||||
}
|
||||
|
250
src/Acquisition/pamAudio/WavAudioFile.java
Normal file
250
src/Acquisition/pamAudio/WavAudioFile.java
Normal file
@ -0,0 +1,250 @@
|
||||
package Acquisition.pamAudio;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
|
||||
import javax.sound.sampled.AudioFormat;
|
||||
import javax.sound.sampled.AudioInputStream;
|
||||
import javax.sound.sampled.AudioSystem;
|
||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
||||
|
||||
import org.codehaus.plexus.util.FileUtils;
|
||||
import Acquisition.offlineFuncs.AquisitionLoadPoint;
|
||||
import PamDetection.RawDataUnit;
|
||||
import PamguardMVC.PamDataBlock;
|
||||
import PamguardMVC.dataOffline.OfflineDataLoadInfo;
|
||||
import dataMap.OfflineDataMap;
|
||||
import dataMap.filemaps.FileDataMapPoint;
|
||||
import dataMap.filemaps.OfflineFileServer;
|
||||
import pamScrollSystem.ViewLoadObserver;
|
||||
import wavFiles.ByteConverter;
|
||||
|
||||
/**
|
||||
* Wav audio file - opens any raw audio file.
|
||||
* <p>
|
||||
* This should be used a standard class for opening audio files
|
||||
*
|
||||
* @author Jamie Macaulay, Doug Gillepsie
|
||||
*
|
||||
*/
|
||||
public class WavAudioFile implements PamAudioFileLoader {
|
||||
|
||||
/**
|
||||
* The audio input stream of the last loaded file.
|
||||
*/
|
||||
private AudioInputStream audioInputStream;
|
||||
|
||||
/**
|
||||
* The audioformat of the last laoded file.
|
||||
*/
|
||||
private AudioFormat audioFormat;
|
||||
|
||||
/**
|
||||
* Get the file extensions associated with loading these data.
|
||||
*/
|
||||
protected ArrayList<String> fileExtensions;
|
||||
|
||||
public WavAudioFile() {
|
||||
fileExtensions = new ArrayList<String>(Arrays.asList(new String[]{".wav", ".aif", ".aiff"}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayList<String> getFileExtensions() {
|
||||
return fileExtensions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "WAV";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadAudioData(OfflineFileServer offlineFileServer, PamDataBlock dataBlock, OfflineDataLoadInfo offlineDataLoadInfo, ViewLoadObserver loadObserver) {
|
||||
|
||||
// Debug.out.println("OfflineFileServer: Load Wav Data: " + offlineDataLoadInfo.getCurrentObserver().getObserverName() );
|
||||
OfflineDataMap<FileDataMapPoint> dataMap = offlineFileServer.getDataMap();
|
||||
Iterator<FileDataMapPoint> mapIt = dataMap.getListIterator();
|
||||
FileDataMapPoint mapPoint = offlineFileServer.findFirstMapPoint(mapIt, offlineDataLoadInfo.getStartMillis(), offlineDataLoadInfo.getEndMillis());
|
||||
|
||||
if (openSoundFile(mapPoint.getSoundFile()) == false) {
|
||||
System.out.println("Could not open .wav sound file " + mapPoint.getSoundFile().getAbsolutePath());
|
||||
return false;
|
||||
}
|
||||
File soundFile;
|
||||
|
||||
ByteConverter byteConverter = ByteConverter.createByteConverter(audioFormat);
|
||||
long currentTime = mapPoint.getStartTime();
|
||||
long prevFileEnd = mapPoint.getEndTime();
|
||||
boolean fileGap = false;
|
||||
int newSamples;
|
||||
double[][] doubleData;
|
||||
int nChannels = audioFormat.getChannels();
|
||||
int blockSamples = Math.max((int) audioFormat.getSampleRate() / 10, 1000);
|
||||
int frameSize = audioFormat.getFrameSize();
|
||||
if (frameSize < 0) {
|
||||
frameSize = audioFormat.getChannels()*audioFormat.getSampleSizeInBits()/8;
|
||||
}
|
||||
if (frameSize <= 0) {
|
||||
System.out.println("The frame size is less than zero " + mapPoint.getSoundFile().getAbsolutePath());
|
||||
return false;
|
||||
}
|
||||
byte[] inputBuffer = new byte[blockSamples * frameSize];
|
||||
int bytesRead = 0;
|
||||
long totalSamples = 0;
|
||||
// long fileSamples = 0;
|
||||
long millisecondsGaps = 0;
|
||||
long ms;
|
||||
|
||||
RawDataUnit newDataUnit;
|
||||
long skipped = 0;
|
||||
if (currentTime < offlineDataLoadInfo.getStartMillis()) {
|
||||
// need to fast forward in current file.
|
||||
long skipBytes = (long) (((offlineDataLoadInfo.getStartMillis()-currentTime)*audioFormat.getSampleRate()*audioFormat.getFrameSize())/1000.);
|
||||
try {
|
||||
|
||||
//System.out.println("Skipped " + skipped+ " " + skipBytes + " " + audioInputStream.available());
|
||||
skipped = audioInputStream.skip(skipBytes);
|
||||
//System.out.println("Offline " + (offlineDataLoadInfo.getStartMillis()-currentTime) + " ms : frame size: " + audioFormat.getFrameSize());
|
||||
|
||||
} catch (IOException e) {
|
||||
/**
|
||||
* The datamap point may be longer than the actual file here ? In any case, with the
|
||||
* NEMO data which is 5 mins per hour, this get's hit for the file before the
|
||||
* file we want every time !
|
||||
*/
|
||||
// System.out.println("End of audio file " + mapPoint.getSoundFile().getName());
|
||||
e.printStackTrace();
|
||||
}
|
||||
currentTime = offlineDataLoadInfo.getStartMillis();
|
||||
}
|
||||
ms = currentTime;
|
||||
while (ms < offlineDataLoadInfo.getEndMillis() && currentTime < offlineDataLoadInfo.getEndMillis()) {
|
||||
if (offlineDataLoadInfo.cancel) {
|
||||
//add the position we got to
|
||||
offlineDataLoadInfo.setLastLoadInfo(new AquisitionLoadPoint(ms, bytesRead));
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
try {
|
||||
if (inputBuffer.length<audioInputStream.available()) {
|
||||
bytesRead = audioInputStream.read(inputBuffer);
|
||||
}
|
||||
else {
|
||||
bytesRead = 0; //force new file to load.
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (bytesRead <= 0) {
|
||||
skipped = 0 ; //reset ot zero because were not skipping anyu bytes here.
|
||||
/*
|
||||
* that's the end of that file, so get the next one if there
|
||||
* is one, if not then break.
|
||||
*/
|
||||
if (mapIt.hasNext() == false) {
|
||||
break;
|
||||
}
|
||||
mapPoint = mapIt.next();
|
||||
fileGap = (mapPoint.getStartTime() - prevFileEnd) > 1000;
|
||||
// if (fileGap) {
|
||||
// System.out.println(String.format("Sound file gap %3.3fs from %s to %s",
|
||||
// (double) (mapPoint.getStartTime()-prevFileEnd) / 1000.,
|
||||
// PamCalendar.formatTime(prevFileEnd), PamCalendar.formatTime(mapPoint.getStartTime())));
|
||||
// }
|
||||
prevFileEnd = mapPoint.getEndTime();
|
||||
if (!fileGap) { // don't carry on if there is a file gap
|
||||
if (openSoundFile(mapPoint.getSoundFile()) == false) {
|
||||
break;
|
||||
}
|
||||
// try again to read data.
|
||||
try {
|
||||
bytesRead = audioInputStream.read(inputBuffer);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (bytesRead <= 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
newSamples = bytesRead / frameSize;
|
||||
doubleData = new double[nChannels][newSamples];
|
||||
int convertedSamples = byteConverter.bytesToDouble(inputBuffer, doubleData, bytesRead);
|
||||
ms = offlineFileServer.getOfflineRawDataStore().getParentProcess().absSamplesToMilliseconds(totalSamples);
|
||||
ms = currentTime + (long)(totalSamples * 1000 / (double) audioFormat.getSampleRate());
|
||||
|
||||
for (int ichan = 0; ichan < nChannels; ichan++) {
|
||||
|
||||
newDataUnit = new RawDataUnit(ms, 1 << ichan, totalSamples, newSamples);
|
||||
newDataUnit.setFileSamples(totalSamples + skipped / frameSize); //set the number samples into the wav file.
|
||||
newDataUnit.setRawData(doubleData[ichan], true);
|
||||
|
||||
//System.out.println("New wav data: " + PamCalendar.formatDateTime(newDataUnit.getTimeMilliseconds()));
|
||||
offlineFileServer.getRawDataBlock().addPamData(newDataUnit);
|
||||
}
|
||||
if (fileGap) {
|
||||
currentTime = mapPoint.getStartTime();
|
||||
totalSamples = 0;
|
||||
// fileSamples = 0;
|
||||
}
|
||||
|
||||
totalSamples += newSamples;
|
||||
// fileSamples += newSamples;
|
||||
}
|
||||
|
||||
// System.out.println("Finished loading wav: " + offlineDataLoadInfo.getCurrentObserver().getObserverName() );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Open a sound file.
|
||||
* @param soundFile
|
||||
* @return
|
||||
*/
|
||||
private boolean openSoundFile(File soundFile) {
|
||||
|
||||
audioInputStream = getAudioStream(soundFile);
|
||||
if (audioInputStream == null) return false;
|
||||
audioFormat = audioInputStream.getFormat();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AudioInputStream getAudioStream(File soundFile) {
|
||||
if (soundFile.exists() == false) return null;
|
||||
if (soundFile != null && isSoundFile(soundFile)) {
|
||||
try {
|
||||
return WavFileInputStream.openInputStream(soundFile);
|
||||
}
|
||||
catch (UnsupportedAudioFileException | IOException e) {
|
||||
e.printStackTrace();
|
||||
// don't do anything and it will try the built in Audiosystem
|
||||
System.err.println("Could not open wav file: trying default audio stream: " + soundFile.getName());
|
||||
}
|
||||
}
|
||||
try {
|
||||
return AudioSystem.getAudioInputStream(soundFile);
|
||||
}
|
||||
catch (Exception e) {
|
||||
System.out.println("Error in audio file " + soundFile.getName() + ": " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean isSoundFile(File soundFile) {
|
||||
String extension = FileUtils.getExtension(soundFile.getName());
|
||||
return (extension.equals(".wav"));
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -33,8 +33,8 @@ import javax.swing.JFileChooser;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import Acquisition.pamAudio.PamAudioFileFilter;
|
||||
import PamDetection.RawDataUnit;
|
||||
import PamUtils.PamAudioFileFilter;
|
||||
import PamUtils.PamFileChooser;
|
||||
|
||||
|
||||
|
@ -0,0 +1,221 @@
|
||||
package Localiser.algorithms.timeDelayLocalisers.bearingLoc;
|
||||
|
||||
|
||||
import Localiser.DelayMeasurementParams;
|
||||
import PamController.SettingsPane;
|
||||
import fftFilter.FFTFilterParams;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.control.Tooltip;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.scene.layout.Pane;
|
||||
import pamViewFX.fxNodes.PamButton;
|
||||
import pamViewFX.fxNodes.PamGridPane;
|
||||
import pamViewFX.fxNodes.PamSpinner;
|
||||
import pamViewFX.fxNodes.pamDialogFX.PamDialogFX;
|
||||
import pamViewFX.fxNodes.utilityPanes.SimpleFilterPaneFX;
|
||||
|
||||
public class DelayOptionsPaneFX extends SettingsPane<DelayMeasurementParams> {
|
||||
|
||||
|
||||
private CheckBox filterBearings, envelopeBearings, useLeadingEdge, upSample;
|
||||
private PamButton filterSettings;
|
||||
private Label filterDescription;
|
||||
|
||||
/**
|
||||
* The current delay measurement parameters.
|
||||
*/
|
||||
private DelayMeasurementParams delayMeasurementParams;
|
||||
|
||||
|
||||
/**
|
||||
* Check box for restricting samples.
|
||||
*/
|
||||
private CheckBox restrictSamples;
|
||||
|
||||
/**
|
||||
* Restrict the number of samples.
|
||||
*/
|
||||
private TextField restrictSamplesField;
|
||||
|
||||
private PamSpinner<Integer> upSampleSpinner;
|
||||
|
||||
|
||||
private SimpleFilterPaneFX simpleFilterPane = new SimpleFilterPaneFX();
|
||||
|
||||
public DelayOptionsPaneFX() {
|
||||
super(null);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
|
||||
public Pane createDelayOptionsPane() {
|
||||
int gridy=0;
|
||||
|
||||
PamGridPane mainPanel = new PamGridPane();
|
||||
// mainPanel.setBorder(new TitledBorder("Delay measurement options"));
|
||||
mainPanel.add(filterBearings = new CheckBox("Filter data before measurement"), 0,gridy);
|
||||
PamGridPane.setColumnSpan(filterBearings, 2);
|
||||
filterBearings.setOnAction((action)->{
|
||||
enableControls();
|
||||
});
|
||||
gridy++;
|
||||
|
||||
mainPanel.add(filterSettings = new PamButton("Settings"), 0,gridy);
|
||||
filterSettings.setOnAction((action)->{
|
||||
FFTFilterParams newParams = simpleFilterPane.getParams(delayMeasurementParams.delayFilterParams);
|
||||
if (newParams != null) {
|
||||
delayMeasurementParams.delayFilterParams = newParams.clone();
|
||||
describeFilter();
|
||||
}
|
||||
});
|
||||
gridy++;
|
||||
|
||||
mainPanel.add(filterDescription = new Label(" "), 0,gridy);
|
||||
gridy++;
|
||||
mainPanel.add(upSample = new CheckBox("Up sample data x2"), 0,gridy);
|
||||
upSample.setTooltip(new Tooltip("Up sampling data to a higher frequency can improve timing accuracy for narrow band clicks (i.e. harbour porpoise)"));
|
||||
gridy++;
|
||||
|
||||
|
||||
//SpinnerListModel spinnerModel = new SpinnerListModel(Arrays.asList(new Integer[] {2,3,4})); //restrict the spinenr options.
|
||||
|
||||
mainPanel.add(upSampleSpinner = new PamSpinner<Integer>(2,4,2,1), 0,gridy);
|
||||
upSampleSpinner.valueProperty().addListener((obsval, oldVa, newVal)->{
|
||||
upSample.setText("Up sample data x" + this.upSampleSpinner.getValue());
|
||||
});
|
||||
gridy++;
|
||||
|
||||
mainPanel.add(envelopeBearings = new CheckBox("Use waveform envelope"), 0, gridy);
|
||||
gridy++;
|
||||
|
||||
|
||||
mainPanel.add(new Label(" "), 0, gridy);
|
||||
gridy++;
|
||||
|
||||
mainPanel.add(new Label(" "), 0, gridy);
|
||||
gridy++;
|
||||
|
||||
|
||||
mainPanel.add(useLeadingEdge = new CheckBox("Use envelope leading edge only"), 0, gridy);
|
||||
gridy++;
|
||||
PamGridPane.setColumnSpan(useLeadingEdge, 2);
|
||||
envelopeBearings.setOnAction((action)->{
|
||||
enableControls();
|
||||
});
|
||||
envelopeBearings.setOnAction((action)->{
|
||||
enableControls();
|
||||
});
|
||||
PamGridPane.setColumnSpan(envelopeBearings, 2);
|
||||
|
||||
|
||||
//restrict
|
||||
mainPanel.add(restrictSamples = new CheckBox("Restrict length"), 0, gridy);
|
||||
gridy++;
|
||||
PamGridPane.setColumnSpan(restrictSamples, 2);
|
||||
restrictSamples.setOnAction((action)->{
|
||||
enableControls();
|
||||
});
|
||||
mainPanel.add(restrictSamplesField = new TextField(), 2, gridy);
|
||||
|
||||
|
||||
restrictSamples.setTooltip(new Tooltip("In environments where echoes are an issue restricting inital samples of detections "
|
||||
+ "(e.g. click snippets) is a simple but effective way to increase the accuracy of time delay calculations. "
|
||||
+ "WARNING: Remember that this must cover the potential time delay in grouped detections "));
|
||||
filterBearings.setTooltip(new Tooltip("Filter data prior to bearing measurement to imporve accuracy"));
|
||||
filterSettings.setTooltip(new Tooltip("Setup filter options"));
|
||||
envelopeBearings.setTooltip(new Tooltip("Using the envelope can provide more accurate bearings for some narrowband pulses"));
|
||||
filterDescription.setTooltip(new Tooltip("Current filter settings"));
|
||||
useLeadingEdge.setTooltip(new Tooltip("For long pulses, or where there are echoes, restrict the calculation to the leading edge of the envelope"));
|
||||
|
||||
BorderPane pane = new BorderPane();
|
||||
pane.setCenter(mainPanel);
|
||||
|
||||
return pane;
|
||||
}
|
||||
|
||||
|
||||
private void enableControls() {
|
||||
filterSettings.setDisable(!filterBearings.isSelected());
|
||||
filterDescription.setDisable(!filterBearings.isSelected());
|
||||
useLeadingEdge.setDisable(!envelopeBearings.isSelected());
|
||||
restrictSamplesField.setDisable(!restrictSamples.isSelected());
|
||||
if (!envelopeBearings.isSelected()) {
|
||||
// useLeadingEdge.setSelected(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void describeFilter() {
|
||||
if (delayMeasurementParams == null || delayMeasurementParams.delayFilterParams == null) {
|
||||
filterDescription.setText("No filter");
|
||||
return;
|
||||
}
|
||||
filterDescription.setText(delayMeasurementParams.delayFilterParams.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParams(DelayMeasurementParams delayMeasurementParams) {
|
||||
this.delayMeasurementParams = delayMeasurementParams;
|
||||
filterBearings.setSelected(delayMeasurementParams.filterBearings);
|
||||
upSample.setSelected(delayMeasurementParams.getUpSample() > 1);
|
||||
envelopeBearings.setSelected(delayMeasurementParams.envelopeBearings);
|
||||
useLeadingEdge.setSelected(delayMeasurementParams.useLeadingEdge);
|
||||
restrictSamples.setSelected(delayMeasurementParams.useRestrictedBins);
|
||||
restrictSamplesField.setText(String.format("%d", delayMeasurementParams.restrictedBins));
|
||||
|
||||
upSample.setText("Up sample data x" + this.upSampleSpinner.getValue());
|
||||
|
||||
enableControls();
|
||||
describeFilter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DelayMeasurementParams getParams(DelayMeasurementParams delayMeasurementParams) {
|
||||
delayMeasurementParams.delayFilterParams = this.delayMeasurementParams.delayFilterParams;
|
||||
delayMeasurementParams.filterBearings = filterBearings.isSelected();
|
||||
delayMeasurementParams.setUpSample(upSample.isSelected() ? ((Integer) this.upSampleSpinner.getValue()).intValue() : 1);
|
||||
delayMeasurementParams.envelopeBearings = envelopeBearings.isSelected();
|
||||
delayMeasurementParams.useLeadingEdge = useLeadingEdge.isSelected() && delayMeasurementParams.envelopeBearings;
|
||||
|
||||
delayMeasurementParams.useRestrictedBins=this.restrictSamples.isSelected();
|
||||
|
||||
try {
|
||||
delayMeasurementParams.restrictedBins=Integer.valueOf(this.restrictSamplesField.getText());
|
||||
}
|
||||
catch(Exception e) {
|
||||
PamDialogFX.showWarning(null, "Delay measurement settings", "The entry in the samples text field is invalid.");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (delayMeasurementParams.useRestrictedBins && delayMeasurementParams.restrictedBins<10) {
|
||||
PamDialogFX.showWarning(null, "Delay measurement settings", "The entry in the samples text field is invalid. It must be >= 10");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (delayMeasurementParams.filterBearings && delayMeasurementParams.delayFilterParams == null) {
|
||||
PamDialogFX.showWarning(null, "Delay measurement settings", "Filter parameters have not been set");
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Delay Measurment Params";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node getContentNode() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paneInitialized() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -765,6 +765,7 @@ final public class PamModel implements PamModelInterface, PamSettings {
|
||||
mi.addDependency(new PamDependency(ClickDetection.class, "clickDetector.ClickControl"));
|
||||
mi.setToolTipText("Classifies clicks based on an ideal template to match and a template to reject. "
|
||||
+ "An example of this is to classify beaked whale clicks in an environment with dolphin clicks");
|
||||
mi.addGUICompatabilityFlag(PamGUIManager.FX);
|
||||
mi.setModulesMenuGroup(classifierGroup);
|
||||
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
package PamUtils;
|
||||
|
||||
import PamUtils.PamFileFilter;
|
||||
|
||||
public class PamAudioFileFilter extends PamFileFilter {
|
||||
|
||||
public PamAudioFileFilter() {
|
||||
|
@ -33,7 +33,7 @@ public class PamFileFilter extends javax.swing.filechooser.FileFilter implements
|
||||
|
||||
private String prefix = null;
|
||||
|
||||
private boolean acceptFolders = true;
|
||||
protected boolean acceptFolders = true;
|
||||
|
||||
|
||||
public PamFileFilter(String description, String defExtension) {
|
||||
|
@ -6,6 +6,7 @@ import javax.sound.sampled.AudioFileFormat;
|
||||
import javax.sound.sampled.AudioFormat;
|
||||
import javax.sound.sampled.AudioInputStream;
|
||||
|
||||
import Acquisition.pamAudio.PamAudioFileManager;
|
||||
import Acquisition.pamAudio.PamAudioSystem;
|
||||
import PamController.PamGUIManager;
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
@ -64,7 +65,7 @@ public class WavFileType extends File {
|
||||
*/
|
||||
private AudioFormat getAudioFormat(File file) {
|
||||
try {
|
||||
AudioInputStream audioStream = PamAudioSystem.getAudioInputStream(file);
|
||||
AudioInputStream audioStream = PamAudioFileManager.getInstance().getAudioInputStream(file);
|
||||
|
||||
AudioFormat audioFormat = audioStream.getFormat();
|
||||
|
||||
|
@ -2,7 +2,7 @@ package PamUtils.worker.filelist;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import PamUtils.PamAudioFileFilter;
|
||||
import Acquisition.pamAudio.PamAudioFileFilter;
|
||||
|
||||
/**
|
||||
* Worker which extracts acoustic files from a folder.
|
||||
|
@ -120,8 +120,8 @@ public class binaryUIDFunctions {
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("Error reading binary UID data from log file");
|
||||
e.printStackTrace();
|
||||
System.out.println("Error reading binary UID data from log file" + logFileData);
|
||||
// e.printStackTrace();
|
||||
}
|
||||
|
||||
// try (BufferedReader br = new BufferedReader(new FileReader(logFileData))) {
|
||||
@ -531,10 +531,12 @@ public class binaryUIDFunctions {
|
||||
out.close();
|
||||
}
|
||||
} catch (TransformerException e) {
|
||||
e.printStackTrace();
|
||||
System.err.println(e.getMessage());
|
||||
// e.printStackTrace();
|
||||
return false;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
System.err.println(e.getMessage());
|
||||
// e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
3664
src/Resources/css/nord-dark.css
Normal file
3664
src/Resources/css/nord-dark.css
Normal file
File diff suppressed because one or more lines are too long
3664
src/Resources/css/nord-light.css
Normal file
3664
src/Resources/css/nord-light.css
Normal file
File diff suppressed because one or more lines are too long
@ -561,3 +561,15 @@
|
||||
-fx-icon-color: black;
|
||||
}
|
||||
|
||||
|
||||
/********************************************
|
||||
* *
|
||||
* Spinner *
|
||||
* *
|
||||
*********************************************/
|
||||
|
||||
|
||||
.spinner {
|
||||
-fx-pref-width: 100px;
|
||||
}
|
||||
|
||||
|
@ -977,4 +977,13 @@
|
||||
-fx-icon-color: black;
|
||||
}
|
||||
|
||||
/********************************************
|
||||
* *
|
||||
* Spinner *
|
||||
* *
|
||||
*********************************************/
|
||||
|
||||
|
||||
.spinner {
|
||||
-fx-pref-width: 100px;
|
||||
}
|
||||
|
3706
src/Resources/css/primer-dark.css
Normal file
3706
src/Resources/css/primer-dark.css
Normal file
File diff suppressed because one or more lines are too long
3664
src/Resources/css/primer-light.css
Normal file
3664
src/Resources/css/primer-light.css
Normal file
File diff suppressed because one or more lines are too long
779
src/Resources/css/primer-pamguard.css
Normal file
779
src/Resources/css/primer-pamguard.css
Normal file
@ -0,0 +1,779 @@
|
||||
|
||||
|
||||
{
|
||||
-color-dark: #010409;
|
||||
-color-light: #ffffff;
|
||||
-color-base-0: #f0f6fc;
|
||||
-color-base-1: #c9d1d9;
|
||||
-color-base-2: #b1bac4;
|
||||
-color-base-3: #8b949e;
|
||||
-color-base-4: #6e7681;
|
||||
-color-base-5: #484f58;
|
||||
-color-base-6: #30363d;
|
||||
-color-base-7: #21262d;
|
||||
-color-base-8: #161b22;
|
||||
-color-base-9: #0d1117;
|
||||
-color-accent-0: #cae8ff;
|
||||
-color-accent-1: #a5d6ff;
|
||||
-color-accent-2: #79c0ff;
|
||||
-color-accent-3: #58a6ff;
|
||||
-color-accent-4: #388bfd;
|
||||
-color-accent-5: #1f6feb;
|
||||
-color-accent-6: #1158c7;
|
||||
-color-accent-7: #0d419d;
|
||||
-color-accent-8: #0c2d6b;
|
||||
-color-accent-9: #051d4d;
|
||||
-color-success-0: #aff5b4;
|
||||
-color-success-1: #7ee787;
|
||||
-color-success-2: #56d364;
|
||||
-color-success-3: #3fb950;
|
||||
-color-success-4: #2ea043;
|
||||
-color-success-5: #238636;
|
||||
-color-success-6: #196c2e;
|
||||
-color-success-7: #0f5323;
|
||||
-color-success-8: #033a16;
|
||||
-color-success-9: #04260f;
|
||||
-color-warning-0: #f8e3a1;
|
||||
-color-warning-1: #f2cc60;
|
||||
-color-warning-2: #e3b341;
|
||||
-color-warning-3: #d29922;
|
||||
-color-warning-4: #bb8009;
|
||||
-color-warning-5: #9e6a03;
|
||||
-color-warning-6: #845306;
|
||||
-color-warning-7: #693e00;
|
||||
-color-warning-8: #4b2900;
|
||||
-color-warning-9: #341a00;
|
||||
-color-danger-0: #ffdcd7;
|
||||
-color-danger-1: #ffc1ba;
|
||||
-color-danger-2: #ffa198;
|
||||
-color-danger-3: #ff7b72;
|
||||
-color-danger-4: #f85149;
|
||||
-color-danger-5: #da3633;
|
||||
-color-danger-6: #b62324;
|
||||
-color-danger-7: #8e1519;
|
||||
-color-danger-8: #67060c;
|
||||
-color-danger-9: #490202;
|
||||
-color-fg-default: #c9d1d9;
|
||||
-color-fg-muted: #8b949e;
|
||||
-color-fg-subtle: #6e7681;
|
||||
-color-fg-emphasis: #ffffff;
|
||||
-color-bg-default: #0d1117;
|
||||
-color-bg-overlay: #0d1117;
|
||||
-color-bg-subtle: #161b22;
|
||||
-color-bg-inset: #010409;
|
||||
-color-border-default: #30363d;
|
||||
-color-border-muted: #21262d;
|
||||
-color-border-subtle: rgba(240, 246, 252, 0.1);
|
||||
-color-shadow-default: #010409;
|
||||
-color-neutral-emphasis-plus: #6e7681;
|
||||
-color-neutral-emphasis: #6e7681;
|
||||
-color-neutral-muted: rgba(110, 118, 129, 0.4);
|
||||
-color-neutral-subtle: rgba(110, 118, 129, 0.1);
|
||||
-color-accent-fg: #58a6ff;
|
||||
-color-accent-emphasis: #1f6feb;
|
||||
-color-accent-muted: rgba(56, 139, 253, 0.4);
|
||||
-color-accent-subtle: rgba(56, 139, 253, 0.15);
|
||||
-color-warning-fg: #d29922;
|
||||
-color-warning-emphasis: #9e6a03;
|
||||
-color-warning-muted: rgba(187, 128, 9, 0.4);
|
||||
-color-warning-subtle: rgba(187, 128, 9, 0.15);
|
||||
-color-success-fg: #3fb950;
|
||||
-color-success-emphasis: #238636;
|
||||
-color-success-muted: rgba(46, 160, 67, 0.4);
|
||||
-color-success-subtle: rgba(46, 160, 67, 0.15);
|
||||
-color-danger-fg: #f85149;
|
||||
-color-danger-emphasis: #da3633;
|
||||
-color-danger-muted: rgba(248, 81, 73, 0.4);
|
||||
-color-danger-subtle: rgba(248, 81, 73, 0.15);
|
||||
-color-chart-1: #f3622d;
|
||||
-color-chart-2: #fba71b;
|
||||
-color-chart-3: #57b757;
|
||||
-color-chart-4: #41a9c9;
|
||||
-color-chart-5: #4258c9;
|
||||
-color-chart-6: #9a42c8;
|
||||
-color-chart-7: #c84164;
|
||||
-color-chart-8: #888888;
|
||||
-color-chart-1-alpha70: rgba(243, 98, 45, 0.7);
|
||||
-color-chart-2-alpha70: rgba(251, 167, 27, 0.7);
|
||||
-color-chart-3-alpha70: rgba(87, 183, 87, 0.7);
|
||||
-color-chart-4-alpha70: rgba(65, 169, 201, 0.7);
|
||||
-color-chart-5-alpha70: rgba(66, 88, 201, 0.7);
|
||||
-color-chart-6-alpha70: rgba(154, 66, 200, 0.7);
|
||||
-color-chart-7-alpha70: rgba(200, 65, 100, 0.7);
|
||||
-color-chart-8-alpha70: rgba(136, 136, 136, 0.7);
|
||||
-color-chart-1-alpha20: rgba(243, 98, 45, 0.2);
|
||||
-color-chart-2-alpha20: rgba(251, 167, 27, 0.2);
|
||||
-color-chart-3-alpha20: rgba(87, 183, 87, 0.2);
|
||||
-color-chart-4-alpha20: rgba(65, 169, 201, 0.2);
|
||||
-color-chart-5-alpha20: rgba(66, 88, 201, 0.2);
|
||||
-color-chart-6-alpha20: rgba(154, 66, 200, 0.2);
|
||||
-color-chart-7-alpha20: rgba(200, 65, 100, 0.2);
|
||||
-color-chart-8-alpha20: rgba(136, 136, 136, 0.2);
|
||||
|
||||
-fx-pambackground: rgba(238,238,238);
|
||||
-fx-darkbackground: -color-bg-default;
|
||||
-fx-darkbackground-trans: rgba(13, 17, 23,0.90);
|
||||
-fx-highlight: -color-base-6;
|
||||
-fx-highlight_border: -color-button-fg;
|
||||
-fx-text: -color-fg-default;
|
||||
-fx-border_col: -color-border-default;
|
||||
-fx-icon_col: -color-fg-default;
|
||||
}
|
||||
|
||||
.root {
|
||||
-fx-background-color:-fx-darkbackground;
|
||||
-fx-font-size: 12px;
|
||||
-fx-background-radius: inherit;
|
||||
-fx-background-insets: inherit;
|
||||
-fx-padding: 5px 5px 5px 5px;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Panes *
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
.pane {
|
||||
-fx-background-color: -fx-darkbackground;
|
||||
}
|
||||
|
||||
.pane-trans{
|
||||
-fx-background-color: -fx-darkbackground-trans;
|
||||
}
|
||||
|
||||
.pane-opaque {
|
||||
-fx-background-color: -fx-pambackground;
|
||||
}
|
||||
|
||||
/*for plot panes*/
|
||||
.pane-plot {
|
||||
-fx-background-color: -fx-plotbackground;
|
||||
}
|
||||
|
||||
|
||||
.button {
|
||||
-color-button-bg: -color-bg-subtle;
|
||||
-color-button-fg: -color-fg-default;
|
||||
-color-button-border: -color-border-default;
|
||||
-color-button-bg-hover: -color-base-6;
|
||||
-color-button-fg-hover: -color-button-fg;
|
||||
-color-button-border-hover: -color-button-border;
|
||||
-color-button-bg-focused: -color-button-bg;
|
||||
-color-button-fg-focused: -color-button-fg;
|
||||
-color-button-border-focused: -color-accent-emphasis;
|
||||
-color-button-bg-pressed: -color-bg-subtle;
|
||||
-color-button-fg-pressed: -color-button-fg;
|
||||
-color-button-border-pressed: transparent;
|
||||
-fx-background-color: -color-button-border, -color-button-bg;
|
||||
-fx-background-insets: 0, 1px;
|
||||
-fx-background-radius: 4px;
|
||||
-fx-graphic-text-gap: 6px;
|
||||
-fx-text-fill: -color-button-fg;
|
||||
-fx-alignment: CENTER;
|
||||
-fx-padding: 8px 12px 8px 12px;
|
||||
}
|
||||
|
||||
.menu-button,
|
||||
.split-menu-button {
|
||||
-color-button-bg: -color-bg-subtle;
|
||||
-color-button-fg: -color-fg-default;
|
||||
-color-button-border: -color-border-default;
|
||||
-color-button-bg-hover: -color-base-6;
|
||||
-color-button-fg-hover: -color-button-fg;
|
||||
-color-button-border-hover: -color-button-border;
|
||||
-color-button-bg-focused: -color-button-bg;
|
||||
-color-button-fg-focused: -color-button-fg;
|
||||
-color-button-border-focused: -color-accent-emphasis;
|
||||
-color-button-bg-pressed: -color-bg-subtle;
|
||||
-color-button-fg-pressed: -color-button-fg;
|
||||
-color-button-border-pressed: transparent;
|
||||
-fx-background-color: -color-button-border, -color-button-bg;
|
||||
-fx-background-insets: 0, 1px;
|
||||
-fx-background-radius: 4px;
|
||||
-fx-graphic-text-gap: 6px;
|
||||
-fx-text-fill: -color-button-fg;
|
||||
-fx-alignment: CENTER;
|
||||
-fx-padding: 0;
|
||||
-fx-alignment: CENTER_LEFT;
|
||||
}
|
||||
|
||||
.menu-button.accent,
|
||||
.split-menu-button.accent {
|
||||
-color-button-bg: -color-accent-emphasis;
|
||||
-color-button-fg: -color-fg-emphasis;
|
||||
-color-button-border: -color-accent-emphasis;
|
||||
-color-button-bg-hover: -color-accent-emphasis;
|
||||
-color-button-fg-hover: -color-fg-emphasis;
|
||||
-color-button-border-hover: -color-accent-emphasis;
|
||||
-color-button-bg-focused: -color-accent-6;
|
||||
-color-button-fg-focused: -color-fg-emphasis;
|
||||
-color-button-border-focused: -color-accent-emphasis;
|
||||
-color-button-bg-pressed: -color-accent-emphasis;
|
||||
-color-button-fg-pressed: -color-fg-emphasis;
|
||||
-color-button-border-pressed: transparent;
|
||||
}
|
||||
.menu-button.accent.button-outlined,
|
||||
.split-menu-button.accent.button-outlined {
|
||||
-color-button-bg: -color-bg-default;
|
||||
-color-button-fg: -color-accent-fg;
|
||||
-color-button-bg-hover: -color-accent-emphasis;
|
||||
-color-button-fg-hover: -color-fg-emphasis;
|
||||
}
|
||||
.menu-button.accent.flat,
|
||||
.split-menu-button.accent.flat {
|
||||
-color-button-fg: -color-accent-fg;
|
||||
-color-button-bg-hover: -color-accent-subtle;
|
||||
}
|
||||
.menu-button.success,
|
||||
.split-menu-button.success {
|
||||
-color-button-bg: -color-success-emphasis;
|
||||
-color-button-fg: -color-fg-emphasis;
|
||||
-color-button-border: -color-success-emphasis;
|
||||
-color-button-bg-hover: -color-success-emphasis;
|
||||
-color-button-fg-hover: -color-fg-emphasis;
|
||||
-color-button-border-hover: -color-success-emphasis;
|
||||
-color-button-bg-focused: -color-success-6;
|
||||
-color-button-fg-focused: -color-fg-emphasis;
|
||||
-color-button-border-focused: -color-success-emphasis;
|
||||
-color-button-bg-pressed: -color-success-emphasis;
|
||||
-color-button-fg-pressed: -color-fg-emphasis;
|
||||
-color-button-border-pressed: transparent;
|
||||
}
|
||||
.menu-button.success.button-outlined,
|
||||
.split-menu-button.success.button-outlined {
|
||||
-color-button-bg: -color-bg-default;
|
||||
-color-button-fg: -color-success-fg;
|
||||
-color-button-bg-hover: -color-success-emphasis;
|
||||
-color-button-fg-hover: -color-fg-emphasis;
|
||||
}
|
||||
.menu-button.success.flat,
|
||||
.split-menu-button.success.flat {
|
||||
-color-button-fg: -color-success-fg;
|
||||
-color-button-bg-hover: -color-success-subtle;
|
||||
}
|
||||
.menu-button.danger,
|
||||
.split-menu-button.danger {
|
||||
-color-button-bg: -color-danger-emphasis;
|
||||
-color-button-fg: -color-fg-emphasis;
|
||||
-color-button-border: -color-danger-emphasis;
|
||||
-color-button-bg-hover: -color-danger-emphasis;
|
||||
-color-button-fg-hover: -color-fg-emphasis;
|
||||
-color-button-border-hover: -color-danger-emphasis;
|
||||
-color-button-bg-focused: -color-danger-6;
|
||||
-color-button-fg-focused: -color-fg-emphasis;
|
||||
-color-button-border-focused: -color-danger-emphasis;
|
||||
-color-button-bg-pressed: -color-danger-emphasis;
|
||||
-color-button-fg-pressed: -color-fg-emphasis;
|
||||
-color-button-border-pressed: transparent;
|
||||
}
|
||||
.menu-button.danger.button-outlined,
|
||||
.split-menu-button.danger.button-outlined {
|
||||
-color-button-bg: -color-bg-default;
|
||||
-color-button-fg: -color-danger-fg;
|
||||
-color-button-bg-hover: -color-danger-emphasis;
|
||||
-color-button-fg-hover: -color-fg-emphasis;
|
||||
}
|
||||
.menu-button.danger.flat,
|
||||
.split-menu-button.danger.flat {
|
||||
-color-button-fg: -color-danger-fg;
|
||||
-color-button-bg-hover: -color-danger-subtle;
|
||||
}
|
||||
.menu-button.flat,
|
||||
.split-menu-button.flat {
|
||||
-color-button-bg: transparent;
|
||||
-color-button-fg: -color-fg-default;
|
||||
-color-button-border: transparent;
|
||||
-color-button-bg-hover: -color-bg-subtle;
|
||||
-color-button-fg-hover: -color-button-fg;
|
||||
-color-button-border-hover: -color-bg-subtle;
|
||||
-color-button-bg-focused: -color-button-bg;
|
||||
-color-button-fg-focused: -color-button-fg;
|
||||
-color-button-border-focused: -color-button-bg;
|
||||
-color-button-bg-pressed: -color-button-bg;
|
||||
-color-button-fg-pressed: -color-button-fg;
|
||||
-color-button-border-pressed: transparent;
|
||||
}
|
||||
|
||||
|
||||
.toggle-button {
|
||||
-color-button-bg: -color-bg-subtle;
|
||||
-color-button-fg: -color-fg-default;
|
||||
-color-button-border: -color-border-default;
|
||||
-color-button-bg-hover: -color-base-6;
|
||||
-color-button-fg-hover: -color-button-fg;
|
||||
-color-button-border-hover: -color-button-border;
|
||||
-color-button-bg-focused: -color-button-bg;
|
||||
-color-button-fg-focused: -color-button-fg;
|
||||
-color-button-border-focused: -color-accent-emphasis;
|
||||
-color-button-bg-pressed: -color-bg-subtle;
|
||||
-color-button-fg-pressed: -color-button-fg;
|
||||
-color-button-border-pressed: transparent;
|
||||
-fx-background-color: -color-button-border, -color-button-bg;
|
||||
-fx-background-insets: 0, 1px;
|
||||
-fx-background-radius: 4px;
|
||||
-fx-graphic-text-gap: 6px;
|
||||
-fx-text-fill: -color-button-fg;
|
||||
-fx-alignment: CENTER;
|
||||
-color-button-bg-selected: -color-accent-emphasis;
|
||||
-color-button-fg-selected: -color-fg-emphasis;
|
||||
-fx-padding: 8px 12px 8px 12px;
|
||||
}
|
||||
|
||||
|
||||
.list-view {
|
||||
-color-cell-bg: -color-bg-default;
|
||||
-color-cell-fg: -color-fg-default;
|
||||
-color-cell-bg-selected: -color-base-6;
|
||||
-color-cell-fg-selected: -color-fg-default;
|
||||
-color-cell-bg-odd: -color-bg-subtle;
|
||||
-color-cell-border: -color-border-default;
|
||||
-fx-border-color: -color-cell-border;
|
||||
-fx-border-width: 1px;
|
||||
-fx-border-radius: 0;
|
||||
}
|
||||
|
||||
.table-view {
|
||||
-color-cell-bg: -color-bg-default;
|
||||
-color-cell-fg: -color-fg-default;
|
||||
-color-cell-bg-selected: -color-base-6;
|
||||
-color-cell-fg-selected: -color-fg-default;
|
||||
-color-cell-bg-odd: -color-bg-subtle;
|
||||
-color-cell-border: -color-border-default;
|
||||
-fx-border-color: -color-cell-border;
|
||||
-fx-border-width: 1px;
|
||||
-fx-border-radius: 0;
|
||||
-color-header-bg: -color-bg-subtle;
|
||||
-color-header-fg: -color-fg-default;
|
||||
}
|
||||
|
||||
.titled-pane > .title > .text {
|
||||
-fx-font-size: 1em;
|
||||
}
|
||||
|
||||
.tree-view {
|
||||
-color-cell-bg: -color-bg-default;
|
||||
-color-cell-fg: -color-fg-default;
|
||||
-color-cell-bg-selected: -color-base-6;
|
||||
-color-cell-fg-selected: -color-fg-default;
|
||||
-color-cell-bg-odd: -color-bg-subtle;
|
||||
-color-cell-border: -color-border-default;
|
||||
-fx-border-color: -color-cell-border;
|
||||
-fx-border-width: 1px;
|
||||
-fx-border-radius: 0;
|
||||
}
|
||||
|
||||
.tree-table-view {
|
||||
-color-cell-bg: -color-bg-default;
|
||||
-color-cell-fg: -color-fg-default;
|
||||
-color-cell-bg-selected: -color-base-6;
|
||||
-color-cell-fg-selected: -color-fg-default;
|
||||
-color-cell-bg-odd: -color-bg-subtle;
|
||||
-color-cell-border: -color-border-default;
|
||||
-fx-border-color: -color-cell-border;
|
||||
-fx-border-width: 1px;
|
||||
-fx-border-radius: 0;
|
||||
-color-header-bg: -color-bg-subtle;
|
||||
-color-header-fg: -color-fg-default;
|
||||
}
|
||||
|
||||
.list-view:focused > .virtual-flow > .clipped-container > .sheet > .list-cell:filled:selected,
|
||||
.tree-view:focused > .virtual-flow > .clipped-container > .sheet > .tree-cell:filled:selected,
|
||||
.table-view:focused > .virtual-flow > .clipped-container > .sheet > .table-row-cell:filled:selected,
|
||||
.tree-table-view:focused > .virtual-flow > .clipped-container > .sheet > .tree-table-row-cell:filled:selected {
|
||||
-color-cell-fg: -color-cell-fg-selected;
|
||||
-fx-background-color: -color-cell-border, -color-cell-bg-selected;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* ikonli icons *
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
#module-pane .ikonli-font-icon {
|
||||
-fx-icon-color: black;
|
||||
}
|
||||
|
||||
|
||||
.titled-pane {
|
||||
-fx-background-color: -color-bg-default;
|
||||
-fx-text-fill: -color-fg-default;
|
||||
-fx-effect: none;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
|
||||
ScrollPane
|
||||
|
||||
****************************************************************/
|
||||
.scroll-pane {
|
||||
-fx-background: #0d1117;
|
||||
-fx-background-color: transparent;
|
||||
}
|
||||
|
||||
.scroll-pane > .viewport {
|
||||
-fx-background-color: transparent;
|
||||
}
|
||||
|
||||
.scroll-pane-dark {
|
||||
-fx-background: -fx-darkbackground;
|
||||
-fx-background-color: -fx-darkbackground;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Hiding Tab *
|
||||
* *
|
||||
******************************************************************************/
|
||||
#hide-tab {
|
||||
-fx-background-color: transparent;
|
||||
-fx-border-radius: 5 5 0 0;
|
||||
-fx-background-radius: 5 5 0 0;
|
||||
-fx-border-color: -fx-border_col;
|
||||
}
|
||||
|
||||
#show-tab {
|
||||
-fx-background-color: transparent;
|
||||
-fx-border-radius: 5 5 0 0;
|
||||
-fx-background-radius: 5 5 0 0;
|
||||
-fx-border-color: -fx-border_col;
|
||||
}
|
||||
|
||||
#hide-tab-highlight {
|
||||
-fx-background-color: -fx-highlight;
|
||||
-fx-border-radius: 5 5 0 0;
|
||||
-fx-background-radius: 5 5 0 0;
|
||||
-fx-border-color: -fx-highlight_border;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Button *
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
/*.button{
|
||||
-fx-text-fill: white;
|
||||
-fx-background-color: -fx-darkbackground;
|
||||
-fx-border-color: -fx-border_col;
|
||||
-fx-border-radius: 5;
|
||||
-fx-background-radius:6;
|
||||
-fx-padding: 3 6 6 6;
|
||||
}*/
|
||||
|
||||
/*.button:hover{
|
||||
-fx-background-color: -fx-highlight;
|
||||
-fx-border-color: -fx-highlight_border;
|
||||
}
|
||||
|
||||
.button:selected{
|
||||
-fx-border-color: -fx-highlight;
|
||||
}
|
||||
*/
|
||||
/**
|
||||
* Button for closing a hiding panel. Right indicates bottoms points towards the right, closing a hiding panel
|
||||
* on the right hand side of the screen. These buttons have a transparent background and rounded corners.
|
||||
*/
|
||||
/** top-left, top-right, bottom-right, and bottom-left corners, in that order. */
|
||||
.close-button-right{
|
||||
-fx-background-color: transparent;
|
||||
-fx-background-radius: 0 10 10 0;
|
||||
-fx-border-color: transparent;
|
||||
-fx-border-radius: 0 10 10 0;
|
||||
}
|
||||
|
||||
|
||||
.close-button-left{
|
||||
-fx-background-color: transparent;
|
||||
-fx-background-radius: 10 0 0 10;
|
||||
-fx-border-color: transparent;
|
||||
-fx-border-radius: 10 0 0 10;
|
||||
}
|
||||
|
||||
|
||||
.close-button-top{
|
||||
-fx-background-color: transparent;
|
||||
-fx-background-radius: 10 10 0 0;
|
||||
-fx-border-color: transparent;
|
||||
-fx-border-radius: 10 10 0 0;
|
||||
}
|
||||
|
||||
|
||||
.close-button-bottom{
|
||||
-fx-background-color: transparent;
|
||||
-fx-background-radius: 0 0 10 10;
|
||||
-fx-border-color: transparent;
|
||||
-fx-border-radius: 0 0 10 10;
|
||||
}
|
||||
|
||||
|
||||
.close-button-bottom-trans{
|
||||
-fx-border-color: transparent;
|
||||
-fx-background-color: transparent;
|
||||
-fx-background-radius: 0 0 10 10;
|
||||
-fx-border-radius: 0 0 10 10;
|
||||
}
|
||||
|
||||
.close-button-left-trans{
|
||||
-fx-border-color: transparent;
|
||||
-fx-background-color: transparent;
|
||||
-fx-background-radius: 10 0 0 10;
|
||||
-fx-border-radius: 10 0 0 10;
|
||||
}
|
||||
|
||||
.close-button-right-trans{
|
||||
-fx-border-color: transparent;
|
||||
-fx-background-color: transparent;
|
||||
-fx-background-radius: 0 10 10 0;
|
||||
-fx-border-radius: 0 10 10 0;
|
||||
}
|
||||
|
||||
.square-button{
|
||||
-fx-background-radius: 0 0 0 0;
|
||||
-fx-border-radius: 0 0 0 0;
|
||||
}
|
||||
|
||||
.square-button-trans{
|
||||
-fx-background-color: transparent;
|
||||
-fx-border-color: transparent;
|
||||
-fx-background-radius: 0 0 0 0;
|
||||
-fx-border-radius: 0 0 0 0;
|
||||
}
|
||||
|
||||
.module-hide-top{
|
||||
-fx-border-color: transparent;
|
||||
-fx-background-radius: 5 5 0 0;
|
||||
-fx-border-radius: 5 5 0 0;
|
||||
}
|
||||
|
||||
.module-hide-bottom{
|
||||
-fx-border-color: transparent;
|
||||
-fx-background-radius: 0 0 5 5;
|
||||
-fx-border-radius: 0 0 5 5;
|
||||
}
|
||||
|
||||
.delete-button:hover{
|
||||
-fx-background-color: rgba(1,0,0,0.7);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Pop over *
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
.popover {
|
||||
-fx-background-color: -fx-darkbackground;
|
||||
-fx-background-radius: 5;
|
||||
-fx-border-radius: 5;
|
||||
}
|
||||
|
||||
.popover > .content {
|
||||
-fx-background-color: -fx-darkbackground;
|
||||
-fx-background-radius: 5;
|
||||
-fx-border-radius: 5;
|
||||
}
|
||||
|
||||
.popover > .arrow {
|
||||
-fx-background-color: -fx-darkbackground;
|
||||
-fx-background-radius: 5;
|
||||
-fx-border-radius: 5;
|
||||
}
|
||||
|
||||
/*weird way to do it but need this to colour the arrow*/
|
||||
.popover > .border {
|
||||
/*-fx-stroke: linear-gradient(to bottom, rgba(0,0,0, .3), rgba(0, 0, 0, .7)) ;*/
|
||||
-fx-stroke-width: 0.5;
|
||||
-fx-fill: -fx-darkbackground; /* instead -fx-background-color */
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* SplitMenuButton *
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
.split-menu-button{
|
||||
-fx-text-fill: -fx-text;
|
||||
-fx-background-color: -fx-darkbackground;
|
||||
-fx-border-color: -fx-border_col;
|
||||
-fx-border-radius: 5;
|
||||
}
|
||||
|
||||
|
||||
.split-menu-button:hover{
|
||||
/*-fx-border-color: -fx-highlight_border;*/
|
||||
}
|
||||
|
||||
|
||||
.split-menu-button .label {
|
||||
-fx-text-fill: white;
|
||||
-fx-background-color: -fx-darkbackground;
|
||||
-fx-border-radius: 5;
|
||||
}
|
||||
|
||||
|
||||
.split-menu-button .label:hover {
|
||||
-fx-background-color: -fx-highlight;
|
||||
}
|
||||
|
||||
|
||||
.split-menu-button .arrow-button {
|
||||
-fx-text-fill: -fx-text;
|
||||
-fx-background-color: -fx-darkbackground;
|
||||
-fx-border-radius: 5;
|
||||
}
|
||||
|
||||
|
||||
.split-menu-button .arrow-button:hover {
|
||||
-fx-background-color: -fx-highlight;
|
||||
}
|
||||
|
||||
|
||||
/**********/
|
||||
|
||||
|
||||
.menu-item {
|
||||
-fx-background-color: -color-bg-default;
|
||||
-fx-padding: 8px 12px 8px 12px;
|
||||
}
|
||||
.menu-item > .graphic-container {
|
||||
-fx-padding: 0 6px 0 0;
|
||||
}
|
||||
.menu-item > .label {
|
||||
-fx-padding: 0 1em 0 0;
|
||||
-fx-text-fill: -color-fg-default;
|
||||
}
|
||||
.menu-item > .left-container {
|
||||
-fx-padding: 0 1em 0 0;
|
||||
}
|
||||
.menu-item > .right-container {
|
||||
-fx-padding: 0 0 0 0.5em;
|
||||
}
|
||||
.menu-item:focused {
|
||||
-fx-background-color: -color-base-7, -color-base-7;
|
||||
}
|
||||
.menu-item:disabled {
|
||||
-fx-opacity: 0.4;
|
||||
-fx-background-color: -color-bg-default;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/********************************************
|
||||
* *
|
||||
* Spinner *
|
||||
* *
|
||||
*********************************************/
|
||||
|
||||
|
||||
.spinner {
|
||||
-fx-pref-width: 120px;
|
||||
}
|
||||
|
||||
.dialog-pane > .content {
|
||||
-fx-padding: 1em 1em 1em 1em;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Hiding Pane *
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/**
|
||||
* Button for closing a hiding panel. Right indicates bottoms points towards the right, closing a hiding panel
|
||||
* on the right hand side of the screen. These buttons have a transparent background and rounded corners.
|
||||
*/
|
||||
/** top-left, top-right, bottom-right, and bottom-left corners, in that order. */
|
||||
.close-button-right{
|
||||
-fx-background-color: transparent;
|
||||
-fx-background-radius: 0 10 10 0;
|
||||
-fx-border-radius: 0 10 10 0;
|
||||
}
|
||||
|
||||
.close-button-right:hover {
|
||||
-fx-background-color: -fx-highlight;
|
||||
}
|
||||
|
||||
|
||||
.close-button-left{
|
||||
-fx-background-color: transparent;
|
||||
-fx-background-radius: 10 0 0 10;
|
||||
-fx-border-radius: 10 0 0 10;
|
||||
}
|
||||
|
||||
.close-button-left:hover {
|
||||
-fx-background-color: -fx-highlight;
|
||||
}
|
||||
|
||||
|
||||
.close-button-top{
|
||||
-fx-background-color: transparent;
|
||||
-fx-background-radius: 10 10 0 0;
|
||||
-fx-border-radius: 10 10 0 0;
|
||||
}
|
||||
|
||||
|
||||
.close-button-bottom {
|
||||
-fx-background-color: transparent;
|
||||
-fx-background-radius: 0 0 10 10;
|
||||
-fx-border-radius: 0 0 10 10;
|
||||
}
|
||||
|
||||
.close-button-bottom:hover {
|
||||
-fx-background-color: -fx-highlight;
|
||||
}
|
||||
|
||||
|
||||
.close-button-bottom-grey{
|
||||
-fx-border-color: transparent;
|
||||
-fx-background-radius: 0 0 10 10;
|
||||
-fx-border-radius: 0 0 10 10;
|
||||
}
|
||||
|
||||
.close-button-left-trans{
|
||||
-fx-border-color: transparent;
|
||||
-fx-background-color: transparent;
|
||||
-fx-background-radius: 10 0 0 10;
|
||||
-fx-border-radius: 10 0 0 10;
|
||||
}
|
||||
|
||||
.close-button-left-trans:focused {
|
||||
-fx-border-color: transparent;
|
||||
-fx-background-color: transparent;
|
||||
-fx-background-radius: 10 0 0 10;
|
||||
-fx-border-radius: 10 0 0 10;
|
||||
}
|
||||
|
||||
.close-button-right-trans{
|
||||
-fx-border-color: transparent;
|
||||
-fx-background-color: transparent;
|
||||
-fx-background-radius: 0 10 10 0;
|
||||
-fx-border-radius: 0 10 10 0;
|
||||
}
|
||||
|
||||
.close-button-right-trans:focused {
|
||||
-fx-border-color: transparent;
|
||||
-fx-background-color: transparent;
|
||||
-fx-background-radius: 0 10 10 0;
|
||||
-fx-border-radius: 0 10 10 0;
|
||||
}
|
||||
|
||||
|
||||
.menu-square-button {
|
||||
-fx-border-color: -fx_border_col;
|
||||
-fx-background-color: transparent;
|
||||
-fx-background-radius: 0 0 0 0;
|
||||
-fx-border-radius: 0 0 0 0;
|
||||
}
|
||||
|
12
src/audioMoth/AudioMothControl.java
Normal file
12
src/audioMoth/AudioMothControl.java
Normal file
@ -0,0 +1,12 @@
|
||||
package audioMoth;
|
||||
|
||||
import PamController.PamControlledUnit;
|
||||
|
||||
public class AudioMothControl extends PamControlledUnit {
|
||||
|
||||
public AudioMothControl(String unitType, String unitName) {
|
||||
super(unitType, unitName);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
}
|
@ -6,7 +6,7 @@ import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
|
||||
import PamUtils.PamAudioFileFilter;
|
||||
import Acquisition.pamAudio.PamAudioFileFilter;
|
||||
import PamUtils.PamCalendar;
|
||||
|
||||
public class TestFileDates {
|
||||
|
@ -28,11 +28,11 @@ public class BTDisplayParameters implements Serializable, Cloneable, ManagedPara
|
||||
public static final String[] angleTypeNames = {"Relative to array", "Relative to vessel", "Relative to north"};
|
||||
|
||||
/**
|
||||
* Rotation options for angles.
|
||||
* Rotation options for angles. These should match the above angleTypeNames.
|
||||
*/
|
||||
static public final int ROTATE_TOARRAY = 0; // no rotation, raw angles relative to the array
|
||||
static public final int ROTATE_PITCHROLL = 1; // fix pitch and roll, but leave the heading relative to the array
|
||||
static public final int ROTATE_HEADPITCHROLL = 2; // rotate by heading pitch and roll.
|
||||
static public final int ROTATE_TOVESSEL = 1; // fix pitch and roll, but leave the heading relative to the array
|
||||
static public final int ROTATE_TONORTH = 2; // rotate by heading pitch and roll.
|
||||
|
||||
|
||||
// main BT display
|
||||
|
@ -1642,16 +1642,26 @@ public class ClickBTDisplay extends ClickDisplay implements PamObserver, PamSett
|
||||
double[] rotAngles = new double[3];
|
||||
rotAngles[1] = Math.toRadians(oll.getPitch());
|
||||
rotAngles[2] = Math.toRadians(oll.getRoll());
|
||||
if (rType == BTDisplayParameters.ROTATE_HEADPITCHROLL) {
|
||||
if (rType == BTDisplayParameters.ROTATE_TOVESSEL) {
|
||||
// use head as well as pitch and roll.
|
||||
rotAngles[0] = Math.toRadians(oll.getHeading());
|
||||
PamVector[] vr = loc.getWorldVectors();
|
||||
if (vr != null && vr.length > 0) {
|
||||
return vr[0];
|
||||
}
|
||||
// rotAngles[0] = Math.toRadians(oll.getHeading());
|
||||
}
|
||||
if (rotAngles[0] == 0 && rotAngles[1] == 0 && rotAngles[2] == 0) {
|
||||
return v;
|
||||
else if (rType == BTDisplayParameters.ROTATE_TONORTH) {
|
||||
PamVector[] vr = loc.getRealWorldVectors();
|
||||
if (vr != null && vr.length > 0) {
|
||||
return vr[0];
|
||||
}
|
||||
}
|
||||
PamQuaternion pq = new PamQuaternion(rotAngles[0], rotAngles[1], rotAngles[2]);
|
||||
PamVector v2 = PamVector.rotateVector(v, pq);
|
||||
return v2;
|
||||
// if (rotAngles[0] == 0 && rotAngles[1] == 0 && rotAngles[2] == 0) {
|
||||
// return v;
|
||||
// }
|
||||
// PamQuaternion pq = new PamQuaternion(rotAngles[0], rotAngles[1], rotAngles[2]);
|
||||
// PamVector v2 = PamVector.rotateVector(v, pq);
|
||||
return v;
|
||||
}
|
||||
|
||||
private double angleFromYPos(int yPos) {
|
||||
|
@ -226,7 +226,7 @@ public class SweepClassifier implements ClickIdentifier , PamSettings {
|
||||
return clickDetector;
|
||||
}
|
||||
|
||||
protected int getNextFreeCode(int currCode) {
|
||||
public int getNextFreeCode(int currCode) {
|
||||
int newCode = currCode;
|
||||
while (codeTaken(++newCode));
|
||||
return newCode;
|
||||
@ -277,7 +277,7 @@ public class SweepClassifier implements ClickIdentifier , PamSettings {
|
||||
* Set the params for the sweep classifier.
|
||||
* @params the sweep classifier params to set.
|
||||
*/
|
||||
public void setSeepClassifierParams(SweepClassifierParameters sweepClassifierParameters) {
|
||||
public void setSweepClassifierParams(SweepClassifierParameters sweepClassifierParameters) {
|
||||
this.sweepClassifierParameters=sweepClassifierParameters;
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,10 @@ public class ClickParameters implements Serializable, Cloneable, ManagedParamete
|
||||
*/
|
||||
public int backgroundIntervalMillis = 5000;
|
||||
|
||||
public int clickClassifierType = ClickClassifierManager.CLASSIFY_BASIC;
|
||||
/**
|
||||
* The type of classifier to use - CLASSIFY_SWEEP is the default.
|
||||
*/
|
||||
public int clickClassifierType = ClickClassifierManager.CLASSIFY_BETTER;
|
||||
|
||||
public boolean runEchoOnline = false;
|
||||
|
||||
|
@ -6,6 +6,7 @@ import java.text.ParseException;
|
||||
import clickDetector.ClickControl;
|
||||
import clickDetector.ClickParameters;
|
||||
import clickDetector.layoutFX.clickClassifiers.ClickClassifyPaneFX;
|
||||
import javafx.geometry.HPos;
|
||||
import javafx.geometry.Orientation;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Node;
|
||||
@ -14,12 +15,14 @@ import javafx.scene.control.Label;
|
||||
import javafx.scene.control.Spinner;
|
||||
import javafx.scene.control.Tab;
|
||||
import javafx.scene.control.TabPane;
|
||||
import javafx.scene.layout.ColumnConstraints;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.shape.Line;
|
||||
import javafx.util.StringConverter;
|
||||
import net.synedra.validatorfx.Validator;
|
||||
import PamController.PamController;
|
||||
import PamController.SettingsPane;
|
||||
import PamDetection.RawDataUnit;
|
||||
@ -43,8 +46,8 @@ import pamViewFX.fxNodes.utilityPanes.GroupedSourcePaneFX;
|
||||
* @author Jamie Macaulay
|
||||
*/
|
||||
public class ClickSettingsPane extends SettingsPane<ClickParameters>{
|
||||
|
||||
public static double PREF_SPINNER_WIDTH = 100;
|
||||
|
||||
public static double PREF_SPINNER_WIDTH = 140;
|
||||
|
||||
/**
|
||||
* Group source pane for the click settings pane.
|
||||
@ -160,25 +163,35 @@ public class ClickSettingsPane extends SettingsPane<ClickParameters>{
|
||||
private Tab tdoaTab;
|
||||
|
||||
/**
|
||||
* The default pane width
|
||||
* The main holder pane.
|
||||
*/
|
||||
public static double paneWidth=500;
|
||||
private PamBorderPane mainPane;
|
||||
|
||||
/**
|
||||
* The default pane height.
|
||||
*/
|
||||
public static double paneHeigt=800;
|
||||
public static double PREF_PANE_HEIGHT=850;
|
||||
|
||||
/**
|
||||
* The main holder pane.
|
||||
* The default pane width
|
||||
*/
|
||||
private PamBorderPane mainPane;
|
||||
public static double PREF_PANE_WIDTH=550;
|
||||
|
||||
|
||||
/**
|
||||
* Validator which checks for errors
|
||||
*/
|
||||
private Validator clickValidator;
|
||||
|
||||
|
||||
|
||||
public ClickSettingsPane(ClickControl clickControl){
|
||||
super(null);
|
||||
this.clickControl=clickControl;
|
||||
mainPane= new PamBorderPane();
|
||||
|
||||
clickValidator = new Validator();
|
||||
|
||||
pamTabbedPane=new PamTabPane();
|
||||
pamTabbedPane.setAddTabButton(false);
|
||||
pamTabbedPane.setTabClosingPolicy(TabPane.TabClosingPolicy.UNAVAILABLE);
|
||||
@ -187,49 +200,49 @@ public class ClickSettingsPane extends SettingsPane<ClickParameters>{
|
||||
PamVBox detectionPane=new PamVBox();
|
||||
detectionPane.setSpacing(20);
|
||||
detectionPane.getChildren().add(createClickDetectionPane());
|
||||
|
||||
|
||||
|
||||
|
||||
PamHBox holder=new PamHBox();
|
||||
holder.setSpacing(20);
|
||||
holder.getChildren().addAll(createClickLengthPane(), createClickTriggerPane());
|
||||
detectionPane.getChildren().add(holder);
|
||||
|
||||
|
||||
detectionPane.getChildren().add(createTriggerGraph());
|
||||
|
||||
//add everything to tabs.
|
||||
pamTabbedPane.getTabs().add(new Tab("Click Detection", detectionPane));
|
||||
clickDelayPane=createDelayPane();
|
||||
pamTabbedPane.getTabs().add(tdoaTab=new Tab("Click TDOA", clickDelayPane.getContentNode()));
|
||||
pamTabbedPane.getTabs().add(tdoaTab=new Tab("TDOA and Echoes", clickDelayPane.getContentNode()));
|
||||
tdoaTab.setOnSelectionChanged((event)->{
|
||||
if (pamTabbedPane.getSelectionModel().getSelectedItem()==tdoaTab){
|
||||
System.out.println("clickDelayPane: "+clickDelayPane);
|
||||
//System.out.println("clickDelayPane: "+clickDelayPane);
|
||||
//need to update the tab with a copy of the current click params.
|
||||
clickDelayPane.setParams(clickClassificationPane.getParams(clickParameters.clone()));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
//pre filter pane.
|
||||
preFilter=new FilterPaneFX(Orientation.VERTICAL);
|
||||
pamTabbedPane.getTabs().add(new Tab("Pre Filter", preFilter.getContentNode()));
|
||||
|
||||
|
||||
//trigger pane
|
||||
triggerFilter=new FilterPaneFX(Orientation.VERTICAL);
|
||||
pamTabbedPane.getTabs().add(new Tab("Trigger Filter", triggerFilter.getContentNode()));
|
||||
|
||||
//echo detection pane.
|
||||
echoDetection= new ClickEchoPane(clickControl);
|
||||
pamTabbedPane.getTabs().add(new Tab("Echo Detection", echoDetection.getContentNode()));
|
||||
|
||||
|
||||
// //echo detection pane.
|
||||
// echoDetection= new ClickEchoPane(clickControl);
|
||||
// pamTabbedPane.getTabs().add(new Tab("Echo Detection", echoDetection.getContentNode()));
|
||||
|
||||
/***Note: FX does not implment click train detection in click detector****/
|
||||
|
||||
//classifiaction pane.
|
||||
pamTabbedPane.getTabs().add(new Tab("Click Classification", clickClassificationPane=new ClickClassifyPaneFX(clickControl)));
|
||||
pamTabbedPane.getTabs().add(new Tab("Classification", clickClassificationPane=new ClickClassifyPaneFX(clickControl)));
|
||||
|
||||
//want a slightly bigger pane as a lot going on in this dialog.
|
||||
//Note JavaFX 8u61 + has auto DPI scaling so this is really the size of a dialog on a standard HD monitor of
|
||||
//reasonable size, rather than actual pixels
|
||||
mainPane.setPrefSize(paneWidth, paneHeigt);
|
||||
mainPane.setPrefSize(PREF_PANE_WIDTH, PREF_PANE_HEIGHT);
|
||||
|
||||
//addTabListeners();
|
||||
mainPane.setCenter(new PamBorderPane(pamTabbedPane));
|
||||
@ -267,16 +280,17 @@ public class ClickSettingsPane extends SettingsPane<ClickParameters>{
|
||||
|
||||
//channels, groups and trigger are all in one pane to make it easy not to make mistakes
|
||||
sourcePane=createClickSourcePane(); //create the source pane.
|
||||
|
||||
|
||||
GridPane.setColumnSpan(sourcePane.getDataBlockBox(), 4);
|
||||
|
||||
|
||||
GridPane.setColumnSpan(sourcePane.getDataBlockBox(), 2);
|
||||
//now create trigger pane. The trigger pane is added to the source pane.
|
||||
Label triggerLabel = new Label("Trigger Channels");
|
||||
PamGuiManagerFX.titleFont2style(triggerLabel);
|
||||
sourcePane.getSourcePane().add(triggerLabel,1,2);
|
||||
|
||||
|
||||
triggerChannels=new Pane();
|
||||
sourcePane.getSourcePane().add(triggerChannels,1,3);
|
||||
GridPane.setHalignment(triggerChannels, HPos.RIGHT);
|
||||
createTriggerChannels();
|
||||
//sourcePane.getSourcePane().add(createClickTriggerPane(), 2, 3);
|
||||
|
||||
@ -285,7 +299,18 @@ public class ClickSettingsPane extends SettingsPane<ClickParameters>{
|
||||
// pamTabbedPane.getTabs().add(new Tab("Click Echoes", createEchoPane()));
|
||||
// pamTabbedPane.getTabs().add(new Tab("Click Delays", createDelayPane()));
|
||||
|
||||
sourcePane.setPrefWidth(paneWidth);
|
||||
ColumnConstraints col1 = new ColumnConstraints();
|
||||
col1.setHgrow(Priority.ALWAYS);
|
||||
|
||||
ColumnConstraints col2 = new ColumnConstraints();
|
||||
col2.setHgrow(Priority.SOMETIMES);
|
||||
col2.setHalignment(HPos.RIGHT);
|
||||
sourcePane.getSourcePane().getColumnConstraints().addAll(col1, col2);
|
||||
|
||||
PamHBox.setHgrow(sourcePane.getChannelPane(), Priority.NEVER);
|
||||
|
||||
//sourcePane.setMinWidth(PREF_PANE_WIDTH);
|
||||
sourcePane.getSourcePane().setPrefWidth(PREF_PANE_WIDTH);
|
||||
|
||||
return sourcePane;
|
||||
}
|
||||
@ -317,7 +342,7 @@ public class ClickSettingsPane extends SettingsPane<ClickParameters>{
|
||||
maxClickLength.setEditable(true);
|
||||
maxClickLength.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL);
|
||||
maxClickLength.setPrefWidth(PREF_SPINNER_WIDTH);
|
||||
|
||||
|
||||
lengthPane.add(maxClickLength,1,1);
|
||||
lengthPane.add(new Label("samples"),2,1);
|
||||
|
||||
@ -326,7 +351,7 @@ public class ClickSettingsPane extends SettingsPane<ClickParameters>{
|
||||
preSampleSpinner=new PamSpinner<Integer>(0, 10000000, 100, 20);
|
||||
preSampleSpinner.setEditable(true);
|
||||
preSampleSpinner.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL);
|
||||
preSampleSpinner.setPrefWidth(PREF_SPINNER_WIDTH);
|
||||
//preSampleSpinner.setPrefWidth(PREF_SPINNER_WIDTH);
|
||||
|
||||
lengthPane.add(preSampleSpinner,1,2);
|
||||
lengthPane.add(new Label("samples"),2,2);
|
||||
@ -336,7 +361,8 @@ public class ClickSettingsPane extends SettingsPane<ClickParameters>{
|
||||
postSampleSpinner=new PamSpinner<Integer>(0, 10000000, 100, 20);
|
||||
postSampleSpinner.setEditable(true);
|
||||
postSampleSpinner.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL);
|
||||
postSampleSpinner.setPrefWidth(PREF_SPINNER_WIDTH);
|
||||
//postSampleSpinner.setPrefWidth(PREF_SPINNER_WIDTH);
|
||||
|
||||
|
||||
lengthPane.add(postSampleSpinner,1,3);
|
||||
lengthPane.add(new Label("samples"),2,3);
|
||||
@ -360,13 +386,24 @@ public class ClickSettingsPane extends SettingsPane<ClickParameters>{
|
||||
else selectNoChannels();
|
||||
});
|
||||
|
||||
//create a list of trigger boxes
|
||||
//create a list of trigger boxesc
|
||||
for (int i=0; i<triggerBoxes.length; i++){
|
||||
triggerBoxes[i]=new CheckBox(("Channel "+i));
|
||||
final int n=i;
|
||||
triggerBoxes[i].setOnAction((action)->{
|
||||
selectionChanged(n);
|
||||
clickValidator.validate(); //make sure all nodes are resrt when one channel is ticked.
|
||||
});
|
||||
clickValidator.createCheck()
|
||||
.dependsOn(("trigger " + n), triggerBoxes[i].selectedProperty())
|
||||
.withMethod(c -> {
|
||||
if (!isATriggerSelected() ) {
|
||||
c.error("At least one trigger channel needs to be selected for the module to work");
|
||||
}
|
||||
})
|
||||
.decorates(triggerBoxes[n])
|
||||
.immediate();
|
||||
|
||||
}
|
||||
|
||||
populateTriggerPane();
|
||||
@ -406,7 +443,7 @@ public class ClickSettingsPane extends SettingsPane<ClickParameters>{
|
||||
threshold.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL);
|
||||
threshold.getValueFactory().valueProperty().addListener((obs, before, after)->{
|
||||
clickParameters.dbThreshold=after;
|
||||
clickTriggerGraph.updateWaveformGraph(this.clickParameters);
|
||||
clickTriggerGraph.updateGraphFilter();
|
||||
});
|
||||
triggerBox.add(threshold,1,0);
|
||||
triggerBox.add(new Label("dB"),2,0);
|
||||
@ -420,7 +457,7 @@ public class ClickSettingsPane extends SettingsPane<ClickParameters>{
|
||||
longFilter.getValueFactory().valueProperty().addListener((obs, before, after)->{
|
||||
clickParameters.longFilter=after;
|
||||
clickTriggerGraph.setLongFilter(clickParameters.longFilter);
|
||||
clickTriggerGraph.updateWaveformGraph(this.clickParameters);
|
||||
clickTriggerGraph.updateGraphFilter();
|
||||
});
|
||||
triggerBox.add(longFilter,1,1);
|
||||
longFilter.setPrefWidth(PREF_SPINNER_WIDTH);
|
||||
@ -444,11 +481,14 @@ public class ClickSettingsPane extends SettingsPane<ClickParameters>{
|
||||
shortFilter.getValueFactory().valueProperty().addListener((obs, before, after)->{
|
||||
clickParameters.shortFilter=after;
|
||||
clickTriggerGraph.setShortFilter(clickParameters.shortFilter);
|
||||
clickTriggerGraph.updateWaveformGraph(this.clickParameters);
|
||||
clickTriggerGraph.updateGraphFilter();
|
||||
});
|
||||
shortFilter.setPrefWidth(PREF_SPINNER_WIDTH);
|
||||
triggerBox.add(shortFilter,1,3);
|
||||
|
||||
//forces the grid pane to be larger - grid panes can be a little funny.
|
||||
shortFilter.setMinWidth(PREF_SPINNER_WIDTH);
|
||||
|
||||
triggerPane.add(triggerBox,0,1);
|
||||
|
||||
//triggerPane.setGridLinesVisible(true);
|
||||
@ -456,7 +496,7 @@ public class ClickSettingsPane extends SettingsPane<ClickParameters>{
|
||||
return triggerPane;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Pane createTriggerGraph() {
|
||||
//trigger graph
|
||||
Label graphLabel = new Label("Filter Graph");
|
||||
@ -469,9 +509,9 @@ public class ClickSettingsPane extends SettingsPane<ClickParameters>{
|
||||
PamVBox triggerGraph = new PamVBox();
|
||||
triggerGraph.setSpacing(5);
|
||||
triggerGraph.getChildren().addAll(graphLabel, clickTriggerGraph);
|
||||
|
||||
|
||||
return triggerGraph;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -525,7 +565,7 @@ public class ClickSettingsPane extends SettingsPane<ClickParameters>{
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current channle bitmap.
|
||||
* Get the current channels bitmap.
|
||||
* @return integer channel bitmap
|
||||
*/
|
||||
private int getChannels(){
|
||||
@ -538,6 +578,32 @@ public class ClickSettingsPane extends SettingsPane<ClickParameters>{
|
||||
}
|
||||
return channels;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the number of selected trigger channels.
|
||||
* @return the number of selected trigger channels.
|
||||
*/
|
||||
private int getNSelectedTrigger() {
|
||||
int channels=getChannels();
|
||||
int n=0;
|
||||
//now add correct trigger children again
|
||||
for (int i = 0; i < Math.min(PamConstants.MAX_CHANNELS, triggerBoxes.length); i++) {
|
||||
if ((channels & 1<<i) != 0 && triggerBoxes[i].isSelected()){
|
||||
n++;
|
||||
};
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether at least one trigger channel is selected.
|
||||
* @return true of a trigger channel is selected.
|
||||
*/
|
||||
private boolean isATriggerSelected() {
|
||||
return getNSelectedTrigger()>0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create trigger channels
|
||||
@ -555,6 +621,8 @@ public class ClickSettingsPane extends SettingsPane<ClickParameters>{
|
||||
triggerChannels.getChildren().add(selectAll);
|
||||
for (int i = 0; i < Math.min(PamConstants.MAX_CHANNELS, triggerBoxes.length); i++) {
|
||||
if ((channels & 1<<i) != 0){
|
||||
|
||||
//triggerBoxes[i] = new CheckBox("Channel " + i);
|
||||
triggerChannels.getChildren().add(triggerBoxes[i]);
|
||||
triggerBoxes[i].layoutYProperty().unbind();
|
||||
triggerBoxes[i].layoutYProperty().bind(sourcePane.getChannelBoxes()[i].layoutYProperty());
|
||||
@ -603,14 +671,14 @@ public class ClickSettingsPane extends SettingsPane<ClickParameters>{
|
||||
return null;
|
||||
}
|
||||
|
||||
// clickParameters.rawDataSource = rawDataBlock.toString();
|
||||
// clickParameters.channelBitmap = sourcePane.getChannelList();
|
||||
// clickParameters.channelGroups = sourcePane.getChannelGroups();
|
||||
// clickParameters.groupingType = sourcePane.getGrouping();
|
||||
|
||||
// clickParameters.rawDataSource = rawDataBlock.toString();
|
||||
// clickParameters.channelBitmap = sourcePane.getChannelList();
|
||||
// clickParameters.channelGroups = sourcePane.getChannelGroups();
|
||||
// clickParameters.groupingType = sourcePane.getGrouping();
|
||||
|
||||
//sets the params for source pane.
|
||||
sourcePane.getParams(clickParameters.getGroupedSourceParameters());
|
||||
|
||||
|
||||
// if (sourcePanel.getParams() == false) return false;
|
||||
try {
|
||||
clickParameters.dbThreshold = Double.valueOf(threshold.getValue());
|
||||
@ -669,6 +737,8 @@ public class ClickSettingsPane extends SettingsPane<ClickParameters>{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
clickParameters = clickClassificationPane.getParams(clickParameters);
|
||||
|
||||
}
|
||||
catch (Exception e){
|
||||
@ -696,12 +766,12 @@ public class ClickSettingsPane extends SettingsPane<ClickParameters>{
|
||||
else {
|
||||
sourcePane.setSourceIndex(0);
|
||||
}
|
||||
|
||||
|
||||
sourcePane.setParams(clickParameters.getGroupedSourceParameters());
|
||||
|
||||
// sourcePane.setGrouping(clickParameters.groupingType);
|
||||
// sourcePane.setChannelGroups(clickParameters.channelGroups);
|
||||
// sourcePane.setChannelList(clickParameters.channelBitmap);
|
||||
|
||||
// sourcePane.setGrouping(clickParameters.groupingType);
|
||||
// sourcePane.setChannelGroups(clickParameters.channelGroups);
|
||||
// sourcePane.setChannelList(clickParameters.channelBitmap);
|
||||
|
||||
//click length pane
|
||||
minClickSep.getValueFactory().setValue(clickParameters.minSep);
|
||||
|
@ -1,15 +1,25 @@
|
||||
package clickDetector.layoutFX;
|
||||
|
||||
import clickDetector.ClickParameters;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import PamUtils.PamArrayUtils;
|
||||
import javafx.concurrent.Task;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.chart.LineChart;
|
||||
import javafx.scene.chart.NumberAxis;
|
||||
import javafx.scene.chart.XYChart.Data;
|
||||
import javafx.scene.chart.XYChart.Series;
|
||||
import javafx.scene.control.ChoiceBox;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import pamViewFX.fxNodes.PamBorderPane;
|
||||
import pamViewFX.fxNodes.PamStackPane;
|
||||
import pamViewFX.fxNodes.pamChart.PamLineChart;
|
||||
import simulatedAcquisition.sounds.ClickSound;
|
||||
import simulatedAcquisition.sounds.ClickSound.WINDOWTYPE;
|
||||
import simulatedAcquisition.sounds.SimSignal;
|
||||
import rawDeepLearningClassifier.layoutFX.exampleSounds.ExampleSound;
|
||||
import rawDeepLearningClassifier.layoutFX.exampleSounds.ExampleSoundFactory;
|
||||
import rawDeepLearningClassifier.layoutFX.exampleSounds.ExampleSoundFactory.ExampleSoundCategory;
|
||||
import rawDeepLearningClassifier.layoutFX.exampleSounds.ExampleSoundFactory.ExampleSoundType;
|
||||
import javafx.application.Platform;
|
||||
|
||||
/**
|
||||
* Graph which shows a click and associated trigger functions
|
||||
@ -17,28 +27,22 @@ import simulatedAcquisition.sounds.SimSignal;
|
||||
*
|
||||
*/
|
||||
public class ClickTriggerGraph extends PamBorderPane {
|
||||
|
||||
public final static int PORPOISE_CLICK=0;
|
||||
|
||||
public final static int SPERM_WHALE=1;
|
||||
|
||||
|
||||
private int currentClick=PORPOISE_CLICK;
|
||||
|
||||
private NumberAxis xAxis;
|
||||
|
||||
private NumberAxis yAxis;
|
||||
|
||||
|
||||
/**
|
||||
* The long filter
|
||||
*/
|
||||
private double longFilter=0.00001;
|
||||
|
||||
|
||||
/**
|
||||
* The short filter
|
||||
*/
|
||||
private double shortFilter=0.01;
|
||||
|
||||
|
||||
/*
|
||||
* Random noise added to the click and surrounding snippet.
|
||||
*/
|
||||
@ -48,48 +52,33 @@ public class ClickTriggerGraph extends PamBorderPane {
|
||||
|
||||
private int freq2;
|
||||
|
||||
public static final int PREF_GRAPH_WIDTH = 400;
|
||||
|
||||
/**
|
||||
* The example sound factory.
|
||||
*/
|
||||
private ExampleSoundFactory exampleSoundFactory;
|
||||
|
||||
private Series<Number, Number> signalLevelSeries;
|
||||
|
||||
private Series<Number, Number> noiseLevelSeries;
|
||||
|
||||
Task<Integer> task;
|
||||
|
||||
private double[] waveform;
|
||||
|
||||
|
||||
|
||||
public ClickTriggerGraph(){
|
||||
this.exampleSoundFactory = new ExampleSoundFactory();
|
||||
this.setCenter(createWaveformGraph());
|
||||
this.setPrefWidth(400);
|
||||
//FIXME - seems to a resize bug in high DPI displays. Seems fixed in 8u60.
|
||||
this.waveform=generateClickWaveform(currentClick, noise);
|
||||
generateClickWaveform(ExampleSoundType.PORPOISE_CLICK, noise);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Update graph. Delete current data series and create new one.
|
||||
*/
|
||||
public void updateWaveformGraph(ClickParameters clickParameters){
|
||||
|
||||
// System.out.println(" Graph width: xAxis: "+xAxis.widthProperty().get());
|
||||
// System.out.println(" Graph width: this: "+this.widthProperty().get());
|
||||
// System.out.println(" Graph width: plotChart: "+plotChart.widthProperty().get());
|
||||
// System.out.println(" xAxisLayout:: "+xAxis.layoutXProperty().get());
|
||||
// System.out.println(" plotLayout:: "+plotChart.layoutXProperty().get());
|
||||
|
||||
Series<Number, Number> waveformSeries = new Series<Number, Number>();
|
||||
Series<Number, Number> signalLevelSeries = new Series<Number, Number>();
|
||||
Series<Number, Number> noiseLevelSeries = new Series<Number, Number>();
|
||||
|
||||
|
||||
double[] signalLevel=calcFilter(waveform, shortFilter);
|
||||
double[] noiseLevel=calcFilter(waveform, longFilter);
|
||||
|
||||
|
||||
for (int i=0; i<waveform.length; i++){
|
||||
waveformSeries.getData().add(new Data<Number, Number>(i, waveform[i]));
|
||||
signalLevelSeries.getData().add(new Data<Number, Number>(i, signalLevel[i]));
|
||||
noiseLevelSeries.getData().add(new Data<Number, Number>(i, noiseLevel[i]));
|
||||
|
||||
}
|
||||
|
||||
plotChart.getData().removeAll(plotChart.getData());
|
||||
plotChart.getData().addAll(waveformSeries,signalLevelSeries,noiseLevelSeries);
|
||||
}
|
||||
|
||||
|
||||
public double[] calcFilter(double[] waveform, double alpha){
|
||||
double[] filterVals=new double[waveform.length];
|
||||
for (int i=0; i<waveform.length; i++){
|
||||
@ -97,55 +86,15 @@ public class ClickTriggerGraph extends PamBorderPane {
|
||||
else filterVals[i]=alpha*Math.abs(waveform[i])+(1-alpha)*filterVals[i-1];
|
||||
}
|
||||
return filterVals;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a click waveform with some added noise.
|
||||
* @param type - the type of click e.g. ClickTriggerGraph.PORPOISE_CLICK.
|
||||
* @param noise. 0 to 1. 1 means max noise amplitude will be same as maximum click amplitude.
|
||||
* @return click and noise waveform.
|
||||
*/
|
||||
private double[] generateClickWaveform(int type, double noise){
|
||||
SimSignal clickSound;
|
||||
int sR;
|
||||
double length;
|
||||
double freq;
|
||||
switch (type){
|
||||
//TODO - add more types of clicks.
|
||||
case PORPOISE_CLICK:
|
||||
clickSound=new ClickSound("Porpoise", freq=140000, freq2=140000, length=0.00015, WINDOWTYPE.HANN);
|
||||
sR=500000;
|
||||
break;
|
||||
case SPERM_WHALE:
|
||||
clickSound=(new ClickSound("Beaked Whale", 30000, 60000, length = 0.3e-3, WINDOWTYPE.HANN));
|
||||
sR=192000;
|
||||
break;
|
||||
default:
|
||||
clickSound=new ClickSound("Porpoise", freq=140000, freq2=140000, length=0.00015, WINDOWTYPE.HANN);
|
||||
sR=500000;
|
||||
break;
|
||||
}
|
||||
|
||||
//now need to work out how many noise samples to add. Use the length of the click
|
||||
int nNoiseSamples=(int) (2*length*sR);
|
||||
double[] waveform=new double[3*nNoiseSamples];
|
||||
int n=0;
|
||||
for (int i=0; i<3*nNoiseSamples; i++){
|
||||
double noiseSample=noise*(Math.random()-0.5);
|
||||
double[] signal=clickSound.getSignal(0,sR,0);
|
||||
if (i>nNoiseSamples && n <signal.length){
|
||||
waveform[i]=signal[n]+noiseSample;
|
||||
n=n+1;
|
||||
}
|
||||
else waveform[i]=noiseSample;
|
||||
}
|
||||
|
||||
return waveform;
|
||||
}
|
||||
|
||||
public LineChart<Number, Number> createWaveformGraph(){
|
||||
|
||||
|
||||
|
||||
public Pane createWaveformGraph(){
|
||||
|
||||
StackPane stackPane = new PamStackPane();
|
||||
|
||||
|
||||
xAxis=new NumberAxis();
|
||||
xAxis.setMaxWidth(Double.MAX_VALUE);
|
||||
xAxis.setLabel("Sample");
|
||||
@ -154,20 +103,39 @@ public class ClickTriggerGraph extends PamBorderPane {
|
||||
yAxis=new NumberAxis(-1,1,0.2);
|
||||
yAxis.setLabel("Amplitude");
|
||||
yAxis.setAutoRanging(false);
|
||||
|
||||
|
||||
plotChart=new PamLineChart<Number, Number>(xAxis, yAxis);
|
||||
plotChart.setMaxWidth(Double.MAX_VALUE);
|
||||
|
||||
plotChart.setAnimated(false);
|
||||
plotChart.setLegendVisible(false);
|
||||
plotChart.setCreateSymbols(false);
|
||||
|
||||
|
||||
plotChart.getStyleClass().add("thin-chart");
|
||||
//plotChart.getXAxis().setSide(Side.BOTTOM);
|
||||
return plotChart;
|
||||
|
||||
ChoiceBox<ExampleSoundType> waveformChoice = new ChoiceBox<ExampleSoundType>();
|
||||
ArrayList<ExampleSoundType> exampleSounds = exampleSoundFactory.getExampleSoundTypes(ExampleSoundCategory.ODONTOCETES_CLICKS, ExampleSoundCategory.BAT);
|
||||
|
||||
for (int i=0; i<exampleSounds.size(); i++) {
|
||||
waveformChoice.getItems().add(exampleSounds.get(i));
|
||||
}
|
||||
waveformChoice.setOnAction((action)->{
|
||||
generateClickWaveform(waveformChoice.getSelectionModel().getSelectedItem(), noise);
|
||||
updateGraphWaveform() ;
|
||||
updateGraphFilter();
|
||||
});
|
||||
waveformChoice.getSelectionModel().select(ExampleSoundType.PORPOISE_CLICK);
|
||||
waveformChoice.setPrefWidth(180);
|
||||
|
||||
StackPane.setAlignment(waveformChoice, Pos.TOP_RIGHT);
|
||||
|
||||
|
||||
stackPane.getChildren().addAll(plotChart, waveformChoice);
|
||||
|
||||
return stackPane;
|
||||
}
|
||||
|
||||
|
||||
public double getLongFilter() {
|
||||
return longFilter;
|
||||
}
|
||||
@ -176,6 +144,131 @@ public class ClickTriggerGraph extends PamBorderPane {
|
||||
this.longFilter = longFilter;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update the waveform of the species.
|
||||
*/
|
||||
public synchronized void updateGraphWaveform() {
|
||||
plotChart.getData().clear();
|
||||
|
||||
|
||||
Series<Number, Number> waveformSeries = new Series<Number, Number>();
|
||||
for (int i=0; i<waveform.length; i++){
|
||||
waveformSeries.getData().add(new Data<Number, Number>(i, waveform[i]));
|
||||
}
|
||||
|
||||
plotChart.getData().add(waveformSeries);
|
||||
}
|
||||
/**
|
||||
* Update graph. Delete current data series and create new one.
|
||||
*/
|
||||
public synchronized void updateGraphFilter(){
|
||||
|
||||
if (waveform.length<500) {
|
||||
if (task!=null) {
|
||||
task.cancel(true);
|
||||
}
|
||||
|
||||
//no need to do on separate thread.
|
||||
plotChart.getData().remove(signalLevelSeries);
|
||||
plotChart.getData().remove(noiseLevelSeries);
|
||||
|
||||
plotChart.getData().add(signalLevelSeries = calcSeries(waveform, shortFilter));
|
||||
plotChart.getData().add(noiseLevelSeries = calcSeries(waveform, longFilter));
|
||||
}
|
||||
else {
|
||||
if (task!=null) {
|
||||
if (task.isRunning()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
* FIXME
|
||||
* This is a little ridiculous but there are two bugs in JavaFX
|
||||
* 1) The line chart is super slow
|
||||
* 2) If you get a freeze in the FX application thread then your trigger the spinner button multiple times.
|
||||
*
|
||||
* Doing this on a thread gets rid of the issue but is not a particular nice solution.
|
||||
*/
|
||||
|
||||
task = new Task<Integer>() {
|
||||
@Override protected Integer call() throws Exception {
|
||||
|
||||
Series<Number, Number> signalLevelSeries1 = calcSeries(waveform, shortFilter);
|
||||
Series<Number, Number> noiseLevelSeries2 = calcSeries(waveform, longFilter);
|
||||
|
||||
Platform.runLater(()->{
|
||||
// if (shortFilter!=shortFilter1 || forceChange) {
|
||||
plotChart.getData().remove(signalLevelSeries);
|
||||
plotChart.getData().add(signalLevelSeries1);
|
||||
signalLevelSeries = signalLevelSeries1;
|
||||
// }
|
||||
|
||||
// if (shortFilter!=shortFilter1 || forceChange) {
|
||||
plotChart.getData().remove(noiseLevelSeries);
|
||||
plotChart.getData().add(noiseLevelSeries2);
|
||||
noiseLevelSeries = noiseLevelSeries2;
|
||||
// }
|
||||
|
||||
});
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
Thread th = new Thread(task);
|
||||
th.setDaemon(true);
|
||||
th.start();
|
||||
}
|
||||
}
|
||||
|
||||
private Series<Number, Number> calcSeries(double[] waveform, double alpha){
|
||||
Series<Number, Number> signalLevelSeries1 = new Series<Number, Number>();
|
||||
double[] signalLevel=calcFilter(waveform, alpha);
|
||||
|
||||
for (int i=0; i<waveform.length; i++){
|
||||
signalLevelSeries1.getData().add(new Data<Number, Number>(i, signalLevel[i]));
|
||||
}
|
||||
|
||||
return signalLevelSeries1;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a click waveform with some added noise.
|
||||
* @param type - the type of click e.g. ClickTriggerGraph.PORPOISE_CLICK.
|
||||
* @param noise. 0 to 1. 1 means max noise amplitude will be same as maximum click amplitude.
|
||||
* @return click and noise waveform.
|
||||
*/
|
||||
private void generateClickWaveform(ExampleSoundType selectedItem, double noise) {
|
||||
|
||||
ExampleSound sound = this.exampleSoundFactory.getExampleSound(selectedItem);
|
||||
|
||||
double sR = sound.getSampleRate();
|
||||
|
||||
//System.out.println("Waveform: " + sound.getWave().length + " " + selectedItem);
|
||||
|
||||
double[] clickWave = PamArrayUtils.divide( sound.getWave(), PamArrayUtils.max( sound.getWave()));
|
||||
//now need to work out how many noise samples to add. Use the length of the click
|
||||
int nNoiseSamples=Math.min((int) (clickWave.length), sound.getWave().length >2000? 0 : 100);
|
||||
double[] waveform=new double[2*nNoiseSamples + clickWave.length];
|
||||
int n=0;
|
||||
double[] signal=clickWave;
|
||||
for (int i=0; i<waveform.length; i++){
|
||||
double noiseSample=noise*(Math.random()-0.5);
|
||||
if (i>nNoiseSamples && n<clickWave.length){
|
||||
waveform[i]=signal[n]+noiseSample;
|
||||
n=n+1;
|
||||
}
|
||||
else waveform[i]=noiseSample;
|
||||
}
|
||||
|
||||
this.waveform=waveform;
|
||||
//System.out.println("Waveform: " + waveform.length);
|
||||
}
|
||||
|
||||
|
||||
public double getShortFilter() {
|
||||
return shortFilter;
|
||||
}
|
||||
@ -185,6 +278,6 @@ public class ClickTriggerGraph extends PamBorderPane {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import clickDetector.ClickClassifiers.basic.BasicClickIdentifier;
|
||||
|
||||
/**
|
||||
* Pane for the basic click classifier.
|
||||
*
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
@ -319,4 +320,13 @@ public class BasicIdentifierPaneFX implements ClassifyPaneFX {
|
||||
return clickClassifiers;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the flip pane. One side shows the table, the other shows the currently selected classifier settings.
|
||||
* @return the flip pane.
|
||||
*/
|
||||
public PamFlipPane getFlipPane() {
|
||||
return flipPane;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -23,10 +23,13 @@ import pamViewFX.fxNodes.PamHBox;
|
||||
import pamViewFX.fxNodes.PamStackPane;
|
||||
import pamViewFX.fxNodes.PamVBox;
|
||||
import pamViewFX.fxNodes.hidingPane.HidingPane;
|
||||
import pamViewFX.fxNodes.utilityPanes.PamToggleSwitch;
|
||||
|
||||
/**
|
||||
* Pane which allows users to select click classifiers. Rather than opening endless dialogs click settings are
|
||||
* handled by sliding panes.
|
||||
* <p>
|
||||
* Note that this is a copy...ish of the swing frameowrk - wouldn't od things this way usually.
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
@ -43,7 +46,7 @@ public class ClickClassifyPaneFX extends PamStackPane {
|
||||
private ClickControl clickControl;
|
||||
|
||||
|
||||
private CheckBox runOnlineCheckBox;
|
||||
private PamToggleSwitch runOnlineCheckBox;
|
||||
|
||||
private CheckBox discardClicksCheckBox;
|
||||
|
||||
@ -120,16 +123,16 @@ public class ClickClassifyPaneFX extends PamStackPane {
|
||||
classifierComboBox.getItems().add(clickControl.getClassifierManager().getClassifierName(i));
|
||||
classifierComboBox.setOnAction((action)->{
|
||||
//get the current click identifier.
|
||||
System.out.println("ClickClassifyPaneFX:setOnAction: " +classifierComboBox.getSelectionModel().getSelectedIndex());
|
||||
//System.out.println("ClickClassifyPaneFX:setOnAction: " +classifierComboBox.getSelectionModel().getSelectedIndex());
|
||||
currentClickIdentifier=clickControl.getClassifierManager().
|
||||
getClassifier(classifierComboBox.getSelectionModel().getSelectedIndex());
|
||||
getClassifier(classifierComboBox.getSelectionModel().getSelectedIndex());
|
||||
//change the centre pane to classifier specific pane
|
||||
setCenterPane();
|
||||
});
|
||||
}
|
||||
|
||||
runOnlineCheckBox=new CheckBox("Run Classifier");
|
||||
discardClicksCheckBox=new CheckBox("Discdard Classified Clicks");
|
||||
runOnlineCheckBox=new PamToggleSwitch("Run Classifier");
|
||||
//discardClicksCheckBox=new CheckBox("Discdard Classified Clicks");
|
||||
|
||||
PamHBox pamHBox=new PamHBox();
|
||||
pamHBox.setAlignment(Pos.CENTER);
|
||||
@ -168,6 +171,9 @@ public class ClickClassifyPaneFX extends PamStackPane {
|
||||
|
||||
//System.out.println("ClickClassifyPaneFX:setParams(): " +classifierComboBox.getSelectionModel().getSelectedIndex());
|
||||
classifierComboBox.getSelectionModel().select(clickParameters.clickClassifierType);
|
||||
|
||||
//System.out.println("ClickClassifyPaneFX: setParams: get selected classifier is: " + clickParameters.clickClassifierType);
|
||||
|
||||
//set classifier parameters
|
||||
if (currentClickIdentifier!=null && currentClickIdentifier.getClassifierPane()!=null) {
|
||||
this.currentClickIdentifier.getClassifierPane().setParams();
|
||||
@ -180,6 +186,8 @@ public class ClickClassifyPaneFX extends PamStackPane {
|
||||
//System.out.println("ClickClassifyPaneFX:getParams(): " +classifierComboBox.getSelectionModel().getSelectedIndex());
|
||||
|
||||
clickParameters.clickClassifierType=classifierComboBox.getSelectionModel().getSelectedIndex();
|
||||
|
||||
//System.out.println("ClickClassifyPaneFX: getParams: get selected classifier is: " + clickParameters.clickClassifierType);
|
||||
if (currentClickIdentifier != null && currentClickIdentifier.getClassifierPane() != null) {
|
||||
currentClickIdentifier.getClassifierPane().getParams();
|
||||
}
|
||||
|
@ -38,6 +38,14 @@ public class SweepClassifierPaneFX extends BasicIdentifierPaneFX {
|
||||
@Override
|
||||
public void setClassifierPane(ClickTypeProperty clickTypeProperty){
|
||||
SweepClassifierSetPaneFX sweepPane=new SweepClassifierSetPaneFX(sweepClickClassifier);
|
||||
|
||||
|
||||
//make it so the title of the pane is the same as the name as the classifier
|
||||
getFlipPane().getAdvLabel().textProperty().unbind();
|
||||
getFlipPane().getAdvLabel().textProperty().bind( sweepPane.getNameTextProperty());
|
||||
|
||||
sweepPane.classifierItemRow = sweepClickClassifier.getSweepClassifierParams().getSetRow((SweepClassifierSet) clickTypeProperty.getClickType());
|
||||
|
||||
sweepPane.setParams(clickTypeProperty);
|
||||
super.getClickTypeHolder().setCenter(sweepPane.getContentNode());
|
||||
|
||||
@ -52,14 +60,20 @@ public class SweepClassifierPaneFX extends BasicIdentifierPaneFX {
|
||||
|
||||
@Override
|
||||
public void setParams() {
|
||||
|
||||
sweepIdParameters = sweepClickClassifier.getSweepClassifierParams().clone();
|
||||
|
||||
|
||||
//change the table
|
||||
tableDataChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getParams() {
|
||||
sweepClickClassifier.setSeepClassifierParams(sweepIdParameters);
|
||||
// System.out.println("Sweep classifier getParams: " + sweepIdParameters);
|
||||
if (sweepIdParameters==null) sweepIdParameters = new SweepClassifierParameters();
|
||||
|
||||
sweepClickClassifier.setSweepClassifierParams(sweepIdParameters);
|
||||
|
||||
//remove all classifiers and add whatever is in the table.
|
||||
sweepClickClassifier.getSweepClassifierParams().removeAll();
|
||||
|
@ -3,6 +3,7 @@ package clickDetector.layoutFX.clickClassifiers;
|
||||
|
||||
import fftFilter.FFTFilterParams;
|
||||
import fftManager.FFTLengthModeled;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.geometry.HPos;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Orientation;
|
||||
@ -30,9 +31,13 @@ import pamViewFX.fxNodes.picker.SymbolPicker;
|
||||
import pamViewFX.fxNodes.utilityPanes.FreqBandPane;
|
||||
import pamViewFX.fxNodes.utilityPanes.PamToggleSwitch;
|
||||
import pamViewFX.fxNodes.utilityPanes.SimpleFilterPaneFX;
|
||||
import pamViewFX.fxNodes.utilsFX.PamUtilsFX;
|
||||
import pamViewFX.PamGuiManagerFX;
|
||||
import net.synedra.validatorfx.Validator;
|
||||
|
||||
import PamController.SettingsPane;
|
||||
import PamView.PamSymbol;
|
||||
import PamView.symbol.SymbolData;
|
||||
import clickDetector.ClickClassifiers.basicSweep.CodeHost;
|
||||
import clickDetector.ClickClassifiers.basicSweep.SweepClassifier;
|
||||
import clickDetector.ClickClassifiers.basicSweep.SweepClassifierSet;
|
||||
@ -95,7 +100,11 @@ public class SweepClassifierSetPaneFX extends SettingsPane<ClickTypeProperty> {
|
||||
*/
|
||||
private AmplitudeBlock amplitudeBlock;
|
||||
|
||||
PamBorderPane mainPane = new PamBorderPane();
|
||||
private PamBorderPane mainPane = new PamBorderPane();
|
||||
|
||||
private Validator validator = new Validator();
|
||||
|
||||
public int classifierItemRow;
|
||||
|
||||
public SweepClassifierSetPaneFX(SweepClassifier sweepClassifier){
|
||||
super(null);
|
||||
@ -325,6 +334,14 @@ public class SweepClassifierSetPaneFX extends SettingsPane<ClickTypeProperty> {
|
||||
*/
|
||||
private Label lengthMS;
|
||||
|
||||
private ComboBox<String> lengthTypeBox;
|
||||
|
||||
private CheckBox restrictLength;
|
||||
|
||||
private ColorPicker lineColourPicker;
|
||||
|
||||
private ColorPicker fillColourPicker;
|
||||
|
||||
OptionsBox() {
|
||||
super("General Options", false);
|
||||
this.getHolderPane().setCenter(createOptionsPane());
|
||||
@ -334,6 +351,7 @@ public class SweepClassifierSetPaneFX extends SettingsPane<ClickTypeProperty> {
|
||||
//create the general options
|
||||
private Node createOptionsPane(){
|
||||
|
||||
|
||||
PamGridPane pamGridPane=new PamGridPane();
|
||||
pamGridPane.setHgap(5);
|
||||
pamGridPane.setVgap(5);
|
||||
@ -343,25 +361,54 @@ public class SweepClassifierSetPaneFX extends SettingsPane<ClickTypeProperty> {
|
||||
|
||||
nameField=new TextField();
|
||||
nameField.setPrefColumnCount(10);
|
||||
pamGridPane.add(nameField, 0, 0);
|
||||
PamGridPane.setColumnSpan(nameField, 2);
|
||||
|
||||
pamGridPane.add(nameField, 1, 0);
|
||||
PamGridPane.setColumnSpan(nameField, 8);
|
||||
PamGridPane.setHgrow(nameField, Priority.ALWAYS);
|
||||
|
||||
pamGridPane.add(new Label("Code"), 3, 0);
|
||||
validator.createCheck()
|
||||
.dependsOn("speciesname", nameField.textProperty())
|
||||
.withMethod(c -> {
|
||||
String userName = c.get("speciesname");
|
||||
if (userName == null || userName.length()<=0) {
|
||||
c.error("The classifier must have a name");
|
||||
}
|
||||
})
|
||||
.decorates(nameField)
|
||||
.immediate();
|
||||
;
|
||||
|
||||
|
||||
pamGridPane.add(new Label("Code"), 0, 1);
|
||||
|
||||
codeSpinner=new PamSpinner<Integer> (0, 500, 0, 1);
|
||||
codeSpinner=new PamSpinner<Integer> (1, 500, 0, 1);
|
||||
codeSpinner.setEditable(true);
|
||||
//codeSpinner.setPrefWidth(150);
|
||||
codeSpinner.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL);
|
||||
pamGridPane.add(codeSpinner, 1, 0);
|
||||
pamGridPane.add(codeSpinner, 1, 1);
|
||||
|
||||
// pamGridPane.add(new Label("Symbol"), 0,1);
|
||||
|
||||
//create colour picker to allow users to change symbol colour.
|
||||
symbolPicker=new SymbolPicker();
|
||||
pamGridPane.add(symbolPicker, 2, 0);
|
||||
pamGridPane.add(symbolPicker, 3,1);
|
||||
|
||||
pamGridPane.add(new Label("Symbol"), 3,0);
|
||||
pamGridPane.add(new Label("Symbol"), 2,1);
|
||||
|
||||
lineColourPicker = new ColorPicker();
|
||||
lineColourPicker.setStyle("-fx-color-label-visible: false ;");
|
||||
lineColourPicker.setOnAction((action)->{
|
||||
symbolPicker.setLineColour(lineColourPicker.getValue());
|
||||
});
|
||||
pamGridPane.add(lineColourPicker, 4, 1);
|
||||
|
||||
|
||||
fillColourPicker = new ColorPicker();
|
||||
fillColourPicker.setStyle("-fx-color-label-visible: false ;");
|
||||
fillColourPicker.setOnAction((action)->{
|
||||
symbolPicker.setFillColour(fillColourPicker.getValue());
|
||||
});
|
||||
pamGridPane.add(fillColourPicker, 5, 1);
|
||||
|
||||
|
||||
// //create a button to allow users to change symbol shape.
|
||||
// symbolColour=new ColorPicker();
|
||||
@ -371,35 +418,46 @@ public class SweepClassifierSetPaneFX extends SettingsPane<ClickTypeProperty> {
|
||||
// });
|
||||
|
||||
//channel options
|
||||
pamGridPane.add(new Label("Channels"), 0,1);
|
||||
pamGridPane.add(new Label("Channels"), 0,2);
|
||||
|
||||
channelsBox = new ComboBox<String>();
|
||||
for (int i = 0; i < 3; i++) {
|
||||
channelsBox.getItems().add(SweepClassifierSet.getChannelOptionsName(i));
|
||||
}
|
||||
pamGridPane.add(channelsBox, 1,1);
|
||||
pamGridPane.add(channelsBox, 1,2);
|
||||
|
||||
PamGridPane.setColumnSpan(channelsBox, 7);
|
||||
PamGridPane.setColumnSpan(channelsBox,8 );
|
||||
|
||||
//restrict parameter to click centre
|
||||
PamHBox clickCenterBox=new PamHBox();
|
||||
clickCenterBox.setSpacing(5);
|
||||
|
||||
clickCenterBox.getChildren().add(new CheckBox("Analyse click "));
|
||||
clickCenterBox.getChildren().add(restrictLength = new CheckBox("Trim click"));
|
||||
|
||||
clickLengthSpinner=new PamSpinner<Integer>(4,102400,128,32);
|
||||
clickLengthSpinner.setEditable(true);
|
||||
//clickLengthSpinner.setPrefWidth(150);
|
||||
clickLengthSpinner.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL);
|
||||
clickLengthSpinner.valueProperty().addListener((obsVal, oldVal, newVal)->{
|
||||
setLengthLabel();
|
||||
});
|
||||
|
||||
clickCenterBox.getChildren().add(clickLengthSpinner);
|
||||
clickCenterBox.getChildren().add(new Label("samples"));
|
||||
Label samplesLabel =new Label("samples");
|
||||
clickCenterBox.getChildren().add(samplesLabel);
|
||||
clickCenterBox.getChildren().add(lengthMS=new Label("()"));
|
||||
clickCenterBox.getChildren().add(new Label("around click center."));
|
||||
clickCenterBox.getChildren().add(lengthTypeBox = new ComboBox<String>());
|
||||
lengthTypeBox.getItems().add("around click center");
|
||||
lengthTypeBox.getItems().add("from start of click");
|
||||
clickCenterBox.setAlignment(Pos.CENTER_LEFT);
|
||||
PamGridPane.setColumnSpan(clickCenterBox, 4);
|
||||
PamGridPane.setHgrow(clickCenterBox, Priority.ALWAYS);
|
||||
pamGridPane.add(clickCenterBox, 0,2);
|
||||
|
||||
restrictLength.setOnAction((action)->{
|
||||
lengthTypeBox.setDisable(!restrictLength.isSelected());
|
||||
clickLengthSpinner.setDisable(!restrictLength.isSelected());
|
||||
samplesLabel.setDisable(!restrictLength.isSelected());
|
||||
lengthMS.setDisable(!restrictLength.isSelected());
|
||||
});
|
||||
|
||||
|
||||
// //column constraints
|
||||
// ColumnConstraints col1 = new ColumnConstraints();
|
||||
@ -414,14 +472,16 @@ public class SweepClassifierSetPaneFX extends SettingsPane<ClickTypeProperty> {
|
||||
// col4.setPercentWidth(35);
|
||||
//
|
||||
// pamGridPane.getColumnConstraints().addAll(col1, col2, col3,col4);
|
||||
|
||||
return pamGridPane;
|
||||
|
||||
|
||||
PamVBox holder = new PamVBox();
|
||||
holder.setSpacing(5);
|
||||
holder.getChildren().addAll(pamGridPane,clickCenterBox);
|
||||
|
||||
return holder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCode() {
|
||||
// TODO Auto-generated method stub
|
||||
return codeSpinner.getValue();
|
||||
}
|
||||
|
||||
@ -441,29 +501,99 @@ public class SweepClassifierSetPaneFX extends SettingsPane<ClickTypeProperty> {
|
||||
float sr = sweepClassifier.getClickDetector().getSampleRate();
|
||||
lengthMS.setText(String.format("(%.2f ms)", fftLength * 1000 / sr));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the length in seconds.
|
||||
*/
|
||||
private void setLengthLabel() {
|
||||
float sr = sweepClassifier.getClickDetector().getSampleRate();
|
||||
lengthMS.setText(String.format("(%.2f ms)", clickLengthSpinner.getValue() * 1000 / sr));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setParams() {
|
||||
nameField.setText(sweepClassifierSet.getName());
|
||||
codeSpinner.getValueFactory().setValue(sweepClassifierSet.getSpeciesCode());
|
||||
|
||||
if (sweepClassifierSet == null) {
|
||||
//symbolViewer.setSymbol(null);
|
||||
symbolPicker.getSelectionModel().select(0);
|
||||
nameField.setText("");
|
||||
setCode(sweepClassifier.getNextFreeCode(0));
|
||||
}
|
||||
else {
|
||||
symbolPicker.setSymbol(sweepClassifierSet.symbol == null? null : sweepClassifierSet.symbol.getSymbol());
|
||||
nameField.setText(sweepClassifierSet.getName());
|
||||
setCode(sweepClassifierSet.getSpeciesCode());
|
||||
}
|
||||
|
||||
if (sweepClassifierSet == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
lengthTypeBox.getSelectionModel().select(sweepClassifierSet.restrictedBinstype);
|
||||
|
||||
channelsBox.getSelectionModel().select(sweepClassifierSet.channelChoices);
|
||||
clickLengthSpinner.getValueFactory().setValue(sweepClassifierSet.restrictedBins);
|
||||
restrictLength.setSelected(sweepClassifierSet.restrictLength);
|
||||
setFFTLength(sweepClassifierSet.restrictedBins);
|
||||
|
||||
|
||||
// nameField.setText(sweepClassifierSet.getName());
|
||||
// codeSpinner.getValueFactory().setValue(sweepClassifierSet.getSpeciesCode());
|
||||
// channelsBox.getSelectionModel().select(sweepClassifierSet.channelChoices);
|
||||
//
|
||||
// //length stuff
|
||||
// clickLengthSpinner.getValueFactory().setValue(sweepClassifierSet.restrictedBins);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean getParams() {
|
||||
sweepClassifierSet.setName(nameField.getText());
|
||||
sweepClassifierSet.setSpeciesCode(codeSpinner.getValue());
|
||||
sweepClassifierSet.channelChoices=channelsBox.getSelectionModel().getSelectedIndex();
|
||||
sweepClassifierSet.restrictedBins=clickLengthSpinner.getValue();
|
||||
|
||||
if (this.symbolPicker.getValue()==null) {
|
||||
return showWarning("You must pick a symbol");
|
||||
}
|
||||
|
||||
SymbolData symbolData = new SymbolData(this.symbolPicker.getValue().getSymbol(), 10,10,true,
|
||||
PamUtilsFX.fxToAWTColor(this.lineColourPicker.getValue()), PamUtilsFX.fxToAWTColor(this.fillColourPicker.getValue()));
|
||||
sweepClassifierSet.symbol= new PamSymbol(symbolData);
|
||||
if (sweepClassifierSet.getName().length() <= 0) {
|
||||
return showWarning("You must enter a name for this type of click");
|
||||
}
|
||||
sweepClassifierSet.setSpeciesCode(getCode());
|
||||
if (sweepClassifier.codeDuplicated(sweepClassifierSet, classifierItemRow) ||
|
||||
sweepClassifierSet.getSpeciesCode() <= 0){
|
||||
return showWarning("You must enter a unique positive integer species code");
|
||||
}
|
||||
if (sweepClassifierSet.symbol == null) {
|
||||
return showWarning("You must select a symbol");
|
||||
}
|
||||
sweepClassifierSet.channelChoices = channelsBox.getSelectionModel().getSelectedIndex();
|
||||
sweepClassifierSet.restrictLength = restrictLength.isSelected();
|
||||
|
||||
sweepClassifierSet.restrictedBinstype = lengthTypeBox.getSelectionModel().getSelectedIndex();
|
||||
|
||||
try {
|
||||
sweepClassifierSet.restrictedBins = clickLengthSpinner.getValue();
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
return showWarning("Invalid Restricted length value");
|
||||
}
|
||||
return true;
|
||||
// sweepClassifierSet.setName(nameField.getText());
|
||||
// sweepClassifierSet.setSpeciesCode(codeSpinner.getValue());
|
||||
// sweepClassifierSet.channelChoices=channelsBox.getSelectionModel().getSelectedIndex();
|
||||
// sweepClassifierSet.restrictedBins=clickLengthSpinner.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void disbleControls(boolean enable) {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
public TextField getNameLabel() {
|
||||
return this.nameField;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1111,4 +1241,15 @@ public class SweepClassifierSetPaneFX extends SettingsPane<ClickTypeProperty> {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public StringProperty getNameTextProperty() {
|
||||
return optionBox.getNameLabel().textProperty();
|
||||
}
|
||||
|
||||
private boolean showWarning(String string) {
|
||||
PamDialogFX.showWarning(string);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -9,10 +9,7 @@ import clickTrainDetector.classification.CTClassifier;
|
||||
import clickTrainDetector.classification.CTClassifierParams;
|
||||
import clickTrainDetector.classification.CTClassifierType;
|
||||
import clickTrainDetector.classification.bearingClassifier.BearingClassifier;
|
||||
import clickTrainDetector.classification.bearingClassifier.BearingClassifierParams;
|
||||
import clickTrainDetector.classification.idiClassifier.IDIClassification;
|
||||
import clickTrainDetector.classification.idiClassifier.IDIClassifier;
|
||||
import clickTrainDetector.classification.simplechi2classifier.Chi2CTClassification;
|
||||
import clickTrainDetector.classification.simplechi2classifier.Chi2ThresholdClassifier;
|
||||
import clickTrainDetector.classification.templateClassifier.CTTemplateClassifier;
|
||||
import clickTrainDetector.layout.classification.CTClassifierGraphics;
|
||||
|
@ -342,7 +342,7 @@ public abstract class OfflineFileServer<TmapPoint extends FileDataMapPoint> impl
|
||||
return "Sound Files";
|
||||
}
|
||||
|
||||
protected TmapPoint findFirstMapPoint(Iterator<TmapPoint> mapIterator, long startMillis, long endMillis) {
|
||||
public TmapPoint findFirstMapPoint(Iterator<TmapPoint> mapIterator, long startMillis, long endMillis) {
|
||||
TmapPoint mapPoint, prevMapPoint = null;
|
||||
while (mapIterator.hasNext()) {
|
||||
mapPoint = mapIterator.next();
|
||||
|
@ -4,6 +4,7 @@ import java.util.ArrayList;
|
||||
|
||||
import PamController.PamController;
|
||||
import PamModel.PamModuleInfo;
|
||||
import atlantafx.base.theme.PrimerDark;
|
||||
import dataModelFX.ConnectionNodeParams.PAMConnectionNodeType;
|
||||
import dataModelFX.connectionNodes.ModuleIconFactory;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
@ -12,6 +13,7 @@ import javafx.event.EventHandler;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.SnapshotParameters;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Tooltip;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.input.ClipboardContent;
|
||||
@ -72,7 +74,9 @@ public class DataModelModulePane extends PamBorderPane {
|
||||
|
||||
private PamScrollPane createPane(){
|
||||
moduleSelectPane=new PamScrollPane();
|
||||
moduleSelectPane.getStylesheets().add(PamStylesManagerFX.getPamStylesManagerFX().getCurStyle().getSlidingDialogCSS());
|
||||
|
||||
moduleSelectPane.getStylesheets().add(PamStylesManagerFX.getPamStylesManagerFX().getCurStyle().getSlidingDialogCSS());
|
||||
|
||||
moduleSelectPane.setPrefWidth(250);
|
||||
moduleSelectPane.getStyleClass().add("scroll-pane-dark");
|
||||
|
||||
|
@ -16,6 +16,7 @@ import pamViewFX.fxNodes.connectionPane.StandardConnectionNode;
|
||||
import pamViewFX.fxNodes.connectionPane.StandardConnectionPlug;
|
||||
import pamViewFX.fxNodes.connectionPane.structures.ConnectionGroupStructure;
|
||||
import pamViewFX.fxNodes.connectionPane.structures.ConnectionStructure;
|
||||
import pamViewFX.fxStyles.PamStylesManagerFX;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.geometry.Orientation;
|
||||
import javafx.scene.control.SplitPane;
|
||||
|
@ -71,7 +71,7 @@ public class ModuleProcessDiagram extends PamBorderPane {
|
||||
|
||||
|
||||
public ModuleProcessDiagram (PamControlledUnit pamControlledUnit){
|
||||
this.getStylesheets().add(PamController.getInstance().getGuiManagerFX().getPamSettingsCSS());
|
||||
//this.getStylesheets().add(PamController.getInstance().getGuiManagerFX().getPamSettingsCSS());
|
||||
this.pamControlledUnit=pamControlledUnit;
|
||||
createUpdateTimer();
|
||||
createControlDataModel();
|
||||
@ -81,7 +81,7 @@ public class ModuleProcessDiagram extends PamBorderPane {
|
||||
private void createControlDataModel(){
|
||||
this.setMinWidth(100);
|
||||
this.setPrefWidth(USE_COMPUTED_SIZE);
|
||||
this.setStyle("-fx-background-color: -fx-darkbackground");
|
||||
//this.setStyle("-fx-background-color: -fx-darkbackground");
|
||||
this.populateDataModel();
|
||||
}
|
||||
|
||||
|
@ -158,7 +158,7 @@ public class TDDisplayFX extends PamBorderPane {
|
||||
/**
|
||||
* The height of the control pane.
|
||||
*/
|
||||
final static double controlPaneHeight=63;
|
||||
final static double CONTROL_PANE_HEIGHT=80;
|
||||
|
||||
|
||||
/**
|
||||
@ -238,7 +238,7 @@ public class TDDisplayFX extends PamBorderPane {
|
||||
//create top hiding panel.
|
||||
controlPane=new TDControlPaneFX(tdControl,this);
|
||||
controlPane.setParams(tdParametersFX);
|
||||
controlPane.setPrefHeight(controlPaneHeight);
|
||||
controlPane.setPrefHeight(CONTROL_PANE_HEIGHT);
|
||||
|
||||
hidingControlPane=new HidingPane(Side.TOP, controlPane, this, false );
|
||||
hidingControlPane.showHidePane(tdParametersFX.showControl);
|
||||
|
@ -272,7 +272,7 @@ public class TDGraphFX extends PamBorderPane {
|
||||
* blocks.
|
||||
*/
|
||||
tdAxisSelPane = new TDDataSelPaneFX(this);
|
||||
tdAxisSelPane.setPrefWidth(250);
|
||||
tdAxisSelPane.setPrefWidth(280);
|
||||
// put pane inside a scroll pane for graph resizing
|
||||
PamScrollPane scrollPane = new PamScrollPane(tdAxisSelPane);
|
||||
// scrollPane.setFitToWidth(true);
|
||||
|
@ -498,7 +498,7 @@
|
||||
plotted on the time-based display by adding Click detections to the
|
||||
display and then using the right</p>
|
||||
<p align="center">
|
||||
<img width="940" height="500" src="resources/clicktrain_TDFx.png">
|
||||
<img width="940" height="500" src="resources/clicktrain_TDFX.png">
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
@ -7,11 +7,14 @@ import java.util.ArrayList;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuItem;
|
||||
import PamController.PamControlledUnit;
|
||||
import PamController.PamControlledUnitGUI;
|
||||
import PamController.PamControlledUnitSettings;
|
||||
import PamController.PamControllerInterface;
|
||||
import PamController.PamGUIManager;
|
||||
import PamController.PamSettingManager;
|
||||
import PamController.PamSettings;
|
||||
import PamController.SettingsPane;
|
||||
import PamView.WrapperControlledGUISwing;
|
||||
import PamView.symbol.SymbolData;
|
||||
import PamguardMVC.PamDataBlock;
|
||||
import clickDetector.ClickClassifiers.ClickTypeProvider;
|
||||
@ -66,6 +69,17 @@ public class MTClassifierControl extends PamControlledUnit implements PamSetting
|
||||
* The offline process.
|
||||
*/
|
||||
private MTOfflineProcess mtOfflineProcess;
|
||||
|
||||
/**
|
||||
* The JavaFX graphics
|
||||
*/
|
||||
private MTControlGUI matchedClickGUIFX;
|
||||
|
||||
/**
|
||||
* The swing graphics - in this case the graphics are JavaFX so this calls a swing wrapper
|
||||
* to hold the JavaFX graphics.
|
||||
*/
|
||||
private PamControlledUnitGUI matchedClickGUIGUISwing;
|
||||
|
||||
|
||||
public MTClassifierControl(String unitName) {
|
||||
@ -379,6 +393,33 @@ public class MTClassifierControl extends PamControlledUnit implements PamSetting
|
||||
return mtOfflineProcess;
|
||||
}
|
||||
|
||||
public void setMTParams(MatchedTemplateParams newParams) {
|
||||
this.matchedTemplateParams = newParams;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the GUI for the PAMControlled unit. This has multiple GUI options which
|
||||
* are instantiated depending on the view type.
|
||||
*
|
||||
* @param flag. The GUI type flag defined in PAMGuiManager.
|
||||
* @return the GUI for the PamControlledUnit unit.
|
||||
*/
|
||||
public PamControlledUnitGUI getGUI(int flag) {
|
||||
if (flag == PamGUIManager.FX) {
|
||||
if (matchedClickGUIFX == null) {
|
||||
matchedClickGUIFX = new MTControlGUI(this);
|
||||
}
|
||||
return matchedClickGUIFX;
|
||||
}
|
||||
if (flag == PamGUIManager.SWING) {
|
||||
if (matchedClickGUIGUISwing == null) {
|
||||
matchedClickGUIGUISwing = new WrapperControlledGUISwing(this);
|
||||
}
|
||||
return matchedClickGUIGUISwing;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
74
src/matchedTemplateClassifer/MTControlGUI.java
Normal file
74
src/matchedTemplateClassifer/MTControlGUI.java
Normal file
@ -0,0 +1,74 @@
|
||||
package matchedTemplateClassifer;
|
||||
|
||||
import PamController.PamControlledUnitGUI;
|
||||
import PamController.PamController;
|
||||
import PamController.PamControllerInterface;
|
||||
import PamController.PamGUIManager;
|
||||
import PamController.SettingsPane;
|
||||
import PamView.WrapperControlledGUISwing;
|
||||
import pamViewFX.PamControlledGUIFX;
|
||||
import rawDeepLearningClassifier.DLControl;
|
||||
import rawDeepLearningClassifier.DLControlGUI;
|
||||
import rawDeepLearningClassifier.RawDLParams;
|
||||
|
||||
/**
|
||||
* The JavaFX GUI for the Matched click classifier control...
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
public class MTControlGUI extends PamControlledGUIFX {
|
||||
|
||||
/**
|
||||
* The dl control.
|
||||
*/
|
||||
private MTClassifierControl mtControl;
|
||||
|
||||
|
||||
public MTControlGUI(MTClassifierControl dlcontrol) {
|
||||
this.mtControl = dlcontrol;
|
||||
}
|
||||
|
||||
/**
|
||||
* The settings pane contains ALL possible setting for the module in one placed.
|
||||
* Settings panes can be divided into tabs for more space etc.
|
||||
*
|
||||
* @param <T>
|
||||
* @return a Pane containing controls to change settings for module.
|
||||
*/
|
||||
public SettingsPane<?> getSettingsPane(){
|
||||
mtControl.getSettingsPane().setParams(mtControl.getMTParams());
|
||||
return mtControl.getSettingsPane();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void updateParams() {
|
||||
MatchedTemplateParams newParams=mtControl.getSettingsPane().getParams(mtControl.getMTParams());
|
||||
if (newParams!=null) {
|
||||
mtControl.setMTParams(newParams);
|
||||
}
|
||||
//setup the controlled unit.
|
||||
mtControl.setupControlledUnit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyGUIChange(int changeType) {
|
||||
switch (changeType) {
|
||||
case PamController.INITIALIZATION_COMPLETE:
|
||||
break;
|
||||
case PamControllerInterface.CHANGED_PROCESS_SETTINGS:
|
||||
//data source may have potentially changed. e.g. by a datamodelfx Need to set in params.
|
||||
//System.out.println("FFTControl: CHANGED_PROCESS_SETTINGS : " +fftProcess.getParentDataBlock());
|
||||
if (mtControl.getParentDataBlock()!=null){
|
||||
mtControl.getMTParams().dataSourceName = mtControl.getParentDataBlock().getDataName();
|
||||
}
|
||||
else mtControl.getMTParams().dataSourceName = "";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
import PamController.PamController;
|
||||
import PamDetection.RawDataUnit;
|
||||
import PamUtils.complex.ComplexArray;
|
||||
import PamView.symbol.PamSymbolManager;
|
||||
import PamguardMVC.PamDataBlock;
|
||||
@ -12,8 +13,10 @@ import PamguardMVC.PamInstantProcess;
|
||||
import PamguardMVC.PamObservable;
|
||||
import PamguardMVC.RawDataHolder;
|
||||
import Spectrogram.WindowFunction;
|
||||
import clickDetector.ClickDetection;
|
||||
import clickDetector.ClickLength;
|
||||
import clickDetector.ClickClassifiers.basicSweep.SweepClassifierSet;
|
||||
import clipgenerator.ClipDataUnit;
|
||||
import fftManager.FastFFT;
|
||||
import matchedTemplateClassifer.annotation.MatchedClickAnnotation;
|
||||
import matchedTemplateClassifer.annotation.MatchedClickAnnotationType;
|
||||
@ -485,6 +488,21 @@ public class MTProcess extends PamInstantProcess {
|
||||
public BeskopeClassifierManager getBespokeClassifierManager() {
|
||||
return bespokeClassifierManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* A list of data block class types which are compatible as parent data blocks
|
||||
* for the PamProcess. This can return null, e.g. in the case of Acquisition
|
||||
* process.
|
||||
*
|
||||
* @return a list of PamDataBlock sub class types which can be used as parent
|
||||
* data blocks for the process.
|
||||
*/
|
||||
@Override
|
||||
public ArrayList getCompatibleDataUnits(){
|
||||
return new ArrayList<Class<? extends PamDataUnit>>(Arrays.asList(ClickDetection.class));
|
||||
}
|
||||
|
||||
|
||||
|
||||
// /**
|
||||
// * Get the parent click data block.
|
||||
|
@ -9,9 +9,10 @@ import java.net.Socket;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.Timer;
|
||||
|
||||
import x3.CRC16;
|
||||
import x3.X3FrameDecode;
|
||||
import x3.X3FrameHeader;
|
||||
import org.pamguard.x3.x3.CRC16;
|
||||
import org.pamguard.x3.x3.X3FrameDecode;
|
||||
import org.pamguard.x3.x3.X3FrameHeader;
|
||||
|
||||
import networkTransfer.NetworkObject;
|
||||
import networkTransfer.receive.BuoyStatusDataUnit;
|
||||
import networkTransfer.receive.NetworkDataUser;
|
||||
|
@ -13,12 +13,15 @@ import pamViewFX.fxNodes.PamVBox;
|
||||
import pamViewFX.fxNodes.internalNode.PamInternalPane;
|
||||
import pamViewFX.fxNodes.pamDialogFX.PamDialogFX;
|
||||
import pamViewFX.fxNodes.pamDialogFX.PamSettingsDialogFX;
|
||||
import pamViewFX.fxStyles.PamAtlantaStyle;
|
||||
import pamViewFX.fxStyles.PamStylesManagerFX;
|
||||
import pamViewFX.pamTask.PamTaskUpdate;
|
||||
import userDisplayFX.UserDisplayNodeFX;
|
||||
import PamModel.PamModel;
|
||||
import PamModel.PamModuleInfo;
|
||||
import PamView.PamViewInterface;
|
||||
import atlantafx.base.theme.PrimerDark;
|
||||
import atlantafx.base.theme.PrimerLight;
|
||||
import dataMap.layoutFX.DataMapPaneFX;
|
||||
import PamController.PAMControllerGUI;
|
||||
import PamController.PamControlledUnit;
|
||||
@ -28,6 +31,7 @@ import PamController.PamGUIManager;
|
||||
import PamController.PamSettingManager;
|
||||
import PamController.PamSettings;
|
||||
import dataModelFX.DataModelPaneFX;
|
||||
import javafx.application.Application;
|
||||
import javafx.application.Platform;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.geometry.Insets;
|
||||
@ -134,11 +138,11 @@ public class PamGuiManagerFX implements PAMControllerGUI, PamSettings {
|
||||
|
||||
|
||||
public PamGuiManagerFX(PamController pamController, Object stage) {
|
||||
|
||||
|
||||
|
||||
this.pamController=pamController;
|
||||
pamGuiSettings= new PAMGuiFXSettings();
|
||||
|
||||
|
||||
primaryStage= (Stage) stage;
|
||||
|
||||
primaryStage.setOnCloseRequest(e->{
|
||||
@ -159,19 +163,22 @@ public class PamGuiManagerFX implements PAMControllerGUI, PamSettings {
|
||||
*/
|
||||
private void start(Stage primaryStage) {
|
||||
|
||||
PamStylesManagerFX.getPamStylesManagerFX().setCurStyle(new PamAtlantaStyle());
|
||||
|
||||
//add stage
|
||||
stages.add(primaryView = new PamGuiFX(primaryStage, this));
|
||||
//create new data model.
|
||||
dataModelFX=stages.get(0).addDataModelTab();
|
||||
|
||||
scene = new Scene(stages.get(0));
|
||||
scene.getStylesheets().add(getPamCSS());
|
||||
|
||||
|
||||
// Application.setUserAgentStylesheet(new PrimerDark().getUserAgentStylesheet());
|
||||
// stages.get(0).prefWidthProperty().bind(scene.widthProperty());
|
||||
// stages.get(0).prefHeightProperty().bind(scene.heightProperty());
|
||||
|
||||
primaryStage.setScene(scene);
|
||||
// scene.getStylesheets().add(pamCSS);
|
||||
scene.getStylesheets().add(getPamCSS());
|
||||
//need to add this for material design icons and fontawesome icons
|
||||
// scene.getStylesheets().addAll(GlyphsStyle.DEFAULT.getStylePath());
|
||||
|
||||
@ -458,7 +465,7 @@ public class PamGuiManagerFX implements PAMControllerGUI, PamSettings {
|
||||
TabSelectionPane tabSelectionPane=new TabSelectionPane(stages.get(0));
|
||||
|
||||
PamSettingsDialogFX<?> settingsDialog=new PamSettingsDialogFX(tabSelectionPane);
|
||||
settingsDialog.getDialogPane().getStylesheets().add(PamController.getInstance().getGuiManagerFX().getPamSettingsCSS());
|
||||
settingsDialog.getDialogPane().getStylesheets().add(PamStylesManagerFX.getPamStylesManagerFX().getCurStyle().getDialogCSS());
|
||||
settingsDialog.initStyle(StageStyle.UNDECORATED);
|
||||
|
||||
// ChoiceDialog<String> dialog = new ChoiceDialog<>(tabStrings.get(1), tabStrings);
|
||||
@ -485,7 +492,7 @@ public class PamGuiManagerFX implements PAMControllerGUI, PamSettings {
|
||||
* Get CSS for PAMGUARD setting 'look and feel' for sliding dialogs
|
||||
* @return the CSS for settings feels.
|
||||
*/
|
||||
public String getPamSettingsCSS() {
|
||||
public String getPamSettingsCSS() {//return new PrimerDark().getUserAgentStylesheet();
|
||||
// return getClass().getResource("/Resources/css/pamSettingsCSS.css").toExternalForm();
|
||||
return PamStylesManagerFX.getPamStylesManagerFX().getCurStyle().getSlidingDialogCSS();
|
||||
}
|
||||
@ -495,6 +502,7 @@ public class PamGuiManagerFX implements PAMControllerGUI, PamSettings {
|
||||
* @return the standard CSS fro PAMGUARD.
|
||||
*/
|
||||
public String getPamCSS() {
|
||||
//return new PrimerLight().getUserAgentStylesheet();
|
||||
// return getClass().getResource("/Resources/css/pamCSS.css").toExternalForm();
|
||||
return PamStylesManagerFX.getPamStylesManagerFX().getCurStyle().getGUICSS();
|
||||
}
|
||||
@ -503,8 +511,9 @@ public class PamGuiManagerFX implements PAMControllerGUI, PamSettings {
|
||||
* Get CSS for PAMGUARD GUI standard 'look and feel' for regular dialogs
|
||||
* @return the standard CSS fro PAMGUARD.
|
||||
*/
|
||||
public String getPamDialogCSS() {
|
||||
return PamStylesManagerFX.getPamStylesManagerFX().getCurStyle().getSlidingDialogCSS();
|
||||
public String getPamDialogCSS() {//return new PrimerDark().getUserAgentStylesheet();
|
||||
|
||||
return PamStylesManagerFX.getPamStylesManagerFX().getCurStyle().getDialogCSS();
|
||||
}
|
||||
|
||||
|
||||
@ -644,7 +653,7 @@ public class PamGuiManagerFX implements PAMControllerGUI, PamSettings {
|
||||
mainPane.getChildren().addAll(title, namePane);
|
||||
|
||||
dialog.getDialogPane().setContent(mainPane);
|
||||
dialog.getDialogPane().getStylesheets().add(PamController.getInstance().getGuiManagerFX().getPamSettingsCSS());
|
||||
dialog.getDialogPane().getStylesheets().add(this.getPamDialogCSS());
|
||||
|
||||
//add listener to prevent close request if the dialog
|
||||
final Button btOk = (Button) dialog.getDialogPane().lookupButton(ButtonType.OK);
|
||||
|
@ -166,6 +166,8 @@ public class PamGuiTabFX extends PamTabFX {
|
||||
//create a new GUI frame.
|
||||
PamGuiFX pamGUIFX=new PamGuiFX(tabPane, newStage, pamGui.getPamGuiManagerFX());
|
||||
pamGUIFX.getStylesheets().add(pamGui.getPamGuiManagerFX().getPamCSS());
|
||||
|
||||
|
||||
//need to add PamGUIFX to list in PamGUIManagerFX.
|
||||
pamGui.getPamGuiManagerFX().getPamGuiFXList().add(pamGUIFX);
|
||||
newStage.setOnCloseRequest(e->{
|
||||
|
@ -18,50 +18,50 @@ public class PamSpinner<T> extends Spinner<T>{
|
||||
* Default widths are way off in JavaFX for spinners.
|
||||
*/
|
||||
// private static final double PAMSPINNER_PREF_WIDTH = USE_COMPUTED_SIZE;
|
||||
private static final double PAMSPINNER_PREF_WIDTH = 100;
|
||||
//private static final double PAMSPINNER_PREF_WIDTH = 100;
|
||||
|
||||
public PamSpinner() {
|
||||
super();
|
||||
this.setPrefWidth(PAMSPINNER_PREF_WIDTH);
|
||||
//this.setPrefWidth(PAMSPINNER_PREF_WIDTH);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
|
||||
public PamSpinner(double min, double max, double initialValue, double amountToStepBy) {
|
||||
super(min, max, initialValue, amountToStepBy);
|
||||
this.setPrefWidth(PAMSPINNER_PREF_WIDTH);
|
||||
//this.setPrefWidth(PAMSPINNER_PREF_WIDTH);
|
||||
addDefocusConverter();
|
||||
}
|
||||
|
||||
|
||||
public PamSpinner(double min, double max, double initialValue) {
|
||||
super(min, max, initialValue);
|
||||
this.setPrefWidth(PAMSPINNER_PREF_WIDTH);
|
||||
//this.setPrefWidth(PAMSPINNER_PREF_WIDTH);
|
||||
addDefocusConverter();
|
||||
}
|
||||
|
||||
public PamSpinner(int min, int max, int initialValue, int amountToStepBy) {
|
||||
super(min, max, initialValue, amountToStepBy);
|
||||
this.setPrefWidth(PAMSPINNER_PREF_WIDTH);
|
||||
//this.setPrefWidth(PAMSPINNER_PREF_WIDTH);
|
||||
addDefocusConverter();
|
||||
}
|
||||
|
||||
public PamSpinner(int min, int max, int initialValue) {
|
||||
super(min, max, initialValue);
|
||||
this.setPrefWidth(PAMSPINNER_PREF_WIDTH);
|
||||
//this.setPrefWidth(PAMSPINNER_PREF_WIDTH);
|
||||
addDefocusConverter();
|
||||
}
|
||||
|
||||
public PamSpinner(ObservableList<T> arg0) {
|
||||
super(arg0);
|
||||
this.setPrefWidth(PAMSPINNER_PREF_WIDTH);
|
||||
//this.setPrefWidth(PAMSPINNER_PREF_WIDTH);
|
||||
addDefocusConverter();
|
||||
}
|
||||
|
||||
public PamSpinner(SpinnerValueFactory<T> arg0) {
|
||||
super(arg0);
|
||||
addDefocusConverter();
|
||||
this.setPrefWidth(PAMSPINNER_PREF_WIDTH);
|
||||
//this.setPrefWidth(PAMSPINNER_PREF_WIDTH);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,492 +0,0 @@
|
||||
/**
|
||||
* CSS for PAMGUARD settings panels. These are dark with clean white buttons and a cyan highlight them.
|
||||
*
|
||||
* Author: Jamie Macaulay;
|
||||
**/
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Declare colour variables *
|
||||
* *
|
||||
******************************************************************************/
|
||||
* {
|
||||
-fx-darkbackground: rgba(60,60,60,.90);
|
||||
-fx-highlight: rgba(0,204,204,.75);
|
||||
-fx-highlight_border: rgba(0,204,204,1);
|
||||
-fx-text: white;
|
||||
-fx-border_col: white;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Panes *
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
.root {
|
||||
-fx-background-color: -fx-darkbackground;
|
||||
-fx-padding: 10;
|
||||
}
|
||||
|
||||
.pane {
|
||||
-fx-background-color: -fx-darkbackground;
|
||||
}
|
||||
|
||||
.border{
|
||||
-fx-background-color: -fx-darkbackground;
|
||||
}
|
||||
|
||||
.grid {
|
||||
-fx-background-color: -fx-darkbackground;
|
||||
}
|
||||
|
||||
.hBox {
|
||||
-fx-background-color: -fx-darkbackground;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Hiding Tab *
|
||||
* *
|
||||
******************************************************************************/
|
||||
#hide-tab {
|
||||
-fx-background-color: transparent;
|
||||
-fx-border-radius: 5 5 0 0;
|
||||
-fx-background-radius: 5 5 0 0;
|
||||
-fx-border-color: -fx-border_col;
|
||||
}
|
||||
|
||||
#show-tab {
|
||||
-fx-background-color: transparent;
|
||||
-fx-border-radius: 5 5 0 0;
|
||||
-fx-background-radius: 5 5 0 0;
|
||||
-fx-border-color: -fx-border_col;
|
||||
}
|
||||
|
||||
#hide-tab-highlight {
|
||||
-fx-background-color: -fx-highlight;
|
||||
-fx-border-radius: 5 5 0 0;
|
||||
-fx-background-radius: 5 5 0 0;
|
||||
-fx-border-color: -fx-highlight_border;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Label *
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
.label{
|
||||
-fx-text-fill: -fx-text;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Slider *
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
.slider .axis {
|
||||
-fx-fill: -fx-text;
|
||||
-fx-stroke: -fx-text;
|
||||
-fx-tick-label-fill: -fx-text;
|
||||
-fx-text-fill: -fx-text;
|
||||
-fx-tick-mark-stroke: -fx-text;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Dialog Pane *
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
.dialog-pane {
|
||||
-fx-background-color: -fx-darkbackground;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Button *
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
.button{
|
||||
-fx-text-fill: white;
|
||||
-fx-background-color: -fx-darkbackground;
|
||||
-fx-border-color: -fx-border_col;
|
||||
-fx-border-radius: 5;
|
||||
-fx-background-radius:6;
|
||||
-fx-padding: 3 6 6 6;
|
||||
}
|
||||
|
||||
.button:hover{
|
||||
-fx-background-color: -fx-highlight;
|
||||
-fx-border-color: -fx-highlight_border;
|
||||
}
|
||||
|
||||
.button:selected{
|
||||
-fx-border-color: -fx-highlight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Button for closing a hiding panel. Right indicates bottoms points towards the right, closing a hiding panel
|
||||
* on the right hand side of the screen. These buttons have a transparent background and rounded corners.
|
||||
*/
|
||||
/** top-left, top-right, bottom-right, and bottom-left corners, in that order. */
|
||||
.close-button-right{
|
||||
-fx-background-color: transparent;
|
||||
-fx-background-radius: 0 10 10 0;
|
||||
-fx-border-radius: 0 10 10 0;
|
||||
}
|
||||
|
||||
|
||||
.close-button-left{
|
||||
-fx-background-color: transparent;
|
||||
-fx-background-radius: 10 0 0 10;
|
||||
-fx-border-radius: 10 0 0 10;
|
||||
}
|
||||
|
||||
|
||||
.close-button-top{
|
||||
-fx-background-color: transparent;
|
||||
-fx-background-radius: 10 10 0 0;
|
||||
-fx-border-radius: 10 10 0 0;
|
||||
}
|
||||
|
||||
|
||||
.close-button-bottom{
|
||||
-fx-background-color: transparent;
|
||||
-fx-background-radius: 0 0 10 10;
|
||||
-fx-border-radius: 0 0 10 10;
|
||||
}
|
||||
|
||||
|
||||
.close-button-bottom-grey{
|
||||
-fx-border-color: transparent;
|
||||
-fx-background-radius: 0 0 10 10;
|
||||
-fx-border-radius: 0 0 10 10;
|
||||
}
|
||||
|
||||
.close-button-left-trans{
|
||||
-fx-border-color: transparent;
|
||||
-fx-background-color: transparent;
|
||||
-fx-background-radius: 10 0 0 10;
|
||||
-fx-border-radius: 10 0 0 10;
|
||||
}
|
||||
|
||||
.close-button-right-trans{
|
||||
-fx-border-color: transparent;
|
||||
-fx-background-color: transparent;
|
||||
-fx-background-radius: 0 10 10 0;
|
||||
-fx-border-radius: 0 10 10 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* TextField *
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
.text-field {
|
||||
-fx-border-color: transparent;
|
||||
-fx-background-color: transparent;
|
||||
-fx-border-color: -fx-border_col;
|
||||
-fx-border-radius: 5;
|
||||
-fx-text-fill: -fx-text;
|
||||
}
|
||||
|
||||
.text-field:selected{
|
||||
-fx-border-color: -fx-highlight;
|
||||
}
|
||||
|
||||
.text-field:focused{
|
||||
-fx-border-color: -fx-highlight;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* MenuButton *
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
.menu-button{
|
||||
-fx-text-fill: -fx-text;
|
||||
-fx-background-color: -fx-darkbackground;
|
||||
-fx-border-color: rgb(255, 255, 255);
|
||||
-fx-border-radius: 5;
|
||||
-fx-padding: 3 6 6 6;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* SplitMenuButton *
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
.split-menu-button{
|
||||
-fx-text-fill: -fx-text;
|
||||
-fx-background-color: -fx-darkbackground;
|
||||
-fx-border-color: -fx-border_col;
|
||||
-fx-border-radius: 5;
|
||||
}
|
||||
|
||||
|
||||
.split-menu-button:hover{
|
||||
-fx-border-color: -fx-highlight_border;
|
||||
}
|
||||
|
||||
|
||||
.split-menu-button .label {
|
||||
-fx-text-fill: white;
|
||||
-fx-background-color: -fx-darkbackground;
|
||||
-fx-border-radius: 5;
|
||||
}
|
||||
|
||||
|
||||
.split-menu-button .label:hover {
|
||||
-fx-background-color: -fx-highlight;
|
||||
}
|
||||
|
||||
|
||||
.split-menu-button .arrow-button {
|
||||
-fx-text-fill: -fx-text;
|
||||
-fx-background-color: -fx-darkbackground;
|
||||
-fx-border-radius: 5;
|
||||
}
|
||||
|
||||
|
||||
.split-menu-button .arrow-button:hover {
|
||||
-fx-background-color: -fx-highlight;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Radio Button *
|
||||
* *
|
||||
******************************************************************************/
|
||||
.radio-button {
|
||||
/* -fx-text-fill: rgb(255, 255, 255, 0.4);*/
|
||||
-fx-text-fill: -fx-text;
|
||||
/* -fx-effect: dropshadow(one-pass-box , rgba(0, 0, 0, 0.6), 0, 0.0 , 0 , 1 );*/
|
||||
-fx-border-width: 0px;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Check Box *
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
.check-box {
|
||||
/* -fx-text-fill: rgb(255, 255, 255, 0.4);*/
|
||||
-fx-text-fill: -fx-text;
|
||||
/* -fx-effect: dropshadow(one-pass-box , rgba(0, 0, 0, 0.6), 0, 0.0 , 0 , 1 );*/
|
||||
-fx-border-width: 0px;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* ComboBox *
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
.combo-box-base{
|
||||
-fx-background-color: -fx-darkbackground;
|
||||
-fx-border-color: -fx-border_col;
|
||||
-fx-border-radius: 5;
|
||||
-fx-padding: 3 6 6 6;
|
||||
}
|
||||
|
||||
.choice-box{
|
||||
-fx-background-color: -fx-darkbackground;
|
||||
-fx-border-color: -fx-border_col;
|
||||
-fx-border-radius: 5;
|
||||
-fx-padding: 3 6 6 6;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* MenuItem *
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
.menu-item .label {
|
||||
-fx-text-fill: -fx-text;
|
||||
/*Must be transpernt so that semi transparent colour is not added to smei transparent*/
|
||||
-fx-background-color: transparent;
|
||||
}
|
||||
|
||||
|
||||
.menu-item:focused {
|
||||
-fx-background-color: -fx-highlight;
|
||||
}
|
||||
|
||||
.menu-item:focused .label {
|
||||
-fx-text-fill: -fx-text;
|
||||
/*Weird fix-must make transparent for correct colour to show*/
|
||||
-fx-background-color: rgba(0,204,204,0);
|
||||
}
|
||||
|
||||
.context-menu {
|
||||
-fx-skin: "com.sun.javafx.scene.control.skin.ContextMenuSkin";
|
||||
-fx-background-color: -fx-darkbackground;
|
||||
-fx-background-insets: 0, 1, 2;
|
||||
-fx-background-radius: 0 6 6 6, 0 5 5 5, 0 4 4 4;
|
||||
/* -fx-padding: 0.666667em 0.083333em 0.666667em 0.083333em; 8 1 8 1 */
|
||||
-fx-padding: 0.333333em 0.083333em 0.666667em 0.083333em; /* 4 1 8 1 */
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
|
||||
ScrollPane
|
||||
|
||||
****************************************************************/
|
||||
.scroll-pane {
|
||||
-fx-background: transparent;
|
||||
-fx-background-color: transparent;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
|
||||
ScrollBar
|
||||
|
||||
****************************************************************/
|
||||
.scroll-bar {
|
||||
-fx-background-color: -fx-darkbackground;
|
||||
-fx-background-radius: 2em;
|
||||
}
|
||||
.scroll-bar:horizontal .track,
|
||||
.scroll-bar:vertical .track {
|
||||
-fx-background-color: transparent;
|
||||
-fx-border-color:transparent;
|
||||
-fx-background-radius: 2em;
|
||||
}
|
||||
.scroll-bar:vertical .track-background,
|
||||
.scroll-bar:horizontal .track-background {
|
||||
-fx-background-color: transparent;
|
||||
-fx-background-insets: 0;
|
||||
-fx-background-radius: 2em;
|
||||
}
|
||||
.scroll-bar:horizontal .thumb {
|
||||
-fx-background-color: rgb(211,211,211);
|
||||
-fx-background-insets: 4 0 4 0;
|
||||
-fx-background-radius: 2em;
|
||||
}
|
||||
.scroll-bar:vertical .thumb {
|
||||
-fx-background-color: rgb(211,211,211);
|
||||
-fx-background-insets: 0 4 0 4;
|
||||
-fx-background-radius: 2em;
|
||||
}
|
||||
.scroll-bar:horizontal .thumb:hover,
|
||||
.scroll-bar:vertical .thumb:hover {
|
||||
-fx-background-color: rgb(231,231,231);
|
||||
}
|
||||
.scroll-bar:horizontal .thumb:pressed,
|
||||
.scroll-bar:vertical .thumb:pressed {
|
||||
-fx-background-color: rgb(255,255,255);
|
||||
}
|
||||
.scroll-bar:vertical .increment-button, .scroll-bar:vertical .decrement-button {
|
||||
-fx-background-color:transparent;
|
||||
-fx-background-radius: 2em;
|
||||
-fx-padding: 5;
|
||||
}
|
||||
.scroll-bar:horizontal .increment-button, .scroll-bar:horizontal .decrement-button {
|
||||
-fx-background-color:transparent;
|
||||
-fx-background-radius: 2em;
|
||||
-fx-padding: 5;
|
||||
}
|
||||
.scroll-bar:horizontal .increment-arrow {
|
||||
-fx-shape: "M 0 0 L 4 8 L 8 0 Z";
|
||||
-fx-background-color: rgb(211,211,211);
|
||||
-fx-padding: 0.25em;
|
||||
-fx-rotate: -90;
|
||||
}
|
||||
.scroll-bar:vertical .increment-arrow {
|
||||
-fx-background-color: rgb(211,211,211);
|
||||
-fx-shape: "M 0 0 L 4 8 L 8 0 Z";
|
||||
-fx-padding: 0.25em;
|
||||
-fx-rotate: 0;
|
||||
}
|
||||
.scroll-bar:horizontal .decrement-arrow {
|
||||
-fx-background-color: rgb(211,211,211);
|
||||
-fx-shape: "M 0 0 L 4 8 L 8 0 Z";
|
||||
-fx-padding: 0.25em;
|
||||
-fx-rotate: 90;
|
||||
}
|
||||
.scroll-bar:vertical .decrement-arrow {
|
||||
-fx-background-color: rgb(211,211,211);
|
||||
-fx-shape: "M 0 0 L 4 8 L 8 0 Z";
|
||||
-fx-padding: 0.25em;
|
||||
-fx-rotate: -180;
|
||||
}
|
||||
.scroll-bar:vertical:focused,
|
||||
.scroll-bar:horizontal:focused {
|
||||
-fx-background-color: transparent,rgb(96,96,96),rgb(96,96,96);
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
|
||||
Spinner
|
||||
|
||||
****************************************************************/
|
||||
|
||||
.spinner {
|
||||
-fx-background: -fx-darkbackground;
|
||||
-fx-background-color: -fx-darkbackground;
|
||||
-fx-background-radius: 10;
|
||||
-fx-border-radius: 10;
|
||||
-fx-border-color: transparent;
|
||||
}
|
||||
|
||||
.spinner .text-field {
|
||||
-fx-background: -fx-darkbackground;
|
||||
-fx-background-color: -fx-darkbackground;
|
||||
-fx-border-radius: 0 0 0 0;
|
||||
-fx-padding: 7 0 7 0;
|
||||
-fx-border-color: transparent;
|
||||
}
|
||||
|
||||
.spinner .increment-arrow-button {
|
||||
-fx-text-fill: white;
|
||||
-fx-background-color: -fx-darkbackground;
|
||||
-fx-border-color: -fx-border_col;
|
||||
-fx-border-radius: 5 5 0 0;
|
||||
-fx-padding: 7 0 7 0;
|
||||
}
|
||||
|
||||
.spinner .increment-arrow {
|
||||
-fx-background-color: white;
|
||||
}
|
||||
|
||||
.spinner .increment-arrow-button:hover {
|
||||
-fx-background-color: -fx-highlight;
|
||||
-fx-border-color: -fx-highlight_border;
|
||||
-fx-background-radius: 6 6 0 0;
|
||||
-fx-border-radius: 6 6 0 0;
|
||||
}
|
||||
|
||||
.spinner .decrement-arrow-button {
|
||||
-fx-text-fill: white;
|
||||
-fx-background-color: -fx-darkbackground;
|
||||
-fx-border-color: -fx-border_col;
|
||||
-fx-border-radius: 0 0 6 6
|
||||
}
|
||||
|
||||
.spinner .decrement-arrow {
|
||||
-fx-background-color: white;
|
||||
}
|
||||
|
||||
.spinner .decrement-arrow-button:hover {
|
||||
-fx-background-color: -fx-highlight;
|
||||
-fx-border-color: -fx-highlight_border;
|
||||
-fx-background-radius: 0 0 6 6;
|
||||
-fx-border-radius: 0 0 6 6;
|
||||
}
|
@ -2,6 +2,7 @@ package pamViewFX.fxNodes.pamDialogFX;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.stage.StageStyle;
|
||||
import pamViewFX.fxStyles.PamStylesManagerFX;
|
||||
@ -25,11 +26,13 @@ public class PamSettingsDialogFX<T> extends PamDialogFX<T> {
|
||||
this.settingsPane=settingsPane;
|
||||
this.setTitle(settingsPane.getName());
|
||||
this.setContent(settingsPane.getContentNode());
|
||||
|
||||
|
||||
// if (PamController.getInstance().getGuiManagerFX()!=null){
|
||||
// this.getDialogPane().getStylesheets().add(PamController.getInstance().getGuiManagerFX().getPamSettingsCSS());
|
||||
// }
|
||||
PamStylesManagerFX stylesManager = PamStylesManagerFX.getPamStylesManagerFX();
|
||||
this.getDialogPane().getStylesheets().add(stylesManager.getCurStyle().getSlidingDialogCSS());
|
||||
this.getDialogPane().getStylesheets().add(stylesManager.getCurStyle().getDialogCSS());
|
||||
this.setOnShown((value)->{
|
||||
settingsPane.paneInitialized();
|
||||
});
|
||||
|
@ -1,5 +1,6 @@
|
||||
package pamViewFX.fxNodes.picker;
|
||||
|
||||
import PamView.PamSymbol;
|
||||
import PamView.PamSymbolType;
|
||||
import javafx.geometry.Point2D;
|
||||
import javafx.scene.canvas.Canvas;
|
||||
@ -127,7 +128,7 @@ public class SymbolPicker extends ComboBox<PamSymbolFX> {
|
||||
|
||||
/**
|
||||
* Set the symbol with a symbol type.
|
||||
* @param symbol
|
||||
* @param symbol - the symbol type.
|
||||
*/
|
||||
public void setValue(PamSymbolType symbol) {
|
||||
for (int i=0; i<getItems().size(); i++){
|
||||
@ -137,5 +138,16 @@ public class SymbolPicker extends ComboBox<PamSymbolFX> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the symbol with a symbol type. Note, replicates setValue for convenience.
|
||||
* @param symbol - the symbol type.
|
||||
*/
|
||||
public void setSymbol(PamSymbolType symbol) {
|
||||
setValue(symbol);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -3,13 +3,16 @@ package pamViewFX.fxNodes.utilityPanes;
|
||||
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.RadioButton;
|
||||
import javafx.scene.control.ToggleGroup;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.layout.Priority;
|
||||
import net.synedra.validatorfx.Validator;
|
||||
import pamViewFX.PamGuiManagerFX;
|
||||
import pamViewFX.fxNodes.PamGridPane;
|
||||
import pamViewFX.fxNodes.PamHBox;
|
||||
@ -50,6 +53,15 @@ public class GroupedSourcePaneFX extends SourcePaneFX {
|
||||
*/
|
||||
private PamGridPane sourcePane;
|
||||
|
||||
/**
|
||||
* Holds channels and group settings.
|
||||
*/
|
||||
private PamVBox channelPanel;
|
||||
|
||||
/**
|
||||
* Validator for channels
|
||||
*/
|
||||
private Validator channelValidator;
|
||||
|
||||
|
||||
public GroupedSourcePaneFX(Class sourceType, boolean hasChannels, boolean includeSubClasses, boolean autoGrouping) {
|
||||
@ -64,6 +76,8 @@ public class GroupedSourcePaneFX extends SourcePaneFX {
|
||||
@Override
|
||||
protected void createPanel() {
|
||||
|
||||
channelValidator = new Validator();
|
||||
|
||||
sourcePane=new PamGridPane();
|
||||
sourcePane.setVgap(5);
|
||||
sourcePane.setHgap(5);
|
||||
@ -90,7 +104,7 @@ public class GroupedSourcePaneFX extends SourcePaneFX {
|
||||
sourcePane.setMaxWidth(Double.MAX_VALUE);
|
||||
|
||||
//create pane to hold channels.
|
||||
PamVBox channelPanel=new PamVBox();
|
||||
channelPanel=new PamVBox();
|
||||
channelPanel.setSpacing(5);
|
||||
|
||||
Label channelLabel = new Label("Channels");
|
||||
@ -124,15 +138,39 @@ public class GroupedSourcePaneFX extends SourcePaneFX {
|
||||
selectAll.setOnAction((action)->{
|
||||
if (selectAll.isSelected()) selectAllChannels();
|
||||
else selectNoChannels();
|
||||
channelValidator.validate(); //makes sure any error signs are removed
|
||||
});
|
||||
|
||||
//create check to show at least some check boxes need to be selected.
|
||||
channelValidator.createCheck()
|
||||
.dependsOn(("select all"), selectAll.selectedProperty())
|
||||
.withMethod(c -> {
|
||||
if (!isAChannelSelected() ) {
|
||||
c.error("At least one channel needs to be selected for the module to work");
|
||||
}
|
||||
})
|
||||
.decorates(selectAll)
|
||||
.immediate();
|
||||
;
|
||||
//create a list of channels and combo boxes for groups.
|
||||
if (isHasChannels()){
|
||||
for (int i = 0; i < PamConstants.MAX_CHANNELS; i++){
|
||||
channelBoxes[i] = new CheckBox("Channel " + i);
|
||||
channelValidator.createCheck()
|
||||
.dependsOn(("channel " + i), channelBoxes[i].selectedProperty())
|
||||
.withMethod(c -> {
|
||||
if (!isAChannelSelected() ) {
|
||||
c.error("At least one channel needs to be selected for the module to work");
|
||||
}
|
||||
})
|
||||
.decorates(channelBoxes[i])
|
||||
.immediate();
|
||||
;
|
||||
//channelPanel.getChildren().add(channelBoxes[i]);
|
||||
final int n=i;
|
||||
channelBoxes[i].setOnAction((action)->{
|
||||
selectionChanged(n);
|
||||
channelValidator.validate(); //makes sure any error signs are removed.
|
||||
});
|
||||
groupList[i]=new ComboBox<Integer>();
|
||||
//System.out.println("SourcePanel.java creatPanel"+i);
|
||||
@ -149,82 +187,43 @@ public class GroupedSourcePaneFX extends SourcePaneFX {
|
||||
PamHBox channelGroupPane=new PamHBox();
|
||||
channelGroupPane.setSpacing(15);
|
||||
channelGroupPane.getChildren().addAll(channelPanel, autoGroupPane);
|
||||
channelGroupPane.setAlignment(Pos.TOP_LEFT);
|
||||
|
||||
sourcePane.add(channelGroupPane,0,3);
|
||||
|
||||
//create source comboBox.
|
||||
this.setCenter(sourcePane);
|
||||
|
||||
|
||||
// //old swing layout panels
|
||||
// panel = new JPanel();
|
||||
// JPanel sourcePanel = new JPanel();
|
||||
// sourcePanel.setLayout(new BorderLayout());
|
||||
// // add stuff to the panel.
|
||||
// if (borderTitle != null) {
|
||||
// sourcePanel.setBorder(new TitledBorder(borderTitle));
|
||||
// }
|
||||
// panel.setLayout(new BorderLayout());
|
||||
//// panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
|
||||
// sourcePanel.add(BorderLayout.CENTER, sourceList = new JComboBox());
|
||||
// panel.add(BorderLayout.NORTH, sourcePanel);
|
||||
// sourceList.addActionListener(this);
|
||||
// if (hasChannels) {
|
||||
// JPanel channelGroupPanel = new JPanel();
|
||||
// channelGroupPanel.setLayout(new BorderLayout());
|
||||
// channelGroupPanel.setBorder(new TitledBorder("Channel list and grouping"));
|
||||
// JPanel channelPanel = new JPanel();
|
||||
// JPanel autoGroupPanel = new JPanel();
|
||||
// autoGroupPanel.setLayout(new BoxLayout(autoGroupPanel, BoxLayout.Y_AXIS));
|
||||
// autoGroupPanel.add(new JLabel("Auto Grouping"));
|
||||
// autoGroupPanel.add(allSingles = new JRadioButton("No grouping"));
|
||||
// autoGroupPanel.add(allTogether = new JRadioButton("One group"));
|
||||
// autoGroupPanel.add(userGrouped = new JRadioButton("User groups"));
|
||||
// allSingles.addActionListener(new GroupAction(GROUP_SINGLES));
|
||||
// allTogether.addActionListener(new GroupAction(GROUP_ALL));
|
||||
// userGrouped.addActionListener(new GroupAction(GROUP_USER));
|
||||
// ButtonGroup bg = new ButtonGroup();
|
||||
// bg.add(allSingles);
|
||||
// bg.add(allTogether);
|
||||
// bg.add(userGrouped);
|
||||
//// channelPanel.setLayout(new BoxLayout(channelPanel, BoxLayout.Y_AXIS));
|
||||
// GridBagLayout layout;
|
||||
//// channelPanel.setBorder(new TitledBorder("Channel list and grouping"));
|
||||
// channelPanel.setLayout(layout = new GridBagLayout());
|
||||
// GridBagConstraints c = new GridBagConstraints();
|
||||
// c.gridwidth = 2;
|
||||
// c.anchor = GridBagConstraints.WEST;
|
||||
// c.gridx = c.gridy = 0;
|
||||
// addComponent(channelPanel, autoGroupPanel, c);
|
||||
//// addComponent(channelPanel, new JLabel("Channel list ..."), c);
|
||||
// c.gridwidth = 1;
|
||||
// c.insets = new Insets(0,5,0,5);
|
||||
// c.gridy++;
|
||||
// c.gridx = 0;
|
||||
// addComponent(channelPanel, new JLabel("Channel"), c);
|
||||
// c.gridx++;
|
||||
// addComponent(channelPanel, new JLabel("Group"), c);
|
||||
// groupList = new JComboBox[PamConstants.MAX_CHANNELS];
|
||||
// channelBoxes = new JCheckBox[PamConstants.MAX_CHANNELS];
|
||||
// for (int i = 0; i < PamConstants.MAX_CHANNELS; i++){
|
||||
// channelBoxes[i] = new JCheckBox("Channel " + i);
|
||||
// groupList[i] = new JComboBox();
|
||||
// c.gridy ++;
|
||||
// c.gridx = 0;
|
||||
// addComponent(channelPanel, channelBoxes[i], c);
|
||||
// c.gridx ++;
|
||||
// addComponent(channelPanel, groupList[i], c);
|
||||
//// channelPanel.add(channelBoxes[i]);
|
||||
// channelBoxes[i].setVisible(false);
|
||||
// groupList[i].setVisible(false);
|
||||
// channelBoxes[i].addActionListener(new SelectionListener(i));
|
||||
// }
|
||||
// channelGroupPanel.add(BorderLayout.WEST, autoGroupPanel);
|
||||
// channelGroupPanel.add(BorderLayout.CENTER, channelPanel);
|
||||
// panel.add(BorderLayout.CENTER, channelGroupPanel);
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validator for the channel. This can identify errors
|
||||
* in
|
||||
* @return
|
||||
*/
|
||||
public Validator getChannelValidator() {
|
||||
return channelValidator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if
|
||||
* @return
|
||||
*/
|
||||
private boolean isAChannelSelected() {
|
||||
int channels = 0;
|
||||
PamDataBlock sb = getSource();
|
||||
if (sb != null) {
|
||||
// channels = sb.getChannelMap();
|
||||
channels = sb.getSequenceMap();
|
||||
}
|
||||
int n=0;
|
||||
//remove all channels from vertical box pane.
|
||||
for (int i = 0; i < Math.min(PamConstants.MAX_CHANNELS, channelBoxes.length); i++) {
|
||||
if ((channels & 1<<i) != 0 && this.channelBoxes[i].isSelected()) n++;
|
||||
}
|
||||
if (n==0) return false;
|
||||
else return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void showChannels() {
|
||||
@ -459,4 +458,12 @@ public class GroupedSourcePaneFX extends SourcePaneFX {
|
||||
return channelListPane;
|
||||
}
|
||||
|
||||
/**
|
||||
* The pane that holds the channels and the group settings.
|
||||
* @return the channel pane.
|
||||
*/
|
||||
public Pane getChannelPane() {
|
||||
return channelPanel;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -270,6 +270,7 @@ public class SourcePaneFX extends PamBorderPane {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tell the pane the source has changed.
|
||||
*/
|
||||
|
@ -39,7 +39,7 @@ public class SettingsFileDialogFX {
|
||||
singleInstance = new SettingsFileDialogFX();
|
||||
singleInstance.settingsDialog=new PamSettingsDialogFX(singleInstance.settingsFilePane);
|
||||
// singleInstance.settingsDialog.getDialogPane().getStylesheets().add(singleInstance.getClass().getResource("/Resources/css/pamSettingsCSS.css").toExternalForm());
|
||||
singleInstance.settingsDialog.getDialogPane().getStylesheets().add(PamStylesManagerFX.getPamStylesManagerFX().getCurStyle().getSlidingDialogCSS());
|
||||
singleInstance.settingsDialog.getDialogPane().getStylesheets().add(PamStylesManagerFX.getPamStylesManagerFX().getCurStyle().getDialogCSS());
|
||||
}
|
||||
|
||||
singleInstance.settingsFilePane.setParams(settingsFileData);
|
||||
|
@ -72,6 +72,9 @@ public class SettingsFilePane extends SettingsPane<SettingsFileData> {
|
||||
browseButton.setOnAction((action)->{
|
||||
browseFile(false);
|
||||
});
|
||||
browseButton.prefHeightProperty().bind(fileBox.heightProperty());
|
||||
|
||||
|
||||
PamButton browseSaveButton = new PamButton();
|
||||
// browseSaveButton.setGraphic(PamGlyphDude.createPamGlyph(MaterialDesignIcon.PLUS, Color.WHITE, PamGuiManagerFX.iconSize));
|
||||
browseSaveButton.setGraphic(PamGlyphDude.createPamIcon("mdi2p-plus", Color.WHITE, PamGuiManagerFX.iconSize));
|
||||
@ -82,6 +85,9 @@ public class SettingsFilePane extends SettingsPane<SettingsFileData> {
|
||||
folderSelectPane.getChildren().addAll(fileBox, browseSaveButton, browseButton);
|
||||
vBox.getChildren().add(folderSelectPane);
|
||||
|
||||
browseSaveButton.prefHeightProperty().bind(fileBox.heightProperty());
|
||||
|
||||
|
||||
fileBox.prefHeightProperty().bind(browseButton.heightProperty());
|
||||
|
||||
// //option to show on start up.
|
||||
|
@ -10,6 +10,7 @@ import binaryFileStorage.BinaryStore;
|
||||
import pamViewFX.fxNodes.PamBorderPane;
|
||||
import pamViewFX.fxNodes.PamGridPane;
|
||||
import pamViewFX.fxNodes.pamDialogFX.PamDialogFX;
|
||||
import pamViewFX.fxStyles.PamStylesManagerFX;
|
||||
import javafx.geometry.HPos;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Node;
|
||||
@ -56,6 +57,8 @@ public class StorageOptionsPane extends SettingsPane<StorageParameters>{
|
||||
|
||||
PamGridPane gridPane=new PamGridPane();
|
||||
|
||||
|
||||
|
||||
|
||||
Label l = new Label(" Binary Store ");
|
||||
l.setTextAlignment(TextAlignment.CENTER);
|
||||
|
68
src/pamViewFX/fxStyles/PamAtlantaStyle.java
Normal file
68
src/pamViewFX/fxStyles/PamAtlantaStyle.java
Normal file
@ -0,0 +1,68 @@
|
||||
package pamViewFX.fxStyles;
|
||||
|
||||
/*
|
||||
* PAMGUARD - Passive Acoustic Monitoring GUARDianship.
|
||||
* To assist in the Detection Classification and Localisation
|
||||
* of marine mammals (cetaceans).
|
||||
*
|
||||
* Copyright (C) 2006
|
||||
*
|
||||
* 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 2
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class defining the default CSS Style sheets to use for JavaFX displays. This class can be extended and one or more methods overridden to
|
||||
* specify new CSS styles. Style sheets can be specified for 3 different categories: sliding dialogs, regular dialogs, and all other components
|
||||
* (incl. displays, etc). In addition, each category can have a style sheet to use for daytime mode and one to use for nighttime mode. The
|
||||
* relative URI paths to the individual style sheets are specified as private fields, and accessed through public methods. The day/night switch
|
||||
* is based on the name of the current PamColors colour scheme being used.
|
||||
*
|
||||
* @author Jamie Macaulay
|
||||
*
|
||||
*/
|
||||
public class PamAtlantaStyle extends PamDefaultStyle {
|
||||
|
||||
/**
|
||||
* Relative location of the CSS style sheet to be used for the Pamguard GUI (but not dialogs)
|
||||
*/
|
||||
//private String guiCSS = "/Resources/css/pamCSS.css";
|
||||
//private String guiCSS = new NordDark().getUserAgentStylesheet();
|
||||
protected String primerGuiCSS = "/Resources/css/primer-light.css";
|
||||
|
||||
|
||||
/**
|
||||
* Relative location of the CSS style sheet to be used for the Pamguard standard dialogs
|
||||
*/
|
||||
//private String dialogCSS = "/Resources/css/pamSettingsCSS.css";
|
||||
//private String dialogCSS = new PrimerDark().getUserAgentStylesheet();
|
||||
protected String primerDialogCSS = "/Resources/css/primer-dark.css";
|
||||
|
||||
|
||||
/**
|
||||
* Relative location of the CSS style sheet to be used for the Pamguard sliding dialogs
|
||||
*/
|
||||
//private String slidingDialogCSS = "/Resources/css/pamCSS.css";
|
||||
//private String slidingDialogCSS = new PrimerDark().getUserAgentStylesheet();
|
||||
protected String primerSlidingDialogCSS = "/Resources/css/primer-pamguard.css";
|
||||
|
||||
public PamAtlantaStyle() {
|
||||
super.guiCSS = primerGuiCSS;
|
||||
super.dialogCSS = primerDialogCSS;
|
||||
super.slidingDialogCSS = primerSlidingDialogCSS;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -42,35 +42,35 @@ public class PamDefaultStyle {
|
||||
/**
|
||||
* Relative location of the CSS style sheet to be used for the Pamguard GUI (but not dialogs)
|
||||
*/
|
||||
private String guiCSS = "/Resources/css/pamCSS.css";
|
||||
protected String guiCSS = "/Resources/css/pamCSS.css";
|
||||
|
||||
/**
|
||||
* Relative location of the CSS style sheet to be used for the Pamguard GUI when in night mode. If there
|
||||
* is not a style sheet specific to night mode, set it to null or point back to the guiCSS field.
|
||||
*/
|
||||
private String guiCSSNightMode = guiCSS;
|
||||
protected String guiCSSNightMode = guiCSS;
|
||||
|
||||
/**
|
||||
* Relative location of the CSS style sheet to be used for the Pamguard standard dialogs
|
||||
*/
|
||||
private String dialogCSS = "/Resources/css/pamDefaultDialogCSS.css";
|
||||
protected String dialogCSS = "/Resources/css/pamDefaultDialogCSS.css";
|
||||
|
||||
/**
|
||||
* Relative location of the CSS style sheet to be used for the Pamguard std dialogs when in night mode. If there
|
||||
* is not a style sheet specific to night mode, set it to null or point back to the dialogCSS field.
|
||||
*/
|
||||
private String dialogCSSNightMode = dialogCSS;
|
||||
protected String dialogCSSNightMode = dialogCSS;
|
||||
|
||||
/**
|
||||
* Relative location of the CSS style sheet to be used for the Pamguard sliding dialogs
|
||||
*/
|
||||
private String slidingDialogCSS = "/Resources/css/pamSettingsCSS.css";
|
||||
protected String slidingDialogCSS = "/Resources/css/pamSettingsCSS.css";
|
||||
|
||||
/**
|
||||
* Relative location of the CSS style sheet to be used for the Pamguard sliding dialogs when in night mode. If there
|
||||
* is not a style sheet specific to night mode, set it to null or point back to the slidingDialogCSS field.
|
||||
*/
|
||||
private String slidingDialogCSSNightMode = slidingDialogCSS;
|
||||
protected String slidingDialogCSSNightMode = slidingDialogCSS;
|
||||
|
||||
/**
|
||||
* <p>Return the CSS Style sheet to be used for the Pamguard GUI (displays and such) but not the dialogs.</p>
|
||||
|
@ -50,7 +50,7 @@ import warnings.PamWarning;
|
||||
public class RawDLSettingsPane extends SettingsPane<RawDLParams>{
|
||||
|
||||
|
||||
public static double MAX_WIDTH = 250;
|
||||
public static double MAX_WIDTH = 270;
|
||||
|
||||
/**
|
||||
* The source for the FFT data source.
|
||||
@ -181,7 +181,6 @@ public class RawDLSettingsPane extends SettingsPane<RawDLParams>{
|
||||
vBox.getChildren().add(label);
|
||||
|
||||
windowLength = new PamSpinner<Integer>(0, Integer.MAX_VALUE, 10, 10000);
|
||||
windowLength.setPrefWidth(100);
|
||||
windowLength.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL);
|
||||
windowLength.setEditable(true);
|
||||
windowLength.valueProperty().addListener((obsVal, oldVal, newVal)->{
|
||||
@ -189,7 +188,6 @@ public class RawDLSettingsPane extends SettingsPane<RawDLParams>{
|
||||
});
|
||||
|
||||
hopLength = new PamSpinner<Integer>(0, Integer.MAX_VALUE, 10, 10000);
|
||||
hopLength.setPrefWidth(100);
|
||||
hopLength.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL);
|
||||
hopLength.setEditable(true);
|
||||
hopLength.valueProperty().addListener((obsVal, oldVal, newVal)->{
|
||||
@ -197,7 +195,6 @@ public class RawDLSettingsPane extends SettingsPane<RawDLParams>{
|
||||
});
|
||||
|
||||
reMergeSeg = new PamSpinner<Integer>(0, Integer.MAX_VALUE, 1, 1);
|
||||
reMergeSeg.setPrefWidth(100);
|
||||
reMergeSeg.getStyleClass().add(Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL);
|
||||
reMergeSeg.setEditable(true);
|
||||
|
||||
|
@ -1,6 +1,12 @@
|
||||
package rawDeepLearningClassifier.layoutFX.exampleSounds;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import simulatedAcquisition.sounds.SimSignal;
|
||||
|
||||
/**
|
||||
* The example sound factory
|
||||
@ -9,6 +15,8 @@ import java.net.URL;
|
||||
*/
|
||||
public class ExampleSoundFactory {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* An example sound type.
|
||||
* @author Jamie macaulay
|
||||
@ -16,21 +24,32 @@ public class ExampleSoundFactory {
|
||||
*/
|
||||
public enum ExampleSoundType {
|
||||
|
||||
BAT_CALL("Bat Call (Myotis daubentonii)"),
|
||||
PORPOISE_CLICK("Harbour Porpoise (Phocoena phocoena)", ExampleSoundCategory.ODONTOCETES_CLICKS),
|
||||
|
||||
SPERM_WHALE("Sperm Whale (Physeter macrocephalus)", ExampleSoundCategory.ODONTOCETES_CLICKS),
|
||||
|
||||
DOLPHIN("Dolphin (Delphinid)", ExampleSoundCategory.ODONTOCETES_CLICKS),
|
||||
|
||||
BEAKED_WHALE("Beaked Whale (Ziphiidae)", ExampleSoundCategory.ODONTOCETES_CLICKS),
|
||||
|
||||
RIGHT_WHALE("Southern Right Whale (Eubalaena australis)"),
|
||||
BAT_CALL("Bat Call (Myotis daubentonii)", ExampleSoundCategory.BAT),
|
||||
|
||||
MINKE_WHALE("Minke Whale (Balaenoptera spp.)"),
|
||||
RIGHT_WHALE("Southern Right Whale (Eubalaena australis)", ExampleSoundCategory.MYSTICETES),
|
||||
|
||||
MINKE_WHALE("Minke Whale (Balaenoptera spp.)", ExampleSoundCategory.MYSTICETES),
|
||||
|
||||
HUMPBACK_WHALE("Humpback whale (Megaptera novaeangliae) ");
|
||||
HUMPBACK_WHALE("Humpback whale (Megaptera novaeangliae) ", ExampleSoundCategory.MYSTICETES);
|
||||
|
||||
private final String text;
|
||||
|
||||
private final ExampleSoundCategory soundCategory;
|
||||
|
||||
/**
|
||||
* @param text
|
||||
*/
|
||||
ExampleSoundType(final String text) {
|
||||
ExampleSoundType(final String text, final ExampleSoundCategory soundCategory) {
|
||||
this.text = text;
|
||||
this.soundCategory = soundCategory;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@ -40,8 +59,173 @@ public class ExampleSoundFactory {
|
||||
public String toString() {
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get category of the example sound.
|
||||
* @return the example sound category.
|
||||
*/
|
||||
public ExampleSoundCategory getCategory() {
|
||||
return soundCategory;
|
||||
}
|
||||
}
|
||||
|
||||
public enum ExampleSoundCategory {MYSTICETES, ODONTOCETES_CLICKS, OCONTOCETES_TONAL, BAT}
|
||||
|
||||
/**
|
||||
* Get all the example sounds for a particular category.
|
||||
* @param - the category of sund to extract.
|
||||
* @return the example sounds for a category.
|
||||
*/
|
||||
private List<ExampleSoundType> getAnExampleSoundTypes(ExampleSoundCategory category) {
|
||||
|
||||
List<ExampleSoundType> exampleSounds = Arrays.asList(ExampleSoundType.values());
|
||||
|
||||
List<ExampleSoundType> resultSet =
|
||||
exampleSounds.stream()
|
||||
.filter(c -> c.getCategory().equals(category))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return resultSet;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the example sounds for a set of categories.
|
||||
* @param - the categories to use.
|
||||
* @return the example sounds for a category.
|
||||
*/
|
||||
public ArrayList<ExampleSoundType> getExampleSoundTypes(ExampleSoundCategory... cateogry) {
|
||||
|
||||
|
||||
ArrayList<ExampleSoundType> resultSet = new ArrayList<ExampleSoundType>();
|
||||
|
||||
for (int i=0; i<cateogry.length; i++) {
|
||||
|
||||
resultSet.addAll(getAnExampleSoundTypes(cateogry[i]));
|
||||
}
|
||||
|
||||
return resultSet;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*Beaked whale click template, sR is 192000;
|
||||
*/
|
||||
public static final double[] beakedWhale1 = {2.47E-04,4.17E-04,-2.08E-04,-4.96E-04,2.10E-04,1.77E-04,-1.94E-04,4.12E-04,
|
||||
-3.52E-04,-4.06E-04,5.34E-04,1.78E-04,-1.57E-04,-3.78E-04,6.04E-04,2.92E-04,-1.11E-03,-9.88E-05,4.69E-04,4.78E-04,-2.56E-04,
|
||||
-6.52E-04,9.52E-04,7.76E-04,-1.24E-03,-2.34E-03,-7.72E-04,5.15E-03,9.90E-03,-7.51E-03,-2.34E-02,1.01E-02,2.53E-02,-1.19E-02,-1.14E-02,
|
||||
8.45E-03,4.52E-04,-7.41E-03,-3.62E-03,1.55E-02,7.40E-03,-1.44E-02,-2.38E-04,7.15E-04,-1.20E-02,3.95E-04,1.57E-02,4.98E-03,1.92E-03,
|
||||
1.54E-02,-2.55E-02,-5.13E-02,2.06E-02,4.93E-02,4.04E-03,1.07E-02,-4.28E-03,-6.29E-02,-2.66E-02,3.46E-02,3.53E-02,3.77E-02,2.10E-02,
|
||||
-5.72E-02,-8.11E-02,-2.50E-03,4.14E-02,7.01E-02,7.57E-02,-4.29E-02,-1.31E-01,-7.97E-02,4.48E-02,1.41E-01,1.17E-01,-3.82E-02,-1.92E-01,
|
||||
-1.16E-01,6.49E-02,1.70E-01,1.65E-01,-1.03E-01,-2.66E-01,-4.51E-02,1.66E-01,2.08E-01,9.35E-03,-2.98E-01,-1.26E-01,2.83E-01,1.67E-01,
|
||||
-1.97E-01,-2.05E-01,9.55E-02,2.64E-01,-3.56E-02,-2.88E-01,2.30E-02,2.49E-01,-2.65E-02,-1.77E-01,1.71E-02,1.22E-01,6.03E-03,-1.18E-01,
|
||||
1.24E-02,1.12E-01,-6.87E-02,-3.49E-02,6.68E-02,-3.83E-02,-1.76E-02,4.04E-02,4.81E-03,-4.35E-02,3.24E-03,5.49E-02,-3.68E-02,-1.93E-02,
|
||||
3.83E-02,-2.45E-02,-6.69E-03,3.95E-02,-1.97E-02,-3.61E-02,4.18E-02,3.72E-03,-3.75E-02,3.54E-02,-4.81E-03,-3.30E-02,3.52E-02,2.50E-03,
|
||||
-3.08E-02,1.80E-02,1.40E-02,-2.37E-02,4.51E-03,1.71E-02,-1.81E-02,-6.25E-04,1.83E-02,-1.33E-02,-9.61E-03,1.96E-02,-2.14E-03,
|
||||
-1.97E-02,1.43E-02,9.88E-03,-1.85E-02,5.62E-03,1.13E-02,-1.41E-02,-6.57E-04,1.33E-02,-6.73E-03,-7.21E-03,1.07E-02,-2.59E-03,
|
||||
-1.03E-02,1.08E-02,5.15E-03,-1.25E-02,7.48E-04,9.56E-03,-5.28E-03,-5.46E-03,7.89E-03,1.54E-04,-8.15E-03,5.09E-03,6.07E-03,-7.92E-03,
|
||||
-7.59E-04,8.78E-03,-5.57E-03,-5.39E-03,8.47E-03,-1.48E-03,-7.02E-03,5.20E-03,3.33E-03,-6.12E-03,8.16E-04,6.54E-03,-4.25E-03,-3.56E-03,
|
||||
4.57E-03,-6.18E-04,-1.87E-03,1.52E-03,3.46E-04};
|
||||
|
||||
|
||||
/**
|
||||
* Dolphin click template. sR is 500000;
|
||||
*/
|
||||
public static final double[] porp1 = {-3.05E-05,-0.002563477,-0.004974365,0.011444092,-0.009521484,-0.025115967,0.043365479,0.006896973,-0.090332031,0.045959473,
|
||||
0.112335205,-0.129669189,-0.099395752,0.208465576,0.036865234,-0.25994873,0.040771484,0.273834229,-0.121124268,-0.264709473,0.18447876,0.235626221,-0.241851807,
|
||||
-0.194458008,0.281036377,0.129699707,-0.306427002,-0.048278809,0.293182373,-0.043273926,-0.243774414,0.110229492,0.162536621,-0.144958496,-0.078491211,0.136444092,
|
||||
0.004547119,-0.105926514,0.037628174,0.058898926,-0.05682373,-0.018371582,0.047973633,-0.018737793,-0.024383545,0.03302002,-0.014404297,-0.030517578,0.045227051,
|
||||
0.002532959,-0.063751221,0.027191162,0.057067871,-0.054901123,-0.042449951,0.065246582,0.016448975,-0.06741333,0.002319336,0.055664063,-0.023345947,-0.040496826,
|
||||
0.030548096,0.015625,-0.033569336,0.002441406,0.022857666,-0.019042969,-0.013702393,0.020965576,0.001831055,-0.023101807,0.001068115,0.01739502,-0.005401611,
|
||||
-0.017944336,0.004394531,0.013427734,-0.008880615,-0.013122559,0.007781982,0.006561279,-0.010650635,-0.004150391,0.005310059};
|
||||
/**
|
||||
* Dolphin click template. sR is 192000;
|
||||
*/
|
||||
public static final double[] dolphin1 = {3.56E-05,1.13E-03,-1.28E-03,4.39E-05,1.17E-04,4.11E-04,-3.05E-04,1.57E-04,-3.45E-04,5.21E-04,-5.18E-04,
|
||||
1.93E-03,-8.44E-04,-1.62E-04,-8.80E-04,2.74E-04,-4.06E-04,1.32E-03,-7.23E-04,5.70E-04,-6.91E-04,6.78E-04,-7.04E-04,-1.36E-03,-4.10E-04,
|
||||
1.41E-03,-1.11E-03,1.36E-03,-9.02E-04,-2.69E-04,-1.49E-04,2.05E-04,-1.53E-04,6.97E-05,-7.78E-04,9.78E-04,-1.04E-03,-9.00E-05,-8.66E-04,
|
||||
6.78E-05,-1.06E-03,1.39E-03,-6.03E-04,3.49E-04,2.80E-04,9.42E-04,-3.65E-04,-5.98E-04,-1.91E-04,4.00E-04,-1.22E-03,4.52E-04,-1.35E-03,8.43E-04,
|
||||
-1.20E-03,5.83E-04,-3.36E-04,1.26E-03,-2.39E-04,1.63E-04,-1.31E-03,1.15E-03,9.60E-04,1.58E-03,-5.09E-04,1.16E-03,-1.15E-03,-2.38E-04,-3.77E-04,
|
||||
1.37E-04,-1.57E-03,1.30E-03,-9.01E-04,1.00E-03,-9.13E-06,8.95E-04,-9.26E-04,3.68E-04,-6.05E-05,5.16E-04,-2.56E-04,2.45E-03,-1.46E-03,1.80E-03,
|
||||
-5.76E-04,4.27E-03,4.60E-03,1.62E-02,2.77E-02,4.65E-02,-2.96E-02,-1.70E-01,-3.27E-01,1.98E-01,7.30E-01,-1.69E-01,-4.94E-01,3.59E-02,1.08E-01,
|
||||
2.70E-02,-9.51E-03,-2.52E-02,-1.19E-02,5.12E-03,3.54E-03,9.35E-03,6.57E-03,5.81E-03,-1.82E-03,-3.81E-03,-1.73E-02,-3.26E-03,1.66E-02,1.47E-02,
|
||||
-1.78E-04,-1.35E-02,-5.18E-03,5.96E-03,1.20E-03,-2.03E-03,8.27E-04,3.08E-03,7.34E-03,2.49E-03,-8.53E-03,-3.58E-03,-4.46E-03,2.39E-03,6.70E-03,
|
||||
2.08E-03,-1.54E-03,3.96E-05,-3.75E-04,4.47E-05,9.08E-04,1.13E-03,-4.51E-04,-1.16E-03,-2.38E-03,1.33E-03,4.09E-03,-4.09E-05,-2.57E-03,-7.47E-05,
|
||||
-4.94E-04,-1.12E-04,-2.10E-04,3.48E-04,-1.33E-04,-8.04E-04,-1.28E-04,2.31E-04,1.63E-03,4.06E-03,-1.90E-03,-4.81E-03,-3.43E-03,2.05E-03,2.64E-03,
|
||||
1.05E-03,-1.25E-03,-1.52E-03,-2.15E-04,5.58E-04,1.09E-03,-2.92E-04,-7.16E-05,-1.62E-04,-7.08E-04,1.37E-03,-3.63E-04,-1.01E-04,-9.10E-04,4.76E-04,
|
||||
-4.89E-04,6.00E-04,-1.97E-03,-3.72E-04,-1.23E-03,-2.13E-03,1.80E-03,1.72E-03,-4.45E-04,8.07E-04,2.73E-03,1.87E-03,-3.51E-04,-1.79E-03,
|
||||
-4.25E-05,-3.60E-04,-6.36E-03,-3.80E-03};
|
||||
/**
|
||||
* Sperm whale click that contains P0 , P1 and P2 pulses. sR is 192000/4
|
||||
*/
|
||||
public static final double[] sperm1 = {6.25E-05,-2.17E-05,4.27E-05,-0.00020994,-0.000214738,4.15E-05,-4.20E-06,-1.19E-05,1.43E-05,-6.63E-06,-0.000131916,7.46E-05,7.74E-05,
|
||||
-3.48E-05,0.000112665,7.23E-05,0.000124127,-0.000327633,-0.000504408,-0.0001821,-9.08E-06,-0.000303635,-0.00091038,-0.000737628,-0.002809006,-0.002485561,0.002436103,
|
||||
0.001387111,-0.000240529,0.008338125,0.01556416,0.003837149,-0.012601288,-0.010037818,0.001317383,0.006350685,0.003097904,-0.003146625,-0.005176637,-0.005103367,
|
||||
-0.003033016,0.000264741,0.000979974,0.001417843,0.001295476,0.000270959,-0.000941692,-0.002497482,-0.001093983,0.001588331,0.001606697,0.000428882,0.000342588,
|
||||
0.000576856,0.000175455,0.000351797,0.000535963,6.16E-05,-2.81E-05,3.01E-05,-4.62E-05,6.29E-05,-0.00032481,-0.000627716,0.000541881,0.000930361,6.94E-05,-8.11E-05,
|
||||
-0.001084492,-0.001999887,-0.000853651,-0.000455461,-0.0009841,-0.000148444,0.000505996,0.000659125,0.002106154,0.00305439,0.002859567,0.002226094,-0.001580242,
|
||||
-0.005047821,-0.003593811,-0.002505516,-0.00239728,0.000993556,0.004712824,0.005116607,0.002759289,-0.000433693,-0.00259594,-0.002059373,6.38E-05,0.00080239,0.001226022,
|
||||
0.000524362,-5.97E-05,0.000218345,0.002725451,0.013643442,0.007104888,-0.013153579,-0.000327077,0.008434641,-0.034580464,-0.058165279,0.001699742,0.050940528,0.016095566,
|
||||
-0.019505718,-0.014421101,0.00069818,0.012322224,0.015961877,0.019905987,0.012646343,-0.003135543,-0.003774804,-0.002494694,-0.004462543,-2.78E-05,0.006201286,0.007524738,
|
||||
-0.000122701,-0.00686273,-0.003151422,0.000472041,-0.004336464,-0.006828523,-0.0036367,-0.004451807,-0.00476565,-0.00059454,0.001060291,0.000210872,0.000292835,0.001312147,
|
||||
0.00354525,0.003836739,-0.001563894,-0.003728106,0.000589295,0.002063008,0.005110769,0.008073922,0.002351888,0.000991397,0.004482293,0.001852083,-0.001210519,-0.003916204,
|
||||
-0.009643673,-0.011895388,-0.011094342,-0.009496773,0.007035453,0.021768597,0.012407682,0.007770304,0.009816115,-0.004929878,-0.02191959,-0.021845953,-0.009616377,0.003728446,
|
||||
0.011398892,0.007160923,-0.001221613,-0.003364027,-0.001979512,-0.00161046,-0.000138627,0.00464312,0.004116845,0.001597662,0.003842689,0.002166315,-0.001378553,-0.005946158,
|
||||
-0.011386535,-0.004845226,0.002418087,-0.003915996,-0.001246813,0.028316573,0.039767874,-0.002601435,-0.030996041,-0.012193441,0.000524819,-0.003479641,-0.001961131,0.005014191,
|
||||
0.000109726,-0.008264739,-0.003328171,-0.003266307,-0.005688887,0.002147438,0.005314515,0.003113408,0.000906803,-0.00362076,-0.004367909,0.001707293,0.004516978,0.002670098,
|
||||
0.005179915,0.005209394,0.000157009,-0.001113109,0.000351461,-0.00070744,-0.002641287,-0.000378381,0.000650114,-0.000699954,0.001493645,0.002380219,0.001847398,0.000957028,
|
||||
-0.00020906,-0.001138818,-0.005258351,-0.004390589,-0.000750034,0.001350919,0.005041997,0.004159317,0.00380484,0.006116095,0.004054061,-0.007240427,-0.015931238,-0.008497872,
|
||||
-0.004869947,-0.005248341,0.005820257,0.017324379,0.015179912,0.001501706,-0.004758621,-0.004807403,-0.004766533,0.000532342,0.001876597,0.002421249,0.002974527,-0.003363805,
|
||||
-0.006394844,-0.004090489,-0.000551194,0.000815621,0.002722833,0.006326427,0.002422239,1.71E-05,0.001718135,0.000155882,-9.98E-06,0.000374249,0.000685689,-0.00060601,
|
||||
-0.002945803,-0.001182812,0.000705219,0.000131511,-0.001627181,-0.004276435,-0.004121385,-0.001013222,-0.000580473,-0.001749975,-0.000810329,0.001049795,0.002380673,
|
||||
0.00092144,-0.001721435,-0.001959407,0.001039882,0.003527076,0.001077526,0.001321712,0.003990982,0.00159095,-6.99E-05,0.000197319,0.000611932,0.000414778,-0.000977586,
|
||||
0.000546997,-0.00015996,-0.003209788,-0.002958488,-0.001050216,0.000691699,-0.002462978,-0.00411392,-0.001070453,-0.002638013};
|
||||
|
||||
// /**
|
||||
// * Generate a click waveform with some added noise.
|
||||
// * @param type - the type of click e.g. ClickTriggerGraph.PORPOISE_CLICK.
|
||||
// * @param noise. 0 to 1. 1 means max noise amplitude will be same as maximum click amplitude.
|
||||
// * @return click and noise waveform.
|
||||
// */
|
||||
// private double[] generateClickWaveform(ExampleSoundType type, double noise){
|
||||
// SimSignal clickSound;
|
||||
// int sR;
|
||||
// double length;
|
||||
// double freq;
|
||||
// switch (type){
|
||||
// //TODO - add more types of clicks.
|
||||
// case PORPOISE_CLICK:
|
||||
// clickSound=new ClickSound("Porpoise", freq=140000, freq2=140000, length=0.00015, WINDOWTYPE.HANN);
|
||||
// sR=500000;
|
||||
// break;
|
||||
// case SPERM_WHALE:
|
||||
// clickSound=(new ClickSound("Beaked Whale", 30000, 60000, length = 0.3e-3, WINDOWTYPE.HANN));
|
||||
// sR=192000;
|
||||
// break;
|
||||
// default:
|
||||
// clickSound=new ClickSound("Porpoise", freq=140000, freq2=140000, length=0.00015, WINDOWTYPE.HANN);
|
||||
// sR=500000;
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// //now need to work out how many noise samples to add. Use the length of the click
|
||||
// int nNoiseSamples=(int) (2*length*sR);
|
||||
// double[] waveform=new double[3*nNoiseSamples];
|
||||
// int n=0;
|
||||
// for (int i=0; i<3*nNoiseSamples; i++){
|
||||
// double noiseSample=noise*(Math.random()-0.5);
|
||||
// double[] signal=clickSound.getSignal(0,sR,0);
|
||||
// if (i>nNoiseSamples && n <signal.length){
|
||||
// waveform[i]=signal[n]+noiseSample;
|
||||
// n=n+1;
|
||||
// }
|
||||
// else waveform[i]=noiseSample;
|
||||
// }
|
||||
//
|
||||
// return waveform;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Get the example sound type.
|
||||
* @param exampleSoundType
|
||||
@ -54,7 +238,7 @@ public class ExampleSoundFactory {
|
||||
switch (exampleSoundType) {
|
||||
case BAT_CALL:
|
||||
path = getClass().getResource("/Resources/exampleSounds/DUB_20200623_000152_885.wav");
|
||||
exampleSound = new SimpleExampleSound(path);
|
||||
exampleSound = new SimpleExampleSound(path, 2500, 5000);
|
||||
break;
|
||||
case RIGHT_WHALE:
|
||||
//file = new File("src/rawDeepLearningClassifier/layoutFX/exampleSounds/southern_right_whale_clip2.wav");
|
||||
@ -71,11 +255,44 @@ public class ExampleSoundFactory {
|
||||
path = getClass().getResource("/Resources/exampleSounds/Humpback_whale.wav");
|
||||
exampleSound = new SimpleExampleSound(path);
|
||||
break;
|
||||
case PORPOISE_CLICK:
|
||||
exampleSound = new SimpleExampleSound(porp1, 500000);
|
||||
break;
|
||||
case SPERM_WHALE:
|
||||
exampleSound = new SimpleExampleSound(sperm1, 48000);
|
||||
break;
|
||||
case BEAKED_WHALE:
|
||||
exampleSound = new SimpleExampleSound(beakedWhale1, 192000);
|
||||
break;
|
||||
case DOLPHIN:
|
||||
exampleSound = new SimpleExampleSound(dolphin1, 192000);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
return exampleSound;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the example sounds for a particular category.
|
||||
* @param - the category of sund to extract.
|
||||
* @return the example sounds for a category.
|
||||
*/
|
||||
public ExampleSoundType[] getExampleSoundTypes(ExampleSoundCategory category) {
|
||||
|
||||
|
||||
List<ExampleSoundType> exampleSounds = Arrays.asList(ExampleSoundType.values());
|
||||
|
||||
List<ExampleSoundType> resultSet =
|
||||
exampleSounds.stream()
|
||||
.filter(c -> c.getCategory().equals(category))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return (ExampleSoundType[]) resultSet.toArray();
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -39,6 +39,21 @@ public class SimpleExampleSound implements ExampleSound{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public SimpleExampleSound(URL path, int start, int end) {
|
||||
try {
|
||||
data = DLUtils.loadWavFile(path);
|
||||
} catch (IOException | UnsupportedAudioFileException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
data = data.trim(start, end);
|
||||
}
|
||||
|
||||
public SimpleExampleSound(double[] wave, float sampleRate) {
|
||||
this.data = new AudioData(wave, sampleRate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] getWave() {
|
||||
@ -50,4 +65,5 @@ public class SimpleExampleSound implements ExampleSound{
|
||||
return data.getSampleRate();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user