Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use SynthFormat in realtime & small fixes #96

Merged
merged 3 commits into from
Aug 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ what is supported, please visit the `SampleSoundfont` documentation in `core`.

## License

XSynth is licensed under the MIT license.
XSynth is licensed under the GNU Lesser General Public License 3.0.
4 changes: 3 additions & 1 deletion core/src/channel_group/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{channel::ChannelInitOptions, AudioStreamParams};
pub enum SynthFormat {
/// Standard MIDI format with 16 channels. Channel 10 will be used for percussion.
#[default]
MidiSingle,
Midi,

/// Creates a custom number of channels with the default settings.
Custom { channels: u32 },
Expand Down Expand Up @@ -83,6 +83,8 @@ pub struct ChannelGroupConfig {

/// Defines the format that the synthesizer will use. See the `SynthFormat`
/// documentation for more information.
///
/// Default: `SynthFormat::Midi`
pub format: SynthFormat,

/// Parameters of the output audio.
Expand Down
4 changes: 2 additions & 2 deletions core/src/channel_group/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ impl ChannelGroup {
};

let channel_count = match config.format {
SynthFormat::MidiSingle => 16,
SynthFormat::Midi => 16,
SynthFormat::Custom { channels } => channels,
};

Expand All @@ -74,7 +74,7 @@ impl ChannelGroup {
sample_cache_vecs.push(Vec::new());
}

if config.format == SynthFormat::MidiSingle {
if config.format == SynthFormat::Midi {
channels[9].push_events_iter(std::iter::once(ChannelEvent::Config(
ChannelConfigEvent::SetPercussionMode(true),
)));
Expand Down
4 changes: 2 additions & 2 deletions core/src/soundfont/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub struct EnvelopeOptions {
/// Controls the type of curve of the attack envelope stage. See the
/// documentation of the `EnvelopeCurveType` enum for available options.
///
/// Default: `Convex`
/// Default: `Exponential`
pub attack_curve: EnvelopeCurveType,

/// Controls the type of curve of the decay envelope stage. See the
Expand Down Expand Up @@ -76,7 +76,7 @@ pub struct SoundfontInitOptions {
/// Default: `None`
pub preset: Option<u8>,

/// Configures the volume envelope curves in the dB scale. See the
/// Configures the volume envelope curves in dB units. See the
/// documentation for `EnvelopeOptions` for more information.
pub vol_envelope_options: EnvelopeOptions,

Expand Down
16 changes: 9 additions & 7 deletions realtime/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use std::ops::RangeInclusive;
pub use xsynth_core::{channel::ChannelInitOptions, channel_group::ThreadCount};
pub use xsynth_core::{
channel::ChannelInitOptions,
channel_group::{SynthFormat, ThreadCount},
};

/// Options for initializing a new RealtimeSynth.
#[derive(Clone, Debug, PartialEq)]
Expand All @@ -14,12 +17,11 @@ pub struct XSynthRealtimeConfig {
/// Default: `10.0`
pub render_window_ms: f64,

/// Amount of VoiceChannel objects to be created (Number of MIDI channels).
/// The MIDI 1 spec uses 16 channels. If the channel count is 16 or
/// greater, then MIDI channel 10 will be set as the percussion channel.
/// Defines the format that the synthesizer will use. See the `SynthFormat`
/// documentation for more information.
///
/// Default: `16`
pub channel_count: u32,
/// Default: `SynthFormat::Midi`
pub format: SynthFormat,

/// Controls the multithreading used for rendering per-voice audio for all
/// the voices stored in a key for a channel. See the `ThreadCount` documentation
Expand All @@ -39,7 +41,7 @@ impl Default for XSynthRealtimeConfig {
Self {
channel_init_options: Default::default(),
render_window_ms: 10.0,
channel_count: 16,
format: Default::default(),
multithreading: ThreadCount::None,
ignore_range: 0..=0,
}
Expand Down
15 changes: 10 additions & 5 deletions realtime/src/realtime_synth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use crossbeam_channel::{bounded, unbounded};
use xsynth_core::{
buffered_renderer::{BufferedRenderer, BufferedRendererStatsReader},
channel::{ChannelConfigEvent, ChannelEvent, VoiceChannel},
channel_group::SynthFormat,
effects::VolumeLimiter,
helpers::{prepapre_cache_vec, sum_simd},
AudioPipe, AudioStreamParams, FunctionAudioPipe,
Expand Down Expand Up @@ -148,11 +149,16 @@ impl RealtimeSynth {
)),
};

let (output_sender, output_receiver) = bounded::<Vec<f32>>(config.channel_count as usize);
let channel_count = match config.format {
SynthFormat::Midi => 16,
SynthFormat::Custom { channels } => channels,
};

let (output_sender, output_receiver) = bounded::<Vec<f32>>(channel_count as usize);

let mut thread_handles = vec![];

for _ in 0u32..(config.channel_count) {
for _ in 0u32..channel_count {
let mut channel =
VoiceChannel::new(config.channel_init_options, stream_params, pool.clone());
let stats = channel.get_channel_stats();
Expand Down Expand Up @@ -183,7 +189,7 @@ impl RealtimeSynth {
thread_handles.push(join_handle);
}

if config.channel_count >= 16 {
if config.format == SynthFormat::Midi {
senders[9]
.send(ChannelEvent::Config(ChannelConfigEvent::SetPercussionMode(
true,
Expand All @@ -192,15 +198,14 @@ impl RealtimeSynth {
}

let mut vec_cache: VecDeque<Vec<f32>> = VecDeque::new();
for _ in 0..(config.channel_count) {
for _ in 0..channel_count {
vec_cache.push_front(Vec::new());
}

let stats = RealtimeSynthStats::new();

let total_voice_count = stats.voice_count.clone();

let channel_count = config.channel_count;
let render = FunctionAudioPipe::new(stream_params, move |out| {
for sender in command_senders.iter() {
let mut buf = vec_cache.pop_front().unwrap();
Expand Down
2 changes: 1 addition & 1 deletion render/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ impl State {
.copied()
.unwrap_or(true),
},
format: SynthFormat::MidiSingle,
format: SynthFormat::Midi,
audio_params: AudioStreamParams::new(
matches.get_one("sample rate").copied().unwrap_or(48000),
matches
Expand Down
Loading