Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
Mattk70 committed Oct 29, 2024
2 parents 55d170a + e81aeab commit da5dc1b
Show file tree
Hide file tree
Showing 9 changed files with 52 additions and 41 deletions.
2 changes: 1 addition & 1 deletion Help/ebird.html
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
<td><b>Why did you choose eBird? Do you have plans to allow sharing with other sites?</b></td>
<td>
<p>eBird is the simplest platform to use. This is because it has a published record format, and perhaps most importantly, the eBird taxonomy aligns to the one
used by the both the BirdNET and Chirpity models.</p>
used by the both the BirdNET and Nocmig models.</p>
<p>I hope to offer the ability to share audio clips with Xeno-Canto in a future release. This depends on them releasing a suitable upload API.</p>
</td>
</tr>
Expand Down
21 changes: 7 additions & 14 deletions Help/settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<td>Choose the model to use for detection.
<ul>
<li>
<b>Chirpity</b> will use the native Chirpity model for analysis.
<b>Nocmig</b> will use a model tuned for the nocturnal flight calls of European birds for analysis.
</li>
<li>
<b>BirdNET</b> will use the <a href="https://github.com/kahst/BirdNET-Analyzer" target="_blank">BirdNET</a> model developed by Stefan Kahl et al. from the K. Lisa Yang Center for Conservation Bioacoustics
Expand Down Expand Up @@ -51,7 +51,7 @@
<li>Precisely define the detections you would like Chirpity to report on</li>
<li>Search only for a specific species</li>
</ol>
You may use a different custom list for both BirdNET and Chirpity models. The format for a
You may use a different custom list for both BirdNET and Nocmig models. The format for a
custom list file is "scientific name_common name", with each species on a new line. <b>Importantly, the custom list needs to use labels in your selected language.</b> You can export a starting
list in the correct format from the Help menu, using the "<i>What species are detected?</i>" link.
</td>
Expand Down Expand Up @@ -82,7 +82,7 @@
</ol>
If you click the icon, it will open the assessment page with the species' range and details of the assessment in your web browser. The data is sourced from:
<cite>
IUCN 2024. IUCN Red List of Threatened Species. Version 2024-1
IUCN 2024. IUCN Red List of Threatened Species. Version 2024-2
</cite>
</td>
</tr>
Expand Down Expand Up @@ -118,7 +118,7 @@
</tr>
<tr>
<th>Backend</th>
<td>This option is only visible when using the Chirpity model. Choose how predictions are calculated on you computer.
<td>This option is only visible when using the Nocmig model. Choose how predictions are calculated on you computer.
<ul>
<li>
<b>CPU</b> will use the CPU for predictions, this is generally faster if you have an integrated
Expand All @@ -132,7 +132,7 @@
<b>WebGPU</b> This employs a new technology and will also use graphics processors. It is similar to WebGL,
but is known to speed up the processing times on Macs, unlike WebGL. WebGPU uses more memory than WebGL, and
if the threads or batch size values are set too high, Chirpity may run out of memory. If this happens
the spectrogram will disappear from the screen. Use a lower value for threads and / or batch size.
the spectrogram may disappear from the screen or the app may become unresponsive. Use a lower value for threads and / or batch size.
</li>
</ul>
</td>
Expand Down Expand Up @@ -292,13 +292,13 @@
</tr>
<tr>
<th>Context Mode</th>
<td> This mode is only available for the native Chirpity model. When enabled, the model will use the surrounding context when making predictions. This helps mitigate
<td> This mode is only available for the Nocmig model. When enabled, the model will use the surrounding context when making predictions. This helps mitigate
against false positive detections.
</td>
</tr>
<tr>
<th>SNR filter</th>
<td>This setting is also only available for the native Chirpity model. The SNR (Signal to Noise Ratio) filter can only be enabled when using the CPU backend.
<td>This setting is also only available for the Nocmig model. The SNR (Signal to Noise Ratio) filter can only be enabled when using the CPU backend.
When enabled, Chirpity will disregard audio segments with no distinct sound event.
A stronger signal is required for a prediction to be attempted when higher signal-to-noise values are set.
The purpose is to deliver significant speed gains, however, the setting may cause Chirpity to miss quieter, more distant calls.
Expand All @@ -312,13 +312,6 @@
This is <b>extremely </b> useful if you want to report a bug - as you can share a screenshot of any errors that appear (these will show up in red in the console).
</td>
</tr>
<tr>
<th>Opt out of usage analytics</th>
<td>
Chirpity sends usage information anonymously to an analytics server. This information is used to help understand how people use Chirpity, and try to identify any bugs
or errors. Both help improve the software and prioritise changes for future releases. If you would prefer that Chirpity did not send any usage data, you can disable it here.
</td>
</tr>
</table>

