Select Git revision
Sound Detector Module.gbo
main.rs 18.74 KiB
//! # 16x16 Hexmatrix OSC-Jack-Mixer
use std::io;
use jack;
use jack::{Port, AudioIn, AudioOut};
use rosc;
use rosc::{OscPacket, OscMessage};
use std::net::{SocketAddrV4, UdpSocket};
use std::str::FromStr;
use std::sync::atomic::{AtomicUsize, Ordering};
use arr_macro::arr;
use clap::{Arg, App};
use rayon::prelude::*;
/*
TODO:
- [ ] Document dependecies
- [ ] Performance improvements:
- [ ] implement performance monitoring
- [ ] Flag volume modulations as dirty
- [x] f32.mul_add() or f32.to_bits() / f32.from_bits()
- [x] only calculate connected ports https://docs.rs/jack/0.7.1/jack/struct.Port.html#method.connected_count
- [x] Support other Buffers than 1024
- [ ] Features:
- [ ] Flags to control printing (--quiet etc)
- [ ] Option to set initial values
- [ ] Option to limit certain inputs/outputs to certain volumes
- [ ] Option to ignore certain modulations
- [ ] GUI/TLI to see matrix and current volumes
- [ ] OSC: Per Channel Solo/Mute/Invert
- [ ] OSC: Output Volumes
- [ ] OSC: Output Levels
*/
// Number of inputs and outputs.
// Careful: this needs to be changed in many places
const N_INPUTS: usize = 16;
const N_OUTPUTS: usize = 16;
// Atomic Variables for Shared Mutability of Modulation values
// One per Input, with n values where n is the number of outputs
// Incoming float values get scaled to a unsigned usize (e.g. 64 bit)
// Static arrays are used here for maximum performance
// (No: it is not possible to nest arr! macro calls. yet.)
static VOLS1: [AtomicUsize; N_INPUTS] = arr![AtomicUsize::new(0); 16];
static VOLS2: [AtomicUsize; N_INPUTS] = arr![AtomicUsize::new(0); 16];
static VOLS3: [AtomicUsize; N_INPUTS] = arr![AtomicUsize::new(0); 16];
static VOLS4: [AtomicUsize; N_INPUTS] = arr![AtomicUsize::new(0); 16];
static VOLS5: [AtomicUsize; N_INPUTS] = arr![AtomicUsize::new(0); 16];
static VOLS6: [AtomicUsize; N_INPUTS] = arr![AtomicUsize::new(0); 16];
static VOLS7: [AtomicUsize; N_INPUTS] = arr![AtomicUsize::new(0); 16];
static VOLS8: [AtomicUsize; N_INPUTS] = arr![AtomicUsize::new(0); 16];
static VOLS9: [AtomicUsize; N_INPUTS] = arr![AtomicUsize::new(0); 16];
static VOLS10: [AtomicUsize; N_INPUTS] = arr![AtomicUsize::new(0); 16];
static VOLS11: [AtomicUsize; N_INPUTS] = arr![AtomicUsize::new(0); 16];
static VOLS12: [AtomicUsize; N_INPUTS] = arr![AtomicUsize::new(0); 16];
static VOLS13: [AtomicUsize; N_INPUTS] = arr![AtomicUsize::new(0); 16];
static VOLS14: [AtomicUsize; N_INPUTS] = arr![AtomicUsize::new(0); 16];
static VOLS15: [AtomicUsize; N_INPUTS] = arr![AtomicUsize::new(0); 16];
static VOLS16: [AtomicUsize; N_INPUTS] = arr![AtomicUsize::new(0); 16];
fn get_volume_for_input_output_pair(input_index: usize, output_index: usize) -> f32 {
// For each input get the corrsponding atomic value for the volume control
match input_index {
0 => VOLS1[output_index].load(Ordering::Relaxed) as f32 / usize::MAX as f32,
1 => VOLS2[output_index].load(Ordering::Relaxed) as f32 / usize::MAX as f32,