File indexing completed on 2024-04-28 15:08:06

0001 /* miniSynth - A Simple Software Synthesizer
0002    SPDX-FileCopyrightText: 2015 Ville Räisänen <vsr at vsr.name>
0003 
0004    SPDX-License-Identifier: GPL-3.0-or-later
0005 */
0006 
0007 #ifndef GENERATOR_H
0008 #define GENERATOR_H
0009 
0010 #include <QAudioDeviceInfo>
0011 #include <QAudioOutput>
0012 #include <QByteArray>
0013 #include <QIODevice>
0014 
0015 #include <QMutex>
0016 #include <QList>
0017 
0018 #include "modulation.h"
0019 #include "ADSRenvelope.h"
0020 
0021 class Preset;
0022 class LinearSynthesis;
0023 
0024 // The state of each active note is described with an Wave object. Wave
0025 // objects are assembled into the QList<Wave> waveList and removed once
0026 // they reach the state STATE_OFF.
0027 
0028 class Wave {
0029 public:
0030     enum {STATE_OFF, STATE_ATTACK, STATE_DECAY, STATE_RELEASE};
0031     unsigned char note, vel, state;
0032     qreal state_age, age;
0033     ADSREnvelope env;
0034 };
0035 
0036 // The synthesizer is implemented as a QIODevice and is connected to
0037 // a QAudioOutput in mainWindow.cpp. QAudioOutput reads data from the
0038 // synthersizer using the function readData(data, size). readData
0039 // returns maximum of 2048 samples generated with generateData(len).
0040 
0041 class Generator : public QIODevice {
0042     Q_OBJECT
0043 public:
0044     explicit Generator(const QAudioFormat &_format, QObject *parent = nullptr);
0045     ~Generator();
0046 
0047     void start    ();
0048     void stop     ();
0049     void setState ();
0050 
0051     void addWave (unsigned char note, unsigned char vel);
0052 
0053     qint64 readData(char *data, qint64 len) override;
0054     qint64 writeData(const char *data, qint64 len) override;
0055     qint64 bytesAvailable() const override;
0056 
0057     void generateData(qint64 len);
0058 
0059 public Q_SLOTS:
0060     void noteOn   (unsigned char chan, unsigned char note, unsigned char vel);
0061     void noteOff  (unsigned char chan, unsigned char note);
0062 
0063     // Slots for manipulation of the current patch.
0064     void setMode      (unsigned int _mode);
0065     void setTimbre    (QVector<int> &amplitudes, QVector<int> &phases);
0066     void setEnvelope  (const ADSREnvelope &env);
0067     void setModulation(Modulation &modulation);
0068     void setPreset    (Preset &preset);
0069     
0070 private:
0071     QAudioFormat format;
0072     QByteArray m_buffer;
0073 
0074     // State of the synthesizer
0075     qreal curtime;
0076     QList<Wave> waveList;
0077 
0078     // Parameters of the current patch
0079     LinearSynthesis *linSyn;
0080     ADSREnvelope     defaultEnv;
0081     Modulation       mod;
0082     Waveform        *mod_waveform;
0083 
0084     static const int m_samplingRate = 22050;
0085     static const int maxUsedBytes = 2048;
0086     
0087     qreal *synthData;
0088     
0089     QMutex m_lock;
0090 };
0091 
0092 #endif // GENERATOR_H