Skip to content

Commit

Permalink
Improve examples
Browse files Browse the repository at this point in the history
  • Loading branch information
ErikNatanael committed Jan 1, 2024
1 parent fe3e6da commit 3b1e940
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 106 deletions.
68 changes: 0 additions & 68 deletions knyst/examples/cpal_example.rs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,14 @@ fn main() -> Result<()> {
graph_output(0, (delay + static_sample_delay(87).input(delay)) * 0.5);
graph_output(1, (delay + static_sample_delay(62).input(delay)) * 0.5);
let outer_graph = upload_graph(knyst_commands().default_graph_settings(), || {});
// Nothing is passed into the delay until now. Pass any output of the "outer_graph" into the delay.
delay.input(outer_graph);
// Make the "outer_graph" the active graph, meaning any new nodes are pushed to it.
outer_graph.activate();

let mut rng = thread_rng();
// Create a node for the frequency value so that this value can be changed once and
// propagated to many other nodes.
let freq_var = bus(1).set(0, 440.);
for _ in 0..10 {
let freq = (sine().freq(
Expand All @@ -45,7 +49,6 @@ fn main() -> Result<()> {
.range(0.0, 400.),
) * 100.0)
+ freq_var;
// let freq = sine().freq(0.5).range(200.0, 200.0 * 9.0 / 8.0);
let node0 = sine();
node0.freq(freq);
let modulator = sine();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
use anyhow::Result;
use knyst::{audio_backend::JackBackend, controller::print_error_handler, prelude::*};
#[allow(unused)]
use knyst::{
audio_backend::{CpalBackend, CpalBackendOptions, JackBackend},
controller::print_error_handler,
prelude::*,
};

fn main() -> Result<()> {
let mut backend = JackBackend::new("Knyst<3JACK")?;
let mut backend = CpalBackend::new(CpalBackendOptions::default())?;
// Uncomment the line below and comment the line above to use the JACK backend instead
// let mut backend = JackBackend::new("Knyst<3JACK")?;

let sample_rate = backend.sample_rate() as Sample;
let block_size = backend.block_size().unwrap_or(64);
println!("sr: {sample_rate}, block: {block_size}");

// Start with an automatic helper thread for scheduling changes and managing resources.
// If you want to manage the `Controller` yourself, use `start_return_controller`.
let _sphere = KnystSphere::start(
&mut backend,
SphereSettings {
Expand All @@ -22,11 +31,14 @@ fn main() -> Result<()> {
// We can also use a shared wavetable oscillator which reads its wavetable from `Resources`. A cosine wavetable
// is created by default.
let modulator = oscillator(WavetableId::cos()).freq(5.);

// Output to the zeroth (left) channel
graph_output(0, node0 * (modulator * 0.25 + 0.5));
let node1 = wavetable_oscillator_owned(Wavetable::sine()).freq(220.);
let modulator = oscillator(WavetableId::cos()).freq(3.);
// Output a different sound to the first (right) channel
graph_output(1, node1 * (modulator * 0.25 + 0.5));

// Respond to user input. This kind of interaction can be put in a different thread and/or in an async runtime.
let mut input = String::new();
loop {
match std::io::stdin().read_line(&mut input) {
Expand Down
55 changes: 21 additions & 34 deletions knyst/examples/sound_file_playback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,23 @@ use std::time::Duration;

use knyst::{
audio_backend::{CpalBackend, CpalBackendOptions},
controller,
controller::print_error_handler,
knyst_commands,
prelude::*,
};

fn main() -> anyhow::Result<()> {
// Create the backend to get the backend settings needed to create a Graph with the correct block size and sample rate etc.
let mut backend = CpalBackend::new(CpalBackendOptions::default())?;

let sample_rate = backend.sample_rate() as Sample;
let block_size = backend.block_size().unwrap_or(64);
let mut resources = Resources::new(ResourcesSettings {
..Default::default()
});
// let mut backend = JackBackend::new("Knyst<3JACK")?;
let _sphere = KnystSphere::start(
&mut backend,
SphereSettings {
num_inputs: 0,
num_outputs: 2,
..Default::default()
},
print_error_handler,
);

// Get file path to a sound file from the user
let file_path = dialog::FileSelection::new("Please select an audio file")
Expand All @@ -24,36 +28,19 @@ fn main() -> anyhow::Result<()> {
.expect("Could not display dialog box")
.unwrap();
// Insert the buffer before sending Resources to the audio thread
let buffer = resources.insert_buffer(Buffer::from_sound_file(file_path)?)?;

let graph_settings = GraphSettings {
block_size,
sample_rate,
num_outputs: backend.num_outputs(),
..Default::default()
};
println!("{graph_settings:#?}");
// Create the Graph with the settings above
let g: Graph = Graph::new(graph_settings);
// The backend will split the Graph into two
let mut k = backend.start_processing(
g,
resources,
RunGraphSettings::default(),
Box::new(controller::print_error_handler),
)?;
let sound_buffer = Buffer::from_sound_file(file_path)?;
let channels = sound_buffer.num_channels();
let buffer = knyst_commands().insert_buffer(sound_buffer);

// Create a node which reads the buffer we inserted earlier and plays it back
// `channels(2)` means we are expecting a stereo buffer
// `looping(false)` means the buffer will not be looped
let buf_playback_node = k.push(
BufferReaderMulti::new(buffer, 1.0, StopAction::FreeSelf)
.channels(2)
.looping(true),
inputs!(),
);
// Connect the buffer to the outputs.
k.connect(buf_playback_node.to_graph_out().channels(2));
let buf_playback_node = BufferReaderMulti::new(buffer, 1.0, StopAction::FreeSelf)
.channels(channels)
.looping(true)
.upload();
// Connect the buffer to the outputs, connecting 2 channels (a mono buffer will be played in both the left and right channels)
graph_output(0, buf_playback_node.channels(2));

println!("Playing back sound for 10 seconds");
std::thread::sleep(Duration::from_millis(10000));
Expand Down
9 changes: 9 additions & 0 deletions knyst/src/gen/osc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,15 @@ impl BufferReaderMulti {
self.read_pointer = new_pointer_pos;
self.finished = false;
}
/// Upload to the current graph, returning a handle to the new node
pub fn upload(self) -> knyst::handles::Handle<BufferReaderMultiHandle> {
let num_channels = self.num_channels;
let id = knyst::prelude::KnystCommands::push_without_inputs(&mut knyst_commands(), self);
knyst::handles::Handle::new(BufferReaderMultiHandle {
node_id: id,
num_channels,
})
}
}

impl Gen for BufferReaderMulti {
Expand Down

0 comments on commit 3b1e940

Please sign in to comment.