-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 06bf1ac
Showing
53 changed files
with
7,261 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
|
||
# Introduction | ||
![plot](logo-med.png#right) `pizzawave` is a set of cross-platform .NET tools for processing audio data streamed by the [callstream plugin](https://github.com/lilhoser/callstream) of [trunk-recorder](https://github.com/robotastic/trunk-recorder). The audio data consists of calls recorded by trunk-recorder from conventional and trunked radio systems, such as local fire/rescue/EMS. `pizzawave` tooling transcribes these calls to text using [OpenAI's Whisper AI model](https://openai.com/research/whisper) as exposed through [whisper.net toolchain](https://github.com/sandrohanea/whisper.net). Among other features, the application allows you to monitor and set alerts for keywords of interest. | ||
|
||
The `pizzawave` project consists of these tools: | ||
* A windows-only .NET UI (`pizzaui` in source) | ||
* A cross-platform .NET command line application (`pizzacmd` in source) | ||
* A cross-platform .NET library (`pizzalib` in source), used by the UI and CLI application | ||
|
||
Please be sure to read the README for each individual tool. | ||
|
||
# Requirements | ||
|
||
Regardless of whether you choose to use the UI, command line application, or roll your own application that uses the cross-platform library, you will need to observe these requirements: | ||
|
||
* A Linux system running trunk-recorder with the [callstream plugin](https://github.com/lilhoser/callstream) configured | ||
* An operating system capable of running .NET 8.0 runtime (e.g, Win, Lin or Mac) | ||
* The pizzawave tools currently target .NET 8.0, but if you are building from source, earlier versions should work as well. | ||
* The requirements as specified in the tool of choice: | ||
* `pizzaui`: Windows-only | [README](https://github.com/lilhoser/pizzawave/tree/main/pizzaui) | ||
* `pizzacmd`: All supported platforms | [README](https://github.com/lilhoser/pizzawave/tree/main/pizzacmd) | ||
* `pizzalib`: All supported platforms | [README](https://github.com/lilhoser/pizzawave/tree/main/pizzalib) | ||
|
||
# Architecture | ||
|
||
![plot](pizzawave-architecture.png#right) | ||
|
||
As shown in the illustration, pizzawave uses a `server`-`client` model, where the server is either the pizzawave UI or command line application and the client is one or more trunk-recorder systems. This design allows pizzawave to accept radio transmissions from multiple instances of trunk-recorder, which might be recording audio data from separate SDR device arrays monitoring broadcasts from different trunked radio systems. | ||
|
||
Pizzawave listens for audio data from trunk-recorder systems, translates the data into textual transcriptions using Whisper AI, and processes alert rules to notify you of interesting broadcasts. | ||
|
||
# Building from Source | ||
|
||
## Windows | ||
You can use Visual Studio Community Edition for free. | ||
|
||
## Mac and Linux | ||
|
||
* [Install .NET core](https://learn.microsoft.com/en-us/dotnet/core/install/) | ||
* clone this repo | ||
* CD into repo source | ||
* run `dotnet build --runtime <RID>` where [RID can be found here](https://learn.microsoft.com/en-us/dotnet/core/rid-catalog) | ||
|
||
# Configuration | ||
|
||
Pizzawave configuration lives in `<user profile>\pizzawave\settings.json`. On Windows, this is `Users\<user>\AppData\Roaming\pizzawave\settings.json`. Please see the READMEs for each individual tool you are using for what settings options are available and how to use them in your setup. `pizzaui` includes a feature that allows you to setup your configuration in a more automated way, but you can always create the file manually. If you run the UI or command line application without a settings file, the default one will be created in the location specified above. | ||
|
||
_Important_: Make sure your `trunk-recorder` system is configured to connect to the right IP address. In an exotic scenario where you're running `pizzacmd` from both a Windows host system and a WSL2 Ubuntu system, the host system and the virtual Ubuntu system will have different IP addresses! In this scenario, you might forget to set the correct IP address on the `trunk-recorder` system, and only one of these machines will receive audio data, while the other might be stuck on this: | ||
|
||
``` | ||
StreamServer Verbose: 1 : 3/22/2024 3:39 PM: Listening on port 9123 | ||
``` | ||
|
||
# Other | ||
|
||
## Diagnostics | ||
|
||
All logs, model files, settings files, and alert data can be found in your operating system's user profile folder. | ||
* `alerts` - this folder contains WAV data for matched alerts | ||
* `Logs` - this folder contains all log files | ||
* `model` - this folder contains all auto-downloaded GGML model files | ||
|
||
If your logs are not detailed enough, adjust the `TraceLevelApp` parameter in `settings.json`. | ||
|
||
## What's up with the name? | ||
I dunno, I like pizza and Teenage Mutant Ninja Turtles, so it seemed to work. | ||
|
||
## Resources | ||
|
||
* If you're struggling to setup trunk-recorder, I recommend [this extremely well-written intro guide](https://www.andrewmohawk.com/2020/06/12/trunked-radio-a-guide/). | ||
* Use [this tool](https://alertapi.alertpage.net/sdr/) to calculate some trunk-recorder configuration parameters like center frequency and to understand how many SDR dongles you will need to cover channels of interest | ||
* Other trunk-recorder related projects performing transcription: | ||
* [trunk-transcribe](https://github.com/CrimeIsDown/trunk-transcribe) | ||
* [trunk-recorder-stack](https://github.com/ge0metrix/trunk-recorder-stack) | ||
* [tr-uploader](https://github.com/TheGreatCodeholio/icad_tr_uploader) and [icad_tone_detection_api](https://github.com/TheGreatCodeholio/icad_tone_detection_api) |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/* | ||
Licensed to the Apache Software Foundation (ASF) under one | ||
or more contributor license agreements. See the NOTICE file | ||
distributed with this work for additional information | ||
regarding copyright ownership. The ASF licenses this file | ||
to you under the Apache License, Version 2.0 (the | ||
"License"); you may not use this file except in compliance | ||
with the License. You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, | ||
software distributed under the License is distributed on an | ||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
KIND, either express or implied. See the License for the | ||
specific language governing permissions and limitations | ||
under the License. | ||
*/ | ||
using System.Reflection; | ||
|
||
namespace pizzacmd; | ||
|
||
class Program | ||
{ | ||
static async Task<int> Main(string[] args) | ||
{ | ||
var pizza = new pizzacmd(); | ||
return await pizza.Run(args); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
|
||
# Introduction | ||
![plot](../docs/logo-med.png#right) `pizzacmd` is a .NET command line application built on top of the [`pizzalib`]((https://github.com/lilhoser/pizzawave/tree/main/pizzalib) library. | ||
|
||
![plot](../docs/screenshot4.png) | ||
|
||
# Requirements | ||
* [Requirements as specified in the `pizzawave` README](https://github.com/lilhoser/pizzawave) | ||
* [Requirements as specified in the `pizzalib` README]((https://github.com/lilhoser/pizzawave/tree/main/pizzalib) | ||
* A supported operating system (Win, Lin, Mac) running .NET 8 or later | ||
|
||
# Configuration | ||
`pizzacmd` currently has no settings beyond what is contained in `pizzalib`. | ||
|
||
# Running on WSL2 | ||
|
||
## Port forwarding | ||
|
||
Remember that `trunk-recorder` needs to be configured to communicate with the server. If you're running `pizzacmd` from within a linux OS in WSL2 on Windows, you'll need to make sure the WSL2 instance is configured to receive the network traffic: | ||
|
||
``` | ||
netsh interface portproxy add v4tov4 listenport=[PORT] listenaddress=0.0.0.0 connectport=[PORT] connectaddress=[WSL_IP] | ||
``` | ||
|
||
Replace `[PORT]` with your listen port, such as `9123` and `[WSL_IP]` with your WSL instance IP address, eg `172.23.192.16`. | ||
|
||
## Whisper issues | ||
|
||
If you receive an error like this: | ||
|
||
``` | ||
Whisper Error: 1 : 3/22/2024 5:12 PM: Failed to transcribe WAV data: Failed to load native whisper library. Error: Unknown error | ||
``` | ||
|
||
It most likely means you have the wrong `Whisper.net` runtime installed. For linux, you must install either `cublas` or revert to CPU only (`Whisper.net.Runtime`). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
/* | ||
Licensed to the Apache Software Foundation (ASF) under one | ||
or more contributor license agreements. See the NOTICE file | ||
distributed with this work for additional information | ||
regarding copyright ownership. The ASF licenses this file | ||
to you under the Apache License, Version 2.0 (the | ||
"License"); you may not use this file except in compliance | ||
with the License. You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, | ||
software distributed under the License is distributed on an | ||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
KIND, either express or implied. See the License for the | ||
specific language governing permissions and limitations | ||
under the License. | ||
*/ | ||
using Newtonsoft.Json; | ||
|
||
namespace pizzacmd | ||
{ | ||
public class Settings : pizzalib.Settings, IEquatable<Settings> | ||
{ | ||
public Settings() : base() | ||
{ | ||
} | ||
|
||
public override bool Equals(object? Other) | ||
{ | ||
if (Other == null) | ||
{ | ||
return false; | ||
} | ||
var field = Other as Settings; | ||
return Equals(field); | ||
} | ||
|
||
public bool Equals(Settings? Other) | ||
{ | ||
if (Other == null) | ||
{ | ||
return false; | ||
} | ||
return base.Equals(Other); | ||
} | ||
|
||
public static bool operator ==(Settings? Settings1, Settings? Settings2) | ||
{ | ||
if ((object)Settings1 == null || (object)Settings2 == null) | ||
return Equals(Settings1, Settings2); | ||
return Settings1.Equals(Settings2); | ||
} | ||
|
||
public static bool operator !=(Settings? Settings1, Settings? Settings2) | ||
{ | ||
if ((object)Settings1 == null || (object)Settings2 == null) | ||
return !Equals(Settings1, Settings2); | ||
return !(Settings1.Equals(Settings2)); | ||
} | ||
|
||
public override int GetHashCode() | ||
{ | ||
return (this).GetHashCode() + base.GetHashCode(); | ||
} | ||
|
||
public override void Validate() | ||
{ | ||
base.Validate(); | ||
} | ||
|
||
public void SaveToFile(string? Target) | ||
{ | ||
string target; | ||
|
||
if (string.IsNullOrEmpty(Target)) | ||
{ | ||
target = DefaultSettingsFileLocation; | ||
} | ||
else | ||
{ | ||
target = Target; | ||
} | ||
|
||
try | ||
{ | ||
Validate(); | ||
var json = JsonConvert.SerializeObject(this, Formatting.Indented); | ||
File.WriteAllText(target, json); | ||
} | ||
catch (Exception ex) | ||
{ | ||
throw new Exception($"Could not save the Settings object " + | ||
$"to JSON: {ex.Message}"); | ||
} | ||
} | ||
} | ||
} | ||
|
Oops, something went wrong.