summaryrefslogtreecommitdiff
path: root/klangfarbrs
diff options
context:
space:
mode:
Diffstat (limited to 'klangfarbrs')
-rw-r--r--klangfarbrs/Cargo.toml3
-rw-r--r--klangfarbrs/src/lib.rs156
-rw-r--r--klangfarbrs/src/main.rs5
3 files changed, 87 insertions, 77 deletions
diff --git a/klangfarbrs/Cargo.toml b/klangfarbrs/Cargo.toml
index 14d2e64..10988cf 100644
--- a/klangfarbrs/Cargo.toml
+++ b/klangfarbrs/Cargo.toml
@@ -6,7 +6,8 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
-crate-type = ["cdylib"]
+crate-type = ["cdylib", "lib"]
+name = "klangfarbrs"
[dependencies]
gdnative = "0.9"
diff --git a/klangfarbrs/src/lib.rs b/klangfarbrs/src/lib.rs
index 2dbc299..0da53b2 100644
--- a/klangfarbrs/src/lib.rs
+++ b/klangfarbrs/src/lib.rs
@@ -1,10 +1,5 @@
use gdnative::api::Resource;
use gdnative::prelude::*;
-use cpal;
-use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
-use dasp::{Sample};
-use dasp_signal::{self as signal, Signal};
-use std::sync::mpsc;
/// The HelloWorld "class"
#[derive(NativeClass)]
@@ -49,86 +44,95 @@ impl Synth {
#[export]
fn _ready(&self, _owner: &Node) {
godot_print!("POOOP");
- play();
+ test::test();
}
}
-fn play() -> Result<(), anyhow::Error> {
- let host = cpal::default_host();
- let device = host
- .default_output_device()
- .expect("failed to find a default output device");
- let config = device.default_output_config()?;
-
- match config.sample_format() {
- cpal::SampleFormat::F32 => run::<f32>(&device, &config.into())?,
- cpal::SampleFormat::I16 => run::<i16>(&device, &config.into())?,
- cpal::SampleFormat::U16 => run::<u16>(&device, &config.into())?,
- }
+pub mod test {
+ use cpal;
+ use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
+ use dasp::{Sample};
+ use dasp_signal::{self as signal, Signal};
+ use std::sync::mpsc;
+
+ pub fn test() -> Result<(), anyhow::Error> {
+ let host = cpal::default_host();
+ let device = host
+ .default_output_device()
+ .expect("failed to find a default output device");
+ let config = device.default_output_config()?;
+
+ match config.sample_format() {
+ cpal::SampleFormat::F32 => run::<f32>(&device, &config.into())?,
+ cpal::SampleFormat::I16 => run::<i16>(&device, &config.into())?,
+ cpal::SampleFormat::U16 => run::<u16>(&device, &config.into())?,
+ }
- Ok(())
-}
+ Ok(())
+ }
-fn run<T>(device: &cpal::Device, config: &cpal::StreamConfig) -> Result<(), anyhow::Error>
-where
- T: cpal::Sample,
-{
- // Create a signal chain to play back 1 second of each oscillator at A4.
- let hz = signal::rate(config.sample_rate.0 as f64).const_hz(440.0);
- let one_sec = config.sample_rate.0 as usize;
- let mut synth = hz
- .clone()
- .sine()
- .take(one_sec)
- .chain(hz.clone().saw().take(one_sec))
- .chain(hz.clone().square().take(one_sec))
- .chain(hz.clone().noise_simplex().take(one_sec))
- .chain(signal::noise(0).take(one_sec))
- .map(|s| s.to_sample::<f32>() * 0.2);
-
- // A channel for indicating when playback has completed.
- let (complete_tx, complete_rx) = mpsc::sync_channel(1);
-
- // Create and run the stream.
- let err_fn = |err| eprintln!("an error occurred on stream: {}", err);
- let channels = config.channels as usize;
- let stream = device.build_output_stream(
- config,
- move |data: &mut [T], _: &cpal::OutputCallbackInfo| {
- write_data(data, channels, &complete_tx, &mut synth)
- },
- err_fn,
- )?;
- stream.play()?;
-
- // Wait for playback to complete.
- complete_rx.recv().unwrap();
- stream.pause()?;
-
- Ok(())
-}
+ fn run<T>(device: &cpal::Device, config: &cpal::StreamConfig) -> Result<(), anyhow::Error>
+ where
+ T: cpal::Sample,
+ {
+ // Create a signal chain to play back 1 second of each oscillator at A4.
+ let hz = signal::rate(config.sample_rate.0 as f64).const_hz(440.0);
+ let one_sec = config.sample_rate.0 as usize;
+ let mut synth = hz
+ .clone()
+ .sine()
+ .take(one_sec)
+ .chain(hz.clone().saw().take(one_sec))
+ .chain(hz.clone().square().take(one_sec))
+ .chain(hz.clone().noise_simplex().take(one_sec))
+ .chain(signal::noise(0).take(one_sec))
+ .map(|s| s.to_sample::<f32>() * 0.2);
+
+ // A channel for indicating when playback has completed.
+ let (complete_tx, complete_rx) = mpsc::sync_channel(1);
+
+ // Create and run the stream.
+ let err_fn = |err| eprintln!("an error occurred on stream: {}", err);
+ let channels = config.channels as usize;
+ let stream = device.build_output_stream(
+ config,
+ move |data: &mut [T], _: &cpal::OutputCallbackInfo| {
+ write_data(data, channels, &complete_tx, &mut synth)
+ },
+ err_fn,
+ )?;
+ stream.play()?;
+
+ // Wait for playback to complete.
+ complete_rx.recv().unwrap();
+ stream.pause()?;
+
+ Ok(())
+ }
-fn write_data<T>(
- output: &mut [T],
- channels: usize,
- complete_tx: &mpsc::SyncSender<()>,
- signal: &mut dyn Iterator<Item = f32>,
-) where
- T: cpal::Sample,
-{
- for frame in output.chunks_mut(channels) {
- let sample = match signal.next() {
- None => {
- complete_tx.try_send(()).ok();
- 0.0
+ fn write_data<T>(
+ output: &mut [T],
+ channels: usize,
+ complete_tx: &mpsc::SyncSender<()>,
+ signal: &mut dyn Iterator<Item = f32>,
+ ) where
+ T: cpal::Sample,
+ {
+ for frame in output.chunks_mut(channels) {
+ let sample = match signal.next() {
+ None => {
+ complete_tx.try_send(()).ok();
+ 0.0
+ }
+ Some(sample) => sample,
+ };
+ let value: T = cpal::Sample::from::<f32>(&sample);
+ for sample in frame.iter_mut() {
+ *sample = value;
}
- Some(sample) => sample,
- };
- let value: T = cpal::Sample::from::<f32>(&sample);
- for sample in frame.iter_mut() {
- *sample = value;
}
}
+
}
// Function that registers all exposed classes to Godot
diff --git a/klangfarbrs/src/main.rs b/klangfarbrs/src/main.rs
new file mode 100644
index 0000000..066cd9d
--- /dev/null
+++ b/klangfarbrs/src/main.rs
@@ -0,0 +1,5 @@
+use klangfarbrs::test::test;
+
+fn main() {
+ test();
+}