Voice Rework -- Events, Track Queues (#806)

This implements a proof-of-concept for an improved audio frontend. The largest change is the introduction of events and event handling: both by time elapsed and by track events, such as ending or looping. Following on from this, the library now includes a basic, event-driven track queue system (which people seem to ask for unusually often). A new sample, `examples/13_voice_events`, demonstrates both the `TrackQueue` system and some basic events via the `~queue` and `~play_fade` commands.

Locks are removed from around the control of `Audio` objects, which should allow the backend to be moved to a more granular futures-based backend solution in a cleaner way.
This commit is contained in:
Kyle Simpson
2020-10-29 20:25:20 +00:00
committed by Alex M. M
commit 7e4392ae68
76 changed files with 8756 additions and 0 deletions

10
utils/Cargo.toml Normal file
View File

@@ -0,0 +1,10 @@
[package]
name = "utils"
version = "0.1.0"
authors = ["Kyle Simpson <kyleandrew.simpson@gmail.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
byteorder = "1"

1
utils/README.md Normal file
View File

@@ -0,0 +1 @@
Test utilities for testing and benchmarking songbird.

67
utils/src/lib.rs Normal file
View File

@@ -0,0 +1,67 @@
use byteorder::{LittleEndian, WriteBytesExt};
use std::mem;
pub fn make_sine(float_len: usize, stereo: bool) -> Vec<u8> {
let sample_len = mem::size_of::<f32>();
let byte_len = float_len * sample_len;
// set period to 100 samples == 480Hz sine.
let mut out = vec![0u8; byte_len];
let mut byte_slice = &mut out[..];
for i in 0..float_len {
let x_val = (i as f32) * 50.0 / std::f32::consts::PI;
byte_slice.write_f32::<LittleEndian>(x_val.sin()).unwrap();
}
if stereo {
let mut new_out = vec![0u8; byte_len * 2];
for (mono_chunk, stereo_chunk) in out[..]
.chunks(sample_len)
.zip(new_out[..].chunks_mut(2 * sample_len))
{
stereo_chunk[..sample_len].copy_from_slice(mono_chunk);
stereo_chunk[sample_len..].copy_from_slice(mono_chunk);
}
new_out
} else {
out
}
}
pub fn make_pcm_sine(i16_len: usize, stereo: bool) -> Vec<u8> {
let sample_len = mem::size_of::<i16>();
let byte_len = i16_len * sample_len;
// set period to 100 samples == 480Hz sine.
// amplitude = 10_000
let mut out = vec![0u8; byte_len];
let mut byte_slice = &mut out[..];
for i in 0..i16_len {
let x_val = (i as f32) * 50.0 / std::f32::consts::PI;
byte_slice
.write_i16::<LittleEndian>((x_val.sin() * 10_000.0) as i16)
.unwrap();
}
if stereo {
let mut new_out = vec![0u8; byte_len * 2];
for (mono_chunk, stereo_chunk) in out[..]
.chunks(sample_len)
.zip(new_out[..].chunks_mut(2 * sample_len))
{
stereo_chunk[..sample_len].copy_from_slice(mono_chunk);
stereo_chunk[sample_len..].copy_from_slice(mono_chunk);
}
new_out
} else {
out
}
}