1 /* miniSynth - A Simple Software Synthesizer
2    SPDX-FileCopyrightText: 2015 Ville Räisänen <vsr at vsr.name>
3 
4    SPDX-License-Identifier: GPL-3.0-or-later
5 */
6 
7 #ifndef GENERATOR_H
8 #define GENERATOR_H
9 
10 #include <QAudioDeviceInfo>
11 #include <QAudioOutput>
12 #include <QByteArray>
13 #include <QIODevice>
14 
15 #include <QMutex>
16 #include <QList>
17 
18 #include "modulation.h"
19 #include "ADSRenvelope.h"
20 
21 class Preset;
22 class LinearSynthesis;
23 
24 // The state of each active note is described with an Wave object. Wave
25 // objects are assembled into the QList<Wave> waveList and removed once
26 // they reach the state STATE_OFF.
27 
28 class Wave {
29 public:
30     enum {STATE_OFF, STATE_ATTACK, STATE_DECAY, STATE_RELEASE};
31     unsigned char note, vel, state;
32     qreal state_age, age;
33     ADSREnvelope env;
34 };
35 
36 // The synthesizer is implemented as a QIODevice and is connected to
37 // a QAudioOutput in mainWindow.cpp. QAudioOutput reads data from the
38 // synthersizer using the function readData(data, size). readData
39 // returns maximum of 2048 samples generated with generateData(len).
40 
41 class Generator : public QIODevice {
42     Q_OBJECT
43 public:
44     explicit Generator(const QAudioFormat &_format, QObject *parent = 0);
45     ~Generator();
46 
47     void start    ();
48     void stop     ();
49     void setState ();
50 
51     void addWave (unsigned char note, unsigned char vel);
52 
53     qint64 readData(char *data, qint64 len);
54     qint64 writeData(const char *data, qint64 len);
55     qint64 bytesAvailable() const;
56 
57     void generateData(qint64 len);
58 
59 public slots:
60     void noteOn   (unsigned char chan, unsigned char note, unsigned char vel);
61     void noteOff  (unsigned char chan, unsigned char note);
62 
63     // Slots for manipulation of the current patch.
64     void setMode      (unsigned int _mode);
65     void setTimbre    (QVector<int> &amplitudes, QVector<int> &phases);
66     void setEnvelope  (const ADSREnvelope &env);
67     void setModulation(Modulation &modulation);
68     void setPreset    (Preset &preset);
69 
70 private:
71     QAudioFormat format;
72     QByteArray m_buffer;
73 
74     // State of the synthesizer
75     qreal curtime;
76     QList<Wave> waveList;
77 
78     // Parameters of the current patch
79     LinearSynthesis *linSyn;
80     ADSREnvelope     defaultEnv;
81     Modulation       mod;
82     Waveform        *mod_waveform;
83 
84     static const int m_samplingRate = 22050;
85     static const int maxUsedBytes = 2048;
86 
87     qreal *synthData;
88 
89     QMutex m_lock;
90 };
91 
92 #endif // GENERATOR_H
93