[−][src]Trait spectrusty_core::audio::Blep
A trait for interfacing Bandwidth-Limited Pulse Buffer implementations by square-wave audio generators.
The perfect square wave can be represented as an infinite sum of sinusoidal waves. The problem is that the frequency of those waves tends to infinity. The digitalization of sound is limited by the finite sample frequency and the maximum frequency that can be sampled is called the Nyquist frequency.
When sampling of a square wave is naively implemented it produces a perceptible, unpleasant aliasing noise.
Square waves that sound "clear" should be constructed from a limited number of sinusoidal waves, but the computation of such a wave could be costly.
However thanks to the Hard Sync technique it is not necessary. Instead, a precomputed pattern is being
applied to each "pulse step". The implementation of this is called the Bandwidth-Limited Pulse Buffer
in short Blimp
or Blep
.
The audio stream is being produced in frames by the Blep
implementation. First, the pulse steps are
being added, then the frame is being finalized and after that, the audio samples can be generated from
the collected pulses.
The way audio samples are being generated is outside of the scope of the Blep
implementation. This trait
only defines an interface for adding pulse steps and finalizing frames.
Associated Types
type SampleDelta: SampleDelta
A type for sample ∆ amplitudes (pulse height).
Required methods
fn ensure_frame_time(
&mut self,
sample_rate: u32,
ts_rate: f64,
frame_ts: FTs,
margin_ts: FTs
)
&mut self,
sample_rate: u32,
ts_rate: f64,
frame_ts: FTs,
margin_ts: FTs
)
This method allows the Blep
implementation to reserve enough memory for the audio
frame with an additional margin and to set up a sample time rate and other internals.
This method should not be called again unless any of the provided parameters changes.
sample_rate
is a number of output audio samples per second.ts_rate
is a number of time units per second which are being used as input time stamps.frame_ts
is a duration of a single frame measured in time units specified withts_rate
.margin_ts
specifies a largest required margin in time units for frame duration fluctuations.
Each frame's duration may fluctuate randomly as long as it's not constantly growing nor shrinking
and on average equals to frame_ts
.
Specifically frame_ts
+ margin_ts
- frame start
specifies the largest value of a time stamp
that can be passed to Blep::add_step or Blep::end_frame.
frame_ts
- margin_ts
- frame start
specifies the smallest value of a time stamp
that can be passed to Blep::end_frame.
The smallest possible time stamp value that can be passed to Blep::add_step is a frame start
time stamp. It starts at 0 after calling this method and is modified by the timestamp
value passed
to the last Blep::end_frame to timestamp
- frame_ts
. In other words, the next frame starts
when the previous ends minus frame duration.
fn add_step(&mut self, channel: usize, timestamp: FTs, delta: Self::SampleDelta)
This method is being used to add square-wave pulse steps within a boundary of a single frame.
timestamp
specifies the time stamp of the pulse.delta
specifies the pulse height (∆ amplitude).
The implementation may panic if timestamp
boundary limits are not uphold.
fn end_frame(&mut self, timestamp: FTs) -> usize
Finalizes audio frame.
Some frames can end little late or earlier and this method should allow for such a flexibility.
timestamp
specifies when the frame should be finalized marking the timestamp of the next frame.
Returns the number of samples that will be produced, single channel wise.
The caller must ensure that no pulse step should be generated with a time stamp past timstamp
given here.
The implementation may panic if this requirement is not uphold.
Implementors
impl<B> Blep for BlepAmpFilter<B> where
B: Blep,
B::SampleDelta: MulNorm + SampleDelta,
[src]
B: Blep,
B::SampleDelta: MulNorm + SampleDelta,
type SampleDelta = B::SampleDelta
fn ensure_frame_time(
&mut self,
sample_rate: u32,
ts_rate: f64,
frame_ts: FTs,
margin_ts: FTs
)
[src]
&mut self,
sample_rate: u32,
ts_rate: f64,
frame_ts: FTs,
margin_ts: FTs
)
fn end_frame(&mut self, timestamp: FTs) -> usize
[src]
fn add_step(&mut self, channel: usize, timestamp: FTs, delta: Self::SampleDelta)
[src]
impl<B> Blep for BlepStereo<B> where
B: Blep,
B::SampleDelta: MulNorm + SampleDelta,
[src]
B: Blep,
B::SampleDelta: MulNorm + SampleDelta,
type SampleDelta = B::SampleDelta
fn ensure_frame_time(
&mut self,
sample_rate: u32,
ts_rate: f64,
frame_ts: FTs,
margin_ts: FTs
)
[src]
&mut self,
sample_rate: u32,
ts_rate: f64,
frame_ts: FTs,
margin_ts: FTs
)