mirror of
https://github.com/RGBCube/serenity
synced 2025-05-18 10:45:08 +00:00

This has mainly performance benefits, so that we only need to call into all processors once for every audio buffer segment. It requires adjusting quite some logic in most processors and in Track, as we have to consider a larger collection of notes and samples at each step. There's some cautionary TODOs in the currently unused LibDSP tracks because they don't do things properly yet.
72 lines
1.7 KiB
C++
72 lines
1.7 KiB
C++
/*
|
|
* Copyright (c) 2021-2022, kleines Filmröllchen <filmroellchen@serenityos.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <AK/SinglyLinkedList.h>
|
|
#include <LibDSP/Music.h>
|
|
#include <LibDSP/Processor.h>
|
|
#include <LibDSP/ProcessorParameter.h>
|
|
#include <LibDSP/Transport.h>
|
|
|
|
namespace LibDSP::Synthesizers {
|
|
|
|
enum Waveform : u8 {
|
|
Sine,
|
|
Triangle,
|
|
Square,
|
|
Saw,
|
|
Noise,
|
|
};
|
|
|
|
struct PitchedEnvelope : Envelope {
|
|
constexpr PitchedEnvelope() = default;
|
|
constexpr PitchedEnvelope(double envelope, u8 note)
|
|
: Envelope(envelope)
|
|
, note(note)
|
|
{
|
|
}
|
|
constexpr PitchedEnvelope(Envelope envelope, u8 note)
|
|
: Envelope(envelope)
|
|
, note(note)
|
|
{
|
|
}
|
|
|
|
u8 note;
|
|
};
|
|
|
|
class Classic : public SynthesizerProcessor {
|
|
public:
|
|
Classic(NonnullRefPtr<Transport>);
|
|
|
|
static Envelope compute_envelope(RollNote&);
|
|
|
|
Waveform wave() const { return m_waveform.value(); }
|
|
|
|
private:
|
|
virtual void process_impl(Signal const&, Signal&) override;
|
|
|
|
double volume_from_envelope(Envelope const&) const;
|
|
double wave_position(u8 note);
|
|
double samples_per_cycle(u8 note) const;
|
|
double sin_position(u8 note) const;
|
|
double triangle_position(u8 note) const;
|
|
double square_position(u8 note) const;
|
|
double saw_position(u8 note) const;
|
|
double noise_position(u8 note);
|
|
double get_random_from_seed(u64 note);
|
|
|
|
ProcessorEnumParameter<Waveform> m_waveform;
|
|
ProcessorRangeParameter m_attack;
|
|
ProcessorRangeParameter m_decay;
|
|
ProcessorRangeParameter m_sustain;
|
|
ProcessorRangeParameter m_release;
|
|
|
|
RollNotes m_playing_notes;
|
|
Array<double, note_frequencies.size()> last_random;
|
|
};
|
|
|
|
}
|