-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathoutputQt.h
136 lines (110 loc) · 4.05 KB
/
outputQt.h
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/* miniSynth - A Simple Software Synthesizer
Copyright (C) 2015 Ville Räisänen <vsr at vsr.name>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUTPUTQT_H
#define OUTPUTQT_H
#include <QAudioDeviceInfo>
#include <QAudioOutput>
#include <QByteArray>
#include <QIODevice>
#include <QList>
#include <QMutableListIterator>
#include "linearSynthesis.h"
#include "ADSRenvelope.h"
#include "modulation.h"
#include "filter.h"
#include "ADSRenvelope.h"
#include "reverb.h"
#ifdef USE_FFTW
#include <fftw3.h>
#else
#include "fft.h"
#endif
// The state of each active note is described with an Wave object. Wave
// objects are assembled into the QList<Wave> waveList and removed once
// they reach the state STATE_OFF.
class Wave {
public:
enum {STATE_OFF, STATE_ATTACK, STATE_DECAY, STATE_RELEASE};
unsigned char note, vel, state;
qreal state_age, age;
ADSREnvelope env;
};
// The synthesizer is implemented as a QIODevice and is connected to
// a QAudioOutput in mainWindow.cpp. QAudioOutput reads data from the
// synthersizer using the function readData(data, size). readData
// returns maximum of 2048 samples generated with generateData(len).
class Generator : public QIODevice {
Q_OBJECT
public:
Generator(const QAudioFormat &_format, QObject *parent = 0);
~Generator();
void start ();
void stop ();
void setState ();
void addWave (unsigned char note, unsigned char vel);
qint64 readData(char *data, qint64 maxlen);
qint64 writeData(const char *data, qint64 len);
qint64 bytesAvailable() const;
void generateData(qint64 len);
signals:
#ifdef USE_FFTW
void fftUpdate(fftw_complex *out, unsigned int size, unsigned int ind_dataset);
#else
void fftUpdate(std::complex<qreal> *out, unsigned int size, unsigned int ind_dataset);
#endif
public slots:
void noteOn (unsigned char chan, unsigned char note, unsigned char vel);
void noteOff (unsigned char chan, unsigned char note);
// Slots for manipulation of the current patch.
void setMode (int _mode);
void setTimbre (QVector<int> &litudes, QVector<int> &phases);
void setEnvelope (ADSREnvelope &env);
void setModulation(Modulation &modulation);
void setFilter (FilterParameters &filtParam);
void setReverb (Reverb &_rev);
private:
QAudioFormat format;
QByteArray m_buffer;
// State of the syntheziser
qreal curtime;
QList<Wave> waveList;
// Parameters of the current patch
LinearSynthesis *linSyn;
ADSREnvelope defaultEnv;
Modulation mod;
Waveform *mod_waveform;
Filter *filter;
Reverb rev;
// convBuffer and filtBuffer are circular buffers used to store the
// previous convBuffer_size samples before and after convolution.
// Both buffers are used as inputs for the FFT in the computation of
// data for the fftUpdate signal. The data in convBuffer is also used
// in the computation of convolution. convBuffer_ind tells the location
// of the last added sample in the buffer.
qreal *convBuffer, *filtBuffer, *delayBuffer;
unsigned int convBuffer_size, delayBuffer_size;
quint32 convBuffer_ind, delayBuffer_ind;
// Impulse response for the current filter.
qreal *convImpulse;
unsigned int convImpulse_size;
qreal fftTimer;
#ifdef USE_FFTW
fftw_complex *fftwIn, *fftwOut;
fftw_plan fftwPlan;
#else
std::complex<qreal> *fftData;
unsigned int fftLength;
#endif
};
#endif // OUTPUTQT_H