</body>
Expand Down
2 changes: 1 addition & 1 deletion IUCNcache.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Author: Matthew Kirkland
![image](https://github.com/Mattk70/Chirpity-Electron/assets/61826357/96b0af44-3893-4288-8291-cf0f6db89a38)

## Key Features
- Uses two Machine Learning models to identify audio files based on the user's needs: BirdNET and the Chirpity model
- Uses two Machine Learning models to identify audio files based on the user's needs: BirdNET and the Nocmig model
- Supports audio input files such as WAV, MP3, MP4/M4A, AAC, Opus, Ogg, and FLAC
- Audio analysis can run in the background while exploring the application
- Tailor species detection based on the season, time of day, or a custom list of species
Expand Down Expand Up @@ -51,7 +51,7 @@ Initialize the source directory with:
npm init
```

Now, install project dependencoies with:
Now, install project dependencies with:

```
npm install --save-dev
Expand Down
19 changes: 14 additions & 5 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,11 @@ <h5 class="offcanvas-title" id="offcanvasExampleLabel">Settings</h5>
<fieldset class="border border-secondary rounded m-2 mt-0 mb-0 p-2">
<legend style="font-size: large;font-weight:bold">Detections</legend>
<div>
<a class="circle" tabindex="-1" data-bs-toggle="popover" data-bs-trigger="focus" data-bs-title="Model" id="Model-circle-help" data-bs-content="Select whether to use Chirpity, optimised for Nocturnal Migration Calls in Europe, or BirdNET, which can detect over 6000 species across the globe.">?</a>
<a class="circle" tabindex="-1" data-bs-toggle="popover" data-bs-trigger="focus" data-bs-title="Model" id="Model-circle-help" data-bs-content="Select whether to use the Nocmig model, optimised for Nocturnal Migration Calls in Europe, or BirdNET, which can detect over 6000 species across the globe.">?</a>
<div class="pe-3 input-group rounded p-2 mb-1">
<label class="input-group-text col-5" for="model-to-use">Model:</label>
<select class="form-select mb-0" id="model-to-use">
<option value="chirpity">Chirpity</option>
<option value="chirpity">Nocmig</option>
<option value="birdnet">BirdNet</option>
</select>
</div>
Expand Down Expand Up @@ -150,14 +150,23 @@ <h5 class="offcanvas-title" id="offcanvasExampleLabel">Settings</h5>
<a class="circle" tabindex="-1" data-bs-toggle="popover" data-bs-trigger="focus" data-bs-title="Nocmig Mode" id="Nocmig Mode-circle-help" data-bs-content="When enabled, this 'Nocmig mode' only searches for and only displays detections found during the night">?</a>
</div>
</div>
<hr>
<div class="form-group rounded p-2 pe-0 mb-2">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="iucn">
<label class="form-check-label" for="iucn">Show species IUCN Red List status in summary.</label>
<a class="circle" tabindex="-1" data-bs-toggle="popover" data-bs-trigger="focus" data-bs-title="Red List Status" id="IUCN-circle-help"
data-bs-content="When enabled, the latest Global ICUN assessment status is displayed for each species in the summary. The icon links to the assesment page on the ICUN website. ">?</a>
data-bs-content="When enabled, the latest Global IUCN assessment status is displayed for each species in the summary. The icon links to the assessment page on the IUCN website. The Assessment Scope will display the IUCN assessment of the species in that region (where available).">?</a>
</div>
</div>
<div class="pe-3 input-group rounded p-2 mb-1">
<label for="iucn-scope" class="input-group-text col-5">Assessment Scope:</label>
<select class="form-select mb-0" id="iucn-scope">
<option value="Global">Global</option>
<option value="Europe">Europe</option>
<option value="Mediterranean">Mediterranean</option>
</select>
</div>
<hr>
<div class="form-group rounded">
<div class="form-check form-switch ps-2">
Expand Down Expand Up @@ -628,7 +637,7 @@ <h5 class="text-center">Getting Started</h5>
<li>First off, set your location in the settings menu.</li>
<li>Next, consider which model best suits your needs:</li>
<ul>
<li><b>Chirpity</b> is tuned for nocturnal migration,<br> but only has birds on the British list</li>
<li><b>Nocmig</b> is tuned for nocturnal migration,<br> but only has birds on the British list</li>
<li><b>BirdNET</b> is trained on global bird species</li>
</ul>
</ol>
Expand All @@ -644,7 +653,7 @@ <h5>Quick access settings panel</h5>
<ol class="text-start ps-5">
<li>Nocmig mode</li>
<li>Audio filters</li>
<li>Context-aware mode (Chirpity model only)</li>
<li>Context-aware mode (Nocmig model only)</li>
<li>Frequency range adjustment for the spectrogram</li>
<li>Which detection list to use</li>
<li>And the confidence threshold</li>
Expand Down
2 changes: 1 addition & 1 deletion js/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export class State {
this.blocked = [],
this.audio = { gain: 0, format: 'mp3', bitrate: 128, padding: false, fade: false, downmix: false, quality: 5, notification: true, normalise: false, maxFrequency: 11950, minFrequency: 0},
this.filters = { active: false, highPassFrequency: 0, lowShelfFrequency: 0, lowShelfAttenuation: 0, SNR: 0, sendToModel: false },
this.detect = { backend: 'webgpu', nocmig: false, contextAware: false, confidence: 450, iucn: false },
this.detect = { backend: 'webgpu', nocmig: false, contextAware: false, confidence: 450, iucn: false, iucnScope: 'Global'},
this.chart = { range: { start: undefined, end: undefined }, species: undefined },
this.explore = { species: undefined, range: { start: undefined, end: undefined } },
this.model = undefined,
Expand Down
2 changes: 1 addition & 1 deletion js/tracking.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const ID_SITE = 3;
const ID_SITE = 2;

function trackEvent(uuid, event, action, name, value){
// Squash result numbers
Expand Down
39 changes: 23 additions & 16 deletions js/ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -1664,7 +1664,7 @@ const defaultConfig = {
latitude: 52.87,
longitude: 0.89,
location: 'Great Snoring, North Norfolk',
detect: { nocmig: false, contextAware: false, confidence: 45, iucn: false },
detect: { nocmig: false, contextAware: false, confidence: 45, iucn: true , iucnScope: 'Global'},
filters: { active: false, highPassFrequency: 0, lowShelfFrequency: 0, lowShelfAttenuation: 0, SNR: 0, sendToModel: false },
warmup: true,
hasNode: false,
Expand Down Expand Up @@ -1783,6 +1783,7 @@ window.onload = async () => {
DOM.audioDownmix.checked = config.audio.downmix;
setNocmig(config.detect.nocmig);
document.getElementById('iucn').checked = config.detect.iucn;
document.getElementById('iucn-scope').selected = config.detect.iucnScope;
modelSettingsDisplay();
// Block powersave?
document.getElementById('power-save-block').checked = config.powerSaveBlocker;
Expand Down Expand Up @@ -2646,7 +2647,7 @@ function onChartData(args) {
resetResults();
setListUIState(config.list);
// Since the custom list function calls for its own update *after* reading the labels, we'll skip updates for custom lists here
config.list === 'custom' || worker.postMessage({ action: 'update-list', list: config.list, refreshResults: STATE.analysisDone })
config.list === 'custom' || refreshResults()
})

DOM.customListSelector.addEventListener('click', async () =>{
Expand Down Expand Up @@ -3160,19 +3161,19 @@ function centreSpec(){

if (showIUCN) {
const record = await getIUCNStatus(item.sname);
const iucn = record.scopes.find(obj => obj.scope === 'Global');
const status = iucn.status;
const url = iucn.url ? 'https://www.iucnredlist.org/species/' + iucn.url : null;
const redListIcon = status;
// there might not be a record...
const iucn = record?.scopes.find(obj => obj.scope === config.detect.iucnScope);
const status = iucn?.status || 'NA';
const url = iucn?.url ? 'https://www.iucnredlist.org/species/' + iucn.url : null;

summaryHTML+=
`<td class="text-end"><a title="${IUCNLabel[status]}: Learn more about this species ICUN assessment"
class="d-inline-block p-1 rounded text-decoration-none text-center ${IUCNMap[redListIcon]} ${!url ? 'disabled-link' : ''}"
href="${url || '#'}" target="_blank"> ${redListIcon}</a></td>`;
class="d-inline-block p-1 w-100 rounded text-decoration-none text-center ${IUCNMap[redListIcon]} ${!url ? 'disabled-link' : ''}"
href="${url || '#'}" target="_blank"> ${status}</a></td>`;
}
summaryHTML += `<td class="text-end">${item.count}</td>
<td class="text-end">${item.calls}</td>
</tr>`;

}
summaryHTML += '</tbody></table>';
// Get rid of flicker...
Expand Down Expand Up @@ -4484,7 +4485,7 @@ function playRegion(){
updatePrefs('config.json', config)
resetResults({clearSummary: true, clearPagination: true, clearResults: true});
setListUIState(config.list);
if (STATE.currentFile && STATE.analysisDone) worker.postMessage({ action: 'update-list', list: config.list, refreshResults: true })
if (STATE.currentFile) refreshResults();
break;
}

Expand Down Expand Up @@ -4651,7 +4652,9 @@ function playRegion(){
target && target !== 'result1' && trackEvent(config.UUID, 'UI', 'Click', target);
})


function refreshResults () {
worker.postMessage({ action: 'update-list', list: config.list, refreshResults: STATE.analysisDone })
}

// Beginnings of the all-powerful document 'change' listener
// One listener to rule them all!
Expand All @@ -4668,12 +4671,16 @@ function playRegion(){
}
config.speciesThreshold = element.value;
worker.postMessage({ action: 'update-state', speciesThreshold: element.value });
worker.postMessage({ action: 'update-list', list: config.list, refreshResults: STATE.analysisDone});
refreshResults();
break;
}
case 'timelineSetting': { timelineToggle(e); break }
case 'nocmig': { changeNocmigMode(e); break }
case 'iucn': { config.detect.iucn = element.checked; break }
case 'iucn': { config.detect.iucn = element.checked } // no break so results are refreshed
case 'iucn-scope': {
config.detect.iucnScope = element.value;
refreshResults();
break }
case 'auto-archive': { config.archive.auto = element.checked } // no break so worker state gets updated
case 'library-trim': { config.archive.trim = element.checked }
case 'archive-format': {
Expand All @@ -4698,7 +4705,7 @@ function playRegion(){

if (! config.useWeek) STATE.week = -1;
worker.postMessage({action:'update-state', useWeek: config.useWeek});
worker.postMessage({ action: 'update-list', list: config.list, refreshResults: STATE.analysisDone});
refreshResults()
break;
}
case 'list-to-use': {
Expand All @@ -4707,7 +4714,7 @@ function playRegion(){
updateListIcon();
resetResults({clearSummary: true, clearPagination: true, clearResults: true});
// Don't call this for custom lists
config.list === 'custom' || worker.postMessage({ action: 'update-list', list: config.list, refreshResults: STATE.analysisDone});
config.list === 'custom' || refreshResults()
break;
}
case 'locale': {
Expand All @@ -4734,7 +4741,7 @@ function playRegion(){
case 'local': {
config.local = element.checked;
worker.postMessage({action: 'update-state', local: config.local })
worker.postMessage({ action: 'update-list', list: config.list });
refreshResults()
break;
}
case 'model-to-use': {
Expand Down
2 changes: 2 additions & 0 deletions js/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -1464,6 +1464,8 @@ function resumeFfmpeg(ffmpegCommand){

let predictQueue = [];

//TODO: refactor and remove header removal logic, don't need wav package

const getWavePredictBuffers = async ({
file = '', start = 0, end = undefined
}) => {
Expand Down

0 comments on commit da5dc1b

Please sign in to comment.