build wrapper with musl

This commit is contained in:
🪞👃🪞 2025-02-24 21:00:57 +02:00
parent 32a693e1c4
commit ed87ea48a9
6 changed files with 422 additions and 20 deletions

View file

@ -6,3 +6,5 @@ vst:
clear; tmux clear-history || true; cargo build && target/debug/vestal bin/vst.dll 2>&1
vst-v:
clear; tmux clear-history || true; cargo build && target/debug/vestal -v bin/vst.dll 2>&1
wrapper:
cargo build -p vestal_wrapper --release --target=x86_64-unknown-linux-musl

View file

@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["cdylib"]
crate-type = ["staticlib"]
[dependencies]
#nih_plug = { git = "https://github.com/robbert-vdh/nih-plug" }

View file

View file

@ -1,8 +1,128 @@
use tek_jack::{*, jack::*};
use std::error::Error;
pub fn main () -> Result<(), Box<dyn Error>> {
let jack = Jack::new("vestal")?.run(|jack|Ok(Host(jack.clone())))?;
Ok(())
}
struct Host(Jack);
pub(crate) use tek_jack::{*, jack::*};
pub(crate) use std::error::Error;
pub(crate) struct Host(pub Jack);
//mod vst2;
audio!(|self: Host, _c, _s|Control::Continue);
#[no_mangle]
pub extern "C" fn main (argc: usize, argv: usize) -> usize {
let plugin = run();
let jack = Jack::new("vestal")
.expect("failed to connect")
.run(|jack|Ok(Host(jack.clone())))
.expect("failed to start");
println!("Hello world {argc} {argv}");
0
}
fn run () -> &'static Plugin {
let callback = Box::new(main_callback);
let pointer = Box::into_raw(callback) as *mut MainCallback;
unsafe { &*VSTPluginMain(pointer) }
}
unsafe extern "C" {
/// Entrypoint of associated plugin.
fn VSTPluginMain (callback: *mut MainCallback) -> *mut Plugin;
}
#[no_mangle]
extern "C" fn main_callback (
effect: *mut Plugin,
opcode: i32,
index: i32,
value: isize,
ptr: *mut std::ffi::c_void,
opt: f32
) -> isize {
println!("{effect:?}");
0
}
#[repr(C)]
#[derive(Debug)]
struct Plugin {
/// Must be `VstP`
magic: [u8;4],
/// See AudioPlugin::dispatcher
dispatcher: DispatchCallback,
/// Deprecated
_process: ProcessCallback<f32>,
/// Set parameter
set_param: GetParamCallback,
/// Get parameter
get_param: SetParamCallback,
/// Number of programs
num_programs: i32,
/// Number of parameters in a program
num_params: i32,
/// Number of audio inputs
num_inputs: i32,
/// Number of audio outputs
num_outputs: i32,
/// Flags
flags: i32,
/// Reserved, must be 0
_reserved_1: i32,
/// Reserved, must be 0
_reserved_2: i32,
/// Latency required
initial_delay: i32,
/// Deprecated
_real_qs: i32,
/// Deprecated
_off_qs: i32,
/// Deprecated
_io_ratio: f32,
/// Pointer to AudioPlugin class
object: *mut std::ffi::c_void,
/// User-defined pointer
user: *mut std::ffi::c_void,
/// Plugin unique ID (registered)
unique_id: i32,
/// Plugin version
version: i32,
/// Process audio samples in replacing mode
process_replacing: *const ProcessCallback<f32>,
/// Process audio samples in replacing mode with double precision
process_double_replacing: *const ProcessCallback<f64>,
/// Reserved for future use
_reserved: [u8;56]
}
type MainCallback = extern "C" fn(
effect: *mut Plugin,
opcode: i32,
index: i32,
value: isize,
ptr: *mut std::ffi::c_void,
opt: f32
) -> isize;
type DispatchCallback = extern "C" fn(
effect: *mut Plugin,
opcode: i32,
index: i32,
value: *mut i32,
ptr: *mut std::ffi::c_void,
opt: f32
) -> isize;
type ProcessCallback<T> = extern "C" fn(
effect: *mut Plugin,
inputs: *const *const T,
outputs: *const *const T,
frames: i32,
);
type SetParamCallback = extern "C" fn(
effect: *mut Plugin,
index: i32,
value: f32
);
type GetParamCallback = extern "C" fn(
effect: *mut Plugin,
index: i32,
) -> f32;

