summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibDSP/Synthesizers.h
blob: 99b660f20fe7e5065871edbfb15afe3f89a07d90 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/*
 * 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 DSP::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(u32 sample_time, u8 note);
    double samples_per_cycle(u8 note) const;
    double sin_position(u32 sample_time, u8 note) const;
    double triangle_position(u32 sample_time, u8 note) const;
    double square_position(u32 sample_time, u8 note) const;
    double saw_position(u32 sample_time, u8 note) const;
    double noise_position(u32 sample_time, 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;
};

}