diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
new file mode 100644
index 0000000..a4ddebe
--- /dev/null
+++ b/.config/dotnet-tools.json
@@ -0,0 +1,18 @@
+{
+ "version": 1,
+ "isRoot": true,
+ "tools": {
+ "fable": {
+ "version": "4.1.4",
+ "commands": [
+ "fable"
+ ]
+ },
+ "paket": {
+ "version": "7.2.1",
+ "commands": [
+ "paket"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..421c0d8
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,9 @@
+# http://editorconfig.org
+root = true
+
+[*.fs]
+indent_style = space
+indent_size = 2
+charset = utf-8
+trim_trailing_whitespace = true
+
diff --git a/.gitignore b/.gitignore
index d12fdd1..c7957a3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,11 @@ Thumbs.db
# local vscode settings
.vscode/
+# jetbrains ide's
+cmake-build-debug
+
+.idea
+
# libsamplerate tests
Dependencies/libsamplerate/
@@ -17,7 +22,23 @@ Dependencies/libsamplerate/
# used by cmake
build/
-
+cmake-build-debug
# private config (see Config.cmake template)
MyConfig.cmake
+# dotnet
+paket-files
+bin
+**/obj
+
+
+# rust
+Source/rust/target
+Source/fsharp/**.fs.rs
+Source/fsharp/**.fs.js
+Source/fsharp/fable_modules
+target
+
+# generated code
+Source/generated
+!/Source/generated/foo/Cargo.toml
diff --git a/CMakeLists.txt b/CMakeLists.txt
index da92454..b1c845e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -13,6 +13,14 @@ execute_process(
string(TIMESTAMP CURRENT_DATE "%Y-%m-%d")
set(PROJECT_DESCRIPTION "ComposeSiren du ${CURRENT_DATE} sur commit n ${GIT_HASH}")
+include(FetchContent)
+FetchContent_Declare(
+ Corrosion
+ GIT_REPOSITORY https://github.com/AndrewGaspar/corrosion.git
+ GIT_TAG origin/master # Optionally specify a version tag or branch here
+)
+FetchContent_MakeAvailable(Corrosion)
+
project(ComposeSiren VERSION 1.5.0 DESCRIPTION ${PROJECT_DESCRIPTION})
set(BaseTargetName ${PROJECT_NAME})
set(VendorName "Mecanique Vivante")
@@ -36,30 +44,30 @@ if (APPLE)
endif()
juce_add_plugin(${BaseTargetName}
- PRODUCT_NAME "${BaseTargetName}"
- COMPANY_NAME "${VendorName}"
- VERSION ${CMAKE_PROJECT_VERSION}
- ICON_BIG "${CMAKE_SOURCE_DIR}/Assets/Icon.png"
- ICON_SMALL "${CMAKE_SOURCE_DIR}/Assets/Icon.png"
- FORMATS ${FORMATS}
- # A four-character manufacturer id with at least one upper-case character
- PLUGIN_MANUFACTURER_CODE McVv
- # A unique four-character plugin id with at least one upper-case character
- PLUGIN_CODE MvCs
- IS_SYNTH TRUE # Is this a synth or an effect?
- NEEDS_MIDI_INPUT TRUE # Does the plugin need midi input?
- NEEDS_MIDI_OUTPUT TRUE # Does the plugin need midi output?
- IS_MIDI_EFFECT FALSE # Is this plugin a MIDI effect?
- EDITOR_WANTS_KEYBOARD_FOCUS TRUE # Does the editor need keyboard focus?
- COPY_PLUGIN_AFTER_BUILD FALSE # Should the plugin be installed to a default location after building?
- # VST3_CATEGORIES
- # AAX_CATEGORY
- # AU_MAIN_TYPE
- # COMPANY_WEBSITE https://www.mecanique-vivante.com
- # COMPANY_EMAIL
- BUNDLE_ID "com.mecaviv.${BaseTargetName}"
- PLUGIN_NAME "${BaseTargetName}"
- PRODUCT_NAME "${BaseTargetName}"
+ PRODUCT_NAME "${BaseTargetName}"
+ COMPANY_NAME "${VendorName}"
+ VERSION ${CMAKE_PROJECT_VERSION}
+ ICON_BIG "${CMAKE_SOURCE_DIR}/Assets/Icon.png"
+ ICON_SMALL "${CMAKE_SOURCE_DIR}/Assets/Icon.png"
+ FORMATS ${FORMATS}
+ # A four-character manufacturer id with at least one upper-case character
+ PLUGIN_MANUFACTURER_CODE McVv
+ # A unique four-character plugin id with at least one upper-case character
+ PLUGIN_CODE MvCs
+ IS_SYNTH TRUE # Is this a synth or an effect?
+ NEEDS_MIDI_INPUT TRUE # Does the plugin need midi input?
+ NEEDS_MIDI_OUTPUT TRUE # Does the plugin need midi output?
+ IS_MIDI_EFFECT FALSE # Is this plugin a MIDI effect?
+ EDITOR_WANTS_KEYBOARD_FOCUS TRUE # Does the editor need keyboard focus?
+ COPY_PLUGIN_AFTER_BUILD FALSE # Should the plugin be installed to a default location after building?
+ # VST3_CATEGORIES
+ # AAX_CATEGORY
+ # AU_MAIN_TYPE
+ # COMPANY_WEBSITE https://www.mecanique-vivante.com
+ # COMPANY_EMAIL
+ BUNDLE_ID "com.mecaviv.${BaseTargetName}"
+ PLUGIN_NAME "${BaseTargetName}"
+ PRODUCT_NAME "${BaseTargetName}"
)
juce_generate_juce_header(${BaseTargetName})
@@ -82,31 +90,37 @@ add_subdirectory(Assets)
add_subdirectory(Source)
target_link_libraries(${BaseTargetName}
- PRIVATE
- # copied from projucer project
- juce::juce_audio_basics
- juce::juce_audio_devices
- juce::juce_audio_formats
- juce::juce_audio_processors
- juce::juce_audio_utils
- juce::juce_core
- juce::juce_data_structures
- juce::juce_events
- juce::juce_graphics
- juce::juce_gui_basics
- juce::juce_gui_extra
- # recommended
- juce::juce_recommended_warning_flags
- juce::juce_recommended_config_flags
- juce::juce_recommended_lto_flags
+ PRIVATE
+ # copied from projucer project
+ juce::juce_audio_basics
+ juce::juce_audio_devices
+ juce::juce_audio_formats
+ juce::juce_audio_processors
+ juce::juce_audio_utils
+ juce::juce_core
+ juce::juce_data_structures
+ juce::juce_events
+ juce::juce_graphics
+ juce::juce_gui_basics
+ juce::juce_gui_extra
+ # recommended
+ juce::juce_recommended_warning_flags
+ juce::juce_recommended_config_flags
+ juce::juce_recommended_lto_flags
)
-target_compile_definitions(${BaseTargetName}
- PUBLIC
- JUCE_VST3_CAN_REPLACE_VST2=0
- JUCE_WEB_BROWSER=0
+target_compile_definitions(${BaseTargetName}
+ PUBLIC
+ JUCE_VST3_CAN_REPLACE_VST2=0
+ JUCE_WEB_BROWSER=0
)
+
+
+corrosion_import_crate(MANIFEST_PATH ${CMAKE_CURRENT_SOURCE_DIR}/Source/rust/Cargo.toml CRATES composesiren-dsp-rs)
+target_link_libraries(${BaseTargetName} PUBLIC composesiren-dsp-rs)
+
+
################################################################################
# packaging
@@ -122,4 +136,4 @@ if(APPLE) # we generate a cmake subproject to build the installer
include(Packaging/Apple/MakePackage.cmake)
elseif(WIN32) # we just proceed the regular way
include(Packaging/Windows/MakePackage.cmake)
-endif()
+endif()
\ No newline at end of file
diff --git a/Source/fsharp/ComposeSiren.fsproj b/Source/fsharp/ComposeSiren.fsproj
new file mode 100644
index 0000000..8598ce3
--- /dev/null
+++ b/Source/fsharp/ComposeSiren.fsproj
@@ -0,0 +1,17 @@
+
+
+
+ net7.0
+ true
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source/fsharp/composesiren.declarations.fs b/Source/fsharp/composesiren.declarations.fs
new file mode 100644
index 0000000..441270d
--- /dev/null
+++ b/Source/fsharp/composesiren.declarations.fs
@@ -0,0 +1,19 @@
+namespace composesiren.declarations
+open Fable.Core.Rust
+[]
+type SirenDataFileSuffix =
+| S1
+| S2
+| S3
+| S4
+| S5
+| S7
+
+[]
+type SirenModel =
+| Alto1
+| Alto2
+| Bass
+| Tenor
+| Soprano
+| Piccolo
diff --git a/Source/fsharp/composesiren.dsp.fs b/Source/fsharp/composesiren.dsp.fs
new file mode 100644
index 0000000..bc5a41c
--- /dev/null
+++ b/Source/fsharp/composesiren.dsp.fs
@@ -0,0 +1,274 @@
+namespace composesiren.dsp
+
+open composesiren.declarations
+//open System.IO
+open System.Collections.Generic
+open Fable.Core.Rust
+(*
+type SirenId =
+ | Piccolo
+ | AltoS1
+ | AltoS2
+ | Bass| Tenor |SopranoS5 | SopranoS6
+*)
+[]
+type SirenModelFileSet =
+ {
+ amp : SirenDataFileSuffix
+ freq: SirenDataFileSuffix
+ length: SirenDataFileSuffix
+ vector: SirenDataFileSuffix
+ }
+[]
+type FileType =
+ | Amp
+ | Freq
+ | Length
+ | Vector // deprecated by approximation formula
+
+module ComposeSirenesLouetteDsp =
+
+ []
+
+ type ReverbParameterId =
+ | Size
+ | DryWet
+ | Depth
+ | Width
+ []
+
+ type SirenDspParameterId =
+ //| DspStereoPan of siren: SirenId
+ | DspGain
+ | DspPartialCount
+ | ReverParameter of reverParameter: ReverbParameterId
+
+ []
+
+ type LengthTable =
+ {
+ sample_count: uint32
+ max_tab_count: uint16
+ average_frequency: float32
+ }
+
+ let NOMBRE_DE_NOTE = 80
+
+ let MAX_Partiel = 200
+
+ let MAX_TAB = 1000
+
+module DspState =
+ []
+ type midi_note_index = midi_note_index of uint8
+ []
+ type midi_velocity = midi_velocity of uint8
+
+ []
+ type midi_pitchbend = midi_pitchbend of uint16
+ []
+ type dsp_frame = dsp_frame of uint64
+ []
+ type VibratoEvent =
+ | NewVibratoValueSample of frame: dsp_frame * vibratoDepthValue: float
+ []
+ type TremoloEvent =
+ | NewTremoloValueSample of frame: dsp_frame * tremoloDepthValue: float
+ []
+ type EngineSpeedUpdate =
+ | LiveMidiNoteOn of note: midi_note_index
+ | LiveMidiNoteOff of note: midi_note_index
+ | PitchbendValue of bend: midi_pitchbend
+ | VibratoEvent of VibratoEvent
+
+ type ShutterUpdateEvent =
+ | TremoloEvent of TremoloEvent
+ | LiveMidiNoteOn of note: midi_note_index
+ | LiveMidiNoteOff of note: midi_note_index
+ type ShutterState =
+ {
+ lastShutterEvent: ShutterUpdateEvent option
+ }
+ //| TuningMap // todo v3
+ type PitchEvent =
+ | MidiNote of midi_note_index * midi_velocity // add isOn isOff, for now, if velocity is 0, it is note off
+
+ type EngineSpeed() =
+ class
+ end
+
+ []
+
+ type EngineState =
+ {
+ lastPlayedNote: PitchEvent option
+ currentSpeed: EngineSpeed
+ }
+ []
+
+ type SirenVoiceDspState =
+ {
+ pan: float
+ engineState: EngineState
+ shutterState: ShutterState
+ }
+ []
+ type SirenDspState =
+ {
+ sirens : SirenVoiceDspState array
+
+ }
+
+#if false
+module Routines =
+ open ComposeSirenesLouetteDsp
+
+ let sirenmodel_get_file_set (sirenModel: SirenModel) : SirenModelFileSet =
+ let amp, length, vector, freq =
+ match sirenModel with
+ |Alto1 -> (S1, S1, S1, S1)
+ |Alto2 -> (S1, S1, S2, S1)
+ |Bass -> (S3, S3, S3, S3)
+ |Tenor -> (S4, S4, S4, S4)
+ |Soprano -> (S5, S5, S5, S5)
+ |Piccolo -> (S7, S7, S5, S7)
+ { amp=amp
+ freq=freq
+ length=length
+ vector=vector}
+
+ let get_filename_and_buffer_size file (suffix: SirenDataFileSuffix) (directory:DirectoryInfo) =
+ //let s = sizeof
+ let filePath, bufferSize =
+ let amplitudeTable = NOMBRE_DE_NOTE * MAX_TAB * MAX_Partiel
+ let lengthTable = NOMBRE_DE_NOTE * (*uint32 * uint16 * f32*) 4 * 2 * 4 //sizeof //"" // LengthTable::dim_1() * std::mem::size_of::() * 3)
+ let dataVectorInterval = (*f32*) 4 * 392
+ let frequencyTable = NOMBRE_DE_NOTE * MAX_TAB * MAX_Partiel
+ match file with
+ | FileType.Amp -> "dataAmp", amplitudeTable
+ | FileType.Freq -> "dataFreq", frequencyTable //FrequencyTable::size_of()
+ | FileType.Length -> "datadureTabs", lengthTable
+ | FileType.Vector -> "dataVectorInterval", dataVectorInterval //, VectorTable::dim_1() * std::mem::size_of::())
+
+ let isEqual = 0 = bufferSize % 4
+ if not isEqual then
+ failwith "rustcodetodo: assert_eq!(0, bufferSize % 4)"
+
+ let directoryName = $"filename{file}"// directory.Name
+ let filePath = directoryName + "/" + filePath + string suffix
+ filePath, bufferSize
+
+ //type FileMap = System.Collections.Generic.IDictionary,Box>>
+ type FileMap = System.Collections.Generic.IDictionary>
+
+
+ let read_siren_dataset (sirenModel: SirenModel) (folder: DirectoryInfo) (fileMap: FileMap) =
+
+ let fileSet = sirenmodel_get_file_set(sirenModel);
+
+ let readFileAsFloatsVector (f: FileType) (suffix: SirenDataFileSuffix) =
+ let file_path, buffer_size = get_filename_and_buffer_size(f, suffix, folder)
+ let fileInfo = FileInfo filePath
+ let buffer_size = buffer_size / sizeof // std::mem::size_of::();
+ let file_size = fileInfo.Length //std::fs::metadata(&file_path).expect("could not get file meta data").len() as usize;
+ let datafile =
+ //
+ failwith $"rustcodetodo: std::fs::File::open(&file_path).expect(&format!( not able to read {fileInfo.FullName})"
+ //let datafile = BufReader::new(datafile);
+ (*let mut floats_buffer = {
+ let mut floats = Vec::::with_capacity(buffer_size);
+ unsafe { floats.set_len(file_size / std::mem::size_of::()); }
+
+ datafile.read_f32_into::(&mut floats[..]).unwrap();
+ floats
+ };
+ if buffer_size != floats_buffer.len() {
+ eprintln!("expected buffersize:{} got:{} {}", buffer_size, floats_buffer.len(), file_path.as_str());
+ floats_buffer.resize(buffer_size, 0.);
+ }
+ *)
+ let float_buffer = ()
+ floats_buffer
+
+ (*
+ let amp = readFileAsFloatsVector(&FileType::Amp, &fileSet.amp);
+ let freq = readFileAsFloatsVector(&FileType::Freq, &fileSet.freq);
+ let length = readFileAsFloatsVector(&FileType::Length, &fileSet.length);
+ let vector = readFileAsFloatsVector(&FileType::Vector, &fileSet.vector);
+
+ let amp = AmplitudeTable { data: Array3::from_shape_vec((AmplitudeTable::dim_1(), AmplitudeTable::dim_2(), AmplitudeTable::dim_3()), amp).unwrap() };
+ let freq = FrequencyTable { data: Array3::from_shape_vec((FrequencyTable::dim_1(), FrequencyTable::dim_2(), FrequencyTable::dim_3()), freq).unwrap() };
+ let length = {
+ let mut v = Vec::::with_capacity(LengthTable::dim_1());
+ for n in 0 .. LengthTable::dim_1() {
+ let (sample_count, max_tab_count, average_frequency) =
+ (length[n * 3]
+ , length[n * 3 + 1]
+ , length[n * 3 + 2])
+ ;
+ let entry = LengthTableEntry {
+ sample_count: sample_count.round() as u32
+ , max_tab_count : max_tab_count.round() as u16
+ , average_frequency
+ };
+ v.push(entry);
+ }
+ if v.len() < LengthTable::dim_1() {
+ eprintln!("expected length table of length {} but got {}", LengthTable::dim_1(), v.len());
+ }
+ LengthTable { data: Array1::from_shape_vec(LengthTable::dim_1(), v).unwrap() }
+
+ };
+ let vector = VectorTable { data: Array1::from_shape_vec(VectorTable::dim_1(), vector).unwrap() };
+ *)
+ let sirenDataset =
+ {
+ amp = amp
+ freq= freq
+ length = length
+ vector = vector
+ }
+ sirenDataset
+#endif
+
+//module TestRoutines =
+//#[cfg(test)]
+
+ //use std::collections::HashMap;
+ //use crate::{sirenmodel_get_file_set, read_siren_dataset};
+
+ //use crate::types::SirenModel::{*};
+ //const folder : &str = "/Users/gauthiersegay/dev/src/mecaviv/benoit/CodesSources/ComposeSirenes2/ComposeSirenes/";
+
+ //[]
+#if false
+ let it_worksreadfiles() =
+ let map = Dictionary()
+ let s1 = read_siren_dataset(&crate::types::SirenModel::Alto2, folder, &map);
+ for v in s1.vector do
+ //let v = s1.vector.data[i];
+ printfn $"{v}"
+
+
+
+ //[]
+ let it_works () =
+ let s1 = sirenmodel_get_file_set(&Alto1)
+ let s2 = sirenmodel_get_file_set(&Alto2)
+ let s3 = sirenmodel_get_file_set(&Bass)
+ let s4 = sirenmodel_get_file_set(&Tenor)
+ let s5 = sirenmodel_get_file_set(&Soprano)
+ let s6 = sirenmodel_get_file_set(&Soprano)
+ let s7 = sirenmodel_get_file_set(&Piccolo)
+
+ printfn $"s1={s1}"
+ printfn $"s2={s2}"
+ printfn $"s3={s3}"
+ printfn $"s4={s4}"
+ printfn $"s5={s5}"
+ printfn $"s6={s6}"
+ printfn $"s7={s7}"
+ //assert_eq!(2 + 2, 4);
+
+
+#endif
\ No newline at end of file
diff --git a/Source/fsharp/composesiren.dsp.processor.fs b/Source/fsharp/composesiren.dsp.processor.fs
new file mode 100644
index 0000000..fcea0e2
--- /dev/null
+++ b/Source/fsharp/composesiren.dsp.processor.fs
@@ -0,0 +1,22 @@
+namespace composesiren.dsp.processor
+
+open composesiren.dsp
+open composesiren.dsp.ComposeSirenesLouetteDsp
+
+open composesiren.dsp.state
+
+//type SirenDspStqIndex
+
+type ProcessorState = {
+
+ sirens : SirenOrchestraDspState
+
+}
+
+type JuceMidiBuffer = | JuceMidiBuffer
+
+type UIEvents =
+ | AdjustSirenControl of parameterooo: SirenDspParameterId * value: uint8
+ | MidiEvents of JuceMidiBuffer
+ | ReplyStateQuery of toCallback : (ProcessorState -> unit)
+
diff --git a/Source/fsharp/lib.fs b/Source/fsharp/lib.fs
new file mode 100644
index 0000000..1c17ba5
--- /dev/null
+++ b/Source/fsharp/lib.fs
@@ -0,0 +1,12 @@
+namespace composesiren
+open Fable.Core.Rust
+[]
+type SirenLibrary =
+ {
+ version: string
+ }
+
+module refs_ =
+ importAll "composesiren.declarations.rs"
+ importAll "composesiren.dsp.rs"
+ importAll "composesiren.dsp.processor.rs"
\ No newline at end of file
diff --git a/Source/fsharp/paket.references b/Source/fsharp/paket.references
new file mode 100644
index 0000000..1d37423
--- /dev/null
+++ b/Source/fsharp/paket.references
@@ -0,0 +1 @@
+Fable.Core
\ No newline at end of file
diff --git a/Source/fsharp/samples/sample.fs b/Source/fsharp/samples/sample.fs
new file mode 100644
index 0000000..b187055
--- /dev/null
+++ b/Source/fsharp/samples/sample.fs
@@ -0,0 +1,60 @@
+module Programs.sample
+
+open composesiren.dsp.processor
+open composesiren.dsp.state
+
+
+[]
+let main args =
+ let sirens =
+ [|
+ composesiren.declarations.Alto1
+ composesiren.declarations.Alto2
+ composesiren.declarations.Bass
+ composesiren.declarations.Tenor
+ composesiren.declarations.Soprano
+ composesiren.declarations.Soprano
+ composesiren.declarations.Piccolo
+ |]
+
+ let engineState =
+ {
+ lastPlayedNote = None// PitchEvent option
+ currentSpeed = EngineSpeed()
+ }
+
+ let shutterState = { lastShutterEvent = None }
+ let sirenState =
+ {
+ pan = 0.
+ engineState = engineState
+ shutterState = shutterState
+ }
+
+ let orchestra : SirenOrchestraDspState =
+ {
+ sirens =
+ [|
+
+ sirenState
+ sirenState
+ sirenState
+ sirenState
+ sirenState
+ sirenState
+ sirenState
+ |]
+ }
+ let state =
+ {
+ ProcessorState.sirens = orchestra
+ }
+
+
+
+
+ printfn "hello F# into rusdt world?"
+ printfn "hello F# irrnto rusdt world?"
+
+
+ 1
\ No newline at end of file
diff --git a/Source/fsharp/samples/sample.fsx b/Source/fsharp/samples/sample.fsx
new file mode 100644
index 0000000..29401d4
--- /dev/null
+++ b/Source/fsharp/samples/sample.fsx
@@ -0,0 +1,54 @@
+#r "bin/Debug/net7.0/ComposeSiren.dll"
+open composesiren.dsp.processor
+open composesiren.dsp.state
+
+[]
+let main args =
+ let sirens =
+ [|
+ composesiren.declarations.Alto1
+ composesiren.declarations.Alto2
+ composesiren.declarations.Bass
+ composesiren.declarations.Tenor
+ composesiren.declarations.Soprano
+ composesiren.declarations.Soprano
+ composesiren.declarations.Piccolo
+ |]
+
+ let engineState =
+ {
+ lastPlayedNote = None// PitchEvent option
+ currentSpeed = EngineSpeed()
+ }
+
+ let shutterState = { lastShutterEvent = None }
+ let sirenState =
+ {
+ pan = 0.
+ engineState = engineState
+ shutterState = shutterState
+ }
+
+ let orchestra : SirenOrchestraDspState =
+ {
+ sirens =
+ [|
+
+ sirenState
+ sirenState
+ sirenState
+ sirenState
+ sirenState
+ sirenState
+ sirenState
+ |]
+ }
+ let state =
+ {
+ ProcessorState.sirens = orchestra
+ }
+
+
+
+
+ 1
\ No newline at end of file
diff --git a/Source/fsharp/samples/samples.fsproj b/Source/fsharp/samples/samples.fsproj
new file mode 100644
index 0000000..79f3506
--- /dev/null
+++ b/Source/fsharp/samples/samples.fsproj
@@ -0,0 +1,16 @@
+
+
+
+ net8.0
+ true
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source/generated/rust/Cargo.toml b/Source/generated/rust/Cargo.toml
new file mode 100644
index 0000000..fbe4d70
--- /dev/null
+++ b/Source/generated/rust/Cargo.toml
@@ -0,0 +1,5 @@
+[workspace]
+members = [
+ "mecaviv-siren-declarations-rs",
+ "samples"
+]
\ No newline at end of file
diff --git a/Source/generated/rust/mecaviv-siren-declarations-rs/Cargo.lock b/Source/generated/rust/mecaviv-siren-declarations-rs/Cargo.lock
new file mode 100644
index 0000000..303acbb
--- /dev/null
+++ b/Source/generated/rust/mecaviv-siren-declarations-rs/Cargo.lock
@@ -0,0 +1,7 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "mecaviv-siren-declarations-rs"
+version = "0.1.0"
diff --git a/Source/generated/rust/mecaviv-siren-declarations-rs/Cargo.toml b/Source/generated/rust/mecaviv-siren-declarations-rs/Cargo.toml
new file mode 100644
index 0000000..03c5d9e
--- /dev/null
+++ b/Source/generated/rust/mecaviv-siren-declarations-rs/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+name = "mecaviv-siren-declarations-rs"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+fable_library_rust = { path="src/fable_modules/fable-library-rust" }
+
+
+
+
+[build-dependencies]
+cmake = "*"
+cbindgen = "*"
\ No newline at end of file
diff --git a/Source/generated/rust/samples/Cargo.toml b/Source/generated/rust/samples/Cargo.toml
new file mode 100644
index 0000000..4609861
--- /dev/null
+++ b/Source/generated/rust/samples/Cargo.toml
@@ -0,0 +1,12 @@
+[package]
+name = "samples"
+version = "0.0.0"
+edition = "2021"
+
+[[example]]
+name = "sample"
+path = "sample.rs"
+
+[dependencies]
+fable_library_rust = { path = "../../../fsharp/fable_modules/fable-library-rust/" }
+mecaviv-siren-declarations-rs = { path = "../mecaviv-siren-declarations-rs" }
\ No newline at end of file
diff --git a/Source/rust/Cargo.lock b/Source/rust/Cargo.lock
new file mode 100644
index 0000000..48fe5a3
--- /dev/null
+++ b/Source/rust/Cargo.lock
@@ -0,0 +1,873 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "aho-corasick"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "android_system_properties"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "arrayvec"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6"
+
+[[package]]
+name = "atty"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
+dependencies = [
+ "hermit-abi 0.1.19",
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "bumpalo"
+version = "3.12.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c6ed94e98ecff0c12dd1b04c15ec0d7d9458ca8fe806cea6f12954efe74c63b"
+
+[[package]]
+name = "bytemuck"
+version = "1.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea"
+
+[[package]]
+name = "byteorder"
+version = "1.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
+
+[[package]]
+name = "cbindgen"
+version = "0.24.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a6358dedf60f4d9b8db43ad187391afe959746101346fe51bb978126bec61dfb"
+dependencies = [
+ "clap",
+ "heck",
+ "indexmap",
+ "log",
+ "proc-macro2",
+ "quote",
+ "serde",
+ "serde_json",
+ "syn 1.0.109",
+ "tempfile",
+ "toml",
+]
+
+[[package]]
+name = "cc"
+version = "1.0.79"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "chrono"
+version = "0.4.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b"
+dependencies = [
+ "iana-time-zone",
+ "js-sys",
+ "num-integer",
+ "num-traits",
+ "time",
+ "wasm-bindgen",
+ "winapi",
+]
+
+[[package]]
+name = "clap"
+version = "3.2.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123"
+dependencies = [
+ "atty",
+ "bitflags",
+ "clap_lex",
+ "indexmap",
+ "strsim",
+ "termcolor",
+ "textwrap",
+]
+
+[[package]]
+name = "clap_lex"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
+dependencies = [
+ "os_str_bytes",
+]
+
+[[package]]
+name = "cmake"
+version = "0.1.50"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "composesiren-dsp-rs-lib"
+version = "0.1.0"
+dependencies = [
+ "bytemuck",
+ "byteorder",
+ "cbindgen",
+ "cmake",
+ "fable_library_rust",
+ "lazy_static",
+ "mecaviv-siren-declarations-rs",
+ "ndarray",
+]
+
+[[package]]
+name = "core-foundation-sys"
+version = "0.8.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
+
+[[package]]
+name = "errno"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a"
+dependencies = [
+ "errno-dragonfly",
+ "libc",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "errno-dragonfly"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
+dependencies = [
+ "cc",
+ "libc",
+]
+
+[[package]]
+name = "fable_library_rust"
+version = "0.1.0"
+dependencies = [
+ "chrono",
+ "getrandom",
+ "num-bigint",
+ "num-integer",
+ "num-traits",
+ "regex",
+ "rust_decimal",
+ "uuid",
+]
+
+[[package]]
+name = "fastrand"
+version = "1.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
+dependencies = [
+ "instant",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4"
+dependencies = [
+ "cfg-if",
+ "js-sys",
+ "libc",
+ "wasi 0.11.0+wasi-snapshot-preview1",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+
+[[package]]
+name = "heck"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
+
+[[package]]
+name = "hermit-abi"
+version = "0.1.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "hermit-abi"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
+
+[[package]]
+name = "iana-time-zone"
+version = "0.1.56"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0722cd7114b7de04316e7ea5456a0bbb20e4adb46fd27a3697adb812cff0f37c"
+dependencies = [
+ "android_system_properties",
+ "core-foundation-sys",
+ "iana-time-zone-haiku",
+ "js-sys",
+ "wasm-bindgen",
+ "windows",
+]
+
+[[package]]
+name = "iana-time-zone-haiku"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "indexmap"
+version = "1.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
+dependencies = [
+ "autocfg",
+ "hashbrown",
+]
+
+[[package]]
+name = "instant"
+version = "0.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "io-lifetimes"
+version = "1.0.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220"
+dependencies = [
+ "hermit-abi 0.3.1",
+ "libc",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "itoa"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
+
+[[package]]
+name = "js-sys"
+version = "0.3.63"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2f37a4a5928311ac501dee68b3c7613a1037d0edb30c8e5427bd832d55d1b790"
+dependencies = [
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
+name = "libc"
+version = "0.2.144"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1"
+
+[[package]]
+name = "linux-raw-sys"
+version = "0.3.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
+
+[[package]]
+name = "log"
+version = "0.4.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "matrixmultiply"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "090126dc04f95dc0d1c1c91f61bdd474b3930ca064c1edc8a849da2c6cbe1e77"
+dependencies = [
+ "autocfg",
+ "rawpointer",
+]
+
+[[package]]
+name = "mecaviv-siren-declarations-rs"
+version = "0.1.0"
+dependencies = [
+ "fable_library_rust",
+]
+
+[[package]]
+name = "memchr"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
+
+[[package]]
+name = "ndarray"
+version = "0.15.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "adb12d4e967ec485a5f71c6311fe28158e9d6f4bc4a447b474184d0f91a8fa32"
+dependencies = [
+ "matrixmultiply",
+ "num-complex",
+ "num-integer",
+ "num-traits",
+ "rawpointer",
+]
+
+[[package]]
+name = "num-bigint"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f"
+dependencies = [
+ "autocfg",
+ "num-integer",
+ "num-traits",
+]
+
+[[package]]
+name = "num-complex"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "02e0d21255c828d6f128a1e41534206671e8c3ea0c62f32291e808dc82cff17d"
+dependencies = [
+ "num-traits",
+]
+
+[[package]]
+name = "num-integer"
+version = "0.1.45"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
+dependencies = [
+ "autocfg",
+ "num-traits",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.17.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
+
+[[package]]
+name = "os_str_bytes"
+version = "6.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.58"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa1fb82fc0c281dd9671101b66b771ebbe1eaf967b96ac8740dcba4b70005ca8"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "rawpointer"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3"
+
+[[package]]
+name = "redox_syscall"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
+name = "regex"
+version = "1.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c"
+
+[[package]]
+name = "rust_decimal"
+version = "1.29.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26bd36b60561ee1fb5ec2817f198b6fd09fa571c897a5e86d1487cfc2b096dfc"
+dependencies = [
+ "arrayvec",
+ "num-traits",
+]
+
+[[package]]
+name = "rustix"
+version = "0.37.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d"
+dependencies = [
+ "bitflags",
+ "errno",
+ "io-lifetimes",
+ "libc",
+ "linux-raw-sys",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "ryu"
+version = "1.0.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
+
+[[package]]
+name = "serde"
+version = "1.0.163"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.163"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.16",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.96"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1"
+dependencies = [
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "strsim"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
+
+[[package]]
+name = "syn"
+version = "1.0.109"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a6f671d4b5ffdb8eadec19c0ae67fe2639df8684bd7bc4b83d986b8db549cf01"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "tempfile"
+version = "3.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998"
+dependencies = [
+ "cfg-if",
+ "fastrand",
+ "redox_syscall",
+ "rustix",
+ "windows-sys 0.45.0",
+]
+
+[[package]]
+name = "termcolor"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "textwrap"
+version = "0.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
+
+[[package]]
+name = "time"
+version = "0.1.45"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
+dependencies = [
+ "libc",
+ "wasi 0.10.0+wasi-snapshot-preview1",
+ "winapi",
+]
+
+[[package]]
+name = "toml"
+version = "0.5.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
+
+[[package]]
+name = "uuid"
+version = "1.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "345444e32442451b267fc254ae85a209c64be56d2890e601a0c37ff0c3c5ecd2"
+dependencies = [
+ "getrandom",
+]
+
+[[package]]
+name = "wasi"
+version = "0.10.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
+
+[[package]]
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.86"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5bba0e8cb82ba49ff4e229459ff22a191bbe9a1cb3a341610c9c33efc27ddf73"
+dependencies = [
+ "cfg-if",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.86"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19b04bc93f9d6bdee709f6bd2118f57dd6679cf1176a1af464fca3ab0d66d8fb"
+dependencies = [
+ "bumpalo",
+ "log",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.16",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.86"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "14d6b024f1a526bb0234f52840389927257beb670610081360e5a03c5df9c258"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.86"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.16",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.86"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93"
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-util"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "windows"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
+dependencies = [
+ "windows-targets 0.48.0",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.45.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
+dependencies = [
+ "windows-targets 0.42.2",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
+dependencies = [
+ "windows-targets 0.48.0",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
+dependencies = [
+ "windows_aarch64_gnullvm 0.42.2",
+ "windows_aarch64_msvc 0.42.2",
+ "windows_i686_gnu 0.42.2",
+ "windows_i686_msvc 0.42.2",
+ "windows_x86_64_gnu 0.42.2",
+ "windows_x86_64_gnullvm 0.42.2",
+ "windows_x86_64_msvc 0.42.2",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5"
+dependencies = [
+ "windows_aarch64_gnullvm 0.48.0",
+ "windows_aarch64_msvc 0.48.0",
+ "windows_i686_gnu 0.48.0",
+ "windows_i686_msvc 0.48.0",
+ "windows_x86_64_gnu 0.48.0",
+ "windows_x86_64_gnullvm 0.48.0",
+ "windows_x86_64_msvc 0.48.0",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.42.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
diff --git a/Source/rust/Cargo.toml b/Source/rust/Cargo.toml
new file mode 100644
index 0000000..56a56c4
--- /dev/null
+++ b/Source/rust/Cargo.toml
@@ -0,0 +1,29 @@
+[package]
+name = "composesiren-dsp-rs-lib"
+version = "0.1.0"
+edition = "2021"
+
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+
+[lib]
+crate-type = ["staticlib"]
+
+
+[[bin]]
+name = "composesiren-dsp-rs-main"
+path = "src/main.rs"
+#
+[dependencies]
+fable_library_rust = { path = "../fsharp/fable_modules/fable-library-rust" }
+mecaviv-siren-declarations-rs = { path = "../generated/rust/mecaviv-siren-declarations-rs"}
+bytemuck = { version = "*", features = ["extern_crate_alloc"]}
+lazy_static = "*"
+ndarray = "*"
+byteorder = "*"
+
+
+[build-dependencies]
+cmake = "*"
+cbindgen = "*"
\ No newline at end of file
diff --git a/Source/rust/build.rs b/Source/rust/build.rs
new file mode 100644
index 0000000..8c62085
--- /dev/null
+++ b/Source/rust/build.rs
@@ -0,0 +1,32 @@
+#![allow(non_snake_case)]
+#![allow(non_camel_case_types)]
+#![allow(unused_imports)]
+#![allow(non_upper_case_globals)]
+#![allow(unused_variables)]
+extern crate cbindgen;
+
+use std::env;
+use std::fs::File;
+use std::path::Path;
+
+fn main() {
+ let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
+ run_cbindgen(&crate_dir);
+}
+
+fn run_cbindgen(crate_dir: &String) {
+ let result =
+ cbindgen::Builder::new()
+ .with_crate(crate_dir)
+ .generate();
+ match result {
+ Ok(bindings) => {
+ bindings.write_to_file("../generated/ffi/composesirenrs.h");
+ println!("generated C binding.");
+ }
+ Err(error) => {
+ println!("failed to do C binding generation: {}", error.to_string());
+ }
+ }
+}
+
diff --git a/Source/rust/src/lib.rs b/Source/rust/src/lib.rs
new file mode 100644
index 0000000..4788094
--- /dev/null
+++ b/Source/rust/src/lib.rs
@@ -0,0 +1,190 @@
+//use composesiren;
+//use composesiren::dsp;
+//use composesiren::declarations;
+//#![feature(type_ascription)]
+#![allow(non_snake_case)]
+#![allow(non_camel_case_types)]
+#![allow(unused_imports)]
+#![allow(non_upper_case_globals)]
+#![allow(unused_variables)]
+//pub mod midiinput;
+pub mod types;
+//pub mod ndarraytests;
+//pub mod siren_send;
+//pub const midiNoteMin: i32 = 0;
+//pub const midiNoteMax: crate::types::midi_note = 127;
+
+use std::collections::HashMap;
+use std::ffi::OsStr;
+use std::io::{BufReader, Read};
+use std::iter::Map;
+use std::os::raw::c_char;
+use std::path::Path;
+use std::rc::Rc;
+use byteorder::{NativeEndian, ReadBytesExt};
+use crate::types::{AmplitudeTable, FrequencyTable, LengthTable, LengthTableEntry, MAX_Partiel, MAX_TAB, NOMBRE_DE_NOTE, SirenDataFileSuffix, SirenDataSet, SirenModel, SirenModelFileSet, VectorTable};
+
+#[no_mangle]
+pub extern "C" fn sirenmodel_get_file_set(sirenModel: &SirenModel) -> SirenModelFileSet {
+ use crate::types::SirenModel::{*};
+
+ use SirenDataFileSuffix::*;
+ let (amp, length, vector, freq) = match sirenModel {
+ Alto1 => (S1, S1, S1, S1),
+ Alto2 => (S1, S1, S2, S1),
+ Bass => (S3, S3, S3, S3),
+ Tenor => (S4, S4, S4, S4),
+ Soprano => (S5, S5, S5, S5),
+ Piccolo => (S7, S7, S5, S7),
+ };
+ SirenModelFileSet { amp,
+ freq,
+ length,
+ vector }
+}
+
+#[derive(PartialEq,Eq,Hash)]
+enum FileType {
+ Amp,
+ Freq,
+ Length,
+ Vector,
+}
+/*
+enum FileData {
+ Amp(Box),
+ Freq(Box),
+ Length(Box),
+ Vector(Box),
+}*/
+
+fn get_filename_and_buffer_size(f: &FileType, suffix: &SirenDataFileSuffix, folder: &str) -> (String, usize) {
+ let s = AmplitudeTable::size_of();
+ let (filePath, bufferSize) = match f {
+ FileType::Amp => ("dataAmp", AmplitudeTable::size_of()),
+ FileType::Freq => ("dataFreq", FrequencyTable::size_of()),
+ FileType::Length => ("datadureTabs", LengthTable::dim_1() * std::mem::size_of::() * 3),
+ FileType::Vector => ("dataVectorInterval", VectorTable::dim_1() * std::mem::size_of::()),
+ };
+ assert_eq!(0, bufferSize % 4);
+ let filePath =
+ format!("{}{}{}",
+ folder,filePath, suffix);
+
+ (filePath, bufferSize)
+}
+
+type FileMap = HashMap,Box>>;
+
+
+use lazy_static::lazy_static;
+use ndarray::{Array1, Array3};
+
+lazy_static! {
+ static ref PRIVILEGES: HashMap<&'static str, Vec<&'static u8>> = {
+ let mut map = HashMap::new();
+ map
+ };
+}
+
+
+pub extern "C" fn read_siren_dataset(sirenModel: &SirenModel, folder: &str, mut fileMap: &FileMap) -> SirenDataSet //-> SirenDataSet
+{
+ let fileSet = sirenmodel_get_file_set(sirenModel);
+
+ let readFileAsFloatsVector = |f: &FileType, suffix: &SirenDataFileSuffix| {
+ let (file_path, buffer_size) = get_filename_and_buffer_size(f, suffix, folder);
+ let buffer_size = buffer_size / std::mem::size_of::();
+ let file_size = std::fs::metadata(&file_path).expect("could not get file meta data").len() as usize;
+ let datafile = std::fs::File::open(&file_path).expect(&format!("not able to read {}", file_path));
+ let mut datafile = BufReader::new(datafile);
+ let mut floats_buffer = {
+ let mut floats = Vec::::with_capacity(buffer_size);
+ unsafe { floats.set_len(file_size / std::mem::size_of::()); }
+
+ datafile.read_f32_into::(&mut floats[..]).unwrap();
+ floats
+ };
+ if buffer_size != floats_buffer.len() {
+ eprintln!("expected buffersize:{} got:{} {}", buffer_size, floats_buffer.len(), file_path.as_str());
+ floats_buffer.resize(buffer_size, 0.);
+ }
+
+ floats_buffer
+ };
+
+ let amp = readFileAsFloatsVector(&FileType::Amp, &fileSet.amp);
+ let freq = readFileAsFloatsVector(&FileType::Freq, &fileSet.freq);
+ let length = readFileAsFloatsVector(&FileType::Length, &fileSet.length);
+ let vector = readFileAsFloatsVector(&FileType::Vector, &fileSet.vector);
+
+ let amp = AmplitudeTable { data: Array3::from_shape_vec((AmplitudeTable::dim_1(), AmplitudeTable::dim_2(), AmplitudeTable::dim_3()), amp).unwrap() };
+ let freq = FrequencyTable { data: Array3::from_shape_vec((FrequencyTable::dim_1(), FrequencyTable::dim_2(), FrequencyTable::dim_3()), freq).unwrap() };
+ let length = {
+ let mut v = Vec::::with_capacity(LengthTable::dim_1());
+ for n in 0 .. LengthTable::dim_1() {
+ let (sample_count, max_tab_count, average_frequency) =
+ (length[n * 3]
+ , length[n * 3 + 1]
+ , length[n * 3 + 2])
+ ;
+ let entry = LengthTableEntry {
+ sample_count: sample_count.round() as u32
+ , max_tab_count : max_tab_count.round() as u16
+ , average_frequency
+ };
+ v.push(entry);
+ }
+ if v.len() < LengthTable::dim_1() {
+ eprintln!("expected length table of length {} but got {}", LengthTable::dim_1(), v.len());
+ }
+ LengthTable { data: Array1::from_shape_vec(LengthTable::dim_1(), v).unwrap() }
+
+ };
+ let vector = VectorTable { data: Array1::from_shape_vec(VectorTable::dim_1(), vector).unwrap() };
+ SirenDataSet{ amp, freq, length, vector }
+
+}
+#[cfg(test)]
+pub mod tests {
+ use std::collections::HashMap;
+ use crate::{sirenmodel_get_file_set, read_siren_dataset};
+
+ use crate::types::SirenModel::{*};
+ const folder : &str = "/Users/gauthiersegay/dev/src/mecaviv/benoit/CodesSources/ComposeSirenes2/ComposeSirenes/";
+ #[test]
+ pub fn a() {}
+
+ #[test]
+ pub fn it_worksreadfiles() {
+ let map = HashMap::new();
+ let s1 = read_siren_dataset(&crate::types::SirenModel::Alto2, folder, &map);
+ for i in 0 .. s1.vector.data.len() {
+ let v = s1.vector.data[i];
+ println!("{}", v);
+ }
+ }
+
+ #[test]
+ pub fn it_works() {
+ let s1 = sirenmodel_get_file_set(&Alto1);
+ let s2 = sirenmodel_get_file_set(&Alto2);
+ let s3 = sirenmodel_get_file_set(&Bass);
+ let s4 = sirenmodel_get_file_set(&Tenor);
+ let s5 = sirenmodel_get_file_set(&Soprano);
+ let s6 = sirenmodel_get_file_set(&Soprano);
+ let s7 = sirenmodel_get_file_set(&Piccolo);
+
+ println!("s1={}", s1);
+ println!("s2={}", s2);
+ println!("s3={}", s3);
+ println!("s4={}", s4);
+ println!("s5={}", s5);
+ println!("s6={}", s6);
+ println!("s7={}", s7);
+ assert_eq!(2 + 2, 4);
+ }
+}
+
+
+
diff --git a/Source/rust/src/main.rs b/Source/rust/src/main.rs
new file mode 100644
index 0000000..7baeb4d
--- /dev/null
+++ b/Source/rust/src/main.rs
@@ -0,0 +1,22 @@
+extern crate mecaviv_siren_declarations_rs;
+
+//use src;
+///++.use crate::meaviv_siren_declarations_rs::composesiren::dsp;
+//use crate::composesiren::dsp;
+
+use std::collections::HashMap;
+//use composesiren::dsp::SirenModel;
+//use mecaviv_siren_declarations_rs::{*};
+//use mecaviv_siren_declarations_rs::composesiren::dsp::processor::{*};
+fn main() {
+
+ let sirens = Default::default();
+ let state = mecaviv_siren_declarations_rs::composesiren::DspState::ProcessorState{ sirens: sirens };
+
+ println!("Hello, world!");
+ //let map = HashMap::new();
+ let folder = "/Users/gauthiersegay/m1/macbookairm1/Library/Developer/Xcode/DerivedData/ComposeSirenes-docslgnkxmlfdudsoqsmkhkympli/Build/Products/Debug/ComposeSirenes.app/Contents/Resources/";
+//composesiren_dsp_rs::types::SirenModel
+ //read_siren_dataset(&SirenModel::Alto1, folder, &map);
+ //libcomposesirendataset::pppp(SirenModel::Alto1, &map);
+}
\ No newline at end of file
diff --git a/Source/rust/src/tests.rs b/Source/rust/src/tests.rs
new file mode 100644
index 0000000..db3917b
--- /dev/null
+++ b/Source/rust/src/tests.rs
@@ -0,0 +1,41 @@
+
+#[cfg(test)]
+pub mod tests {
+ use std::collections::HashMap;
+ use crate::{sirenmodel_get_file_set, read_siren_dataset};
+
+ use crate::types::SirenModel::{*};
+ const folder : &str = "/Users/gauthiersegay/dev/src/mecaviv/benoit/CodesSources/ComposeSirenes2/ComposeSirenes/";
+ #[test]
+ pub fn a() {}
+
+ #[test]
+ pub fn it_worksreadfiles() {
+ let map = HashMap::new();
+ let s1 = read_siren_dataset(&crate::types::SirenModel::Alto2, folder, &map);
+ for i in 0 .. s1.vector.data.len() {
+ let v = s1.vector.data[i];
+ println!("{}", v);
+ }
+ }
+
+ #[test]
+ pub fn it_works() {
+ let s1 = sirenmodel_get_file_set(&Alto1);
+ let s2 = sirenmodel_get_file_set(&Alto2);
+ let s3 = sirenmodel_get_file_set(&Bass);
+ let s4 = sirenmodel_get_file_set(&Tenor);
+ let s5 = sirenmodel_get_file_set(&Soprano);
+ let s6 = sirenmodel_get_file_set(&Soprano);
+ let s7 = sirenmodel_get_file_set(&Piccolo);
+
+ println!("s1={}", s1);
+ println!("s2={}", s2);
+ println!("s3={}", s3);
+ println!("s4={}", s4);
+ println!("s5={}", s5);
+ println!("s6={}", s6);
+ println!("s7={}", s7);
+ assert_eq!(2 + 2, 4);
+ }
+}
diff --git a/Source/rust/src/types.rs b/Source/rust/src/types.rs
new file mode 100644
index 0000000..bb39fb7
--- /dev/null
+++ b/Source/rust/src/types.rs
@@ -0,0 +1,122 @@
+
+#[repr(C)]
+pub enum SirenModel {
+ Alto1,
+ Alto2,
+ Bass,
+ Tenor,
+ Soprano,
+ Piccolo,
+}
+
+#[derive(PartialEq,Eq,Hash)]
+#[repr(C)]
+pub enum SirenDataFileSuffix {
+ S1,
+ S2,
+ S3,
+ S4,
+ S5,
+ //S6,
+ S7,
+}
+
+pub const NOMBRE_DE_NOTE: usize = 80;
+pub const MAX_Partiel: usize = 200;
+pub const MAX_TAB: usize = 1000;
+
+#[repr(C)]
+pub struct Array3D
+{
+ pub data: ndarray::Array3
+
+}
+
+impl Array3D {
+ pub fn dim_1 () -> usize { Dim1 }
+ pub fn dim_2 () -> usize { Dim2 }
+ pub fn dim_3 () -> usize { Dim3 }
+ pub fn size_of() -> usize {
+ std::mem::size_of::() * Dim1 * Dim2 * Dim3
+ }
+}
+
+#[repr(C)]
+pub struct Array1D
+{
+ pub data: ndarray::Array1
+}
+
+impl Array1D{
+ pub fn dim_1 () -> usize { Dim1 }
+ /*fn size_of() -> usize {
+ std::mem::size_of::() * Dim1
+ }*/
+}
+
+#[repr(C)]
+pub struct LengthTableEntry {
+ pub sample_count: u32
+ , pub max_tab_count: u16
+ , pub average_frequency: f32
+}
+
+
+pub type AmplitudeTable = Array3D;
+
+pub type FrequencyTable = Array3D;
+
+pub type LengthTable = Array1D;
+
+pub type VectorTable = Array1D;
+
+//typedef float AmpTable[NOMBRE_DE_NOTE][MAX_TAB][MAX_Partiel];
+//typedef float FreqTable[NOMBRE_DE_NOTE][MAX_TAB][MAX_Partiel];
+//typedef float DurationTable[NOMBRE_DE_NOTE][3];
+//typedef float VectorTable [392];
+
+type i7 = i8;
+pub type midi_note = i7;
+
+#[repr(C)]
+pub struct SirenDataSet {
+ pub amp: AmplitudeTable,
+ pub freq: FrequencyTable,
+ pub length: LengthTable,
+ pub vector: VectorTable,
+}
+
+#[repr(C)]
+pub struct SirenSpec {
+ lowest_note: midi_note,
+ highest_note: midi_note,
+}
+#[repr(C)]
+pub struct SirenModelFileSet {
+ pub(crate) amp: SirenDataFileSuffix,
+ pub(crate) freq: SirenDataFileSuffix,
+ pub(crate) length: SirenDataFileSuffix,
+ pub(crate) vector: SirenDataFileSuffix,
+}
+
+impl std::fmt::Display for SirenDataFileSuffix {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ use SirenDataFileSuffix::*;
+ let result = match self {
+ S1 => "S1",
+ S2 => "S2",
+ S3 => "S3",
+ S4 => "S4",
+ S5 => "S5",
+ S7 => "S7",
+ };
+ write!(f, "{}", result)
+ }
+}
+impl std::fmt::Display for SirenModelFileSet {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(f,
+ "SirenDataSet(freq:{},amp:{},length:{},vector:{})",
+ self.freq, self.amp, self.length, self.vector)
+ }
+}
\ No newline at end of file
diff --git a/build.dotnet.sh b/build.dotnet.sh
new file mode 100755
index 0000000..5ca9ff9
--- /dev/null
+++ b/build.dotnet.sh
@@ -0,0 +1,10 @@
+dotnet tool restore
+dotnet build
+dotnet fable Source/fsharp/ComposeSiren.fsproj -o Source/generated/rust/mecaviv-siren-declarations-rs/src --lang rust
+
+#dotnet fable Source/fsharp/ComposeSiren.fsproj -o Source/generated/python --lang python
+# dotnet fable Source/fsharp/ComposeSiren.fsproj -o Source/generated/php --lang php
+#dotnet fable Source/fsharp/ComposeSiren.fsproj -o Source/generated/typescript --lang ts
+# dotnet fable Source/fsharp/ComposeSiren.fsproj -o Source/generated/dart --lang dart
+
+
diff --git a/build.rust.sh b/build.rust.sh
new file mode 100755
index 0000000..0876ac5
--- /dev/null
+++ b/build.rust.sh
@@ -0,0 +1,5 @@
+bash build.dotnet.sh
+cd ./Source/rust
+cargo build
+cd ../generated/rust/samples
+cargo run --example sample
\ No newline at end of file
diff --git a/dotnet.sln b/dotnet.sln
new file mode 100644
index 0000000..abe6725
--- /dev/null
+++ b/dotnet.sln
@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "ComposeSiren", "Source\fsharp\ComposeSiren.fsproj", "{C6CF8E55-F53B-4EF1-A6A4-56D155B88C42}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "samples", "Source\fsharp\samples\samples.fsproj", "{1678588D-72F5-462C-93EF-ACA4ABD18A6A}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {C6CF8E55-F53B-4EF1-A6A4-56D155B88C42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C6CF8E55-F53B-4EF1-A6A4-56D155B88C42}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C6CF8E55-F53B-4EF1-A6A4-56D155B88C42}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C6CF8E55-F53B-4EF1-A6A4-56D155B88C42}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1678588D-72F5-462C-93EF-ACA4ABD18A6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1678588D-72F5-462C-93EF-ACA4ABD18A6A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1678588D-72F5-462C-93EF-ACA4ABD18A6A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1678588D-72F5-462C-93EF-ACA4ABD18A6A}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+EndGlobal
diff --git a/funbuild.fsx b/funbuild.fsx
new file mode 100644
index 0000000..9418d46
--- /dev/null
+++ b/funbuild.fsx
@@ -0,0 +1,43 @@
+#r "nuget: Fun.Result"
+#r "nuget: Fun.Build, 0.3.8"
+
+open Fun.Result
+open Fun.Build
+
+pipeline "Fun.Build" {
+ description "building f# & rust code"
+ stage "F#" {
+ run "dotnet tool restore"
+ run "dotnet restore"
+ run "dotnet fable Source/fsharp/ComposeSiren.fsproj -o Source/generated/rust/mecaviv-siren-declarations-rs/src --lang rust"
+ }
+ stage "rust" {
+ workingDir "./Source/rust"
+ run "cargo build"
+ }
+ runIfOnlySpecified false
+}
+
+pipeline "watch" {
+ description "developer mode watch"
+
+ stage "run" {
+ run "dotnet fable Source/fsharp/ComposeSiren.fsproj -o Source/generated/rust/mecaviv-siren-declarations-rs/src --lang rust --watch bash build.dotnet.sh"
+ //workingDir "./Source/generated/Source/generated/rust/mecaviv-siren-declarations-rs/"
+ //run "cargo build"
+ }
+ runIfOnlySpecified
+
+}
+pipeline "run" {
+ description "running the rust sample program"
+
+ stage "run" {
+ workingDir "./Source/rust"
+ run "cargo run"
+
+ }
+ runIfOnlySpecified
+}
+
+tryPrintPipelineCommandHelp ()
\ No newline at end of file
diff --git a/paket.dependencies b/paket.dependencies
new file mode 100644
index 0000000..5f697b0
--- /dev/null
+++ b/paket.dependencies
@@ -0,0 +1,5 @@
+source https://api.nuget.org/v3/index.json
+
+storage: none
+
+nuget Fable.Core
\ No newline at end of file
diff --git a/watch.sh b/watch.sh
new file mode 100755
index 0000000..8233f30
--- /dev/null
+++ b/watch.sh
@@ -0,0 +1 @@
+dotnet fable watch Source/fsharp/samples/samples.fsproj --lang rust --run bash build.rust
\ No newline at end of file