Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
lilhoser committed Mar 22, 2024
0 parents commit 06bf1ac
Show file tree
Hide file tree
Showing 53 changed files with 7,261 additions and 0 deletions.
75 changes: 75 additions & 0 deletions docs/README.md
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)
Binary file added docs/logo-med.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/pizzawave-architecture.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/screenshot1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/screenshot2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/screenshot3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/screenshot4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions pizzacmd/Program.cs
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);
}
}
35 changes: 35 additions & 0 deletions pizzacmd/README.md
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`).
99 changes: 99 additions & 0 deletions pizzacmd/Settings.cs
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}");
}
}
}
}

Loading

0 comments on commit 06bf1ac

Please sign in to comment.