Skip to content

Commit

Permalink
Merge pull request #1 from aizcutei/fix/spectrogram
Browse files Browse the repository at this point in the history
Fix/spectrogram
  • Loading branch information
aizcutei authored Jun 1, 2024
2 parents 9175dd2 + 3301247 commit f77674b
Show file tree
Hide file tree
Showing 18 changed files with 575 additions and 225 deletions.
Binary file modified .DS_Store
Binary file not shown.
119 changes: 116 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,116 @@
/target
/dist
/.zed
# Created by https://www.toptal.com/developers/gitignore/api/rust,macos,windows,linux,visualstudiocode
# Edit at https://www.toptal.com/developers/gitignore?templates=rust,macos,windows,linux,visualstudiocode

### Linux ###
*~

# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*

# KDE directory preferences
.directory

# Linux trash folder which might appear on any partition or disk
.Trash-*

# .nfs files are created when an open file is removed but is still being accessed
.nfs*

### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride

# Icon must end with two \r
Icon


# Thumbnails
._*

# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent

# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk

### macOS Patch ###
# iCloud generated files
*.icloud

### Rust ###
# Generated by Cargo
# will have compiled files and executables
debug/
target/

# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock

# These are backup files generated by rustfmt
**/*.rs.bk

# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb

### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets

# Local History for Visual Studio Code
.history/

# Built Visual Studio Code Extensions
*.vsix

### VisualStudioCode Patch ###
# Ignore all local history of files
.history
.ionide

### Zed ###
.zed

### Windows ###
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db

# Dump file
*.stackdump

# Folder config file
[Dd]esktop.ini

# Recycle Bin used on file shares
$RECYCLE.BIN/

# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp

# Windows shortcuts
*.lnk

# End of https://www.toptal.com/developers/gitignore/api/rust,macos,windows,linux,visualstudiocode
23 changes: 17 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,31 @@

# NanoMeters

Crossplatform audio visualizer with Rust & WebGPU.
Crossplatform audio visualizer with Rust.

Aim for CPU/GPU/Memory friendly.

A practice that mimics but not to replace the Minimeters.

**Under development. Unstable. Not ready for use. Not responsible for loss of project files due to plugin crashes.**
**⚠️ Under development. Unstable. Not responsible for loss of project files due to plugin or system crashes.**

Use together with [nanometers-plugin](https://github.com/aizcutei/nanometers_plug) (VST3 & CLAP).
Use together with [nanometers-plugin](https://github.com/aizcutei/nanometers_plug) (VST3 & CLAP) and [nanometers-au](https://github.com/aizcutei/nanometers_au) (AU is in plan).

---
## Preview

![nanometers](./static/example.gif)

Preview:
---
## Audio routing support

![nanometers](./static/Example.gif)
||Audio Input/Microphone|Desktop Audio Capture|[NanometersServer Plugin](https://github.com/aizcutei/nanometers_plug)|
|-|-|-|-|
|Windows|🚧|✅ * Not compatible with ASIO drivers||
|macOS|🚧|✅ * macOS 13.0 Ventura or later only|✅ * only VST3 & CLAP|
|Linux|🚧|✅ * No test yet|✅ * No test yet|

---
### Testing locally

Make sure you are using the latest version of stable rust by running `rustup update`.
Expand All @@ -32,4 +43,4 @@ On Linux you need to first run:

On Fedora Rawhide you need to run:

`dnf install clang clang-devel clang-tools-extra libxkbcommon-devel pkg-config openssl-devel libxcb-devel gtk3-devel atk fontconfig-devel`
`dnf install clang clang-devel clang-tools-extra libxkbcommon-devel pkg-config openssl-devel libxcb-devel gtk3-devel atk fontconfig-devel`
Binary file removed assets/favicon.ico
Binary file not shown.
Binary file modified assets/icon-1024.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 assets/icon-black.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 assets/icon-white.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 0 additions & 28 deletions assets/manifest.json

This file was deleted.

Binary file removed assets/maskable_icon_x512.png
Binary file not shown.
1 change: 0 additions & 1 deletion check.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,3 @@ cargo fmt --all -- --check
cargo clippy --quiet --workspace --all-targets --all-features -- -D warnings -W clippy::all
cargo test --quiet --workspace --all-targets --all-features
cargo test --quiet --workspace --doc
trunk build
60 changes: 32 additions & 28 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,27 @@ use std::{thread, vec};
#[derive(serde::Deserialize, serde::Serialize)]
#[serde(default)] // if we add new fields, give them default values when deserializing old state
pub struct NanometersApp {
/// Thread to capture audio data and process it.
#[serde(skip)]
pub(crate) audio_source: Option<Box<dyn AudioSource>>,
/// Audio source data buffer.
#[serde(skip)]
pub(crate) audio_source_buffer: Arc<Mutex<AudioSourceBuffer>>,
/// Calculate the frame time and FPS.
#[serde(skip)]
pub(crate) frame_history: FrameHistory,

/// Data channel between audio source and GUI.
#[serde(skip)]
pub(crate) tx: Option<Sender<SendData>>,
pub(crate) tx_data: Option<Sender<SendData>>,
#[serde(skip)]
pub(crate) rx: Option<Receiver<SendData>>,
pub(crate) rx_data: Option<Receiver<SendData>>,

/// Setting channel between GUI and audio source.
#[serde(skip)]
pub(crate) audio_source_buffer: Arc<Mutex<AudioSourceBuffer>>,
pub(crate) tx_setting: Option<Sender<Setting>>,
#[serde(skip)]
pub(crate) audio_source_setting: Arc<Mutex<Setting>>,
pub(crate) rx_setting: Option<Receiver<Setting>>,

pub(crate) setting: Setting,
pub(crate) sample_rate: AtomicU32,
Expand All @@ -51,32 +58,33 @@ pub struct NanometersApp {

impl Default for NanometersApp {
fn default() -> Self {
let (tx, rx) = unbounded();
// let (tx_setting, rx_setting) = unbounded();
let (tx_data, rx_data) = unbounded();
let (tx_setting, rx_setting) = unbounded();
let audio_source_buffer = Arc::new(Mutex::new(AudioSourceBuffer::new()));
let setting = Setting::default();
let audio_source_setting = Arc::new(Mutex::new(setting.clone()));
let mut system_capture = SystemCapture::new(get_callback(
tx.clone(),
tx_data.clone(),
rx_setting.clone(),
audio_source_buffer.clone(),
audio_source_setting.clone(),
));
system_capture.start();
let audio_source = Some(Box::new(system_capture) as Box<dyn AudioSource>);

Self {
audio_source,
frame_history: Default::default(),
tx: Some(tx),
rx: Some(rx),
audio_source_buffer,
audio_source_setting,
frame_history: Default::default(),
tx_data: Some(tx_data),
rx_data: Some(rx_data),
tx_setting: Some(tx_setting),
rx_setting: Some(rx_setting),
setting,
sample_rate: AtomicU32::new(48000),
setting_switch: false,
allways_on_top: false,
meter_size: Rect::from_two_pos([0.0, 0.0].into(), [600.0, 200.0].into()),
meters_rects: vec![],
meters_rects: Vec::new(),
waveform: Default::default(),
peak: Default::default(),
vectorscope: Default::default(),
Expand All @@ -89,35 +97,31 @@ impl Default for NanometersApp {
impl NanometersApp {
/// Called once before the first frame.
pub fn new(cc: &eframe::CreationContext<'_>) -> Self {
// This is also where you can customize the look and feel of egui using
// `cc.egui_ctx.set_visuals` and `cc.egui_ctx.set_fonts`.
let version = env!("CARGO_PKG_VERSION").to_string();

if let Some(storage) = cc.storage {
let mut app: NanometersApp =
eframe::get_value(storage, eframe::APP_KEY).unwrap_or_default();
cc.egui_ctx.set_visuals(set_theme(&mut app));
app.audio_source_setting = Arc::new(Mutex::new(app.setting.clone()));
app.audio_source_buffer = Arc::new(Mutex::new(AudioSourceBuffer::new_with_setting(
app.setting.clone(),
)));
match app.setting.audio_device.device {
AudioDevice::OutputCapture => {
let tx = app.tx.clone().unwrap();
let callback = get_callback(
tx,
let mut system_capture = SystemCapture::new(get_callback(
app.tx_data.clone().unwrap(),
app.rx_setting.clone().unwrap(),
app.audio_source_buffer.clone(),
app.audio_source_setting.clone(),
);
let mut system_capture = SystemCapture::new(callback);
));
system_capture.start();
app.audio_source = Some(Box::new(system_capture) as Box<dyn AudioSource>);
}
AudioDevice::PluginCapture => {
let tx = app.tx.clone().unwrap();
let callback = get_callback(
tx,
let mut plugin_client = PluginClient::new(get_callback(
app.tx_data.clone().unwrap(),
app.rx_setting.clone().unwrap(),
app.audio_source_buffer.clone(),
app.audio_source_setting.clone(),
);
let mut plugin_client = PluginClient::new(callback);
));
plugin_client.start();
app.audio_source = Some(Box::new(plugin_client) as Box<dyn AudioSource>);
}
Expand Down
Loading

0 comments on commit f77674b

Please sign in to comment.