292
crates/wrapper/src/vst2.rs Normal file
View file

@ -0,0 +1,292 @@
// https://raw.githubusercontent.com/RustAudio/vst2-sys/refs/heads/master/src/lib.rs
// see https://github.com/RustAudio/vst2-sys for autorship and license.
use std::ffi::c_void;
use std::mem;
use std::os::raw::c_char;
pub const fn cconst(a: u8, b: u8, c: u8, d: u8) -> i32 {
((a as i32) << 24) | ((b as i32) << 16) | ((c as i32) << 8) | ((d as i32) << 0)
}
pub mod host_opcodes {
pub const AUTOMATE: i32 = 0;
pub const VERSION: i32 = 1;
pub const CURRENT_ID: i32 = 2;
pub const IDLE: i32 = 3;
pub const PIN_CONNECTED: i32 = 4;
pub const WANT_MIDI: i32 = 6;
pub const GET_TIME: i32 = 7;
pub const PROCESS_EVENTS: i32 = 8;
pub const SET_TIME: i32 = 9;
pub const TEMPO_AT: i32 = 10;
pub const GET_NUM_AUTOMATABLE_PARAMETERS: i32 = 11;
pub const GET_PARAMETER_QUANTIZATION: i32 = 12;
pub const IO_CHANGED: i32 = 13;
pub const NEED_IDLE: i32 = 14;
pub const SIZE_WINDOW: i32 = 15;
pub const GET_SAMPLE_RATE: i32 = 16;
pub const GET_BLOCK_SIZE: i32 = 17;
pub const GET_INPUT_LATENCY: i32 = 18;
pub const GET_OUTPUT_LATENCY: i32 = 19;
pub const GET_PREVIOUS_PLUG: i32 = 20;
pub const GET_NEXT_PLUG: i32 = 21;
pub const WILL_REPLACE_OR_ACCUMULATE: i32 = 22;
pub const GET_CURRENT_PROCESS_LEVEL: i32 = 23;
pub const GET_AUTOMATION_STATE: i32 = 24;
pub const OFFLINE_START: i32 = 25;
pub const OFFLINE_READ: i32 = 26;
pub const OFFLINE_WRITE: i32 = 27;
pub const OFFLINE_GET_CURRENT_PASS: i32 = 28;
pub const OFFLINE_GET_CURRENT_META_PASS: i32 = 29;
pub const SET_OUTPUT_SAMPLE_RATE: i32 = 30;
pub const GET_SPEAKER_ARRANGEMENT: i32 = 31;
pub const GET_VENDOR_STRING: i32 = 32;
pub const GET_PRODUCT_STRING: i32 = 33;
pub const GET_VENDOR_VERSION: i32 = 34;
pub const VENDOR_SPECIFIC: i32 = 35;
pub const SET_ICON: i32 = 36;
pub const CAN_DO: i32 = 37;
pub const GET_LANGUAGE: i32 = 38;
pub const OPEN_WINDOW: i32 = 39;
pub const CLOSE_WINDOW: i32 = 40;
pub const GET_DIRECTORY: i32 = 41;
pub const UPDATE_DISPLAY: i32 = 42;
pub const BEGIN_EDIT: i32 = 43;
pub const END_EDIT: i32 = 44;
pub const OPEN_FILE_SELECTOR: i32 = 45;
pub const CLOSE_FILE_SELECTOR: i32 = 46;
pub const EDIT_FILE: i32 = 47;
pub const GET_CHUNK_FILE: i32 = 48;
pub const GET_INPUT_SPEAKER_ARRANGEMENT: i32 = 49;
}
pub mod effect_flags {
pub const HAS_EDITOR: i32 = 1;
pub const CAN_REPLACING: i32 = 1 << 4;
pub const PROGRAM_CHUNKS: i32 = 1 << 5;
pub const IS_SYNTH: i32 = 1 << 8;
}
pub mod effect_opcodes {
pub const OPEN: i32 = 0;
pub const CLOSE: i32 = 1;
pub const SET_PROGRAM: i32 = 2;
pub const GET_PROGRAM: i32 = 3;
pub const GET_PROGRAM_NAME: i32 = 5;
pub const GET_PARAM_LABEL: i32 = 6;
pub const GET_PARAM_DISPLAY: i32 = 7;
pub const GET_PARAM_NAME: i32 = 8;
pub const SET_SAMPLE_RATE: i32 = 10;
pub const SET_BLOCK_SIZE: i32 = 11;
pub const MAINS_CHANGED: i32 = 12;
pub const EDIT_GET_RECT: i32 = 13;
pub const EDIT_OPEN: i32 = 14;
pub const EDIT_CLOSE: i32 = 15;
pub const EDIT_IDLE: i32 = 19;
pub const EDIT_TOP: i32 = 20;
pub const GET_CHUNK: i32 = 23;
pub const SET_CHUNK: i32 = 24;
pub const PROCESS_EVENTS: i32 = 25;
pub const CAN_BE_AUTOMATED: i32 = 26;
pub const STRING_TO_PARAMETER: i32 = 27;
pub const GET_PLUG_CATEGORY: i32 = 35;
pub const SET_BYPASS: i32 = 44;
pub const GET_EFFECT_NAME: i32 = 45;
pub const GET_VENDOR_STRING: i32 = 47;
pub const GET_PRODUCT_STRING: i32 = 48;
pub const GET_VENDOR_VERSION: i32 = 49;
pub const VENDOR_SPECIFIC: i32 = 50;
pub const CAN_DO: i32 = 51;
pub const IDLE: i32 = 53;
pub const GET_PARAMETER_PROPERTIES: i32 = 56;
pub const GET_VST_VERSION: i32 = 58;
pub const SHELL_GET_NEXT_PLUGIN: i32 = 70;
pub const START_PROCESS: i32 = 71;
pub const STOP_PROCESS: i32 = 72;
pub const BEGIN_SET_PROGRAM: i32 = 67;
pub const END_SET_PROGRAM: i32 = 68;
}
pub const MAGIC: i32 = cconst(b'V', b's', b't', b'P');
pub const LANG_ENGLISH: i32 = 1;
pub const MIDI_TYPE: i32 = 1;
pub const SYSEX_TYPE: i32 = 6;
pub mod transport {
pub const CHANGED: i32 = 1;
pub const PLAYING: i32 = 1 << 1;
pub const CYCLE_ACTIVE: i32 = 1 << 2;
pub const RECORDING: i32 = 1 << 3;
}
pub mod automation {
pub const WRITING: i32 = 1 << 6;
pub const READING: i32 = 1 << 7;
}
pub mod time_info_flags {
pub const NANOS_VALID: i32 = 1 << 8;
pub const PPQ_POS_VALID: i32 = 1 << 9;
pub const TEMPO_VALID: i32 = 1 << 10;
pub const BARS_VALID: i32 = 1 << 11;
pub const CYCLE_POS_VALID: i32 = 1 << 12;
pub const TIME_SIG_VALID: i32 = 1 << 13;
pub const SMPTE_VALID: i32 = 1 << 14;
pub const CLOCK_VALID: i32 = 1 << 15;
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct MidiEvent {
pub event_type: i32,
pub byte_size: i32,
pub delta_frames: i32,
pub flags: i32,
pub note_length: i32,
pub note_offset: i32,
pub midi_data: [u8; 4],
pub detune: i8,
pub note_off_velocity: u8,
pub reserved_1: u8,
pub reserved_2: u8,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct SysExEvent {
pub event_type: i32,
pub byte_size: i32,
pub delta_frames: i32,
pub flags: i32,
pub dump_bytes: i32,
pub reserved_1: *const c_void,
pub sysex_dump: *const i8,
pub reserved_2: *const c_void,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct Event {
pub dump: [u8; mem::size_of::<MidiEvent>()],
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct Events {
pub num_events: i32,
pub reserved: *const c_void,
pub events: [*const Event; 2],
}
pub mod string_constants {
pub const MAX_NAME_LEN: usize = 64;
pub const MAX_LABEL_LEN: usize = 64;
pub const MAX_SHORT_LABEL_LEN: usize = 8;
pub const MAX_CATEG_LABEL_LEN: usize = 24;
pub const MAX_FILE_NAME_LEN: usize = 100;
}
pub mod plug_category {
pub const UNKNOWN: i32 = 0;
pub const EFFECT: i32 = 1;
pub const SYNTH: i32 = 2;
pub const ANALYSIS: i32 = 3;
pub const MASTERING: i32 = 4;
pub const SPACIALIZER: i32 = 5;
pub const ROOM_FX: i32 = 6;
pub const SURROUND_FX: i32 = 7;
pub const RESTORATION: i32 = 8;
pub const OFFLINE_PROCESS: i32 = 9;
pub const SHELL: i32 = 10;
pub const GENERATOR: i32 = 11;
pub const MAX_COUNT: i32 = 12;
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct ParameterProperties {
pub step_float: f32,
pub small_step_float: f32,
pub large_step_float: f32,
pub label: [c_char; string_constants::MAX_LABEL_LEN],
pub flags: i32,
pub min_integer: i32,
pub max_integer: i32,
pub step_integer: i32,
pub large_step_integer: i32,
pub short_label: [c_char; string_constants::MAX_SHORT_LABEL_LEN],
pub display_index: i16,
pub category: i16,
pub num_parameters_in_category: i16,
pub reserved: i16,
pub category_label: [c_char; string_constants::MAX_CATEG_LABEL_LEN],
pub future: [u8; 16],
}
pub mod parameter_flags {
pub const IS_SWITCH: i32 = 1 << 0;
pub const USES_INTEGER_MIN_MAX: i32 = 1 << 1;
pub const USES_FLOAT_STEP: i32 = 1 << 2;
pub const USES_INT_STEP: i32 = 1 << 3;
pub const SUPPORTS_DISPLAY_INDEX: i32 = 1 << 4;
pub const SUPPORTS_DISPLAY_CATEGORY: i32 = 1 << 5;
pub const CAN_RAMP: i32 = 1 << 6;
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct AEffect {
pub magic: i32,
pub dispatcher: extern "C" fn(*mut AEffect, i32, i32, isize, *mut c_void, f32) -> isize,
pub process: extern "C" fn(*mut AEffect, *const *const f32, *mut *mut f32, i32),
pub set_parameter: extern "C" fn(*mut AEffect, i32, f32),
pub get_parameter: extern "C" fn(*mut AEffect, i32) -> f32,
pub num_programs: i32,
pub num_params: i32,
pub num_inputs: i32,
pub num_outputs: i32,
pub flags: i32,
pub ptr_1: *mut c_void,
pub ptr_2: *mut c_void,
pub initial_delay: i32,
pub empty_2: [u8; 4 + 4],
pub unknown_float: f32,
pub object: *mut c_void,
pub user: *mut c_void,
pub unique_id: i32,
pub version: i32,
pub process_replacing: extern "C" fn(*mut AEffect, *const *const f32, *mut *mut f32, i32),
pub process_double_replacing: extern "C" fn(*mut AEffect, *const *const f64, *mut *mut f64, i32),
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct TimeInfo {
pub sample_pos: f64,
pub sample_rate: f64,
pub nano_seconds: f64,
pub ppq_pos: f64,
pub tempo: f64,
pub bar_start_pos: f64,
pub cycle_start_pos: f64,
pub cycle_end_pos: f64,
pub time_sig_numerator: i32,
pub time_sig_denominator: i32,
pub smpte_offset: i32,
pub smpte_frame_rate: i32,
pub samples_to_next_clock: i32,
pub flags: i32,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct Rect {
pub top: i16,
pub left: i16,
pub bottom: i16,
pub right: i16,
}
pub type HostCallbackProc = extern "C" fn(*mut AEffect, i32, i32, isize, *mut c_void, f32) -> isize;

View file

@ -1,12 +0,0 @@
Copyright (C) 2023 - 2025 by H. L. Goldberg.
The contained software is given to use under a freeware license.
This software is provided free of charge but the author retains copyright.
You are not allowed to make any copies or redistribute this software including but not limited to making the software available for download or making this software part of a software CD/DVD/Blue-ray compilation.
You are not allowed to sell or to rent this software. You are not allowed to reverse engineer this software.
You are allowed to use this software for any artistic application including commercial music production.
This software is provided 'as-is', without any express or implied warranty. In no event will the author be held liable for any damages arising from the use of this software.