├── AudioBufferDevice.cpp ├── AudioBufferDevice.h ├── AudioPlayer.cpp ├── AudioPlayer.h ├── EQFilterGroup.cpp ├── EQFilterGroup.h ├── Parametric-equalizer.pro ├── README.md ├── bandpassFilter ├── fir1.cpp ├── fir1.h ├── fir1_data.cpp ├── fir1_data.h ├── fir1_emxutil.cpp ├── fir1_emxutil.h ├── fir1_initialize.cpp ├── fir1_initialize.h ├── fir1_rtwutil.cpp ├── fir1_rtwutil.h ├── fir1_terminate.cpp ├── fir1_terminate.h ├── fir1_types.h ├── firls.cpp ├── firls.h ├── mldivide.cpp ├── mldivide.h ├── rtGetInf.cpp ├── rtGetInf.h ├── rtGetNaN.cpp ├── rtGetNaN.h ├── rt_nonfinite.cpp ├── rt_nonfinite.h ├── rtwtypes.h ├── string1.cpp ├── string1.h ├── tmwtypes.h ├── validatestring.cpp ├── validatestring.h ├── xnrm2.cpp ├── xnrm2.h ├── xzgeqp3.cpp └── xzgeqp3.h ├── fdacoefs.h ├── frequency.md ├── icon.qrc ├── icon └── eq.png ├── main.cpp ├── widget.cpp ├── widget.h ├── widget.ui └── 附件 ├── EQ02.png ├── EQFIR.png ├── EQFilterGroup01.png ├── EQSS.png ├── EQYX.jpg ├── FDAToolExample_04.png ├── FIR filter01.png ├── FIR filter02.png ├── FIR filter03.png ├── FIRSJ01.png ├── FIRSJ02.png ├── FIRfilter01.png ├── FIRfilter02.png ├── FIRfilter03.png ├── IIR filter01.png ├── IIR filter02.png ├── M03.jpg ├── M04.jpg ├── M05.jpg ├── encod02.png ├── encod04.png ├── fft01.png ├── fft02.png ├── filter01.png ├── filter02.png ├── filter03.png ├── filter04.png ├── math01.png ├── math02.png ├── 频率响应.png └── 频率响应特性.png /AudioBufferDevice.cpp: -------------------------------------------------------------------------------- 1 | #include "AudioBufferDevice.h" 2 | #include 3 | 4 | AudioBufferDevice::AudioBufferDevice(QAudioDecoder *decoder, QObject *parent): 5 | QIODevice(parent), 6 | _decoder(decoder), 7 | _isFinished(false) 8 | { 9 | connect(_decoder, SIGNAL(bufferReady()), this, SLOT(onBufferReady())); 10 | connect(_decoder, SIGNAL(finished()), this, SLOT(onFinished())); 11 | connect(_decoder, SIGNAL(error(QAudioDecoder::Error)), this, SLOT(onErroe(QAudioDecoder::Error))); 12 | _filter = new EQFilterGroup(); 13 | _decoder->start(); 14 | } 15 | 16 | bool AudioBufferDevice::atEnd() const 17 | { 18 | return _isFinished && _queue.empty(); 19 | } 20 | 21 | qint64 AudioBufferDevice::readData(char *data, qint64 size) 22 | { 23 | if (_queue.empty() && _abuffer_queue.empty()) { 24 | return 0; 25 | } 26 | 27 | if (_queue.empty()) { 28 | QAudioBuffer *buffer = _abuffer_queue.first(); 29 | QBuffer *qb = _filter->filter(*buffer); 30 | _queue.push_back(qb); 31 | _abuffer_queue.removeFirst(); 32 | delete buffer; 33 | } 34 | 35 | QBuffer *buffer = _queue.first(); 36 | if (!buffer->isOpen()) { 37 | buffer->open(QIODevice::ReadOnly); 38 | } 39 | 40 | qint64 n = buffer->read(data, size); 41 | qDebug() << "-----------------------------------------------------------------------------data" << strlen(data); 42 | if (buffer->atEnd()) { 43 | _queue.removeFirst(); 44 | delete buffer; 45 | } 46 | 47 | 48 | return n; 49 | } 50 | 51 | qint64 AudioBufferDevice::writeData(const char *data, qint64 maxSize) 52 | { 53 | return 0; 54 | } 55 | 56 | qint64 AudioBufferDevice::bytesAvailable() const 57 | { 58 | if (_queue.empty()) { 59 | return 0; 60 | } else { 61 | return _queue.first()->bytesAvailable(); 62 | } 63 | } 64 | 65 | void AudioBufferDevice::onBufferReady() 66 | { 67 | QAudioBuffer buffer = _decoder->read(); 68 | if (buffer.isValid()) { 69 | _abuffer_queue.push_back(new QAudioBuffer(buffer)); 70 | } 71 | } 72 | 73 | void AudioBufferDevice::onFinished() 74 | { 75 | _isFinished = true; 76 | } 77 | 78 | void AudioBufferDevice::clearQAbuffer() 79 | { 80 | _queue.clear(); 81 | _abuffer_queue.clear(); 82 | } 83 | 84 | void AudioBufferDevice::onErroe(QAudioDecoder::Error error) 85 | { 86 | qDebug() << error; 87 | } 88 | -------------------------------------------------------------------------------- /AudioBufferDevice.h: -------------------------------------------------------------------------------- 1 | #ifndef AUDIOBUFFERDEVICE_H 2 | #define AUDIOBUFFERDEVICE_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "EQFilterGroup.h" 11 | 12 | class AudioBufferDevice : public QIODevice 13 | { 14 | Q_OBJECT 15 | public: 16 | explicit AudioBufferDevice(QAudioDecoder *decoder, QObject *parent = nullptr); 17 | virtual bool atEnd() const override; 18 | virtual qint64 bytesAvailable() const override; 19 | 20 | protected: 21 | virtual qint64 readData(char *data, qint64 size) override; 22 | 23 | virtual qint64 writeData(const char *data, qint64 maxSize); 24 | signals: 25 | 26 | public slots: 27 | void onBufferReady(); 28 | void onFinished(); 29 | void clearQAbuffer(); 30 | void onErroe(QAudioDecoder::Error error); 31 | 32 | void set_FC_HZ_32(float gain, float adaptation) {_filter->set_FC_HZ_32(gain, adaptation);} 33 | void set_FC_HZ_63(float gain, float adaptation) {_filter->set_FC_HZ_63(gain, adaptation);} 34 | void set_FC_HZ_125(float gain, float adaptation) {_filter->set_FC_HZ_125(gain, adaptation);} 35 | void set_FC_HZ_250(float gain, float adaptation) {_filter->set_FC_HZ_250(gain, adaptation);} 36 | void set_FC_HZ_500(float gain, float adaptation) {_filter->set_FC_HZ_500(gain, adaptation);} 37 | void set_FC_HZ_1000(float gain) {_filter->set_FC_HZ_1000(gain);} 38 | void set_FC_HZ_2000(float gain) {_filter->set_FC_HZ_2000(gain);} 39 | void set_FC_HZ_4000(float gain) {_filter->set_FC_HZ_4000(gain);} 40 | void set_FC_HZ_8000(float gain) {_filter->set_FC_HZ_8000(gain);} 41 | void set_FC_HZ_16000(float gain) {_filter->set_FC_HZ_16000(gain);} 42 | 43 | 44 | private: 45 | QAudioDecoder *_decoder; 46 | QQueue _queue; 47 | QQueue _abuffer_queue; 48 | EQFilterGroup *_filter; 49 | bool _isFinished; 50 | }; 51 | 52 | #endif // AUDIOBUFFERDEVICE_H 53 | -------------------------------------------------------------------------------- /AudioPlayer.cpp: -------------------------------------------------------------------------------- 1 | #include "AudioPlayer.h" 2 | 3 | AudioPlayer::AudioPlayer(QObject *parent) 4 | { 5 | 6 | QAudioFormat format; 7 | 8 | format.setSampleRate(44100); 9 | format.setChannelCount(2); 10 | format.setCodec("audio/pcm"); 11 | format.setSampleSize(32); 12 | format.setByteOrder(QAudioFormat::LittleEndian); 13 | format.setSampleType(QAudioFormat::SignedInt); 14 | 15 | decoder = new QAudioDecoder(this); 16 | decoder->setAudioFormat(format); 17 | qDebug() << "isvalide: " << format.isValid(); 18 | 19 | _output = new QAudioOutput(format, this); 20 | _buffer = new AudioBufferDevice(decoder, this); 21 | _buffer->open(QIODevice::ReadOnly); 22 | } 23 | 24 | void AudioPlayer::setSourceFilename(const QString &fileName) 25 | { 26 | qDebug() << "setSourceFilename" << fileName ; 27 | 28 | // auto content = new QMediaContent(QUrl(fname)); 29 | // QMediaResource resource = content->canonicalResource(); 30 | // decoder->setSourceFilename(fname); 31 | 32 | _buffer->clearQAbuffer(); 33 | decoder->stop(); 34 | decoder->setSourceFilename(fileName); 35 | decoder->start(); 36 | } 37 | 38 | void AudioPlayer::play() 39 | { 40 | //播放 41 | _output->start(_buffer); 42 | } 43 | 44 | void AudioPlayer::suspend() 45 | { 46 | // 暂停 47 | _output->suspend(); 48 | } 49 | 50 | void AudioPlayer::reset() 51 | { 52 | // 停止 53 | _output->reset(); 54 | } 55 | -------------------------------------------------------------------------------- /AudioPlayer.h: -------------------------------------------------------------------------------- 1 | #ifndef AUDIOPLAYER_H 2 | #define AUDIOPLAYER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "AudioBufferDevice.h" 11 | #include 12 | 13 | class AudioPlayer : public QObject 14 | { 15 | Q_OBJECT 16 | public: 17 | explicit AudioPlayer(QObject *parent = nullptr); 18 | 19 | void setSourceFilename(const QString &fileName); 20 | 21 | void play(); 22 | void suspend(); 23 | void reset(); 24 | 25 | public: 26 | void set_FC_HZ_32(float gain, float adaptation) {_buffer->set_FC_HZ_32(gain, adaptation);} 27 | void set_FC_HZ_63(float gain, float adaptation) {_buffer->set_FC_HZ_63(gain, adaptation);} 28 | void set_FC_HZ_125(float gain, float adaptation) {_buffer->set_FC_HZ_125(gain, adaptation);} 29 | void set_FC_HZ_250(float gain, float adaptation) {_buffer->set_FC_HZ_250(gain, adaptation);} 30 | void set_FC_HZ_500(float gain, float adaptation) {_buffer->set_FC_HZ_500(gain, adaptation);} 31 | void set_FC_HZ_1000(float gain) {_buffer->set_FC_HZ_1000(gain);} 32 | void set_FC_HZ_2000(float gain) {_buffer->set_FC_HZ_2000(gain);} 33 | void set_FC_HZ_4000(float gain) {_buffer->set_FC_HZ_4000(gain);} 34 | void set_FC_HZ_8000(float gain) {_buffer->set_FC_HZ_8000(gain);} 35 | void set_FC_HZ_16000(float gain) {_buffer->set_FC_HZ_16000(gain);} 36 | 37 | signals: 38 | 39 | public slots: 40 | 41 | public: 42 | QAudioOutput *_output = nullptr; 43 | AudioBufferDevice *_buffer = nullptr; 44 | QAudioDecoder *decoder = nullptr; 45 | }; 46 | 47 | #endif // AUDIOPLAYER_H 48 | -------------------------------------------------------------------------------- /EQFilterGroup.cpp: -------------------------------------------------------------------------------- 1 | #include "EQFilterGroup.h" 2 | #include "fdacoefs.h" 3 | 4 | #include "fir1.h" 5 | #include "fir1_terminate.h" 6 | #include "rt_nonfinite.h" 7 | 8 | #include 9 | #include 10 | 11 | EQFilterGroup::EQFilterGroup() 12 | { 13 | 14 | } 15 | 16 | void EQFilterGroup::filterCoefficient(double Fc01, double Fc02, double b[]) 17 | { 18 | /*-------计算滤波器系数---------*/ 19 | 20 | double dv[2] = {0}; 21 | dv[0] = Fc01 / (44100 / 2); 22 | dv[1] = Fc02 / (44100 / 2); 23 | 24 | // "bandpass"; 25 | char b_cv[8] = {'b', 'a', 'n', 'd', 'p', 'a', 's', 's'}; 26 | 27 | double dv1[100] = { 28 | 0.0800, 0.0809, 0.0837, 0.0883, 0.0947, 0.1030, 0.1130, 0.1247, 0.1380, 0.1530, 29 | 0.1696, 0.1876, 0.2071, 0.2279, 0.2499, 0.2732, 0.2975, 0.3228, 0.3489, 0.3758, 30 | 0.4034, 0.4316, 0.4601, 0.4890, 0.5181, 0.5473, 0.5765, 0.6055, 0.6342, 0.6626, 31 | 0.6905, 0.7177, 0.7443, 0.7700, 0.7948, 0.8186, 0.8412, 0.8627, 0.8828, 0.9016, 32 | 0.9189, 0.9347, 0.9489, 0.9614, 0.9723, 0.9814, 0.9887, 0.9942, 0.9979, 0.9998, 33 | 0.9998, 0.9979, 0.9942, 0.9887, 0.9814, 0.9723, 0.9614, 0.9489, 0.9347, 0.9189, 34 | 0.9016, 0.8828, 0.8627, 0.8412, 0.8186, 0.7948, 0.7700, 0.7443, 0.7177, 0.6905, 35 | 0.6626, 0.6342, 0.6055, 0.5765, 0.5473, 0.5181, 0.4890, 0.4601, 0.4316, 0.4034, 36 | 0.3758, 0.3489, 0.3228, 0.2975, 0.2732, 0.2499, 0.2279, 0.2071, 0.1876, 0.1696, 37 | 0.1530, 0.1380, 0.1247, 0.1130, 0.1030, 0.0947, 0.0883, 0.0837, 0.0809, 0.0800 38 | }; 39 | 40 | 41 | // "scale"; 42 | char cv1[5] = {'s', 'c', 'a', 'l', 'e'}; 43 | 44 | // double ba[100]; 45 | double a; 46 | 47 | fir1(99, dv, b_cv, dv1, cv1, b, &a); 48 | 49 | // fir1_terminate(); 50 | } 51 | 52 | void EQFilterGroup::updateCoefficient(double Fc01, double Fc02, int coefficientGroup) 53 | { 54 | double ba[100] = {0}; 55 | 56 | float *znum = nullptr; 57 | 58 | switch (coefficientGroup) { 59 | case 1: 60 | znum = FC_HZ_32; 61 | break; 62 | case 2: 63 | znum = FC_HZ_63; 64 | break; 65 | case 3: 66 | znum = FC_HZ_125; 67 | break; 68 | case 4: 69 | znum = FC_HZ_250; 70 | break; 71 | case 5: 72 | znum = FC_HZ_500; 73 | break; 74 | case 6: 75 | znum = FC_HZ_1000; 76 | break; 77 | case 7: 78 | znum = FC_HZ_2000; 79 | break; 80 | case 8: 81 | znum = FC_HZ_4000; 82 | break; 83 | case 9: 84 | znum = FC_HZ_8000; 85 | break; 86 | case 10: 87 | znum = FC_HZ_16000; 88 | break; 89 | 90 | default: 91 | break; 92 | } 93 | 94 | memset(ba, 0, 100); 95 | filterCoefficient(Fc01, Fc02, ba); 96 | for (int i = 0; i < 100; i++) { 97 | znum[i] = ba[i]; 98 | } 99 | } 100 | 101 | void EQFilterGroup::clearFdacoefs() 102 | { 103 | for (int i = 0; i < 100; i++) { 104 | FC_HZ_32[i] = 0.0; 105 | FC_HZ_63[i] = 0.0; 106 | FC_HZ_125[i] = 0.0; 107 | FC_HZ_250[i] = 0.0; 108 | FC_HZ_500[i] = 0.0; 109 | FC_HZ_1000[i] = 0.0; 110 | FC_HZ_2000[i] = 0.0; 111 | FC_HZ_4000[i] = 0.0; 112 | FC_HZ_8000[i] = 0.0; 113 | FC_HZ_16000[i] = 0.0; 114 | } 115 | } 116 | 117 | QBuffer *EQFilterGroup::filter(const QAudioBuffer &buffer) 118 | { 119 | QVector channel1; 120 | QVector channel2; 121 | decode_channel(channel1, channel2, buffer); 122 | QVector filtered_channel1; 123 | QVector filtered_channel2; 124 | 125 | // qDebug() << _FC_HZ_32 << " " << _FC_HZ_63 << " " << _FC_HZ_125 << " " << _FC_HZ_250 << " " 126 | // << _FC_HZ_500 << " " << _FC_HZ_1000 << " " << _FC_HZ_2000 << " " << _FC_HZ_4000 << " " 127 | // << _FC_HZ_8000 << " " << _FC_HZ_16000; 128 | 129 | for (auto i = 0; i < channel1.count() ; ++i) { 130 | float left = _FC_HZ_32 * band_filter_channel(channel1[i], 0, 1) + 131 | _FC_HZ_63 * band_filter_channel(channel1[i], 0, 2) + 132 | _FC_HZ_125 * band_filter_channel(channel1[i], 0, 3) + 133 | _FC_HZ_250 * band_filter_channel(channel1[i], 0, 4) + 134 | _FC_HZ_500 * band_filter_channel(channel1[i], 0, 5) + 135 | _FC_HZ_1000 * band_filter_channel(channel1[i], 0, 6) + 136 | _FC_HZ_2000 * band_filter_channel(channel1[i], 0, 7) + 137 | _FC_HZ_4000 * band_filter_channel(channel1[i], 0, 8) + 138 | _FC_HZ_8000 * band_filter_channel(channel1[i], 0, 9) + 139 | _FC_HZ_16000 * band_filter_channel(channel1[i], 0, 10); 140 | 141 | filtered_channel1.append(left); 142 | } 143 | 144 | QByteArray array; 145 | encode_channel(filtered_channel1, filtered_channel2, array); 146 | auto qb = new QBuffer(); 147 | qb->setData(array); 148 | return qb; 149 | } 150 | 151 | 152 | 153 | float EQFilterGroup::band_filter_channel(float invar, float initval, int setic) 154 | { 155 | float sumnum = 0.0; 156 | static float states[99] = {0}; 157 | 158 | float *znum = nullptr; 159 | 160 | switch (setic) { 161 | case 1: 162 | znum = FC_HZ_32; 163 | break; 164 | case 2: 165 | znum = FC_HZ_63; 166 | break; 167 | case 3: 168 | znum = FC_HZ_125; 169 | break; 170 | case 4: 171 | znum = FC_HZ_250; 172 | break; 173 | case 5: 174 | znum = FC_HZ_500; 175 | break; 176 | case 6: 177 | znum = FC_HZ_1000; 178 | break; 179 | case 7: 180 | znum = FC_HZ_2000; 181 | break; 182 | case 8: 183 | znum = FC_HZ_4000; 184 | break; 185 | case 9: 186 | znum = FC_HZ_8000; 187 | break; 188 | case 10: 189 | znum = FC_HZ_16000; 190 | break; 191 | 192 | default: 193 | break; 194 | } 195 | 196 | 197 | for (int i = 0; i < 99; i++) { 198 | sumnum += states[i] * znum[i]; 199 | if (i < 98) 200 | states[i] = states[i + 1]; 201 | } 202 | states[98] = invar; 203 | sumnum += states[98] * znum[0]; 204 | return sumnum * 0.4; 205 | } 206 | 207 | 208 | 209 | 210 | -------------------------------------------------------------------------------- /EQFilterGroup.h: -------------------------------------------------------------------------------- 1 | #ifndef EQFILTERGROUP_H 2 | #define EQFILTERGROUP_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | class EQFilterGroup 12 | { 13 | public: 14 | EQFilterGroup(); 15 | 16 | static void filterCoefficient(double Fc01, double Fc02, double b[]); 17 | 18 | static void updateCoefficient(double Fc01, double Fc02, int coefficientGroup); 19 | 20 | static void clearFdacoefs(); 21 | 22 | void set_FC_HZ_32(float gain, float adaptation) 23 | { 24 | _FC_HZ_32 = gain * adaptation; 25 | } 26 | void set_FC_HZ_63(float gain, float adaptation) 27 | { 28 | _FC_HZ_63 = gain * adaptation; 29 | } 30 | void set_FC_HZ_125(float gain, float adaptation) 31 | { 32 | _FC_HZ_125 = gain * adaptation; 33 | } 34 | void set_FC_HZ_250(float gain, float adaptation) 35 | { 36 | _FC_HZ_250 = gain * adaptation; 37 | } 38 | void set_FC_HZ_500(float gain, float adaptation) 39 | { 40 | _FC_HZ_500 = gain * adaptation; 41 | } 42 | void set_FC_HZ_1000(float gain) 43 | { 44 | _FC_HZ_1000 = gain; 45 | } 46 | void set_FC_HZ_2000(float gain) 47 | { 48 | _FC_HZ_2000 = gain; 49 | } 50 | void set_FC_HZ_4000(float gain) 51 | { 52 | _FC_HZ_4000 = gain; 53 | } 54 | void set_FC_HZ_8000(float gain) 55 | { 56 | _FC_HZ_8000 = gain; 57 | } 58 | void set_FC_HZ_16000(float gain) 59 | { 60 | _FC_HZ_16000 = gain; 61 | } 62 | 63 | 64 | template 65 | void decode_channel(QVector &channel1, QVector &channel2, QAudioBuffer const &buffer) 66 | { 67 | T *data = (T *)(buffer.data()); 68 | size_t len = buffer.sampleCount(); 69 | 70 | for (size_t i = 0; i < len; i += 1) { 71 | T left = data[i]; 72 | 73 | left = std::isnan(left) ? 0.0 : left; 74 | 75 | channel1.append(float(left) / std::numeric_limits::max()); 76 | } 77 | } 78 | 79 | template 80 | void encode_channel(QVector const &channel1, QVector const &channel2, QByteArray &bytes) 81 | { 82 | for (size_t i = 0; i < channel1.count() ; ++i) { 83 | float left = channel1[i] > 1.0 ? 1.0 : channel1[i]; 84 | 85 | T lpcm = T(std::floor(left * std::numeric_limits::max())); 86 | bytes.append((char *)&lpcm, sizeof(lpcm)); 87 | } 88 | } 89 | 90 | QBuffer *filter(QAudioBuffer const &buffer); 91 | 92 | float band_filter_channel(float invar, float initval, int setic); 93 | 94 | private: 95 | 96 | float _FC_HZ_32 = 1.0; 97 | float _FC_HZ_63 = 1.0; 98 | float _FC_HZ_125 = 1.0; 99 | float _FC_HZ_250 = 1.0; 100 | float _FC_HZ_500 = 1.0; 101 | float _FC_HZ_1000 = 1.0; 102 | float _FC_HZ_2000 = 1.0; 103 | float _FC_HZ_4000 = 1.0; 104 | float _FC_HZ_8000 = 1.0; 105 | float _FC_HZ_16000 = 1.0; 106 | }; 107 | 108 | #endif // EQFILTERGROUP_H 109 | -------------------------------------------------------------------------------- /Parametric-equalizer.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2018-11-11T00:48:27 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui 8 | QT += multimedia 9 | 10 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 11 | 12 | TARGET = equalizer 13 | TEMPLATE = app 14 | 15 | # The following define makes your compiler emit warnings if you use 16 | # any feature of Qt which has been marked as deprecated (the exact warnings 17 | # depend on your compiler). Please consult the documentation of the 18 | # deprecated API in order to know how to port your code away from it. 19 | DEFINES += QT_DEPRECATED_WARNINGS 20 | 21 | # You can also make your code fail to compile if you use deprecated APIs. 22 | # In order to do so, uncomment the following line. 23 | # You can also select to disable deprecated APIs only up to a certain version of Qt. 24 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 25 | 26 | 27 | SOURCES += \ 28 | main.cpp \ 29 | AudioPlayer.cpp \ 30 | AudioBufferDevice.cpp \ 31 | EQFilterGroup.cpp \ 32 | widget.cpp \ 33 | bandpassFilter/fir1_data.cpp \ 34 | bandpassFilter/fir1_emxutil.cpp \ 35 | bandpassFilter/fir1_initialize.cpp \ 36 | bandpassFilter/fir1_rtwutil.cpp \ 37 | bandpassFilter/fir1_terminate.cpp \ 38 | bandpassFilter/fir1.cpp \ 39 | bandpassFilter/firls.cpp \ 40 | bandpassFilter/mldivide.cpp \ 41 | bandpassFilter/rt_nonfinite.cpp \ 42 | bandpassFilter/rtGetInf.cpp \ 43 | bandpassFilter/rtGetNaN.cpp \ 44 | bandpassFilter/string1.cpp \ 45 | bandpassFilter/validatestring.cpp \ 46 | bandpassFilter/xnrm2.cpp \ 47 | bandpassFilter/xzgeqp3.cpp 48 | 49 | 50 | HEADERS += \ 51 | AudioPlayer.h \ 52 | AudioBufferDevice.h \ 53 | EQFilterGroup.h \ 54 | fdacoefs.h \ 55 | widget.h \ 56 | bandpassFilter/fir1_data.h \ 57 | bandpassFilter/fir1_emxutil.h \ 58 | bandpassFilter/fir1_initialize.h \ 59 | bandpassFilter/fir1_rtwutil.h \ 60 | bandpassFilter/fir1_terminate.h \ 61 | bandpassFilter/fir1_types.h \ 62 | bandpassFilter/fir1.h \ 63 | bandpassFilter/firls.h \ 64 | bandpassFilter/mldivide.h \ 65 | bandpassFilter/rt_nonfinite.h \ 66 | bandpassFilter/rtGetInf.h \ 67 | bandpassFilter/rtGetNaN.h \ 68 | bandpassFilter/rtwtypes.h \ 69 | bandpassFilter/string1.h \ 70 | bandpassFilter/tmwtypes.h \ 71 | bandpassFilter/validatestring.h \ 72 | bandpassFilter/xnrm2.h \ 73 | bandpassFilter/xzgeqp3.h 74 | 75 | 76 | FORMS += \ 77 | widget.ui 78 | 79 | 80 | INCLUDEPATH += $$PWD/bandpassFilter 81 | DEPENDPATH += $$PWD/bandpassFilter 82 | 83 | RESOURCES += \ 84 | icon.qrc 85 | 86 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

数字音频均衡器设计技术调研报告

2 | 3 | ## 相关术语 4 | 5 | | 缩写 | 全称 | 描述 | 6 | | :---: | :-----------------------: | :------------------------------------------: | 7 | | `PCM` | `Pulse Code Modulation` | 脉冲编码调制,数字通信的编码方式 | 8 | | `FIR` | `Finite Impulse Response` | 有限长单位冲激响应滤波器 | 9 | | `FFT` | `Fast Fourier transform` | 快速傅立叶变换,时域至频域变换方法之一 | 10 | | `FS` | `Frequency Sampling` | 每秒从连续信号中提取并组成离散信号的采样个数 | 11 | 12 | ## 问题 13 | 14 | ​ 均衡器是一种按照一定的规律,把人耳可听的频率`20Hz~20000Hz`划分为若干的频段,每个频段用户可以进行增益调节。可以根据需要,对输入的音频信号按照特定的频段进行单独的增益或衰减,实现各种音效效果。市场上常见的数字音频均衡器缺点是频率带宽都是固定不变,能实现的音效效果相对较少。为了用户可以体验更多的音效效果,本方案设计了一种的数字音频均衡器的频带是可变的,可以实现更多的音效效果。 15 | 16 | ## 现状 17 | 18 | ​ 现有方案一,是10个中心频点为:`31Hz,63Hz,125Hz, 250Hz, 500Hz, 1000Hz, 2000Hz, 4000Hz, 8000Hz, 16000Hz`,按一倍频程公式计算各个频段的边界频率,然后设计各频段的滤波器,最后级联增益调节器再并接起来就构成了10段均衡器。 19 | 20 | ​ 倍频程是指`20Hz`到`20000Hz`的声频范围分为几个频带,频带的上限频率比下限频率高一倍,即频率之比为2,这样划分的每一个频程称1倍频程,简称倍频程。如果在一个倍频程的上、下限频率之间再插入两个频率,使 4个频率之间的比值相同。这样将一个倍频程划分为3个频程,称这种频程为1/3倍频程。30段均衡器就是1/3倍频程均衡器。两个频率相比为2的声音间的频程,一倍频程之间为八度的音高关系,即频率每增加一倍,音高增加一个倍频程。频程的上限频率为`fu`,下限频率为`f1`,中心频率值为`f0`,则上下限频率之差值为*△f*,亦称为频带宽度。 21 | 22 | ​ 现有方案二,是10个中心频点为:`60HZ`, `170Hz`,` 310Hz`, `600Hz`, `1KHz`, `3KHz`,` 6KHz`, `12KHz`,`14KHz`, `16KHz`,依据频率的音感特征设计各滤波器频段,最后级联增益调节器再并接起来就构成了10段均衡器。 23 | 24 | ​ 频率的音感特征有如下几种,`30~60Hz` 频段影响声音的音色空间感;`60~100Hz `频段影响声音的混厚感,是低音的基音区;`100~200Hz` 频段影响声音的厚实感,有底气;`200-500Hz` 频段影响声音的厚度和力度,好则人声明亮、清晰,否则单薄、混浊;`500-1KHz` 频段影响声音的明朗度;`1K-2KHz` 频段影响声音的明亮度,过多会使声音发硬;`2K-4Kz` 频段影响声音的亮度影响很大,对音乐的层次影响较大;`4K-8KzHz` 频段影响声音的清晰度、明亮度、如果这频率成分缺少,音色则变得平平淡淡;如果这段频率成分过多,音色则变得尖锐;`8k-12kHz` 频段影响声音的高音区,对音响的高频表现感觉最为敏感;`12k-16kHz` 频段影响声音的整体色彩感,这段过于黯淡会导致乐器失去个性,过多则会产生毛刺感;`16k-20kHz` 频段影响声音的高频的亮度,以及整体的空间感。 25 | 26 | 27 | 28 | ## 技术方案 29 | 30 | ​ 本方案设计一种的数字音频均衡器的频带是可变的,均衡器可以生成更多的音效效果。根据不同的音效效果,自动调节均衡器的频率带宽和增益,如图3所示。均衡器使用FIR滤波器进行各频段数据过滤,由上限截止频率和下限截止频率生成频率带宽。 31 | 32 | ```mermaid 33 | sequenceDiagram 34 | Note over 音频流 : 打开音频文件 35 | Note over 音频流 : 音频解码器 36 | Note over 音频流 : 获取PCM数据 37 | 38 | 音频流 ->> 均衡器音效效果 : 音频帧 39 | Note over 均衡器音效效果 : 获取音效效果 40 | Note over 均衡器音效效果 : 更新均衡器频率带宽 41 | Note over 均衡器音效效果 : 设置各个频带增益 42 | 43 | 均衡器音效效果 ->> 音频播放 : 数据合成 44 | Note over 音频播放 : 各滤波数据的加权求和 45 | Note over 音频播放 : 推送音频服务 46 | Note over 音频播放 : 音乐播放 47 | ``` 48 | 49 |
图-3 技术方案
50 | 51 | ### 整体设计 52 | 53 | ​ 本方案的数字音频均衡器,使用2种默认频率带宽,分别是倍频程频率带宽和频率的音感特征频率带宽。可调频率带宽的均衡器,能实现更多的均衡器音效效果 。也可以按照其他的规律,设计频率带宽,来扩展均衡器音效效果。均衡器是由10个FIR带通滤波器并联而成的滤波器组构成。这些构成均衡器的滤波器带宽都是根据不同的音效效果进行设置的。用户通过选择均衡音效效果改变整体频响。数字音频均衡器实现流程,如图4所示。 54 | 55 | ![](附件/EQYX.jpg) 56 | 57 |
图-4 均衡器整体设计
58 | 59 | #### 均衡器工作原理 60 | 61 | ​  音频解码的`PCM `数据,是一个一个采样点顺序存放的方式存储,转换时只要逐个对采样数据进行转换即可。离散傅里叶变换需要对原始的连续信号进行离散化,原始信号离散化的过程其实就是以一定的采样周期对原始信号进行采样的过程。脉冲编码调制技术对音频信号的处理方式,连续的声音信号(模拟信号),通过采样,变成一个一个采样数据(数字信号)。如果采样周期是 `44100Hz`,则一秒钟的的声音会变成 44100 个采样数据。均衡器音效实现流程,如图5所示。 62 | 63 | ```mermaid 64 | sequenceDiagram 65 | Note over 音频帧 : PCM数据缓存 66 | Note over 音频帧 : PCM数据处理 67 | 音频帧 ->> 均衡器音效处理 : 数据过滤 68 | Note over 均衡器音效处理 : 音频数据进行分解 69 | Note over 均衡器音效处理 : 获取采样点数据 70 | Note over 均衡器音效处理 : FIR滤波器滤波 71 | Note over 均衡器音效处理 : 各滤数据乘以增益系数 72 | Note over 均衡器音效处理 : 音频数据进行合成 73 | 均衡器音效处理 ->> 音频播放 : 数据读取 74 | Note over 音频播放 : 写入播放缓存区 75 | 76 | ``` 77 | 78 |
图-5 均衡器音效处理
79 | 80 | #### 均衡器频带数据 81 | 82 | ​ 傅里叶变换是指任何连续周期信号可以由一组适当的正弦曲线组合而成,这个转换就称为傅里叶转换。离散时间傅里叶变换在时域是离散的,但是在频域是连续的,而离散傅里叶变换则在时域和频域都以离散的形式呈现,因此,离散傅里叶变换更适用于所有使用计算机处理数据的场合。均衡器频带数据,是使用一段窗口函数与原信号中等大的一部分进行卷积。时域上的乘积等于频域上的卷积,使用窗口函数来处理源信号,卷积完这第一部分后时间后移一位,继续卷积,并把结果累加到输出信号中。均衡器频带数据处理,如图6所示 83 | 84 | ```mermaid 85 | sequenceDiagram 86 | Note over 均衡器数据处理 : 滤波系数乘以采样点 87 | Note over 均衡器数据处理 : 数据和叠加 88 | Note over 均衡器数据处理 : 采样数据更新 89 | Note over 均衡器数据处理 : 循环执行N次 90 | Note over 均衡器数据处理 : 卷积数据 91 | 均衡器数据处理 ->> 均衡器频带增益: 数据过滤 92 | Note over 均衡器频带增益 : 滤波数据乘以增益系数 93 | 均衡器频带增益 ->> 均衡器数据合成: 数据合成 94 | Note over 均衡器数据合成 : 各滤波器数据叠加 95 | Note over 均衡器数据合成 : 输出音频播放 96 | 97 | ``` 98 | 99 |
图-6 滤波器数据过滤
100 | 101 | ### 关键技术 102 | 103 | #### FIR数字滤波原理 104 | 105 | ​ 本方案数字音频均衡器是由10个FIR带通滤波器并联而成的滤波器组构成。滑动平均滤波器是每一次新的数据进来都在窗口进行一次平局然后输出。滑动平均滤波器也是FIR滤波器的一种,如图7所示。 106 | 107 | ![](附件/FIRfilter01.png) 108 | 109 |
图-7 3点滑动平均滤波器
110 | 111 | ​ 在这个滤波器中,可以看到每次把前三个数据进行平均(分别乘以0.33333)然后输出。 这三个系数的不同组合(0.3333, 0.333, 0.3333)就组成了各种FIR滤波器。这些系数叫做滤波系数。 在`matlab`中,他们叫做 b,滤波系数。下面是一个滑动平均滤波器的例子,使用plot函数绘制图形显示,如图8所示。 112 | 113 | ```matlab 114 | npts=1000; 115 | b=[.2 .2 .2 .2 .2]; % create filter coefficients for 5- point moving average 116 | 117 | x=(rand(npts,1)*2)-1; % raw data from -1 to +1 118 | filtered_data=filter(b,1,x); % filter using 'b' coefficients 119 | 120 | subplot(2,2,1); % 1st subplot 121 | plot(x); % plot raw data 122 | title('Raw Data'); 123 | subplot(2,2,3); % 2nd subplot 124 | plot(filtered_data); %plot filtered data 125 | title('Filtered Data'); 126 | xlabel('Time') 127 | 128 | % Perform FFT on original and filtered signal 129 | fftpts=npts; % number points in FFT 130 | hpts=fftpts/2; % half number of FFT points 131 | x_fft=abs(fft(x))/hpts; %scaled FFT of original signal 132 | filtered_fft=abs(fft(filtered_data))/hpts; %scaled FFT of filtered signal 133 | 134 | subplot(2,2,2) %1st subplot 135 | plot(x_fft(1:hpts)); %plot first half of data points 136 | title('Raw Data'); 137 | subplot(2,2,4) %2nd subplot 138 | plot(filtered_fft(1:hpts));%plot first half data points 139 | title('Filtered Data'); 140 | xlabel('Frequency'); 141 | ``` 142 | 143 | ​ 左边是原始数据和过滤数据,在时域的对比,右边是原始数据和过滤数据,在频域的对比。 144 | 145 | ![](附件/FIRfilter02.png) 146 | 147 |
图-8 FIR低通滤波器
148 | 149 | ​ 滑动平均滤波器 一开始滤波的时候没有之前的数据做平均, filter函数是这样计算的 150 | 151 |
filtered_data(2) = x(1)*0.2 + x(2)*0.2
152 | 153 | ​ 整体的5点滑动滤波的计算公式是: 154 | 155 |
filtered_data(n) = b(1)*x(n) + b(2)*x(n-1) + b(3)*x(n-2) + b(4)*x(n-3) + b(5)*x(n-4)
156 | 157 | 158 | 159 | ​ 如果滤波器的阶数太大(N) 那么滤波后的数据要比原始信号"迟缓" 很多,这叫做相位延时。上图可以看出,5点滑动平均滤波器会使高频分量衰减。这是一种低通滤波器, 通低频,阻高频。FIR滤波器基本结构,如图9所示。 160 | 161 | ![](附件/FIRfilter03.png) 162 | 163 |
图-9 FIR滤波器基本结构
164 | 165 | #### 代码实现FIR滤波器 166 | 167 | `MATLAB`的`FIR1`功能,设计的FIR带通滤波器的系数, 根据上限频率和下限频率设计的FIR带通滤波器代码如下 168 | 169 | ```matlab 170 | function y = bandpassFilter(a, b) 171 | %BANDPASS Returns a discrete-time filter object. 172 | 173 | % MATLAB Code 174 | % Generated by MATLAB(R) 9.7 and DSP System Toolbox 9.9. 175 | % Generated on: 15-Mar-2021 21:03:40 176 | 177 | % FIR Window Bandpass filter designed using the FIR1 function. 178 | 179 | % All frequency values are in Hz. 180 | Fs = 44100; % 采样频率 181 | 182 | N = 99; % 滤波阶数 183 | Fc1 = a; % 上限频率 184 | Fc2 = b; % 下限频率 185 | flag = 'scale'; % 采样标志 186 | % Create the window vector for the design algorithm. 187 | win = hamming(N+1); % 海明窗 188 | 189 | % Calculate the coefficients using the FIR1 function. 190 | y = fir1(N, [Fc1 Fc2]/(Fs/2), 'bandpass', win, flag); 191 | end 192 | ``` 193 | 194 | 借助`MATLAB® Coder™` 从` MATLAB` 代码生成 C++ 代码,如下 195 | 196 | ```matlab 197 | void EQFilterGroup::filterCoefficient(double Fc01, double Fc02, double b[]) 198 | { 199 | /*-------计算滤波器系数---------*/ 200 | 201 | double dv[2] = {0}; 202 | dv[0] = Fc01 / (44100 / 2); 203 | dv[1] = Fc02 / (44100 / 2); 204 | 205 | // "bandpass"; 206 | char b_cv[8] = {'b', 'a', 'n', 'd', 'p', 'a', 's', 's'}; 207 | 208 | double dv1[100] = { 209 | 0.0800, 0.0809, 0.0837, 0.0883, 0.0947, 0.1030, 0.1130, 0.1247, 0.1380, 0.1530, 210 | 0.1696, 0.1876, 0.2071, 0.2279, 0.2499, 0.2732, 0.2975, 0.3228, 0.3489, 0.3758, 211 | 0.4034, 0.4316, 0.4601, 0.4890, 0.5181, 0.5473, 0.5765, 0.6055, 0.6342, 0.6626, 212 | 0.6905, 0.7177, 0.7443, 0.7700, 0.7948, 0.8186, 0.8412, 0.8627, 0.8828, 0.9016, 213 | 0.9189, 0.9347, 0.9489, 0.9614, 0.9723, 0.9814, 0.9887, 0.9942, 0.9979, 0.9998, 214 | 0.9998, 0.9979, 0.9942, 0.9887, 0.9814, 0.9723, 0.9614, 0.9489, 0.9347, 0.9189, 215 | 0.9016, 0.8828, 0.8627, 0.8412, 0.8186, 0.7948, 0.7700, 0.7443, 0.7177, 0.6905, 216 | 0.6626, 0.6342, 0.6055, 0.5765, 0.5473, 0.5181, 0.4890, 0.4601, 0.4316, 0.4034, 217 | 0.3758, 0.3489, 0.3228, 0.2975, 0.2732, 0.2499, 0.2279, 0.2071, 0.1876, 0.1696, 218 | 0.1530, 0.1380, 0.1247, 0.1130, 0.1030, 0.0947, 0.0883, 0.0837, 0.0809, 0.0800 219 | }; 220 | 221 | // "scale"; 222 | char cv1[5] = {'s', 'c', 'a', 'l', 'e'}; 223 | 224 | double a; 225 | 226 | fir1(99, dv, b_cv, dv1, cv1, b, &a); 227 | } 228 | ``` 229 | 230 | ​ 计算机不能处理无限长度的数据,离散傅里叶变换算法只能对数据一批一批地进行变换,每次只能对限时间长度的信号片段进行分析。具体的做法就是从信号中截取一段时间的片段,然后对这个片段的信号数据进行周期延拓处理,得到虚拟的无限长度的信号,再对这个虚拟的无限长度信号进行傅里叶变换。但是信号被按照时间片截取成片段后,其频谱就会发生畸变,这种情况也称为频谱能量泄露。为了减少能量泄露,有很多截断函数对信号进行截取操作,这些截断函数称为窗函数。上面代码中的win = hamming(N+1)就是海明窗函数,hamming(100)的结果就是`dv1[100]`的数据. 231 | 232 | 根据FIR滤波的计算公式进行滤波: 233 | 234 |
filtered_data(n) = b(1)*x(n) + b(2)*x(n-1) + b(3)*x(n-2) + b(4)*x(n-3) + b(5)*x(n-4) + ... + b(100)*x(n-100)
235 | 236 | ```c++ 237 | float EQFilterGroup::band_filter_channel(float invar, float initval, int setic) 238 | { 239 | float sumnum = 0.0f; 240 | static float states[100] = {0.0f}; 241 | 242 | float znum[100] = { 243 | 0.001361345398931, 0.0007361591105546, -0.002775009118357, 0.006304868331772, 244 | 0.001040452262413, -0.0002770112131964, -0.001453722777184, -0.0007378443913672, 245 | 0.0003625284111798, -9.969769896632e-05, -0.0003263851063626, 0.001729067206534, 246 | 0.002945009923102, -0.0001962141514101, -0.003861909443325, -0.002472950918829, 247 | 0.0008220985349677, 3.383796188636e-05, -0.001098566606894, 0.003641557546842, 248 | 0.00757618885114, 0.0008736684395685, -0.008768647170994, -0.006837901243826, 249 | 0.001361345398931, 0.0007361591105546, -0.002775009118357, 0.006304868331772, 250 | 0.01656674268137, 0.004697153863227, -0.01723797336878, -0.01645728383034, 251 | 0.001387894104364, 0.00282101365825, -0.006049185931793, 0.009777777896249, 252 | 0.03466852746827, 0.01581700040377, -0.03358563196718, -0.04046909418586, 253 | -0.0009471368037346, 0.00925543066797, -0.0144442707042, 0.01689395701075, 254 | 0.09525246230802, 0.06697372840554, -0.106529672483, -0.2028415340701, 255 | -0.03938604121605, 0.2050198071024, 0.2050198071024, -0.03938604121605, 256 | -0.2028415340701, -0.106529672483, 0.06697372840554, 0.09525246230802, 257 | 0.01689395701075, -0.0144442707042, 0.00925543066797, -0.0009471368037346, 258 | -0.04046909418586, -0.03358563196718, 0.01581700040377, 0.03466852746827, 259 | 0.009777777896249, -0.006049185931793, 0.00282101365825, 0.001387894104364, 260 | -0.01645728383034, -0.01723797336878, 0.004697153863227, 0.01656674268137, 261 | 0.006304868331772, -0.002775009118357, 0.0007361591105546, 0.001361345398931, 262 | -0.006837901243826, -0.008768647170994, 0.0008736684395685, 0.00757618885114, 263 | 0.003641557546842, -0.001098566606894, 3.383796188636e-05, 0.0008220985349677, 264 | -0.002472950918829, -0.003861909443325, -0.0001962141514101, 0.002945009923102, 265 | 0.001729067206534, -0.0003263851063626, -9.969769896632e-05, 0.0003625284111798, 266 | -0.0007378443913672, -0.001453722777184, -0.0002770112131964, 0.001040452262413, 267 | 0.0007788265053118, -7.741730824063e-05, -9.112622961418e-05, 0.000187889002521 268 | }; 269 | 270 | // 滤波器计算 271 | for (int i = 99; i > 0; --i) { 272 | states[i] = states[i - 1]; // 左移历史状态 273 | } 274 | states[0] = invar; // 更新最新输入值 275 | 276 | for (int i = 0; i < 100; ++i) { 277 | sumnum += states[i] * znum[i]; // 滤波器卷积计算 278 | } 279 | 280 | return sumnum * 0.4f; // 输出加权结果 281 | } 282 | 283 | ``` 284 | 285 | #### 均衡器音效实现 286 | 287 | ​ 数字音频均衡器由10个带通滤波器并联而成的滤波器组构成。这些构成均衡器的滤波器的频率带宽根据不同的音效改变,每个滤波器后接一个增益调节器,总输出为各个滤波器的加权求和,如图10所示。用户通过调节每个滤波器的输出增益,来改变均衡器的整体频响。 288 | 289 | ​ 增益dB的定义与倍数换算如下,信号放大输出与输入的比值为放大倍数,单位“倍”,如10倍放大器,100倍放大器。当改用“分贝”做单位时,放大倍数就称之为增益。功率放大倍数分贝数定义:`K=10lg(Po/Pi)`,其中K为放大倍数的分贝数,Po为放大信号输出,Pi为信号输入;K>0说明信号被放大,K=0信号直通,K<0说明信号被衰减;增益为`0dB`时,信号直通,未经放大;增益为`1dB`时,实际放大倍数约为1.33. 290 | 291 | ![](附件/EQFIR.png) 292 | 293 |
图-10 数据加权求和
294 | 295 | ​ 均衡器效果实现代码如下,decode_channel函数功能是把数据包分解成音频帧,`bandGain`是频段数据增益系数,band_filter_channel函数是频段数据过滤,encode_channel函数是把音频帧转化为音频数据包。 296 | 297 | ```c++ 298 | QBuffer *EQFilterGroup::filter(const QAudioBuffer &buffer) 299 | { 300 | QVector channel1; 301 | QVector channel2; 302 | decode_channel(channel1, channel2, buffer); 303 | QVector filtered_channel1; 304 | 305 | for (auto i = 0; i < channel1.count() ; ++i) { 306 | float left = bandGain_01 * band_filter_channel(channel1[i], 0, 1) + 307 | bandGain_02 * band_filter_channel(channel1[i], 0, 2) + 308 | bandGain_03 * band_filter_channel(channel1[i], 0, 3) + 309 | bandGain_04 * band_filter_channel(channel1[i], 0, 4) + 310 | bandGain_05 * band_filter_channel(channel1[i], 0, 5) + 311 | bandGain_06 * band_filter_channel(channel1[i], 0, 6) + 312 | bandGain_07 * band_filter_channel(channel1[i], 0, 7) + 313 | bandGain_08 * band_filter_channel(channel1[i], 0, 8) + 314 | bandGain_09 * band_filter_channel(channel1[i], 0, 9) + 315 | bandGain_10 * band_filter_channel(channel1[i], 0, 10); 316 | 317 | filtered_channel1.append(left); 318 | } 319 | 320 | QByteArray array; 321 | encode_channel(filtered_channel1, filtered_channel2, array); 322 | auto qb = new QBuffer(); 323 | qb->setData(array); 324 | return qb; 325 | } 326 | ``` 327 | 328 | ​ 倍频程是指`20Hz`到`20000Hz`的声频范围分为几个频带,频带的上限频率比下限频率高一倍,即频率之比为2,这样划分的每一个频程称1倍频程,简称倍频程。一倍频程之间为八度的音高关系,即频率每增加一倍,音高增加一个倍频程。根据1倍频程设计的10个滤波器频率带宽,如图11所示,不同频段增益的音效效果如图12所示,实现了20种不同音效效果。 329 | 330 | | 段号 | 上截止频率(HZ) | 下截止频率(HZ) | 带宽(HZ) | 331 | | :--: | :------------: | :------------: | :------: | 332 | | 1 | 21 | 42 | 21 | 333 | | 2 | 42 | 85 | 42 | 334 | | 3 | 85 | 170 | 85 | 335 | | 4 | 170 | 339 | 169 | 336 | | 5 | 339 | 679 | 340 | 337 | | 6 | 679 | 1385 | 679 | 338 | | 7 | 1385 | 2715 | 1357 | 339 | | 8 | 2715 | 5431 | 2716 | 340 | | 9 | 5431 | 10861 | 5430 | 341 | | 10 | 10861 | 21722 | 10861 | 342 | 343 |
图-11 1倍频程设计滤波器带宽
344 | 345 | | 段号 | 音乐风格 | 1-10频段预设增益(dB) | 346 | | :------: | :-----------------------------: | :-----------------------------: | 347 | | 1 | 默认 | { 0,0,0, 0,0,0,0,0,0,0 } | 348 | | 2 | 大型俱乐部| { 0,0,0, 1,2,3,3,2, 1,0 } | 349 | | 3 | 舞蹈 | {9,8,5,2, 1,0,-3,-4,-3, 0 } | 350 | | 4 | 全低音 | {8,8,8, 7,4,0,-3,-5,-7,-9 }; | 351 | | 5 | 全高音 | { -9,-8,-7,-6,-3,1,5,8,10, 12 } | 352 | | 6 | 流行乐 | {-2,-1, 0,2,3,2,0,-2,-2,-1} | 353 | | 7 | 演唱 | {6,5,2,-2,-5,-2,0,3,5, 6} | 354 | | 8 | 神韵 | { 2, 1,0,0,-1,0,1.23.4} | 355 | | 9 | 演播室 | { 8,7,6,3,2, 0,-1,-2,-1,0 } | 356 | | 10 | 民谣 | { 4,4,3,2, 0,0,0,0,0,4 } | 357 | | 11 | 现场 | { 4,2,0,-3,-6,-6,-3,0,1,3 } | 358 | | 12 | 舞曲 | { 7,6,3,0,0,-4,-6,-6,0,0 } | 359 | | 13 | 蓝调 | { 3,6,8,3,-2,0,4,7,9,10 } | 360 | | 14 | 古风 | { 0,0,0,0,0,0,-6,-6,-6,-8 } | 361 | | 15 | 爵士 | { 0,0,1,4,4,4,0,1,3,3 } | 362 | | 16 | 慢歌 | { 5,4,2,0,-2,0,3,6,7,8 } | 363 | | 17 | 电子管 | { 6,5,0,-5,-4,0,6,8,8,7 } | 364 | | 18 | 舞台 | { 7,4,-4,7,-2,1,5,7,9,9 } | 365 | | 19 | 乡村 | { 5,6,2,-5,1,1,-5,3,8,5 } | 366 | | 20 | 人声 | { -2,-1,-1,0,3,4,3,0,0,1 } | 367 | 368 |
图-12 1倍频程实现的音效效果
369 | 370 | ​ 频率的音感特征,`30~60Hz` 频段影响声音的音色空间感;`60~100Hz `频段影响声音的混厚感,是低音的基音区;`100~200Hz` 频段影响声音的厚实感,有底气;`200-500Hz` 频段影响声音的厚度和力度,好则人声明亮、清晰,否则单薄、混浊;`500-1KHz` 频段影响声音的明朗度;`1K-2KHz` 频段影响声音的明亮度,过多会使声音发硬;`2K-4Kz` 频段影响声音的亮度影响很大,对音乐的层次影响较大;`4K-8KzHz` 频段影响声音的清晰度、明亮度、如果这频率成分缺少,音色则变得平平淡淡;如果这段频率成分过多,音色则变得尖锐;`8k-12kHz` 频段影响声音的高音区,对音响的高频表现感觉最为敏感;`12k-16kHz` 频段影响声音的整体色彩感,这段过于黯淡会导致乐器失去个性,过多则会产生毛刺感;`16k-20kHz` 频段影响声音的高频的亮度,以及整体的空间感。根据频率的音感特征设计的10个滤波器频率带宽,如图13所示,不同频段增益的音效效果如图14所示,实现了16种不同音效效果。 371 | 372 | | 段号 | 上截止频率(HZ) | 下截止频率(HZ) | 带宽(HZ) | 373 | | :--: | :------------: | :------------: | :------: | 374 | | 1 | 60 | 100 | 40 | 375 | | 2 | 100 | 200 | 100 | 376 | | 3 | 200 | 500 | 300 | 377 | | 4 | 500 | 1000 | 500 | 378 | | 5 | 1000 | 2000 | 1000 | 379 | | 6 | 2000 | 4000 | 2000 | 380 | | 7 | 4000 | 8000 | 4000 | 381 | | 8 | 8000 | 12000 | 4000 | 382 | | 9 | 12000 | 16000 | 4000 | 383 | | 10 | 16000 | 20000 | 4000 | 384 | 385 |
图-13 音感特征设计滤波器带宽
386 | 387 | | 段号 | 音乐风格 | 1-10频段预设增益(dB) | 388 | | :--: | :------: | :-------------------------------------: | 389 | | 1 | 古典 | {0, 0, 0, 0, 0, 0, -7, -7, -7, -9} | 390 | | 2 | 俱乐部 | {0, 0, 8, 5, 5, 5, 3, 0, 0, 0} | 391 | | 3 | 舞曲 | {9, 7, 2, 0, 0, -5, -7, -7, 0, 0} | 392 | | 4 | 全低音 | {-8, 9, 9, 5, 1, -4, -8, -10, -11, -11} | 393 | | 5 | 全高音 | {-9, -9, -9, -4, 2, 11, 16, 16, 16, 16} | 394 | | 6 | 耳机 | {4, 11, 5, -3, -2, 1, 4, 9, 12, 14} | 395 | | 7 | 大厅 | {10, 10, 5, 5, 0, -4, -4, -4, 0, 0} | 396 | | 8 | 实况 | {-4, 0, 4, 5, 5, 5, 4, 2, 2, 2} | 397 | | 9 | 聚会 | {7, 7, 0, 0, 0, 0, 0, 0, 7, 7} | 398 | | 10 | 流行 | {-1, 4, 7, 8, 5, 0, -2, -2, -1, -1} | 399 | | 11 | 雷鬼 | {0, 0, 0, -5, 0, 6, 6, 0, 0, 0} | 400 | | 12 | 摇滚 | { 8, 4, -5, -8, -3, 4, 8, 11, 11, 11} | 401 | | 13 | 斯卡 | {-2, -4, -4, 0, 4, 5, 8, 9, 11, 9} | 402 | | 14 | 柔和 | {4, 1, 0, -2, 0, 4, 8, 9, 11, 12} | 403 | | 15 | 慢摇 | {4, 4, 2, 0, -4, -5, -3, 0, 2, 8} | 404 | | 16 | 电子乐 | {8, 5, 0, -5, -4, 0, 8, 9, 9, 8} | 405 | 406 |
图-14 音感特征设计实现的音效效果
407 | 408 | ## 实验验证 409 | 410 | 1. 首先最重要的是提供这个滤波器组, 一个滤波器组调节10段滤波器各频段的增益,代码如下。   411 | 412 | 413 | ```cpp 414 | for (auto i = 0; i < channel1.count() ; ++i) { 415 | float left = _FC_HZ_32 * band_filter_channel(channel1[i], 0, 1) + 416 | _FC_HZ_63 * band_filter_channel(channel1[i], 0, 2) + 417 | _FC_HZ_125 * band_filter_channel(channel1[i], 0, 3) + 418 | _FC_HZ_250 * band_filter_channel(channel1[i], 0, 4) + 419 | _FC_HZ_500 * band_filter_channel(channel1[i], 0, 5) + 420 | _FC_HZ_1000 * band_filter_channel(channel1[i], 0, 6) + 421 | _FC_HZ_2000 * band_filter_channel(channel1[i], 0, 7) + 422 | _FC_HZ_4000 * band_filter_channel(channel1[i], 0, 8) + 423 | _FC_HZ_8000 * band_filter_channel(channel1[i], 0, 9) + 424 | _FC_HZ_16000 * band_filter_channel(channel1[i], 0, 10); 425 | 426 | filtered_channel1.append(left); 427 | } 428 | ``` 429 | 2. 数字音频均衡器是对音频流进行处理,使用Qt的`QAudioOutput`进行音频流播放代码如下。 430 | 431 | ```cpp 432 | QFile sourceFile; 433 | QAudioOutput *audio = new QAudioOutput(this); 434 | sourceFile.setFileName("/tmp/test.raw"); 435 | sourceFile.open(QIODevice::ReadOnly); 436 | 437 | QAudioFormat format; 438 | format.setSampleRate(8000); 439 | format.setChannelCount(1); 440 | format.setSampleSize(8); 441 | format.setCodec("audio/pcm"); 442 | format.setByteOrder(QAudioFormat::LittleEndian); 443 | format.setSampleType(QAudioFormat::UnSignedInt); 444 | 445 | QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice()); 446 | if (!info.isFormatSupported(format)) { 447 | qWarning() << "Raw audio format not supported by backend, cannot play audio."; 448 | return; 449 | } 450 | 451 | audio = new QAudioOutput(format, this); 452 | audio->start(&sourceFile); 453 | ``` 454 | 3. `QAudioOutput`这个组件设置好播放的音频格式参数,然后提供一个音频流就可以播放这个音频流了,在Qt里面所有的数据流都被抽象称为了`QIODevice`, 当然音频流也不例外,代码片段中的`sourceFile`就是一个音频文件数据流,它是`QIODevice`的子类。封装的类需要继承`QIODevice`然后实现对应的接口并且集成`EQFilterGroup`的滤波功能就可以实现一个可以滤波的`QIODevice` ,如下所示. 455 | 456 | ```cpp 457 | class AudioBufferDevice : public QIODevice 458 | { 459 | Q_OBJECT 460 | public: 461 | explicit AudioBufferDevice(QAudioDecoder *decoder, EQFilterGroup* filter, QObject *parent = nullptr); 462 | virtual bool atEnd() const override; 463 | virtual qint64 bytesAvailable() const override; 464 | 465 | protected: 466 | virtual qint64 readData(char* data, qint64 size) override; 467 | virtual qint64 writeData(const char *data, qint64 maxSize); 468 | 469 | private: 470 | QAudioDecoder* _decoder; 471 | QQueue _queue; 472 | QQueue _abuffer_queue; 473 | EQFilterGroup* _filter; 474 | bool _isFinished; 475 | }; 476 | ``` 477 | 478 | 4. 播放的是`mp3`文件,所以我们首先要通过`QAudioDecoder`来将`mp3`文件解码成音频帧,然后将音频帧输入滤波器组,滤波器组将滤波后的音频帧写入一个缓冲区内,并且通过`QIODevice::readData`接口向外界提供这些滤波后音频帧的数据流。当然,出于性能考虑,从`QAudioDecoder`解码到`EQFilterGroup`将滤波后数据写入缓冲池这一个过程也可以放入另一个线程中进行,如下所示。 479 | 480 | ```c++ 481 | qint64 AudioBufferDevice::readData(char *data, qint64 size) 482 | { 483 | if (_queue.empty() && _abuffer_queue.empty()) { 484 | return 0; 485 | } 486 | 487 | if (_queue.empty()) { 488 | QAudioBuffer *buffer = _abuffer_queue.first(); 489 | QBuffer *qb = _filter->filter(*buffer); 490 | _queue.push_back(qb); 491 | _abuffer_queue.removeFirst(); 492 | delete buffer; 493 | } 494 | 495 | QBuffer *buffer = _queue.first(); 496 | if (!buffer->isOpen()) { 497 | buffer->open(QIODevice::ReadOnly); 498 | } 499 | 500 | qint64 n = buffer->read(data, size); 501 | if (buffer->atEnd()) { 502 | _queue.removeFirst(); 503 | delete buffer; 504 | } 505 | 506 | return n; 507 | } 508 | ``` 509 | 510 | 5. 一次独立的离散傅里叶转换只能将有限个数的数据转换到频域,如果一段音频数据比较长,需要进行多次傅里叶变换,就需要对转换后的频域数据进行叠加,然后推送到声卡进行播放。时域数据显示了音频信号强度随时间变化的趋势,横坐标轴就是时间,纵坐标轴就是信号强度。时间坐标轴的分辨率由采样率 T 决定,其值为 1/T(1/T 就是采样周期)。如果采样周期是 `44100Hz`,则一秒钟的的声音会变成 44100 个采样数据。把音频流转为采样数据,如下所示。 511 | 512 | ```c++ 513 | template 514 | void decode_channel(QVector &channel1, QVector &channel2, QAudioBuffer const &buffer) 515 | { 516 | T *data = (T *)(buffer.data()); 517 | size_t len = buffer.sampleCount(); 518 | 519 | for (size_t i = 0; i < len; i += 1) { 520 | T left = data[i]; 521 | 522 | left = std::isnan(left) ? 0.0 : left; 523 | 524 | channel1.append(float(left) / std::numeric_limits::max()); 525 | } 526 | } 527 | ``` 528 | 529 | 6. 频域信号显示了音频信号强度随频率变化的趋势,横坐标轴是频率,纵坐标轴是信号强度(功率)。频率坐标轴的分辨率由时域采样率 T 和离散傅里叶转换点数 N 共同决定,其值为 T/N。因为离散傅里叶转换将时域信号一对一的转换为频域信号,也就是说,N 个时域信号转换后会得到 N 个频域信号,这 N个频域信号对应的频率范围是 0~T,所以每个频域信号的对应的频段宽度是 T/N。把采样数据合为音频帧,如下所示。 530 | 531 | ```c++ 532 | template 533 | void encode_channel(QVector const &channel1, QVector const &channel2, QByteArray &bytes) 534 | { 535 | for (size_t i = 0; i < channel1.count() ; ++i) { 536 | float left = channel1[i] > 1.0 ? 1.0 : channel1[i]; 537 | 538 | T lpcm = T(std::floor(left * std::numeric_limits::max())); 539 | bytes.append((char *)&lpcm, sizeof(lpcm)); 540 | } 541 | } 542 | ``` 543 | 544 | 7. 本方案数字音频均衡器,10段滤波器系数计算时间只需`1ms`,两种不同方案的音效切换,延时非常小,性能较好,如图15所示。 545 | 546 | ![](附件/FIRSJ01.png) 547 | 548 |
图-15 滤波器系数计算
549 | 550 | 551 | 552 | 8. 本方案数字音频均衡器,10段滤波器音频数据处理时间只需要`7ms`,相位延迟很小,如图16所示。 553 | 554 | ![](附件/FIRSJ02.png) 555 | 556 |
图-16 音效数据处理
557 | 558 | 9. `EQFilterGroup`工程目录中,`bandpassFilter`文件夹下面的代码是实现` fir1(99, dv, b_cv, dv1, cv1, b, &a)`函数,主要功能是根据带宽频率生产不同的滤波器系数。 `fdacoefs.h`头文件是10段均衡器滤波器系数。`EQFilterGroup.cpp`的代码是滤波组过滤数据的过程。程序运行结果如图17所示。 559 | 560 | ![](附件/EQSS.png) 561 | 562 |
图-17 程序运行
563 | 564 | 565 | 566 | ## 小结 567 | 568 | ​ 均衡器分为时域均衡器和频域均衡器两种类型。时域均衡器对时域音频信号通过叠加一系列滤波器实现对音色的改变,无论是传统的音响设备还是众多音乐播放软件,绝大多数都是使用时域均衡器。时域均衡器通常由一系列二次` IIR `滤波器或 FIR 滤波器串联组合而成,每个波段对应一个滤波器,各个滤波器可以单独调节,串联在一起形成最终的效果。但是,传统的 `IIR` 滤波器具有反馈回路,会出现相位偏差,而 FIR 滤波器阶数太大会造成时间延迟。另外,如果使用 `IIR` 或者 FIR 滤波器,均衡器波段越多,需要串联的滤波器的个数也越多,运算量也越大。频域均衡器是在频域内直接对指定频率的音频信号进行增益或衰减,从而达到改变音色的目的。数字音频均衡器的频率带宽是固定的,能实现的音效效果相对较少。 569 | 570 | ## 参考资料 571 | 572 | * [数字滤波器设计实践介绍](https://ww2.mathworks.cn/help/signal/ug/practical-introduction-to-digital-filter-design.html) 573 | * [数字滤波实践介绍](https://ww2.mathworks.cn/help/signal/ug/practical-introduction-to-digital-filtering.html) 574 | * [滤波器设计库](https://ww2.mathworks.cn/help/signal/ug/filter-design-gallery.html) 575 | * [滤波器设计工具简介](https://ww2.mathworks.cn/help/signal/ug/introduction-to-filter-designer.html) 576 | * [如何快速设计一个FIR滤波器](https://zhuanlan.zhihu.com/p/45520018) 577 | 578 | -------------------------------------------------------------------------------- /bandpassFilter/fir1.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // File: fir1.cpp 3 | // 4 | // MATLAB Coder version : 4.3 5 | // C/C++ source code generated on : 17-Mar-2021 14:44:58 6 | // 7 | 8 | // Include Files 9 | #include "fir1.h" 10 | #include "fir1_data.h" 11 | #include "fir1_emxutil.h" 12 | #include "fir1_initialize.h" 13 | #include "fir1_rtwutil.h" 14 | #include "firls.h" 15 | #include "rt_nonfinite.h" 16 | #include "string1.h" 17 | #include "validatestring.h" 18 | #include 19 | #include 20 | 21 | // Function Declarations 22 | static void parseOptArgs(const char varargin_1[8], const char varargin_3[5], 23 | char ftype_Value_data[], int ftype_Value_size[2], double *scaling); 24 | 25 | // Function Definitions 26 | 27 | // 28 | // Arguments : const char varargin_1[8] 29 | // const char varargin_3[5] 30 | // char ftype_Value_data[] 31 | // int ftype_Value_size[2] 32 | // double *scaling 33 | // Return Type : void 34 | // 35 | static void parseOptArgs(const char varargin_1[8], const char varargin_3[5], 36 | char ftype_Value_data[], int ftype_Value_size[2], double *scaling) 37 | { 38 | int scale_Value_size_idx_1; 39 | int kstr; 40 | char scale_Value_data[8]; 41 | static const char varargin_1_f1_Value[5] = { 'S', 'C', 'A', 'L', 'E' }; 42 | 43 | boolean_T ftypeFound; 44 | static const char varargin_2_f3_Value[8] = { 'B', 'A', 'N', 'D', 'P', 'A', 'S', 45 | 'S' }; 46 | 47 | boolean_T scaleFound; 48 | char strOption_Value_data[8]; 49 | int strOption_Value_size[2]; 50 | boolean_T equal; 51 | int exitg1; 52 | static const char b[7] = { 'N', 'O', 'S', 'C', 'A', 'L', 'E' }; 53 | 54 | static const char varargin_2_f2_Value[4] = { 'H', 'I', 'G', 'H' }; 55 | 56 | static const char varargin_2_f1_Value[3] = { 'L', 'O', 'W' }; 57 | 58 | static const char varargin_2_f4_Value[4] = { 'S', 'T', 'O', 'P' }; 59 | 60 | static const char varargin_2_f5_Value[4] = { 'D', 'C', '-', '0' }; 61 | 62 | static const char varargin_2_f6_Value[4] = { 'D', 'C', '-', '1' }; 63 | 64 | static const char b_cv[7] = { 'N', 'O', 'S', 'C', 'A', 'L', 'E' }; 65 | 66 | *scaling = 1.0; 67 | scale_Value_size_idx_1 = 5; 68 | for (kstr = 0; kstr < 5; kstr++) { 69 | scale_Value_data[kstr] = varargin_1_f1_Value[kstr]; 70 | } 71 | 72 | ftype_Value_size[0] = 1; 73 | ftype_Value_size[1] = 8; 74 | for (kstr = 0; kstr < 8; kstr++) { 75 | ftype_Value_data[kstr] = varargin_2_f3_Value[kstr]; 76 | } 77 | 78 | ftypeFound = false; 79 | scaleFound = false; 80 | validatestring(varargin_1, strOption_Value_data, strOption_Value_size); 81 | equal = false; 82 | if (5 == strOption_Value_size[1]) { 83 | kstr = 0; 84 | do { 85 | exitg1 = 0; 86 | if (kstr < 5) { 87 | if (varargin_1_f1_Value[kstr] != strOption_Value_data[kstr]) { 88 | exitg1 = 1; 89 | } else { 90 | kstr++; 91 | } 92 | } else { 93 | equal = true; 94 | exitg1 = 1; 95 | } 96 | } while (exitg1 == 0); 97 | } 98 | 99 | if (equal) { 100 | kstr = 0; 101 | } else { 102 | equal = false; 103 | if (7 == strOption_Value_size[1]) { 104 | kstr = 0; 105 | do { 106 | exitg1 = 0; 107 | if (kstr < 7) { 108 | if (b[kstr] != strOption_Value_data[kstr]) { 109 | exitg1 = 1; 110 | } else { 111 | kstr++; 112 | } 113 | } else { 114 | equal = true; 115 | exitg1 = 1; 116 | } 117 | } while (exitg1 == 0); 118 | } 119 | 120 | if (equal) { 121 | kstr = 0; 122 | } else { 123 | equal = false; 124 | if (3 == strOption_Value_size[1]) { 125 | kstr = 0; 126 | do { 127 | exitg1 = 0; 128 | if (kstr < 3) { 129 | if (varargin_2_f1_Value[kstr] != strOption_Value_data[kstr]) { 130 | exitg1 = 1; 131 | } else { 132 | kstr++; 133 | } 134 | } else { 135 | equal = true; 136 | exitg1 = 1; 137 | } 138 | } while (exitg1 == 0); 139 | } 140 | 141 | if (equal) { 142 | kstr = 1; 143 | } else if (string_eq(varargin_2_f2_Value, strOption_Value_data, 144 | strOption_Value_size)) { 145 | kstr = 1; 146 | } else { 147 | equal = false; 148 | if (8 == strOption_Value_size[1]) { 149 | kstr = 0; 150 | do { 151 | exitg1 = 0; 152 | if (kstr < 8) { 153 | if (varargin_2_f3_Value[kstr] != strOption_Value_data[kstr]) { 154 | exitg1 = 1; 155 | } else { 156 | kstr++; 157 | } 158 | } else { 159 | equal = true; 160 | exitg1 = 1; 161 | } 162 | } while (exitg1 == 0); 163 | } 164 | 165 | if (equal) { 166 | kstr = 1; 167 | } else if (string_eq(varargin_2_f4_Value, strOption_Value_data, 168 | strOption_Value_size)) { 169 | kstr = 1; 170 | } else if (string_eq(varargin_2_f5_Value, strOption_Value_data, 171 | strOption_Value_size)) { 172 | kstr = 1; 173 | } else if (string_eq(varargin_2_f6_Value, strOption_Value_data, 174 | strOption_Value_size)) { 175 | kstr = 1; 176 | } else { 177 | kstr = -1; 178 | } 179 | } 180 | } 181 | } 182 | 183 | switch (kstr) { 184 | case 0: 185 | scale_Value_size_idx_1 = strOption_Value_size[1]; 186 | kstr = strOption_Value_size[0] * strOption_Value_size[1]; 187 | if (0 <= kstr - 1) { 188 | std::memcpy(&scale_Value_data[0], &strOption_Value_data[0], kstr * sizeof 189 | (char)); 190 | } 191 | 192 | scaleFound = true; 193 | break; 194 | 195 | case 1: 196 | ftype_Value_size[0] = 1; 197 | ftype_Value_size[1] = strOption_Value_size[1]; 198 | kstr = strOption_Value_size[0] * strOption_Value_size[1]; 199 | if (0 <= kstr - 1) { 200 | std::memcpy(&ftype_Value_data[0], &strOption_Value_data[0], kstr * sizeof 201 | (char)); 202 | } 203 | 204 | ftypeFound = true; 205 | break; 206 | } 207 | 208 | b_validatestring(varargin_3, strOption_Value_data, strOption_Value_size); 209 | equal = false; 210 | if (5 == strOption_Value_size[1]) { 211 | kstr = 0; 212 | do { 213 | exitg1 = 0; 214 | if (kstr < 5) { 215 | if (varargin_1_f1_Value[kstr] != strOption_Value_data[kstr]) { 216 | exitg1 = 1; 217 | } else { 218 | kstr++; 219 | } 220 | } else { 221 | equal = true; 222 | exitg1 = 1; 223 | } 224 | } while (exitg1 == 0); 225 | } 226 | 227 | if (equal) { 228 | kstr = 0; 229 | } else { 230 | equal = false; 231 | if (7 == strOption_Value_size[1]) { 232 | kstr = 0; 233 | do { 234 | exitg1 = 0; 235 | if (kstr < 7) { 236 | if (b[kstr] != strOption_Value_data[kstr]) { 237 | exitg1 = 1; 238 | } else { 239 | kstr++; 240 | } 241 | } else { 242 | equal = true; 243 | exitg1 = 1; 244 | } 245 | } while (exitg1 == 0); 246 | } 247 | 248 | if (equal) { 249 | kstr = 0; 250 | } else { 251 | equal = false; 252 | if (3 == strOption_Value_size[1]) { 253 | kstr = 0; 254 | do { 255 | exitg1 = 0; 256 | if (kstr < 3) { 257 | if (varargin_2_f1_Value[kstr] != strOption_Value_data[kstr]) { 258 | exitg1 = 1; 259 | } else { 260 | kstr++; 261 | } 262 | } else { 263 | equal = true; 264 | exitg1 = 1; 265 | } 266 | } while (exitg1 == 0); 267 | } 268 | 269 | if (equal) { 270 | kstr = 1; 271 | } else if (string_eq(varargin_2_f2_Value, strOption_Value_data, 272 | strOption_Value_size)) { 273 | kstr = 1; 274 | } else { 275 | equal = false; 276 | if (8 == strOption_Value_size[1]) { 277 | kstr = 0; 278 | do { 279 | exitg1 = 0; 280 | if (kstr < 8) { 281 | if (varargin_2_f3_Value[kstr] != strOption_Value_data[kstr]) { 282 | exitg1 = 1; 283 | } else { 284 | kstr++; 285 | } 286 | } else { 287 | equal = true; 288 | exitg1 = 1; 289 | } 290 | } while (exitg1 == 0); 291 | } 292 | 293 | if (equal) { 294 | kstr = 1; 295 | } else if (string_eq(varargin_2_f4_Value, strOption_Value_data, 296 | strOption_Value_size)) { 297 | kstr = 1; 298 | } else if (string_eq(varargin_2_f5_Value, strOption_Value_data, 299 | strOption_Value_size)) { 300 | kstr = 1; 301 | } else if (string_eq(varargin_2_f6_Value, strOption_Value_data, 302 | strOption_Value_size)) { 303 | kstr = 1; 304 | } else { 305 | kstr = -1; 306 | } 307 | } 308 | } 309 | } 310 | 311 | switch (kstr) { 312 | case 0: 313 | if (!scaleFound) { 314 | scale_Value_size_idx_1 = strOption_Value_size[1]; 315 | kstr = strOption_Value_size[0] * strOption_Value_size[1]; 316 | if (0 <= kstr - 1) { 317 | std::memcpy(&scale_Value_data[0], &strOption_Value_data[0], kstr * 318 | sizeof(char)); 319 | } 320 | } 321 | break; 322 | 323 | case 1: 324 | if (!ftypeFound) { 325 | ftype_Value_size[0] = 1; 326 | ftype_Value_size[1] = strOption_Value_size[1]; 327 | kstr = strOption_Value_size[0] * strOption_Value_size[1]; 328 | if (0 <= kstr - 1) { 329 | std::memcpy(&ftype_Value_data[0], &strOption_Value_data[0], kstr * 330 | sizeof(char)); 331 | } 332 | } 333 | break; 334 | } 335 | 336 | equal = false; 337 | if (scale_Value_size_idx_1 == 7) { 338 | kstr = 0; 339 | do { 340 | exitg1 = 0; 341 | if (kstr < 7) { 342 | if (scale_Value_data[kstr] != b_cv[kstr]) { 343 | exitg1 = 1; 344 | } else { 345 | kstr++; 346 | } 347 | } else { 348 | equal = true; 349 | exitg1 = 1; 350 | } 351 | } while (exitg1 == 0); 352 | } 353 | 354 | if (equal) { 355 | *scaling = 0.0; 356 | } 357 | } 358 | 359 | // 360 | // Arguments : double varargin_1 361 | // const double varargin_2[2] 362 | // const char varargin_3[8] 363 | // const double varargin_4[100] 364 | // const char varargin_5[5] 365 | // double b[100] 366 | // double *a 367 | // Return Type : void 368 | // 369 | void fir1(double varargin_1, const double varargin_2[2], const char varargin_3[8], 370 | const double varargin_4[100], const char varargin_5[5], double b[100], 371 | double *a) 372 | { 373 | char ftype_Value_data[8]; 374 | int ftype_Value_size[2]; 375 | double scaling; 376 | boolean_T equal; 377 | int idx; 378 | int exitg1; 379 | double freq[6]; 380 | static const char b_cv[8] = { 'B', 'A', 'N', 'D', 'P', 'A', 'S', 'S' }; 381 | 382 | static const char cv1[4] = { 'D', 'C', '-', '0' }; 383 | 384 | int k; 385 | double N; 386 | signed char i; 387 | double magnitude[6]; 388 | static const char cv2[4] = { 'H', 'I', 'G', 'H' }; 389 | 390 | emxArray_real_T *hh; 391 | double r; 392 | emxArray_creal_T *y; 393 | if (isInitialized_fir1 == false) { 394 | fir1_initialize(); 395 | } 396 | 397 | parseOptArgs(varargin_3, varargin_5, ftype_Value_data, ftype_Value_size, 398 | &scaling); 399 | equal = false; 400 | if (ftype_Value_size[1] == 8) { 401 | idx = 0; 402 | do { 403 | exitg1 = 0; 404 | if (idx < 8) { 405 | if (ftype_Value_data[idx] != b_cv[idx]) { 406 | exitg1 = 1; 407 | } else { 408 | idx++; 409 | } 410 | } else { 411 | equal = true; 412 | exitg1 = 1; 413 | } 414 | } while (exitg1 == 0); 415 | } 416 | 417 | if (equal) { 418 | ftype_Value_size[1] = 4; 419 | ftype_Value_data[0] = 'D'; 420 | ftype_Value_data[1] = 'C'; 421 | ftype_Value_data[2] = '-'; 422 | ftype_Value_data[3] = '0'; 423 | } 424 | 425 | freq[0] = 0.0; 426 | freq[1] = varargin_2[0]; 427 | freq[2] = varargin_2[0]; 428 | freq[3] = varargin_2[1]; 429 | freq[4] = varargin_2[1]; 430 | freq[5] = 1.0; 431 | equal = false; 432 | if (ftype_Value_size[1] == 4) { 433 | idx = 0; 434 | do { 435 | exitg1 = 0; 436 | if (idx < 4) { 437 | if (ftype_Value_data[idx] != cv1[idx]) { 438 | exitg1 = 1; 439 | } else { 440 | idx++; 441 | } 442 | } else { 443 | equal = true; 444 | exitg1 = 1; 445 | } 446 | } while (exitg1 == 0); 447 | } 448 | 449 | if (!equal) { 450 | equal = false; 451 | if (ftype_Value_size[1] == 4) { 452 | idx = 0; 453 | do { 454 | exitg1 = 0; 455 | if (idx < 4) { 456 | if (ftype_Value_data[idx] != cv2[idx]) { 457 | exitg1 = 1; 458 | } else { 459 | idx++; 460 | } 461 | } else { 462 | equal = true; 463 | exitg1 = 1; 464 | } 465 | } while (exitg1 == 0); 466 | } 467 | 468 | if (!equal) { 469 | equal = true; 470 | } else { 471 | equal = false; 472 | } 473 | } else { 474 | equal = false; 475 | } 476 | 477 | idx = -1; 478 | for (k = 0; k < 3; k++) { 479 | i = static_cast(rt_remd_snf(static_cast(k) + 480 | static_cast(equal), 2.0)); 481 | idx++; 482 | magnitude[idx] = i; 483 | idx++; 484 | magnitude[idx] = i; 485 | } 486 | 487 | N = varargin_1; 488 | if ((!(varargin_1 != rt_roundd_snf(varargin_1))) && (!(varargin_1 <= 0.0)) && 489 | (magnitude[5] != 0.0)) { 490 | if (rtIsNaN(varargin_1) || rtIsInf(varargin_1)) { 491 | r = rtNaN; 492 | } else { 493 | r = std::fmod(varargin_1, 2.0); 494 | } 495 | 496 | if (r == 1.0) { 497 | N = varargin_1 + 1.0; 498 | } 499 | } 500 | 501 | emxInit_real_T(&hh, 2); 502 | firls((N + 1.0) - 1.0, freq, magnitude, hh); 503 | for (idx = 0; idx < 100; idx++) { 504 | b[idx] = hh->data[idx] * varargin_4[idx]; 505 | } 506 | 507 | if (scaling != 0.0) { 508 | if (equal) { 509 | scaling = b[0]; 510 | for (k = 0; k < 99; k++) { 511 | scaling += b[k + 1]; 512 | } 513 | 514 | for (idx = 0; idx < 100; idx++) { 515 | b[idx] /= scaling; 516 | } 517 | } else { 518 | if (rtIsNaN((N + 1.0) - 1.0)) { 519 | idx = hh->size[0] * hh->size[1]; 520 | hh->size[0] = 1; 521 | hh->size[1] = 1; 522 | emxEnsureCapacity_real_T(hh, idx); 523 | hh->data[0] = rtNaN; 524 | } else if (rtIsInf((N + 1.0) - 1.0) && (0.0 == (N + 1.0) - 1.0)) { 525 | idx = hh->size[0] * hh->size[1]; 526 | hh->size[0] = 1; 527 | hh->size[1] = 1; 528 | emxEnsureCapacity_real_T(hh, idx); 529 | hh->data[0] = rtNaN; 530 | } else { 531 | idx = hh->size[0] * hh->size[1]; 532 | hh->size[0] = 1; 533 | k = static_cast(std::floor((N + 1.0) - 1.0)); 534 | hh->size[1] = k + 1; 535 | emxEnsureCapacity_real_T(hh, idx); 536 | for (idx = 0; idx <= k; idx++) { 537 | hh->data[idx] = idx; 538 | } 539 | } 540 | 541 | emxInit_creal_T(&y, 2); 542 | if (varargin_2[1] == 1.0) { 543 | scaling = 1.0; 544 | } else { 545 | scaling = (varargin_2[0] + varargin_2[1]) / 2.0; 546 | } 547 | 548 | scaling /= 2.0; 549 | idx = y->size[0] * y->size[1]; 550 | y->size[0] = 1; 551 | y->size[1] = hh->size[1]; 552 | emxEnsureCapacity_creal_T(y, idx); 553 | k = hh->size[0] * hh->size[1]; 554 | for (idx = 0; idx < k; idx++) { 555 | y->data[idx].re = scaling * (hh->data[idx] * -0.0); 556 | y->data[idx].im = scaling * (hh->data[idx] * -6.2831853071795862); 557 | } 558 | 559 | idx = y->size[1]; 560 | for (k = 0; k < idx; k++) { 561 | if (y->data[k].im == 0.0) { 562 | y->data[k].re = std::exp(y->data[k].re); 563 | y->data[k].im = 0.0; 564 | } else if (rtIsInf(y->data[k].im) && rtIsInf(y->data[k].re) && (y-> 565 | data[k].re < 0.0)) { 566 | y->data[k].re = 0.0; 567 | y->data[k].im = 0.0; 568 | } else { 569 | r = std::exp(y->data[k].re / 2.0); 570 | y->data[k].re = r * (r * std::cos(y->data[k].im)); 571 | y->data[k].im = r * (r * std::sin(y->data[k].im)); 572 | } 573 | } 574 | 575 | scaling = 0.0; 576 | N = 0.0; 577 | for (idx = 0; idx < 100; idx++) { 578 | scaling += y->data[idx].re * b[idx] - y->data[idx].im * 0.0; 579 | N += y->data[idx].re * 0.0 + y->data[idx].im * b[idx]; 580 | } 581 | 582 | emxFree_creal_T(&y); 583 | scaling = rt_hypotd_snf(scaling, N); 584 | for (idx = 0; idx < 100; idx++) { 585 | b[idx] /= scaling; 586 | } 587 | } 588 | } 589 | 590 | emxFree_real_T(&hh); 591 | *a = 1.0; 592 | } 593 | 594 | // 595 | // File trailer for fir1.cpp 596 | // 597 | // [EOF] 598 | // 599 | -------------------------------------------------------------------------------- /bandpassFilter/fir1.h: -------------------------------------------------------------------------------- 1 | // 2 | // File: fir1.h 3 | // 4 | // MATLAB Coder version : 4.3 5 | // C/C++ source code generated on : 17-Mar-2021 14:44:58 6 | // 7 | #ifndef FIR1_H 8 | #define FIR1_H 9 | 10 | // Include Files 11 | #include 12 | #include 13 | #include "rtwtypes.h" 14 | #include "fir1_types.h" 15 | 16 | // Function Declarations 17 | extern void fir1(double varargin_1, const double varargin_2[2], const char 18 | varargin_3[8], const double varargin_4[100], const char 19 | varargin_5[5], double b[100], double *a); 20 | 21 | #endif 22 | 23 | // 24 | // File trailer for fir1.h 25 | // 26 | // [EOF] 27 | // 28 | -------------------------------------------------------------------------------- /bandpassFilter/fir1_data.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // File: fir1_data.cpp 3 | // 4 | // MATLAB Coder version : 4.3 5 | // C/C++ source code generated on : 17-Mar-2021 14:44:58 6 | // 7 | 8 | // Include Files 9 | #include "fir1_data.h" 10 | #include "fir1.h" 11 | #include "rt_nonfinite.h" 12 | 13 | // Variable Definitions 14 | boolean_T isInitialized_fir1 = false; 15 | 16 | // 17 | // File trailer for fir1_data.cpp 18 | // 19 | // [EOF] 20 | // 21 | -------------------------------------------------------------------------------- /bandpassFilter/fir1_data.h: -------------------------------------------------------------------------------- 1 | // 2 | // File: fir1_data.h 3 | // 4 | // MATLAB Coder version : 4.3 5 | // C/C++ source code generated on : 17-Mar-2021 14:44:58 6 | // 7 | #ifndef FIR1_DATA_H 8 | #define FIR1_DATA_H 9 | 10 | // Include Files 11 | #include 12 | #include 13 | #include "rtwtypes.h" 14 | #include "fir1_types.h" 15 | 16 | // Variable Declarations 17 | extern boolean_T isInitialized_fir1; 18 | 19 | #endif 20 | 21 | // 22 | // File trailer for fir1_data.h 23 | // 24 | // [EOF] 25 | // 26 | -------------------------------------------------------------------------------- /bandpassFilter/fir1_emxutil.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // File: fir1_emxutil.cpp 3 | // 4 | // MATLAB Coder version : 4.3 5 | // C/C++ source code generated on : 17-Mar-2021 14:44:58 6 | // 7 | 8 | // Include Files 9 | #include "fir1_emxutil.h" 10 | #include "fir1.h" 11 | #include "rt_nonfinite.h" 12 | #include 13 | #include 14 | 15 | // Function Definitions 16 | 17 | // 18 | // Arguments : emxArray_creal_T *emxArray 19 | // int oldNumel 20 | // Return Type : void 21 | // 22 | void emxEnsureCapacity_creal_T(emxArray_creal_T *emxArray, int oldNumel) 23 | { 24 | int newNumel; 25 | int i; 26 | void *newData; 27 | if (oldNumel < 0) { 28 | oldNumel = 0; 29 | } 30 | 31 | newNumel = 1; 32 | for (i = 0; i < emxArray->numDimensions; i++) { 33 | newNumel *= emxArray->size[i]; 34 | } 35 | 36 | if (newNumel > emxArray->allocatedSize) { 37 | i = emxArray->allocatedSize; 38 | if (i < 16) { 39 | i = 16; 40 | } 41 | 42 | while (i < newNumel) { 43 | if (i > 1073741823) { 44 | i = MAX_int32_T; 45 | } else { 46 | i *= 2; 47 | } 48 | } 49 | 50 | newData = std::calloc(static_cast(i), sizeof(creal_T)); 51 | if (emxArray->data != NULL) { 52 | std::memcpy(newData, emxArray->data, sizeof(creal_T) * oldNumel); 53 | if (emxArray->canFreeData) { 54 | std::free(emxArray->data); 55 | } 56 | } 57 | 58 | emxArray->data = (creal_T *)newData; 59 | emxArray->allocatedSize = i; 60 | emxArray->canFreeData = true; 61 | } 62 | } 63 | 64 | // 65 | // Arguments : emxArray_int32_T *emxArray 66 | // int oldNumel 67 | // Return Type : void 68 | // 69 | void emxEnsureCapacity_int32_T(emxArray_int32_T *emxArray, int oldNumel) 70 | { 71 | int newNumel; 72 | int i; 73 | void *newData; 74 | if (oldNumel < 0) { 75 | oldNumel = 0; 76 | } 77 | 78 | newNumel = 1; 79 | for (i = 0; i < emxArray->numDimensions; i++) { 80 | newNumel *= emxArray->size[i]; 81 | } 82 | 83 | if (newNumel > emxArray->allocatedSize) { 84 | i = emxArray->allocatedSize; 85 | if (i < 16) { 86 | i = 16; 87 | } 88 | 89 | while (i < newNumel) { 90 | if (i > 1073741823) { 91 | i = MAX_int32_T; 92 | } else { 93 | i *= 2; 94 | } 95 | } 96 | 97 | newData = std::calloc(static_cast(i), sizeof(int)); 98 | if (emxArray->data != NULL) { 99 | std::memcpy(newData, emxArray->data, sizeof(int) * oldNumel); 100 | if (emxArray->canFreeData) { 101 | std::free(emxArray->data); 102 | } 103 | } 104 | 105 | emxArray->data = (int *)newData; 106 | emxArray->allocatedSize = i; 107 | emxArray->canFreeData = true; 108 | } 109 | } 110 | 111 | // 112 | // Arguments : emxArray_real_T *emxArray 113 | // int oldNumel 114 | // Return Type : void 115 | // 116 | void emxEnsureCapacity_real_T(emxArray_real_T *emxArray, int oldNumel) 117 | { 118 | int newNumel; 119 | int i; 120 | void *newData; 121 | if (oldNumel < 0) { 122 | oldNumel = 0; 123 | } 124 | 125 | newNumel = 1; 126 | for (i = 0; i < emxArray->numDimensions; i++) { 127 | newNumel *= emxArray->size[i]; 128 | } 129 | 130 | if (newNumel > emxArray->allocatedSize) { 131 | i = emxArray->allocatedSize; 132 | if (i < 16) { 133 | i = 16; 134 | } 135 | 136 | while (i < newNumel) { 137 | if (i > 1073741823) { 138 | i = MAX_int32_T; 139 | } else { 140 | i *= 2; 141 | } 142 | } 143 | 144 | newData = std::calloc(static_cast(i), sizeof(double)); 145 | if (emxArray->data != NULL) { 146 | std::memcpy(newData, emxArray->data, sizeof(double) * oldNumel); 147 | if (emxArray->canFreeData) { 148 | std::free(emxArray->data); 149 | } 150 | } 151 | 152 | emxArray->data = (double *)newData; 153 | emxArray->allocatedSize = i; 154 | emxArray->canFreeData = true; 155 | } 156 | } 157 | 158 | // 159 | // Arguments : emxArray_creal_T **pEmxArray 160 | // Return Type : void 161 | // 162 | void emxFree_creal_T(emxArray_creal_T **pEmxArray) 163 | { 164 | if (*pEmxArray != (emxArray_creal_T *)NULL) { 165 | if (((*pEmxArray)->data != (creal_T *)NULL) && (*pEmxArray)->canFreeData) { 166 | std::free((*pEmxArray)->data); 167 | } 168 | 169 | std::free((*pEmxArray)->size); 170 | std::free(*pEmxArray); 171 | *pEmxArray = (emxArray_creal_T *)NULL; 172 | } 173 | } 174 | 175 | // 176 | // Arguments : emxArray_int32_T **pEmxArray 177 | // Return Type : void 178 | // 179 | void emxFree_int32_T(emxArray_int32_T **pEmxArray) 180 | { 181 | if (*pEmxArray != (emxArray_int32_T *)NULL) { 182 | if (((*pEmxArray)->data != (int *)NULL) && (*pEmxArray)->canFreeData) { 183 | std::free((*pEmxArray)->data); 184 | } 185 | 186 | std::free((*pEmxArray)->size); 187 | std::free(*pEmxArray); 188 | *pEmxArray = (emxArray_int32_T *)NULL; 189 | } 190 | } 191 | 192 | // 193 | // Arguments : emxArray_real_T **pEmxArray 194 | // Return Type : void 195 | // 196 | void emxFree_real_T(emxArray_real_T **pEmxArray) 197 | { 198 | if (*pEmxArray != (emxArray_real_T *)NULL) { 199 | if (((*pEmxArray)->data != (double *)NULL) && (*pEmxArray)->canFreeData) { 200 | std::free((*pEmxArray)->data); 201 | } 202 | 203 | std::free((*pEmxArray)->size); 204 | std::free(*pEmxArray); 205 | *pEmxArray = (emxArray_real_T *)NULL; 206 | } 207 | } 208 | 209 | // 210 | // Arguments : emxArray_creal_T **pEmxArray 211 | // int numDimensions 212 | // Return Type : void 213 | // 214 | void emxInit_creal_T(emxArray_creal_T **pEmxArray, int numDimensions) 215 | { 216 | emxArray_creal_T *emxArray; 217 | int i; 218 | *pEmxArray = (emxArray_creal_T *)std::malloc(sizeof(emxArray_creal_T)); 219 | emxArray = *pEmxArray; 220 | emxArray->data = (creal_T *)NULL; 221 | emxArray->numDimensions = numDimensions; 222 | emxArray->size = (int *)std::malloc(sizeof(int) * numDimensions); 223 | emxArray->allocatedSize = 0; 224 | emxArray->canFreeData = true; 225 | for (i = 0; i < numDimensions; i++) { 226 | emxArray->size[i] = 0; 227 | } 228 | } 229 | 230 | // 231 | // Arguments : emxArray_int32_T **pEmxArray 232 | // int numDimensions 233 | // Return Type : void 234 | // 235 | void emxInit_int32_T(emxArray_int32_T **pEmxArray, int numDimensions) 236 | { 237 | emxArray_int32_T *emxArray; 238 | int i; 239 | *pEmxArray = (emxArray_int32_T *)std::malloc(sizeof(emxArray_int32_T)); 240 | emxArray = *pEmxArray; 241 | emxArray->data = (int *)NULL; 242 | emxArray->numDimensions = numDimensions; 243 | emxArray->size = (int *)std::malloc(sizeof(int) * numDimensions); 244 | emxArray->allocatedSize = 0; 245 | emxArray->canFreeData = true; 246 | for (i = 0; i < numDimensions; i++) { 247 | emxArray->size[i] = 0; 248 | } 249 | } 250 | 251 | // 252 | // Arguments : emxArray_real_T **pEmxArray 253 | // int numDimensions 254 | // Return Type : void 255 | // 256 | void emxInit_real_T(emxArray_real_T **pEmxArray, int numDimensions) 257 | { 258 | emxArray_real_T *emxArray; 259 | int i; 260 | *pEmxArray = (emxArray_real_T *)std::malloc(sizeof(emxArray_real_T)); 261 | emxArray = *pEmxArray; 262 | emxArray->data = (double *)NULL; 263 | emxArray->numDimensions = numDimensions; 264 | emxArray->size = (int *)std::malloc(sizeof(int) * numDimensions); 265 | emxArray->allocatedSize = 0; 266 | emxArray->canFreeData = true; 267 | for (i = 0; i < numDimensions; i++) { 268 | emxArray->size[i] = 0; 269 | } 270 | } 271 | 272 | // 273 | // File trailer for fir1_emxutil.cpp 274 | // 275 | // [EOF] 276 | // 277 | -------------------------------------------------------------------------------- /bandpassFilter/fir1_emxutil.h: -------------------------------------------------------------------------------- 1 | // 2 | // File: fir1_emxutil.h 3 | // 4 | // MATLAB Coder version : 4.3 5 | // C/C++ source code generated on : 17-Mar-2021 14:44:58 6 | // 7 | #ifndef FIR1_EMXUTIL_H 8 | #define FIR1_EMXUTIL_H 9 | 10 | // Include Files 11 | #include 12 | #include 13 | #include "rtwtypes.h" 14 | #include "fir1_types.h" 15 | 16 | // Function Declarations 17 | extern void emxEnsureCapacity_creal_T(emxArray_creal_T *emxArray, int oldNumel); 18 | extern void emxEnsureCapacity_int32_T(emxArray_int32_T *emxArray, int oldNumel); 19 | extern void emxEnsureCapacity_real_T(emxArray_real_T *emxArray, int oldNumel); 20 | extern void emxFree_creal_T(emxArray_creal_T **pEmxArray); 21 | extern void emxFree_int32_T(emxArray_int32_T **pEmxArray); 22 | extern void emxFree_real_T(emxArray_real_T **pEmxArray); 23 | extern void emxInit_creal_T(emxArray_creal_T **pEmxArray, int numDimensions); 24 | extern void emxInit_int32_T(emxArray_int32_T **pEmxArray, int numDimensions); 25 | extern void emxInit_real_T(emxArray_real_T **pEmxArray, int numDimensions); 26 | 27 | #endif 28 | 29 | // 30 | // File trailer for fir1_emxutil.h 31 | // 32 | // [EOF] 33 | // 34 | -------------------------------------------------------------------------------- /bandpassFilter/fir1_initialize.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // File: fir1_initialize.cpp 3 | // 4 | // MATLAB Coder version : 4.3 5 | // C/C++ source code generated on : 17-Mar-2021 14:44:58 6 | // 7 | 8 | // Include Files 9 | #include "fir1_initialize.h" 10 | #include "fir1.h" 11 | #include "fir1_data.h" 12 | #include "rt_nonfinite.h" 13 | 14 | // Function Definitions 15 | 16 | // 17 | // Arguments : void 18 | // Return Type : void 19 | // 20 | void fir1_initialize() 21 | { 22 | rt_InitInfAndNaN(); 23 | isInitialized_fir1 = true; 24 | } 25 | 26 | // 27 | // File trailer for fir1_initialize.cpp 28 | // 29 | // [EOF] 30 | // 31 | -------------------------------------------------------------------------------- /bandpassFilter/fir1_initialize.h: -------------------------------------------------------------------------------- 1 | // 2 | // File: fir1_initialize.h 3 | // 4 | // MATLAB Coder version : 4.3 5 | // C/C++ source code generated on : 17-Mar-2021 14:44:58 6 | // 7 | #ifndef FIR1_INITIALIZE_H 8 | #define FIR1_INITIALIZE_H 9 | 10 | // Include Files 11 | #include 12 | #include 13 | #include "rtwtypes.h" 14 | #include "fir1_types.h" 15 | 16 | // Function Declarations 17 | extern void fir1_initialize(); 18 | 19 | #endif 20 | 21 | // 22 | // File trailer for fir1_initialize.h 23 | // 24 | // [EOF] 25 | // 26 | -------------------------------------------------------------------------------- /bandpassFilter/fir1_rtwutil.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // File: fir1_rtwutil.cpp 3 | // 4 | // MATLAB Coder version : 4.3 5 | // C/C++ source code generated on : 17-Mar-2021 14:44:58 6 | // 7 | 8 | // Include Files 9 | #include "fir1_rtwutil.h" 10 | #include "fir1.h" 11 | #include "rt_nonfinite.h" 12 | #include 13 | #include 14 | 15 | // Function Definitions 16 | 17 | // 18 | // Arguments : double u0 19 | // double u1 20 | // Return Type : double 21 | // 22 | double rt_hypotd_snf(double u0, double u1) 23 | { 24 | double y; 25 | double a; 26 | a = std::abs(u0); 27 | y = std::abs(u1); 28 | if (a < y) { 29 | a /= y; 30 | y *= std::sqrt(a * a + 1.0); 31 | } else if (a > y) { 32 | y /= a; 33 | y = a * std::sqrt(y * y + 1.0); 34 | } else { 35 | if (!rtIsNaN(y)) { 36 | y = a * 1.4142135623730951; 37 | } 38 | } 39 | 40 | return y; 41 | } 42 | 43 | // 44 | // Arguments : double u0 45 | // double u1 46 | // Return Type : double 47 | // 48 | double rt_remd_snf(double u0, double u1) 49 | { 50 | double y; 51 | double b_u1; 52 | if (rtIsNaN(u0) || rtIsNaN(u1) || rtIsInf(u0)) { 53 | y = rtNaN; 54 | } else if (rtIsInf(u1)) { 55 | y = u0; 56 | } else { 57 | if (u1 < 0.0) { 58 | b_u1 = std::ceil(u1); 59 | } else { 60 | b_u1 = std::floor(u1); 61 | } 62 | 63 | if ((u1 != 0.0) && (u1 != b_u1)) { 64 | b_u1 = std::abs(u0 / u1); 65 | if (std::abs(b_u1 - std::floor(b_u1 + 0.5)) <= DBL_EPSILON * b_u1) { 66 | y = 0.0 * u0; 67 | } else { 68 | y = std::fmod(u0, u1); 69 | } 70 | } else { 71 | y = std::fmod(u0, u1); 72 | } 73 | } 74 | 75 | return y; 76 | } 77 | 78 | // 79 | // Arguments : double u 80 | // Return Type : double 81 | // 82 | double rt_roundd_snf(double u) 83 | { 84 | double y; 85 | if (std::abs(u) < 4.503599627370496E+15) { 86 | if (u >= 0.5) { 87 | y = std::floor(u + 0.5); 88 | } else if (u > -0.5) { 89 | y = u * 0.0; 90 | } else { 91 | y = std::ceil(u - 0.5); 92 | } 93 | } else { 94 | y = u; 95 | } 96 | 97 | return y; 98 | } 99 | 100 | // 101 | // File trailer for fir1_rtwutil.cpp 102 | // 103 | // [EOF] 104 | // 105 | -------------------------------------------------------------------------------- /bandpassFilter/fir1_rtwutil.h: -------------------------------------------------------------------------------- 1 | // 2 | // File: fir1_rtwutil.h 3 | // 4 | // MATLAB Coder version : 4.3 5 | // C/C++ source code generated on : 17-Mar-2021 14:44:58 6 | // 7 | #ifndef FIR1_RTWUTIL_H 8 | #define FIR1_RTWUTIL_H 9 | 10 | // Include Files 11 | #include 12 | #include 13 | #include "rtwtypes.h" 14 | #include "fir1_types.h" 15 | 16 | // Function Declarations 17 | extern double rt_hypotd_snf(double u0, double u1); 18 | extern double rt_remd_snf(double u0, double u1); 19 | extern double rt_roundd_snf(double u); 20 | 21 | #endif 22 | 23 | // 24 | // File trailer for fir1_rtwutil.h 25 | // 26 | // [EOF] 27 | // 28 | -------------------------------------------------------------------------------- /bandpassFilter/fir1_terminate.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // File: fir1_terminate.cpp 3 | // 4 | // MATLAB Coder version : 4.3 5 | // C/C++ source code generated on : 17-Mar-2021 14:44:58 6 | // 7 | 8 | // Include Files 9 | #include "fir1_terminate.h" 10 | #include "fir1.h" 11 | #include "fir1_data.h" 12 | #include "rt_nonfinite.h" 13 | 14 | // Function Definitions 15 | 16 | // 17 | // Arguments : void 18 | // Return Type : void 19 | // 20 | void fir1_terminate() 21 | { 22 | // (no terminate code required) 23 | isInitialized_fir1 = false; 24 | } 25 | 26 | // 27 | // File trailer for fir1_terminate.cpp 28 | // 29 | // [EOF] 30 | // 31 | -------------------------------------------------------------------------------- /bandpassFilter/fir1_terminate.h: -------------------------------------------------------------------------------- 1 | // 2 | // File: fir1_terminate.h 3 | // 4 | // MATLAB Coder version : 4.3 5 | // C/C++ source code generated on : 17-Mar-2021 14:44:58 6 | // 7 | #ifndef FIR1_TERMINATE_H 8 | #define FIR1_TERMINATE_H 9 | 10 | // Include Files 11 | #include 12 | #include 13 | #include "rtwtypes.h" 14 | #include "fir1_types.h" 15 | 16 | // Function Declarations 17 | extern void fir1_terminate(); 18 | 19 | #endif 20 | 21 | // 22 | // File trailer for fir1_terminate.h 23 | // 24 | // [EOF] 25 | // 26 | -------------------------------------------------------------------------------- /bandpassFilter/fir1_types.h: -------------------------------------------------------------------------------- 1 | // 2 | // File: fir1_types.h 3 | // 4 | // MATLAB Coder version : 4.3 5 | // C/C++ source code generated on : 17-Mar-2021 14:44:58 6 | // 7 | #ifndef FIR1_TYPES_H 8 | #define FIR1_TYPES_H 9 | 10 | // Include Files 11 | #include "rtwtypes.h" 12 | 13 | // Type Definitions 14 | struct emxArray_int32_T 15 | { 16 | int *data; 17 | int *size; 18 | int allocatedSize; 19 | int numDimensions; 20 | boolean_T canFreeData; 21 | }; 22 | 23 | struct emxArray_creal_T 24 | { 25 | creal_T *data; 26 | int *size; 27 | int allocatedSize; 28 | int numDimensions; 29 | boolean_T canFreeData; 30 | }; 31 | 32 | struct emxArray_real_T 33 | { 34 | double *data; 35 | int *size; 36 | int allocatedSize; 37 | int numDimensions; 38 | boolean_T canFreeData; 39 | }; 40 | 41 | #endif 42 | 43 | // 44 | // File trailer for fir1_types.h 45 | // 46 | // [EOF] 47 | // 48 | -------------------------------------------------------------------------------- /bandpassFilter/firls.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // File: firls.cpp 3 | // 4 | // MATLAB Coder version : 4.3 5 | // C/C++ source code generated on : 17-Mar-2021 14:44:58 6 | // 7 | 8 | // Include Files 9 | #include "firls.h" 10 | #include "fir1.h" 11 | #include "fir1_emxutil.h" 12 | #include "fir1_rtwutil.h" 13 | #include "mldivide.h" 14 | #include "rt_nonfinite.h" 15 | #include 16 | 17 | // Function Declarations 18 | static int div_s32_floor(int numerator, int denominator); 19 | 20 | // Function Definitions 21 | 22 | // 23 | // Arguments : int numerator 24 | // int denominator 25 | // Return Type : int 26 | // 27 | static int div_s32_floor(int numerator, int denominator) 28 | { 29 | int quotient; 30 | unsigned int absNumerator; 31 | unsigned int absDenominator; 32 | boolean_T quotientNeedsNegation; 33 | unsigned int tempAbsQuotient; 34 | if (denominator == 0) { 35 | if (numerator >= 0) { 36 | quotient = MAX_int32_T; 37 | } else { 38 | quotient = MIN_int32_T; 39 | } 40 | } else { 41 | if (numerator < 0) { 42 | absNumerator = ~static_cast(numerator) + 1U; 43 | } else { 44 | absNumerator = static_cast(numerator); 45 | } 46 | 47 | if (denominator < 0) { 48 | absDenominator = ~static_cast(denominator) + 1U; 49 | } else { 50 | absDenominator = static_cast(denominator); 51 | } 52 | 53 | quotientNeedsNegation = ((numerator < 0) != (denominator < 0)); 54 | tempAbsQuotient = absNumerator / absDenominator; 55 | if (quotientNeedsNegation) { 56 | absNumerator %= absDenominator; 57 | if (absNumerator > 0U) { 58 | tempAbsQuotient++; 59 | } 60 | 61 | quotient = -static_cast(tempAbsQuotient); 62 | } else { 63 | quotient = static_cast(tempAbsQuotient); 64 | } 65 | } 66 | 67 | return quotient; 68 | } 69 | 70 | // 71 | // Arguments : double varargin_1 72 | // const double varargin_2[6] 73 | // const double varargin_3[6] 74 | // emxArray_real_T *h 75 | // Return Type : void 76 | // 77 | void firls(double varargin_1, const double varargin_2[6], const double 78 | varargin_3[6], emxArray_real_T *h) 79 | { 80 | double N; 81 | int ixLead; 82 | emxArray_real_T *m; 83 | double max_freq[6]; 84 | emxArray_real_T *k; 85 | double min_freq[6]; 86 | emxArray_real_T *b; 87 | emxArray_real_T *I1; 88 | emxArray_real_T *I2; 89 | emxArray_real_T *G; 90 | emxArray_real_T *y; 91 | emxArray_real_T *a; 92 | emxArray_real_T *x; 93 | emxArray_real_T *b_x; 94 | emxArray_real_T *c_x; 95 | emxArray_real_T *d_x; 96 | emxArray_real_T *b_k; 97 | double work; 98 | int iyLead; 99 | int b_m; 100 | boolean_T fullband; 101 | double tmp2; 102 | boolean_T exitg1; 103 | double dF[5]; 104 | double L; 105 | boolean_T Nodd; 106 | double b0; 107 | int i; 108 | int loop_ub; 109 | int s; 110 | unsigned int unnamed_idx_1; 111 | int b_loop_ub; 112 | int c_loop_ub; 113 | double m_s_tmp_tmp; 114 | double b1; 115 | double b_a; 116 | N = varargin_1; 117 | for (ixLead = 0; ixLead < 6; ixLead++) { 118 | max_freq[ixLead] = varargin_2[ixLead]; 119 | min_freq[ixLead] = varargin_2[ixLead]; 120 | } 121 | 122 | emxInit_real_T(&m, 2); 123 | emxInit_real_T(&k, 1); 124 | emxInit_real_T(&b, 1); 125 | emxInit_real_T(&I1, 2); 126 | emxInit_real_T(&I2, 2); 127 | emxInit_real_T(&G, 2); 128 | emxInit_real_T(&y, 1); 129 | emxInit_real_T(&a, 1); 130 | emxInit_real_T(&x, 2); 131 | emxInit_real_T(&b_x, 2); 132 | emxInit_real_T(&c_x, 2); 133 | emxInit_real_T(&d_x, 2); 134 | emxInit_real_T(&b_k, 1); 135 | if ((!(max_freq[0] > 1.0)) && (!(min_freq[0] < 0.0))) { 136 | if ((!(varargin_1 != rt_roundd_snf(varargin_1))) && (!(varargin_1 <= 0.0)) && 137 | (varargin_3[5] != 0.0)) { 138 | if (rtIsNaN(varargin_1) || rtIsInf(varargin_1)) { 139 | work = rtNaN; 140 | } else { 141 | work = std::fmod(varargin_1, 2.0); 142 | } 143 | 144 | if (work == 1.0) { 145 | N = varargin_1 + 1.0; 146 | } 147 | } 148 | 149 | N++; 150 | for (ixLead = 0; ixLead < 6; ixLead++) { 151 | max_freq[ixLead] = varargin_2[ixLead] / 2.0; 152 | } 153 | 154 | ixLead = 1; 155 | iyLead = 0; 156 | work = 0.0; 157 | for (b_m = 0; b_m < 5; b_m++) { 158 | tmp2 = work; 159 | work = max_freq[ixLead]; 160 | dF[iyLead] = max_freq[ixLead] - tmp2; 161 | ixLead++; 162 | iyLead++; 163 | } 164 | 165 | fullband = true; 166 | ixLead = 0; 167 | exitg1 = false; 168 | while ((!exitg1) && (ixLead < 2)) { 169 | if (dF[(ixLead << 1) + 1] != 0.0) { 170 | fullband = false; 171 | exitg1 = true; 172 | } else { 173 | ixLead++; 174 | } 175 | } 176 | 177 | L = (N - 1.0) / 2.0; 178 | Nodd = (rt_remd_snf(N, 2.0) == 1.0); 179 | b0 = 0.0; 180 | if (!Nodd) { 181 | if (rtIsNaN(L)) { 182 | i = m->size[0] * m->size[1]; 183 | m->size[0] = 1; 184 | m->size[1] = 1; 185 | emxEnsureCapacity_real_T(m, i); 186 | m->data[0] = rtNaN; 187 | } else if (rtIsInf(L) && (0.0 == L)) { 188 | i = m->size[0] * m->size[1]; 189 | m->size[0] = 1; 190 | m->size[1] = 1; 191 | emxEnsureCapacity_real_T(m, i); 192 | m->data[0] = rtNaN; 193 | } else { 194 | i = m->size[0] * m->size[1]; 195 | m->size[0] = 1; 196 | loop_ub = static_cast(std::floor(L)); 197 | m->size[1] = loop_ub + 1; 198 | emxEnsureCapacity_real_T(m, i); 199 | for (i = 0; i <= loop_ub; i++) { 200 | m->data[i] = i; 201 | } 202 | } 203 | 204 | i = m->size[0] * m->size[1]; 205 | s = m->size[0] * m->size[1]; 206 | m->size[0] = 1; 207 | emxEnsureCapacity_real_T(m, s); 208 | loop_ub = i - 1; 209 | for (i = 0; i <= loop_ub; i++) { 210 | m->data[i] += 0.5; 211 | } 212 | } else if (rtIsNaN(L)) { 213 | i = m->size[0] * m->size[1]; 214 | m->size[0] = 1; 215 | m->size[1] = 1; 216 | emxEnsureCapacity_real_T(m, i); 217 | m->data[0] = rtNaN; 218 | } else if (rtIsInf(L) && (0.0 == L)) { 219 | i = m->size[0] * m->size[1]; 220 | m->size[0] = 1; 221 | m->size[1] = 1; 222 | emxEnsureCapacity_real_T(m, i); 223 | m->data[0] = rtNaN; 224 | } else { 225 | i = m->size[0] * m->size[1]; 226 | m->size[0] = 1; 227 | loop_ub = static_cast(std::floor(L)); 228 | m->size[1] = loop_ub + 1; 229 | emxEnsureCapacity_real_T(m, i); 230 | for (i = 0; i <= loop_ub; i++) { 231 | m->data[i] = i; 232 | } 233 | } 234 | 235 | i = k->size[0]; 236 | k->size[0] = m->size[1]; 237 | emxEnsureCapacity_real_T(k, i); 238 | loop_ub = m->size[1]; 239 | for (i = 0; i < loop_ub; i++) { 240 | k->data[i] = m->data[i]; 241 | } 242 | 243 | fullband = !fullband; 244 | i = static_cast(std::floor(L + 1.0)); 245 | s = I1->size[0] * I1->size[1]; 246 | I1->size[0] = i; 247 | I1->size[1] = i; 248 | emxEnsureCapacity_real_T(I1, s); 249 | ixLead = i * i; 250 | for (s = 0; s < ixLead; s++) { 251 | I1->data[s] = 0.0; 252 | } 253 | 254 | s = I2->size[0] * I2->size[1]; 255 | I2->size[0] = i; 256 | I2->size[1] = i; 257 | emxEnsureCapacity_real_T(I2, s); 258 | for (s = 0; s < ixLead; s++) { 259 | I2->data[s] = 0.0; 260 | } 261 | 262 | s = G->size[0] * G->size[1]; 263 | G->size[0] = i; 264 | G->size[1] = i; 265 | emxEnsureCapacity_real_T(G, s); 266 | loop_ub = i * i; 267 | for (i = 0; i < loop_ub; i++) { 268 | G->data[i] = 0.0; 269 | } 270 | 271 | if (fullband) { 272 | unnamed_idx_1 = static_cast(m->size[1]); 273 | loop_ub = k->size[0]; 274 | i = I1->size[0] * I1->size[1]; 275 | I1->size[0] = k->size[0]; 276 | I1->size[1] = static_cast(unnamed_idx_1); 277 | emxEnsureCapacity_real_T(I1, i); 278 | b_loop_ub = static_cast(unnamed_idx_1); 279 | for (i = 0; i < b_loop_ub; i++) { 280 | for (s = 0; s < loop_ub; s++) { 281 | I1->data[s + I1->size[0] * i] = k->data[s] + m->data[i]; 282 | } 283 | } 284 | 285 | unnamed_idx_1 = static_cast(m->size[1]); 286 | loop_ub = k->size[0]; 287 | i = I2->size[0] * I2->size[1]; 288 | I2->size[0] = k->size[0]; 289 | I2->size[1] = static_cast(unnamed_idx_1); 290 | emxEnsureCapacity_real_T(I2, i); 291 | b_loop_ub = static_cast(unnamed_idx_1); 292 | for (i = 0; i < b_loop_ub; i++) { 293 | for (s = 0; s < loop_ub; s++) { 294 | I2->data[s + I2->size[0] * i] = k->data[s] - m->data[i]; 295 | } 296 | } 297 | } 298 | 299 | if (Nodd) { 300 | if (2 > k->size[0]) { 301 | i = 0; 302 | s = 0; 303 | } else { 304 | i = 1; 305 | s = k->size[0]; 306 | } 307 | 308 | loop_ub = s - i; 309 | s = b_k->size[0]; 310 | b_k->size[0] = loop_ub; 311 | emxEnsureCapacity_real_T(b_k, s); 312 | for (s = 0; s < loop_ub; s++) { 313 | b_k->data[s] = k->data[i + s]; 314 | } 315 | 316 | i = k->size[0]; 317 | k->size[0] = b_k->size[0]; 318 | emxEnsureCapacity_real_T(k, i); 319 | loop_ub = b_k->size[0]; 320 | for (i = 0; i < loop_ub; i++) { 321 | k->data[i] = b_k->data[i]; 322 | } 323 | } 324 | 325 | i = b->size[0]; 326 | b->size[0] = k->size[0]; 327 | emxEnsureCapacity_real_T(b, i); 328 | loop_ub = k->size[0]; 329 | for (i = 0; i < loop_ub; i++) { 330 | b->data[i] = 0.0; 331 | } 332 | 333 | loop_ub = k->size[0]; 334 | b_loop_ub = k->size[0]; 335 | c_loop_ub = k->size[0]; 336 | for (b_m = 0; b_m < 3; b_m++) { 337 | s = b_m << 1; 338 | m_s_tmp_tmp = max_freq[s + 1]; 339 | work = m_s_tmp_tmp - max_freq[s]; 340 | tmp2 = (varargin_3[s + 1] - varargin_3[s]) / work; 341 | N = tmp2 * max_freq[s]; 342 | b1 = varargin_3[s] - N; 343 | if (Nodd) { 344 | b0 += b1 * work + tmp2 / 2.0 * (m_s_tmp_tmp * m_s_tmp_tmp - max_freq[s] * 345 | max_freq[s]); 346 | } 347 | 348 | i = a->size[0]; 349 | a->size[0] = k->size[0]; 350 | emxEnsureCapacity_real_T(a, i); 351 | for (i = 0; i < loop_ub; i++) { 352 | a->data[i] = 6.2831853071795862 * k->data[i]; 353 | } 354 | 355 | i = y->size[0]; 356 | y->size[0] = a->size[0]; 357 | emxEnsureCapacity_real_T(y, i); 358 | ixLead = a->size[0]; 359 | for (i = 0; i < ixLead; i++) { 360 | y->data[i] = a->data[i] * m_s_tmp_tmp; 361 | } 362 | 363 | ixLead = y->size[0]; 364 | for (iyLead = 0; iyLead < ixLead; iyLead++) { 365 | y->data[iyLead] = std::cos(y->data[iyLead]); 366 | } 367 | 368 | ixLead = a->size[0]; 369 | for (i = 0; i < ixLead; i++) { 370 | a->data[i] *= max_freq[s]; 371 | } 372 | 373 | ixLead = a->size[0]; 374 | for (iyLead = 0; iyLead < ixLead; iyLead++) { 375 | a->data[iyLead] = std::cos(a->data[iyLead]); 376 | } 377 | 378 | b_a = tmp2 / 39.478417604357432; 379 | ixLead = b->size[0]; 380 | for (i = 0; i < ixLead; i++) { 381 | b->data[i] += b_a * (y->data[i] - a->data[i]) / (k->data[i] * k->data[i]); 382 | } 383 | 384 | b_a = m_s_tmp_tmp * (tmp2 * m_s_tmp_tmp + b1); 385 | i = a->size[0]; 386 | a->size[0] = k->size[0]; 387 | emxEnsureCapacity_real_T(a, i); 388 | for (i = 0; i < b_loop_ub; i++) { 389 | a->data[i] = 2.0 * k->data[i] * m_s_tmp_tmp; 390 | } 391 | 392 | i = a->size[0]; 393 | for (iyLead = 0; iyLead < i; iyLead++) { 394 | if (std::abs(a->data[iyLead]) < 1.0020841800044864E-292) { 395 | a->data[iyLead] = 1.0; 396 | } else { 397 | tmp2 = 3.1415926535897931 * a->data[iyLead]; 398 | tmp2 = std::sin(tmp2) / tmp2; 399 | a->data[iyLead] = tmp2; 400 | } 401 | } 402 | 403 | work = max_freq[s] * (N + b1); 404 | i = y->size[0]; 405 | y->size[0] = k->size[0]; 406 | emxEnsureCapacity_real_T(y, i); 407 | for (i = 0; i < c_loop_ub; i++) { 408 | y->data[i] = 2.0 * k->data[i] * max_freq[s]; 409 | } 410 | 411 | i = y->size[0]; 412 | for (iyLead = 0; iyLead < i; iyLead++) { 413 | if (std::abs(y->data[iyLead]) < 1.0020841800044864E-292) { 414 | y->data[iyLead] = 1.0; 415 | } else { 416 | tmp2 = 3.1415926535897931 * y->data[iyLead]; 417 | tmp2 = std::sin(tmp2) / tmp2; 418 | y->data[iyLead] = tmp2; 419 | } 420 | } 421 | 422 | ixLead = b->size[0]; 423 | for (i = 0; i < ixLead; i++) { 424 | b->data[i] += b_a * a->data[i] - work * y->data[i]; 425 | } 426 | 427 | if (fullband) { 428 | i = x->size[0] * x->size[1]; 429 | x->size[0] = I1->size[0]; 430 | x->size[1] = I1->size[1]; 431 | emxEnsureCapacity_real_T(x, i); 432 | ixLead = I1->size[0] * I1->size[1]; 433 | for (i = 0; i < ixLead; i++) { 434 | x->data[i] = 2.0 * I1->data[i] * m_s_tmp_tmp; 435 | } 436 | 437 | i = x->size[0] * x->size[1]; 438 | for (iyLead = 0; iyLead < i; iyLead++) { 439 | if (std::abs(x->data[iyLead]) < 1.0020841800044864E-292) { 440 | x->data[iyLead] = 1.0; 441 | } else { 442 | x->data[iyLead] *= 3.1415926535897931; 443 | x->data[iyLead] = std::sin(x->data[iyLead]) / x->data[iyLead]; 444 | } 445 | } 446 | 447 | i = b_x->size[0] * b_x->size[1]; 448 | b_x->size[0] = I2->size[0]; 449 | b_x->size[1] = I2->size[1]; 450 | emxEnsureCapacity_real_T(b_x, i); 451 | ixLead = I2->size[0] * I2->size[1]; 452 | for (i = 0; i < ixLead; i++) { 453 | b_x->data[i] = 2.0 * I2->data[i] * m_s_tmp_tmp; 454 | } 455 | 456 | i = b_x->size[0] * b_x->size[1]; 457 | for (iyLead = 0; iyLead < i; iyLead++) { 458 | if (std::abs(b_x->data[iyLead]) < 1.0020841800044864E-292) { 459 | b_x->data[iyLead] = 1.0; 460 | } else { 461 | b_x->data[iyLead] *= 3.1415926535897931; 462 | b_x->data[iyLead] = std::sin(b_x->data[iyLead]) / b_x->data[iyLead]; 463 | } 464 | } 465 | 466 | i = c_x->size[0] * c_x->size[1]; 467 | c_x->size[0] = I1->size[0]; 468 | c_x->size[1] = I1->size[1]; 469 | emxEnsureCapacity_real_T(c_x, i); 470 | ixLead = I1->size[0] * I1->size[1]; 471 | for (i = 0; i < ixLead; i++) { 472 | c_x->data[i] = 2.0 * I1->data[i] * max_freq[s]; 473 | } 474 | 475 | i = c_x->size[0] * c_x->size[1]; 476 | for (iyLead = 0; iyLead < i; iyLead++) { 477 | if (std::abs(c_x->data[iyLead]) < 1.0020841800044864E-292) { 478 | c_x->data[iyLead] = 1.0; 479 | } else { 480 | c_x->data[iyLead] *= 3.1415926535897931; 481 | c_x->data[iyLead] = std::sin(c_x->data[iyLead]) / c_x->data[iyLead]; 482 | } 483 | } 484 | 485 | i = d_x->size[0] * d_x->size[1]; 486 | d_x->size[0] = I2->size[0]; 487 | d_x->size[1] = I2->size[1]; 488 | emxEnsureCapacity_real_T(d_x, i); 489 | ixLead = I2->size[0] * I2->size[1]; 490 | for (i = 0; i < ixLead; i++) { 491 | d_x->data[i] = 2.0 * I2->data[i] * max_freq[s]; 492 | } 493 | 494 | i = d_x->size[0] * d_x->size[1]; 495 | for (iyLead = 0; iyLead < i; iyLead++) { 496 | if (std::abs(d_x->data[iyLead]) < 1.0020841800044864E-292) { 497 | d_x->data[iyLead] = 1.0; 498 | } else { 499 | d_x->data[iyLead] *= 3.1415926535897931; 500 | d_x->data[iyLead] = std::sin(d_x->data[iyLead]) / d_x->data[iyLead]; 501 | } 502 | } 503 | 504 | b_a = 0.5 * m_s_tmp_tmp; 505 | work = 0.5 * max_freq[s]; 506 | ixLead = G->size[0] * G->size[1]; 507 | for (i = 0; i < ixLead; i++) { 508 | G->data[i] += b_a * (x->data[i] + b_x->data[i]) - work * (c_x->data[i] 509 | + d_x->data[i]); 510 | } 511 | } 512 | } 513 | 514 | if (Nodd) { 515 | i = k->size[0]; 516 | k->size[0] = b->size[0] + 1; 517 | emxEnsureCapacity_real_T(k, i); 518 | k->data[0] = b0; 519 | loop_ub = b->size[0]; 520 | for (i = 0; i < loop_ub; i++) { 521 | k->data[i + 1] = b->data[i]; 522 | } 523 | 524 | i = b->size[0]; 525 | b->size[0] = k->size[0]; 526 | emxEnsureCapacity_real_T(b, i); 527 | loop_ub = k->size[0]; 528 | for (i = 0; i < loop_ub; i++) { 529 | b->data[i] = k->data[i]; 530 | } 531 | } 532 | 533 | if (fullband) { 534 | mldiv(G, b); 535 | } else { 536 | loop_ub = b->size[0]; 537 | for (i = 0; i < loop_ub; i++) { 538 | b->data[i] *= 4.0; 539 | } 540 | 541 | if (Nodd) { 542 | b->data[0] /= 2.0; 543 | } 544 | } 545 | 546 | if (Nodd) { 547 | if (2.0 > L + 1.0) { 548 | s = 0; 549 | ixLead = 1; 550 | iyLead = -1; 551 | b_m = 0; 552 | i = 0; 553 | } else { 554 | i = static_cast((L + 1.0)); 555 | s = i - 1; 556 | ixLead = -1; 557 | iyLead = 1; 558 | b_m = 1; 559 | } 560 | 561 | c_loop_ub = h->size[0] * h->size[1]; 562 | h->size[0] = 1; 563 | loop_ub = div_s32_floor(iyLead - s, ixLead); 564 | h->size[1] = ((loop_ub + i) - b_m) + 2; 565 | emxEnsureCapacity_real_T(h, c_loop_ub); 566 | for (iyLead = 0; iyLead <= loop_ub; iyLead++) { 567 | h->data[iyLead] = b->data[s + ixLead * iyLead] / 2.0; 568 | } 569 | 570 | h->data[loop_ub + 1] = b->data[0]; 571 | b_loop_ub = i - b_m; 572 | for (i = 0; i < b_loop_ub; i++) { 573 | h->data[(i + loop_ub) + 2] = b->data[b_m + i] / 2.0; 574 | } 575 | } else { 576 | i = a->size[0]; 577 | a->size[0] = b->size[0]; 578 | emxEnsureCapacity_real_T(a, i); 579 | loop_ub = b->size[0]; 580 | for (i = 0; i < loop_ub; i++) { 581 | a->data[i] = b->data[i]; 582 | } 583 | 584 | b_m = b->size[0] - 1; 585 | iyLead = b->size[0] >> 1; 586 | for (ixLead = 0; ixLead < iyLead; ixLead++) { 587 | work = a->data[ixLead]; 588 | c_loop_ub = b_m - ixLead; 589 | a->data[ixLead] = a->data[c_loop_ub]; 590 | a->data[c_loop_ub] = work; 591 | } 592 | 593 | i = h->size[0] * h->size[1]; 594 | h->size[0] = 1; 595 | h->size[1] = a->size[0] + b->size[0]; 596 | emxEnsureCapacity_real_T(h, i); 597 | loop_ub = a->size[0]; 598 | for (i = 0; i < loop_ub; i++) { 599 | h->data[i] = 0.5 * a->data[i]; 600 | } 601 | 602 | loop_ub = b->size[0]; 603 | for (i = 0; i < loop_ub; i++) { 604 | h->data[i + a->size[0]] = 0.5 * b->data[i]; 605 | } 606 | } 607 | } 608 | 609 | emxFree_real_T(&b_k); 610 | emxFree_real_T(&d_x); 611 | emxFree_real_T(&c_x); 612 | emxFree_real_T(&b_x); 613 | emxFree_real_T(&x); 614 | emxFree_real_T(&a); 615 | emxFree_real_T(&y); 616 | emxFree_real_T(&G); 617 | emxFree_real_T(&I2); 618 | emxFree_real_T(&I1); 619 | emxFree_real_T(&b); 620 | emxFree_real_T(&k); 621 | emxFree_real_T(&m); 622 | } 623 | 624 | // 625 | // File trailer for firls.cpp 626 | // 627 | // [EOF] 628 | // 629 | -------------------------------------------------------------------------------- /bandpassFilter/firls.h: -------------------------------------------------------------------------------- 1 | // 2 | // File: firls.h 3 | // 4 | // MATLAB Coder version : 4.3 5 | // C/C++ source code generated on : 17-Mar-2021 14:44:58 6 | // 7 | #ifndef FIRLS_H 8 | #define FIRLS_H 9 | 10 | // Include Files 11 | #include 12 | #include 13 | #include "rtwtypes.h" 14 | #include "fir1_types.h" 15 | 16 | // Function Declarations 17 | extern void firls(double varargin_1, const double varargin_2[6], const double 18 | varargin_3[6], emxArray_real_T *h); 19 | 20 | #endif 21 | 22 | // 23 | // File trailer for firls.h 24 | // 25 | // [EOF] 26 | // 27 | -------------------------------------------------------------------------------- /bandpassFilter/mldivide.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // File: mldivide.cpp 3 | // 4 | // MATLAB Coder version : 4.3 5 | // C/C++ source code generated on : 17-Mar-2021 14:44:58 6 | // 7 | 8 | // Include Files 9 | #include "mldivide.h" 10 | #include "fir1.h" 11 | #include "fir1_emxutil.h" 12 | #include "rt_nonfinite.h" 13 | #include "xzgeqp3.h" 14 | #include 15 | 16 | // Function Definitions 17 | 18 | // 19 | // Arguments : const emxArray_real_T *A 20 | // emxArray_real_T *B 21 | // Return Type : void 22 | // 23 | void mldiv(const emxArray_real_T *A, emxArray_real_T *B) 24 | { 25 | emxArray_real_T *b_A; 26 | emxArray_int32_T *jpvt; 27 | int n; 28 | int u0; 29 | int i; 30 | int minmana; 31 | int minmn; 32 | int k; 33 | int ldap1; 34 | int u1; 35 | emxArray_real_T *tau; 36 | int j; 37 | int mmj_tmp; 38 | int jj; 39 | int b_i; 40 | int rankR; 41 | double tol; 42 | int ix; 43 | double s; 44 | emxArray_real_T *b_B; 45 | emxInit_real_T(&b_A, 2); 46 | emxInit_int32_T(&jpvt, 2); 47 | if (A->size[0] == A->size[1]) { 48 | n = A->size[1]; 49 | i = b_A->size[0] * b_A->size[1]; 50 | b_A->size[0] = A->size[0]; 51 | b_A->size[1] = A->size[1]; 52 | emxEnsureCapacity_real_T(b_A, i); 53 | minmn = A->size[0] * A->size[1]; 54 | for (i = 0; i < minmn; i++) { 55 | b_A->data[i] = A->data[i]; 56 | } 57 | 58 | minmana = A->size[1]; 59 | i = jpvt->size[0] * jpvt->size[1]; 60 | jpvt->size[0] = 1; 61 | jpvt->size[1] = A->size[1]; 62 | emxEnsureCapacity_int32_T(jpvt, i); 63 | jpvt->data[0] = 1; 64 | minmn = 1; 65 | for (k = 2; k <= minmana; k++) { 66 | minmn++; 67 | jpvt->data[k - 1] = minmn; 68 | } 69 | 70 | ldap1 = A->size[1]; 71 | u0 = A->size[1] - 1; 72 | u1 = A->size[1]; 73 | if (u0 < u1) { 74 | u1 = u0; 75 | } 76 | 77 | for (j = 0; j < u1; j++) { 78 | mmj_tmp = n - j; 79 | u0 = j * (n + 1); 80 | jj = j * (ldap1 + 1); 81 | rankR = u0 + 2; 82 | if (mmj_tmp < 1) { 83 | minmana = -1; 84 | } else { 85 | minmana = 0; 86 | if (mmj_tmp > 1) { 87 | ix = u0; 88 | tol = std::abs(b_A->data[jj]); 89 | for (k = 2; k <= mmj_tmp; k++) { 90 | ix++; 91 | s = std::abs(b_A->data[ix]); 92 | if (s > tol) { 93 | minmana = k - 1; 94 | tol = s; 95 | } 96 | } 97 | } 98 | } 99 | 100 | if (b_A->data[jj + minmana] != 0.0) { 101 | if (minmana != 0) { 102 | minmn = j + minmana; 103 | jpvt->data[j] = minmn + 1; 104 | ix = j; 105 | for (k = 0; k < n; k++) { 106 | tol = b_A->data[ix]; 107 | b_A->data[ix] = b_A->data[minmn]; 108 | b_A->data[minmn] = tol; 109 | ix += n; 110 | minmn += n; 111 | } 112 | } 113 | 114 | i = jj + mmj_tmp; 115 | for (b_i = rankR; b_i <= i; b_i++) { 116 | b_A->data[b_i - 1] /= b_A->data[jj]; 117 | } 118 | } 119 | 120 | minmn = u0 + n; 121 | minmana = jj + ldap1; 122 | for (u0 = 0; u0 <= mmj_tmp - 2; u0++) { 123 | tol = b_A->data[minmn]; 124 | if (b_A->data[minmn] != 0.0) { 125 | ix = jj + 1; 126 | i = minmana + 2; 127 | b_i = mmj_tmp + minmana; 128 | for (rankR = i; rankR <= b_i; rankR++) { 129 | b_A->data[rankR - 1] += b_A->data[ix] * -tol; 130 | ix++; 131 | } 132 | } 133 | 134 | minmn += n; 135 | minmana += n; 136 | } 137 | } 138 | 139 | i = A->size[1]; 140 | for (minmn = 0; minmn <= i - 2; minmn++) { 141 | b_i = jpvt->data[minmn]; 142 | if (b_i != minmn + 1) { 143 | tol = B->data[minmn]; 144 | B->data[minmn] = B->data[b_i - 1]; 145 | B->data[b_i - 1] = tol; 146 | } 147 | } 148 | 149 | for (k = 0; k < n; k++) { 150 | minmn = n * k; 151 | if (B->data[k] != 0.0) { 152 | i = k + 2; 153 | for (b_i = i; b_i <= n; b_i++) { 154 | B->data[b_i - 1] -= B->data[k] * b_A->data[(b_i + minmn) - 1]; 155 | } 156 | } 157 | } 158 | 159 | for (k = n; k >= 1; k--) { 160 | minmn = n * (k - 1); 161 | tol = B->data[k - 1]; 162 | if (tol != 0.0) { 163 | B->data[k - 1] = tol / b_A->data[(k + minmn) - 1]; 164 | for (b_i = 0; b_i <= k - 2; b_i++) { 165 | B->data[b_i] -= B->data[k - 1] * b_A->data[b_i + minmn]; 166 | } 167 | } 168 | } 169 | } else { 170 | n = A->size[1]; 171 | u0 = A->size[0]; 172 | minmana = A->size[1]; 173 | if (u0 < minmana) { 174 | minmana = u0; 175 | } 176 | 177 | i = jpvt->size[0] * jpvt->size[1]; 178 | jpvt->size[0] = 1; 179 | jpvt->size[1] = A->size[1]; 180 | emxEnsureCapacity_int32_T(jpvt, i); 181 | minmn = A->size[1]; 182 | for (i = 0; i < minmn; i++) { 183 | jpvt->data[i] = 0; 184 | } 185 | 186 | for (k = 0; k < n; k++) { 187 | jpvt->data[k] = k + 1; 188 | } 189 | 190 | i = b_A->size[0] * b_A->size[1]; 191 | b_A->size[0] = A->size[0]; 192 | b_A->size[1] = A->size[1]; 193 | emxEnsureCapacity_real_T(b_A, i); 194 | minmn = A->size[0] * A->size[1]; 195 | for (i = 0; i < minmn; i++) { 196 | b_A->data[i] = A->data[i]; 197 | } 198 | 199 | emxInit_real_T(&tau, 1); 200 | i = tau->size[0]; 201 | tau->size[0] = minmana; 202 | emxEnsureCapacity_real_T(tau, i); 203 | for (i = 0; i < minmana; i++) { 204 | tau->data[i] = 0.0; 205 | } 206 | 207 | qrpf(b_A, A->size[0], A->size[1], tau, jpvt); 208 | rankR = 0; 209 | if (b_A->size[0] < b_A->size[1]) { 210 | minmn = b_A->size[0]; 211 | minmana = b_A->size[1]; 212 | } else { 213 | minmn = b_A->size[1]; 214 | minmana = b_A->size[0]; 215 | } 216 | 217 | tol = 2.2204460492503131E-15 * static_cast(minmana); 218 | if (1.4901161193847656E-8 < tol) { 219 | tol = 1.4901161193847656E-8; 220 | } 221 | 222 | tol *= std::abs(b_A->data[0]); 223 | while ((rankR < minmn) && (!(std::abs(b_A->data[rankR + b_A->size[0] * rankR]) 224 | <= tol))) { 225 | rankR++; 226 | } 227 | 228 | emxInit_real_T(&b_B, 1); 229 | i = b_B->size[0]; 230 | b_B->size[0] = B->size[0]; 231 | emxEnsureCapacity_real_T(b_B, i); 232 | minmn = B->size[0]; 233 | for (i = 0; i < minmn; i++) { 234 | b_B->data[i] = B->data[i]; 235 | } 236 | 237 | i = B->size[0]; 238 | B->size[0] = b_A->size[1]; 239 | emxEnsureCapacity_real_T(B, i); 240 | minmn = b_A->size[1]; 241 | for (i = 0; i < minmn; i++) { 242 | B->data[i] = 0.0; 243 | } 244 | 245 | minmn = b_A->size[0]; 246 | u0 = b_A->size[0]; 247 | minmana = b_A->size[1]; 248 | if (u0 < minmana) { 249 | minmana = u0; 250 | } 251 | 252 | for (j = 0; j < minmana; j++) { 253 | if (tau->data[j] != 0.0) { 254 | tol = b_B->data[j]; 255 | i = j + 2; 256 | for (b_i = i; b_i <= minmn; b_i++) { 257 | tol += b_A->data[(b_i + b_A->size[0] * j) - 1] * b_B->data[b_i - 1]; 258 | } 259 | 260 | tol *= tau->data[j]; 261 | if (tol != 0.0) { 262 | b_B->data[j] -= tol; 263 | i = j + 2; 264 | for (b_i = i; b_i <= minmn; b_i++) { 265 | b_B->data[b_i - 1] -= b_A->data[(b_i + b_A->size[0] * j) - 1] * tol; 266 | } 267 | } 268 | } 269 | } 270 | 271 | emxFree_real_T(&tau); 272 | for (b_i = 0; b_i < rankR; b_i++) { 273 | B->data[jpvt->data[b_i] - 1] = b_B->data[b_i]; 274 | } 275 | 276 | emxFree_real_T(&b_B); 277 | for (j = rankR; j >= 1; j--) { 278 | i = jpvt->data[j - 1]; 279 | B->data[i - 1] /= b_A->data[(j + b_A->size[0] * (j - 1)) - 1]; 280 | for (b_i = 0; b_i <= j - 2; b_i++) { 281 | B->data[jpvt->data[b_i] - 1] -= B->data[jpvt->data[j - 1] - 1] * 282 | b_A->data[b_i + b_A->size[0] * (j - 1)]; 283 | } 284 | } 285 | } 286 | 287 | emxFree_int32_T(&jpvt); 288 | emxFree_real_T(&b_A); 289 | } 290 | 291 | // 292 | // File trailer for mldivide.cpp 293 | // 294 | // [EOF] 295 | // 296 | -------------------------------------------------------------------------------- /bandpassFilter/mldivide.h: -------------------------------------------------------------------------------- 1 | // 2 | // File: mldivide.h 3 | // 4 | // MATLAB Coder version : 4.3 5 | // C/C++ source code generated on : 17-Mar-2021 14:44:58 6 | // 7 | #ifndef MLDIVIDE_H 8 | #define MLDIVIDE_H 9 | 10 | // Include Files 11 | #include 12 | #include 13 | #include "rtwtypes.h" 14 | #include "fir1_types.h" 15 | 16 | // Function Declarations 17 | extern void mldiv(const emxArray_real_T *A, emxArray_real_T *B); 18 | 19 | #endif 20 | 21 | // 22 | // File trailer for mldivide.h 23 | // 24 | // [EOF] 25 | // 26 | -------------------------------------------------------------------------------- /bandpassFilter/rtGetInf.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // File: rtGetInf.cpp 3 | // 4 | // MATLAB Coder version : 4.3 5 | // C/C++ source code generated on : 17-Mar-2021 14:44:58 6 | 7 | 8 | // 9 | // Abstract: 10 | // MATLAB for code generation function to initialize non-finite, Inf and MinusInf 11 | 12 | #include "rtGetInf.h" 13 | 14 | // Function: rtGetInf ================================================================== 15 | // Abstract: 16 | // Initialize rtInf needed by the generated code. 17 | 18 | real_T rtGetInf(void) 19 | { 20 | return rtInf; 21 | } 22 | 23 | // Function: rtGetInfF ================================================================= 24 | // Abstract: 25 | // Initialize rtInfF needed by the generated code. 26 | 27 | real32_T rtGetInfF(void) 28 | { 29 | return rtInfF; 30 | } 31 | 32 | // Function: rtGetMinusInf ============================================================= 33 | // Abstract: 34 | // Initialize rtMinusInf needed by the generated code. 35 | 36 | real_T rtGetMinusInf(void) 37 | { 38 | return rtMinusInf; 39 | } 40 | 41 | // Function: rtGetMinusInfF ============================================================ 42 | // Abstract: 43 | // Initialize rtMinusInfF needed by the generated code. 44 | 45 | real32_T rtGetMinusInfF(void) 46 | { 47 | return rtMinusInfF; 48 | } 49 | 50 | // 51 | // File trailer for rtGetInf.cpp 52 | // 53 | // [EOF] 54 | 55 | -------------------------------------------------------------------------------- /bandpassFilter/rtGetInf.h: -------------------------------------------------------------------------------- 1 | // 2 | // File: rtGetInf.h 3 | // 4 | // MATLAB Coder version : 4.3 5 | // C/C++ source code generated on : 17-Mar-2021 14:44:58 6 | 7 | 8 | #ifndef RTGETINF_H 9 | #define RTGETINF_H 10 | #include "rtwtypes.h" 11 | #include "rt_nonfinite.h" 12 | #ifdef __cplusplus 13 | 14 | extern "C" { 15 | 16 | #endif 17 | 18 | extern real_T rtGetInf(void); 19 | extern real32_T rtGetInfF(void); 20 | extern real_T rtGetMinusInf(void); 21 | extern real32_T rtGetMinusInfF(void); 22 | 23 | #ifdef __cplusplus 24 | 25 | } 26 | #endif 27 | #endif 28 | 29 | // 30 | // File trailer for rtGetInf.h 31 | // 32 | // [EOF] 33 | 34 | -------------------------------------------------------------------------------- /bandpassFilter/rtGetNaN.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // File: rtGetNaN.cpp 3 | // 4 | // MATLAB Coder version : 4.3 5 | // C/C++ source code generated on : 17-Mar-2021 14:44:58 6 | 7 | 8 | // 9 | // Abstract: 10 | // MATLAB for code generation function to initialize non-finite, NaN 11 | 12 | #include "rtGetNaN.h" 13 | 14 | // Function: rtGetNaN ====================================================================== 15 | // Abstract: 16 | // Initialize rtNaN needed by the generated code. 17 | // NaN is initialized as non-signaling. Assumes IEEE. 18 | 19 | real_T rtGetNaN(void) 20 | { 21 | return rtNaN; 22 | } 23 | 24 | // Function: rtGetNaNF ===================================================================== 25 | // Abstract: 26 | // Initialize rtNaNF needed by the generated code. 27 | // NaN is initialized as non-signaling. Assumes IEEE. 28 | 29 | real32_T rtGetNaNF(void) 30 | { 31 | return rtNaNF; 32 | } 33 | 34 | // 35 | // File trailer for rtGetNaN.cpp 36 | // 37 | // [EOF] 38 | 39 | -------------------------------------------------------------------------------- /bandpassFilter/rtGetNaN.h: -------------------------------------------------------------------------------- 1 | // 2 | // File: rtGetNaN.h 3 | // 4 | // MATLAB Coder version : 4.3 5 | // C/C++ source code generated on : 17-Mar-2021 14:44:58 6 | 7 | 8 | #ifndef RTGETNAN_H 9 | #define RTGETNAN_H 10 | #include 11 | #include "rtwtypes.h" 12 | #include "rt_nonfinite.h" 13 | #ifdef __cplusplus 14 | 15 | extern "C" { 16 | 17 | #endif 18 | 19 | extern real_T rtGetNaN(void); 20 | extern real32_T rtGetNaNF(void); 21 | 22 | #ifdef __cplusplus 23 | 24 | } 25 | #endif 26 | #endif 27 | 28 | // 29 | // File trailer for rtGetNaN.h 30 | // 31 | // [EOF] 32 | 33 | -------------------------------------------------------------------------------- /bandpassFilter/rt_nonfinite.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // File: rt_nonfinite.cpp 3 | // 4 | // MATLAB Coder version : 4.3 5 | // C/C++ source code generated on : 17-Mar-2021 14:44:58 6 | 7 | 8 | // 9 | // Abstract: 10 | // MATLAB for code generation function to initialize non-finites, 11 | // (Inf, NaN and -Inf). 12 | 13 | #include "rt_nonfinite.h" 14 | #include 15 | #include 16 | 17 | real_T rtInf; 18 | real_T rtMinusInf; 19 | real_T rtNaN; 20 | real32_T rtInfF; 21 | real32_T rtMinusInfF; 22 | real32_T rtNaNF; 23 | 24 | // Function: rt_InitInfAndNaN ================================================== 25 | // Abstract: 26 | // Initialize the rtInf, rtMinusInf, and rtNaN needed by the 27 | // generated code. NaN is initialized as non-signaling. Assumes IEEE. 28 | 29 | void rt_InitInfAndNaN() 30 | { 31 | rtNaN = std::numeric_limits::quiet_NaN(); 32 | rtNaNF = std::numeric_limits::quiet_NaN(); 33 | rtInf = std::numeric_limits::infinity(); 34 | rtInfF = std::numeric_limits::infinity(); 35 | rtMinusInf = -std::numeric_limits::infinity(); 36 | rtMinusInfF = -std::numeric_limits::infinity(); 37 | } 38 | 39 | // Function: rtIsInf ================================================== 40 | // Abstract: 41 | // Test if value is infinite 42 | 43 | boolean_T rtIsInf(real_T value) 44 | { 45 | return ((value==rtInf || value==rtMinusInf) ? 1U : 0U); 46 | } 47 | 48 | // Function: rtIsInfF ================================================= 49 | // Abstract: 50 | // Test if single-precision value is infinite 51 | 52 | boolean_T rtIsInfF(real32_T value) 53 | { 54 | return(((value)==rtInfF || (value)==rtMinusInfF) ? 1U : 0U); 55 | } 56 | 57 | // Function: rtIsNaN ================================================== 58 | // Abstract: 59 | // Test if value is not a number 60 | 61 | boolean_T rtIsNaN(real_T value) 62 | { 63 | return ((value!=value)? 1U : 0U); 64 | } 65 | 66 | // Function: rtIsNaNF ================================================= 67 | // Abstract: 68 | // Test if single-precision value is not a number 69 | 70 | boolean_T rtIsNaNF(real32_T value) 71 | { 72 | return ((value!=value)? 1U : 0U); 73 | } 74 | 75 | // 76 | // File trailer for rt_nonfinite.cpp 77 | // 78 | // [EOF] 79 | 80 | -------------------------------------------------------------------------------- /bandpassFilter/rt_nonfinite.h: -------------------------------------------------------------------------------- 1 | // 2 | // File: rt_nonfinite.h 3 | // 4 | // MATLAB Coder version : 4.3 5 | // C/C++ source code generated on : 17-Mar-2021 14:44:58 6 | 7 | 8 | #ifndef RT_NONFINITE_H 9 | #define RT_NONFINITE_H 10 | #include "rtwtypes.h" 11 | #ifdef __cplusplus 12 | 13 | extern "C" { 14 | 15 | #endif 16 | 17 | extern real_T rtInf; 18 | extern real_T rtMinusInf; 19 | extern real_T rtNaN; 20 | extern real32_T rtInfF; 21 | extern real32_T rtMinusInfF; 22 | extern real32_T rtNaNF; 23 | extern void rt_InitInfAndNaN(); 24 | extern boolean_T rtIsInf(real_T value); 25 | extern boolean_T rtIsInfF(real32_T value); 26 | extern boolean_T rtIsNaN(real_T value); 27 | extern boolean_T rtIsNaNF(real32_T value); 28 | 29 | #ifdef __cplusplus 30 | 31 | } 32 | #endif 33 | #endif 34 | 35 | // 36 | // File trailer for rt_nonfinite.h 37 | // 38 | // [EOF] 39 | 40 | -------------------------------------------------------------------------------- /bandpassFilter/rtwtypes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: rtwtypes.h 3 | * 4 | * MATLAB Coder version : 4.3 5 | * C/C++ source code generated on : 17-Mar-2021 14:44:58 6 | */ 7 | 8 | #ifndef RTWTYPES_H 9 | #define RTWTYPES_H 10 | 11 | /*=======================================================================* 12 | * Fixed width word size data types: * 13 | * int64_T - signed 64 bit integers * 14 | * uint64_T - unsigned 64 bit integers * 15 | *=======================================================================*/ 16 | #if defined(__APPLE__) 17 | # ifndef INT64_T 18 | # define INT64_T long 19 | # define FMT64 "l" 20 | # if defined(__LP64__) && !defined(INT_TYPE_64_IS_LONG) 21 | # define INT_TYPE_64_IS_LONG 22 | # endif 23 | # endif 24 | #endif 25 | 26 | #if defined(__APPLE__) 27 | # ifndef UINT64_T 28 | # define UINT64_T unsigned long 29 | # define FMT64 "l" 30 | # if defined(__LP64__) && !defined(INT_TYPE_64_IS_LONG) 31 | # define INT_TYPE_64_IS_LONG 32 | # endif 33 | # endif 34 | #endif 35 | 36 | #include "tmwtypes.h" 37 | #endif 38 | 39 | /* 40 | * File trailer for rtwtypes.h 41 | * 42 | * [EOF] 43 | */ 44 | -------------------------------------------------------------------------------- /bandpassFilter/string1.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // File: string1.cpp 3 | // 4 | // MATLAB Coder version : 4.3 5 | // C/C++ source code generated on : 17-Mar-2021 14:44:58 6 | // 7 | 8 | // Include Files 9 | #include "string1.h" 10 | #include "fir1.h" 11 | #include "rt_nonfinite.h" 12 | 13 | // Function Definitions 14 | 15 | // 16 | // Arguments : const char obj1_Value[4] 17 | // const char obj2_Value_data[] 18 | // const int obj2_Value_size[2] 19 | // Return Type : boolean_T 20 | // 21 | boolean_T string_eq(const char obj1_Value[4], const char obj2_Value_data[], 22 | const int obj2_Value_size[2]) 23 | { 24 | boolean_T equal; 25 | int kstr; 26 | int exitg1; 27 | equal = false; 28 | if (4 == obj2_Value_size[1]) { 29 | kstr = 0; 30 | do { 31 | exitg1 = 0; 32 | if (kstr < 4) { 33 | if (obj1_Value[kstr] != obj2_Value_data[kstr]) { 34 | exitg1 = 1; 35 | } else { 36 | kstr++; 37 | } 38 | } else { 39 | equal = true; 40 | exitg1 = 1; 41 | } 42 | } while (exitg1 == 0); 43 | } 44 | 45 | return equal; 46 | } 47 | 48 | // 49 | // File trailer for string1.cpp 50 | // 51 | // [EOF] 52 | // 53 | -------------------------------------------------------------------------------- /bandpassFilter/string1.h: -------------------------------------------------------------------------------- 1 | // 2 | // File: string1.h 3 | // 4 | // MATLAB Coder version : 4.3 5 | // C/C++ source code generated on : 17-Mar-2021 14:44:58 6 | // 7 | #ifndef STRING1_H 8 | #define STRING1_H 9 | 10 | // Include Files 11 | #include 12 | #include 13 | #include "rtwtypes.h" 14 | #include "fir1_types.h" 15 | 16 | // Function Declarations 17 | extern boolean_T string_eq(const char obj1_Value[4], const char obj2_Value_data[], 18 | const int obj2_Value_size[2]); 19 | 20 | #endif 21 | 22 | // 23 | // File trailer for string1.h 24 | // 25 | // [EOF] 26 | // 27 | -------------------------------------------------------------------------------- /bandpassFilter/tmwtypes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 1984-2018 The MathWorks, Inc. 3 | */ 4 | 5 | #if defined(_MSC_VER) 6 | # pragma once 7 | #endif 8 | #if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3)) 9 | # pragma once 10 | #endif 11 | 12 | #ifndef tmwtypes_h 13 | #define tmwtypes_h 14 | 15 | #ifndef __TMWTYPES__ 16 | #define __TMWTYPES__ 17 | /* 18 | * File : tmwtypes.h 19 | * Abstract: 20 | * Data types for use with MATLAB/SIMULINK and the Real-Time Workshop. 21 | * 22 | * When compiling stand-alone model code, data types can be overridden 23 | * via compiler switches. 24 | * 25 | * Define NO_FLOATS to eliminate reference to real_T, etc. 26 | */ 27 | 28 | #include 29 | 30 | /* __STDC_VERSION__ version check below means "check for a C99 compiler". 31 | 32 | Visual Studio (checked on versions 2015 and 2017) does 33 | not define __STDC_VERSION__, however it has stdbool.h available, 34 | thus a separate check for _MSC_VER below. 35 | */ 36 | #if defined(__APPLE_CC__) \ 37 | || (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) \ 38 | || (defined(_MSC_VER) && (_MSC_VER >= 1900)) 39 | #include 40 | #endif 41 | 42 | #define LOGICAL_IS_A_TYPE 43 | #define SPARSE_GENERALIZATION 44 | 45 | #ifdef NO_FLOATS 46 | # define double double_not_allowed 47 | # define float float_not_allowed 48 | #endif /*NO_FLOATS*/ 49 | 50 | #ifndef NO_FLOATS 51 | 52 | #ifndef __MWERKS__ 53 | # ifdef __STDC__ 54 | # include 55 | # else 56 | # define FLT_MANT_DIG 24 57 | # define DBL_MANT_DIG 53 58 | # endif 59 | #endif 60 | 61 | #endif /*NO_FLOATS*/ 62 | 63 | /* 64 | * The following data types cannot be overridden when building MEX files. 65 | */ 66 | #ifdef MATLAB_MEX_FILE 67 | # undef CHARACTER_T 68 | # undef INTEGER_T 69 | # undef BOOLEAN_T 70 | # undef REAL_T 71 | # undef TIME_T 72 | #endif 73 | 74 | /* 75 | * The uchar_T, ushort_T and ulong_T types are needed for compilers which do 76 | * not allow defines to be specified, at the command line, with spaces in them. 77 | */ 78 | 79 | typedef unsigned char uchar_T; 80 | typedef unsigned short ushort_T; 81 | typedef unsigned long ulong_T; 82 | 83 | #if (defined(_MSC_VER) && _MSC_VER >= 1500) \ 84 | || defined(__x86_64__) || defined(__LP64__) \ 85 | || defined(__LCC64__) 86 | 87 | typedef unsigned long long ulonglong_T; 88 | #endif 89 | 90 | 91 | 92 | /*=======================================================================* 93 | * Fixed width word size data types: * 94 | * int8_T, int16_T, int32_T - signed 8, 16, or 32 bit integers * 95 | * uint8_T, uint16_T, uint32_T - unsigned 8, 16, or 32 bit integers * 96 | * real32_T, real64_T - 32 and 64 bit floating point numbers * 97 | *=======================================================================*/ 98 | 99 | /* When used with Real Time Workshop generated code, this 100 | * header file can be used with a variety of compilers. 101 | * 102 | * The compiler could be for an 8 bit embedded processor that 103 | * only had 8 bits per integer and 16 bits per long. 104 | * In that example, a 32 bit integer size is not even available. 105 | * This header file should be robust to that. 106 | * 107 | * For the case of an 8 bit processor, the preprocessor 108 | * may be limited to 16 bit math like its target. That limitation 109 | * would mean that 32 bit comparisons can't be done accurately. 110 | * To increase robustness to this, comparisons are done against 111 | * smaller values first. An inaccurate 32 bit comparison isn't 112 | * attempted if the 16 bit comparison has already succeeded. 113 | * 114 | * Limitations on preprocessor math can also be stricter than 115 | * for the target. There are known cases where a compiler 116 | * targeting processors with 64 bit longs can't do accurate 117 | * preprocessor comparisons on more than 32 bits. 118 | */ 119 | 120 | /* Determine the number of bits for int, long, short, and char. 121 | * If one fails to be determined, set the number of bits to -1 122 | */ 123 | 124 | #ifndef TMW_BITS_PER_INT 125 | # if INT_MAX == 0x7FL 126 | # define TMW_BITS_PER_INT 8 127 | # elif INT_MAX == 0x7FFFL 128 | # define TMW_BITS_PER_INT 16 129 | # elif INT_MAX == 0x7FFFFFFFL 130 | # define TMW_BITS_PER_INT 32 131 | # else 132 | # define TMW_BITS_PER_INT -1 133 | # endif 134 | #endif 135 | 136 | #ifndef TMW_BITS_PER_LONG 137 | # if LONG_MAX == 0x7FL 138 | # define TMW_BITS_PER_LONG 8 139 | # elif LONG_MAX == 0x7FFFL 140 | # define TMW_BITS_PER_LONG 16 141 | # elif LONG_MAX == 0x7FFFFFFFL 142 | # define TMW_BITS_PER_LONG 32 143 | # else 144 | # define TMW_BITS_PER_LONG -1 145 | # endif 146 | #endif 147 | 148 | #ifndef TMW_BITS_PER_SHRT 149 | # if SHRT_MAX == 0x7FL 150 | # define TMW_BITS_PER_SHRT 8 151 | # elif SHRT_MAX == 0x7FFFL 152 | # define TMW_BITS_PER_SHRT 16 153 | # elif SHRT_MAX == 0x7FFFFFFFL 154 | # define TMW_BITS_PER_SHRT 32 155 | # else 156 | # define TMW_BITS_PER_SHRT -1 157 | # endif 158 | #endif 159 | 160 | #ifndef TMW_BITS_PER_SCHAR 161 | # if SCHAR_MAX == 0x7FL 162 | # define TMW_BITS_PER_SCHAR 8 163 | # elif SCHAR_MAX == 0x7FFFL 164 | # define TMW_BITS_PER_SCHAR 16 165 | # elif SCHAR_MAX == 0x7FFFFFFFL 166 | # define TMW_BITS_PER_SCHAR 32 167 | # else 168 | # define TMW_BITS_PER_SCHAR -1 169 | # endif 170 | #endif 171 | 172 | #ifndef TMW_CHAR_SIGNED 173 | # if SCHAR_MAX == CHAR_MAX 174 | # define TMW_CHAR_SIGNED 1 175 | # else 176 | # define TMW_CHAR_SIGNED 0 177 | # endif 178 | #endif 179 | 180 | /* It is common for one or more of the integer types 181 | * to be the same size. For example, on many embedded 182 | * processors, both shorts and ints are 16 bits. On 183 | * processors used for workstations, it is quite common 184 | * for both int and long to be 32 bits. 185 | * When there is more than one choice for typdef'ing 186 | * a portable type like int16_T or uint32_T, in 187 | * concept, it should not matter which choice is made. 188 | * However, some style guides and some code checking 189 | * tools do identify and complain about seemingly 190 | * irrelevant differences. For example, a code 191 | * checking tool may complain about an implicit 192 | * conversion from int to short even though both 193 | * are 16 bits. To reduce these types of 194 | * complaints, it is best to make int the 195 | * preferred choice when more than one is available. 196 | */ 197 | 198 | #ifndef INT8_T 199 | # if TMW_BITS_PER_INT == 8 200 | # define INT8_T int 201 | # elif TMW_BITS_PER_LONG == 8 202 | # define INT8_T long 203 | # elif TMW_BITS_PER_SCHAR == 8 204 | # define INT8_T signed char 205 | # elif TMW_BITS_PER_SHRT == 8 206 | # define INT8_T short 207 | # endif 208 | #endif 209 | #ifdef INT8_T 210 | typedef INT8_T int8_T; 211 | #endif 212 | 213 | #ifndef UINT8_T 214 | # if TMW_BITS_PER_INT == 8 215 | # define UINT8_T unsigned int 216 | # elif TMW_BITS_PER_LONG == 8 217 | # define UINT8_T unsigned long 218 | # elif TMW_BITS_PER_SCHAR == 8 219 | # define UINT8_T unsigned char 220 | # elif TMW_BITS_PER_SHRT == 8 221 | # define UINT8_T unsigned short 222 | # endif 223 | #endif 224 | #ifdef UINT8_T 225 | typedef UINT8_T uint8_T; 226 | #endif 227 | 228 | 229 | #ifndef INT16_T 230 | # if TMW_BITS_PER_INT == 16 231 | # define INT16_T int 232 | # elif TMW_BITS_PER_LONG == 16 233 | # define INT16_T long 234 | # elif TMW_BITS_PER_SCHAR == 16 235 | # define INT16_T signed char 236 | # elif TMW_BITS_PER_SHRT == 16 237 | # define INT16_T short 238 | # endif 239 | #endif 240 | #ifdef INT16_T 241 | typedef INT16_T int16_T; 242 | #endif 243 | 244 | 245 | #ifndef UINT16_T 246 | # if TMW_BITS_PER_INT == 16 247 | # define UINT16_T unsigned int 248 | # elif TMW_BITS_PER_LONG == 16 249 | # define UINT16_T unsigned long 250 | # elif TMW_BITS_PER_SCHAR == 16 251 | # define UINT16_T unsigned char 252 | # elif TMW_BITS_PER_SHRT == 16 253 | # define UINT16_T unsigned short 254 | # endif 255 | #endif 256 | #ifdef UINT16_T 257 | typedef UINT16_T uint16_T; 258 | #endif 259 | 260 | 261 | #ifndef INT32_T 262 | # if TMW_BITS_PER_INT == 32 263 | # define INT32_T int 264 | # elif TMW_BITS_PER_LONG == 32 265 | # define INT32_T long 266 | # elif TMW_BITS_PER_SCHAR == 32 267 | # define INT32_T signed char 268 | # elif TMW_BITS_PER_SHRT == 32 269 | # define INT32_T short 270 | # endif 271 | #endif 272 | #ifdef INT32_T 273 | typedef INT32_T int32_T; 274 | #endif 275 | 276 | 277 | #ifndef UINT32_T 278 | # if TMW_BITS_PER_INT == 32 279 | # define UINT32_T unsigned int 280 | # elif TMW_BITS_PER_LONG == 32 281 | # define UINT32_T unsigned long 282 | # elif TMW_BITS_PER_SCHAR == 32 283 | # define UINT32_T unsigned char 284 | # elif TMW_BITS_PER_SHRT == 32 285 | # define UINT32_T unsigned short 286 | # endif 287 | #endif 288 | #ifdef UINT32_T 289 | typedef UINT32_T uint32_T; 290 | #endif 291 | 292 | /* The following is used to emulate smaller integer types when only 293 | * larger types are available. For example, compilers for TI C3x/C4x DSPs 294 | * define char and short to be 32 bits, so 8 and 16 bits are not directly 295 | * available. This target is commonly used with RTW rapid prototyping. 296 | * Other DSPs define char to be 16 bits, so 8 bits is not directly 297 | * available. 298 | */ 299 | #ifndef INT8_T 300 | # ifdef INT16_T 301 | # define INT8_T INT16_T 302 | typedef INT8_T int8_T; 303 | # else 304 | # ifdef INT32_T 305 | # define INT8_T INT32_T 306 | typedef INT8_T int8_T; 307 | # endif 308 | # endif 309 | #endif 310 | 311 | #ifndef UINT8_T 312 | # ifdef UINT16_T 313 | # define UINT8_T UINT16_T 314 | typedef UINT8_T uint8_T; 315 | # else 316 | # ifdef UINT32_T 317 | # define UINT8_T UINT32_T 318 | typedef UINT8_T uint8_T; 319 | # endif 320 | # endif 321 | #endif 322 | 323 | #ifndef INT16_T 324 | # ifdef INT32_T 325 | # define INT16_T INT32_T 326 | typedef INT16_T int16_T; 327 | # endif 328 | #endif 329 | 330 | #ifndef UINT16_T 331 | # ifdef UINT32_T 332 | # define UINT16_T UINT32_T 333 | typedef UINT16_T uint16_T; 334 | # endif 335 | #endif 336 | 337 | 338 | #ifndef NO_FLOATS 339 | 340 | #ifndef REAL32_T 341 | # ifndef __MWERKS__ 342 | # if FLT_MANT_DIG >= 23 343 | # define REAL32_T float 344 | # endif 345 | # else 346 | # define REAL32_T float 347 | # endif 348 | #endif 349 | #ifdef REAL32_T 350 | typedef REAL32_T real32_T; 351 | #endif 352 | 353 | 354 | #ifndef REAL64_T 355 | # ifndef __MWERKS__ 356 | # if DBL_MANT_DIG >= 52 357 | # define REAL64_T double 358 | # endif 359 | # else 360 | # define REAL64_T double 361 | # endif 362 | #endif 363 | #ifdef REAL64_T 364 | typedef REAL64_T real64_T; 365 | #endif 366 | 367 | #endif /* NO_FLOATS*/ 368 | 369 | /*=======================================================================* 370 | * Fixed width word size data types: * 371 | * int64_T - signed 64 bit integers * 372 | * uint64_T - unsigned 64 bit integers * 373 | *=======================================================================*/ 374 | 375 | 376 | 377 | #ifndef INT64_T 378 | # if defined(__APPLE__) 379 | # define INT64_T long long 380 | # define FMT64 "ll" 381 | # if defined(__LP64__) && !defined(INT_TYPE_64_IS_LONG) 382 | # define INT_TYPE_64_IS_LONG 383 | # endif 384 | # elif (defined(__x86_64__) || defined(__LP64__))&& !defined(__MINGW64__) 385 | # define INT64_T long 386 | # define FMT64 "l" 387 | # if !defined(INT_TYPE_64_IS_LONG) 388 | # define INT_TYPE_64_IS_LONG 389 | # endif 390 | # elif defined(_MSC_VER) || (defined(__BORLANDC__) && __BORLANDC__ >= 0x530) \ 391 | || (defined(__WATCOMC__) && __WATCOMC__ >= 1100) 392 | # define INT64_T __int64 393 | # define FMT64 "I64" 394 | # elif defined(__GNUC__) || defined(TMW_ENABLE_INT64) \ 395 | || defined(__LCC64__) 396 | # define INT64_T long long 397 | # define FMT64 "ll" 398 | # endif 399 | #endif 400 | 401 | 402 | 403 | #if defined(INT64_T) 404 | # if defined(__GNUC__) && \ 405 | ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >=9))) 406 | __extension__ 407 | # endif 408 | typedef INT64_T int64_T; 409 | #endif 410 | 411 | 412 | 413 | #ifndef UINT64_T 414 | # if defined(__APPLE__) 415 | # define UINT64_T unsigned long long 416 | # define FMT64 "ll" 417 | # if defined(__LP64__) && !defined(INT_TYPE_64_IS_LONG) 418 | # define INT_TYPE_64_IS_LONG 419 | # endif 420 | # elif (defined(__x86_64__) || defined(__LP64__))&& !defined(__MINGW64__) 421 | # define UINT64_T unsigned long 422 | # define FMT64 "l" 423 | # if !defined(INT_TYPE_64_IS_LONG) 424 | # define INT_TYPE_64_IS_LONG 425 | # endif 426 | # elif defined(_MSC_VER) || (defined(__BORLANDC__) && __BORLANDC__ >= 0x530) \ 427 | || (defined(__WATCOMC__) && __WATCOMC__ >= 1100) 428 | # define UINT64_T unsigned __int64 429 | # define FMT64 "I64" 430 | # elif defined(__GNUC__) || defined(TMW_ENABLE_INT64) \ 431 | || defined(__LCC64__) 432 | # define UINT64_T unsigned long long 433 | # define FMT64 "ll" 434 | # endif 435 | #endif 436 | 437 | #if defined(_WIN64) || (defined(__APPLE__) && defined(__LP64__)) \ 438 | || defined(__x86_64__) \ 439 | || defined(__LP64__) 440 | # define INT_TYPE_64_IS_SUPPORTED 441 | #endif 442 | 443 | #if defined(UINT64_T) 444 | # if defined(__GNUC__) && \ 445 | ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >=9))) 446 | __extension__ 447 | # endif 448 | typedef UINT64_T uint64_T; 449 | #endif 450 | 451 | /*===========================================================================* 452 | * Format string modifiers for using size_t variables in printf statements. * 453 | *===========================================================================*/ 454 | 455 | #ifndef FMT_SIZE_T 456 | # if (defined( __GNUC__ ) || defined(_STDC_C99))&& !defined(__MINGW64__) 457 | # define FMT_SIZE_T "z" 458 | # elif defined (__WATCOMC__) 459 | # define FMT_SIZE_T "l" 460 | # elif defined (_WIN32 ) 461 | # define FMT_SIZE_T "I" 462 | # else 463 | # define FMT_SIZE_T "l" 464 | # endif 465 | #endif 466 | 467 | #ifndef FMT_PTRDIFF_T 468 | # if defined(__APPLE__) 469 | # define FMT_PTRDIFF_T "l" 470 | # elif defined( __GNUC__ ) || defined(_STDC_C99) 471 | # define FMT_PTRDIFF_T "t" 472 | # elif defined (__WATCOMC__) 473 | # define FMT_PTRDIFF_T "l" 474 | # elif defined (_WIN32 ) 475 | # define FMT_PTRDIFF_T "I" 476 | # else 477 | # define FMT_PTRDIFF_T "l" 478 | # endif 479 | #endif 480 | 481 | /*===========================================================================* 482 | * General or logical data types where the word size is not guaranteed. * 483 | * real_T - possible settings include real32_T or real64_T * 484 | * time_T - possible settings include real32_T or real64_T * 485 | * boolean_T * 486 | * char_T * 487 | * int_T * 488 | * uint_T * 489 | * byte_T * 490 | *===========================================================================*/ 491 | 492 | #ifndef NO_FLOATS 493 | 494 | #ifndef REAL_T 495 | # ifdef REAL64_T 496 | # define REAL_T real64_T 497 | # else 498 | # ifdef REAL32_T 499 | # define REAL_T real32_T 500 | # endif 501 | # endif 502 | #endif 503 | #ifdef REAL_T 504 | typedef REAL_T real_T; 505 | #endif 506 | 507 | #ifndef TIME_T 508 | # ifdef REAL_T 509 | # define TIME_T real_T 510 | # endif 511 | #endif 512 | #ifdef TIME_T 513 | typedef TIME_T time_T; 514 | #endif 515 | 516 | #endif /* NO_FLOATS */ 517 | 518 | #ifndef BOOLEAN_T 519 | # if defined(UINT8_T) 520 | # define BOOLEAN_T UINT8_T 521 | # else 522 | # define BOOLEAN_T unsigned int 523 | # endif 524 | #endif 525 | typedef BOOLEAN_T boolean_T; 526 | 527 | 528 | #ifndef CHARACTER_T 529 | # define CHARACTER_T char 530 | #endif 531 | typedef CHARACTER_T char_T; 532 | 533 | 534 | #ifndef INTEGER_T 535 | # define INTEGER_T int 536 | #endif 537 | typedef INTEGER_T int_T; 538 | 539 | 540 | #ifndef UINTEGER_T 541 | # define UINTEGER_T unsigned 542 | #endif 543 | typedef UINTEGER_T uint_T; 544 | 545 | 546 | #ifndef BYTE_T 547 | # define BYTE_T unsigned char 548 | #endif 549 | typedef BYTE_T byte_T; 550 | 551 | 552 | /*===========================================================================* 553 | * Define Complex Structures * 554 | *===========================================================================*/ 555 | #ifndef NO_FLOATS 556 | 557 | #ifndef CREAL32_T 558 | # ifdef REAL32_T 559 | typedef struct { 560 | real32_T re, im; 561 | } creal32_T; 562 | # define CREAL32_T creal32_T 563 | # endif 564 | #endif 565 | 566 | #ifndef CREAL64_T 567 | # ifdef REAL64_T 568 | typedef struct { 569 | real64_T re, im; 570 | } creal64_T; 571 | # define CREAL64_T creal64_T 572 | # endif 573 | #endif 574 | 575 | #ifndef CREAL_T 576 | # ifdef REAL_T 577 | typedef struct { 578 | real_T re, im; 579 | } creal_T; 580 | # define CREAL_T creal_T 581 | # endif 582 | #endif 583 | 584 | #endif /* NO_FLOATS */ 585 | 586 | #ifndef CINT8_T 587 | # ifdef INT8_T 588 | typedef struct { 589 | int8_T re, im; 590 | } cint8_T; 591 | # define CINT8_T cint8_T 592 | # endif 593 | #endif 594 | 595 | #ifndef CUINT8_T 596 | # ifdef UINT8_T 597 | typedef struct { 598 | uint8_T re, im; 599 | } cuint8_T; 600 | # define CUINT8_T cuint8_T 601 | # endif 602 | #endif 603 | 604 | #ifndef CINT16_T 605 | # ifdef INT16_T 606 | typedef struct { 607 | int16_T re, im; 608 | } cint16_T; 609 | # define CINT16_T cint16_T 610 | # endif 611 | #endif 612 | 613 | #ifndef CUINT16_T 614 | # ifdef UINT16_T 615 | typedef struct { 616 | uint16_T re, im; 617 | } cuint16_T; 618 | # define CUINT16_T cuint16_T 619 | # endif 620 | #endif 621 | 622 | #ifndef CINT32_T 623 | # ifdef INT32_T 624 | typedef struct { 625 | int32_T re, im; 626 | } cint32_T; 627 | # define CINT32_T cint32_T 628 | # endif 629 | #endif 630 | 631 | #ifndef CUINT32_T 632 | # ifdef UINT32_T 633 | typedef struct { 634 | uint32_T re, im; 635 | } cuint32_T; 636 | # define CUINT32_T cuint32_T 637 | # endif 638 | #endif 639 | 640 | #ifndef CINT64_T 641 | # ifdef INT64_T 642 | typedef struct { 643 | int64_T re, im; 644 | } cint64_T; 645 | # define CINT64_T cint64_T 646 | # endif 647 | #endif 648 | 649 | #ifndef CUINT64_T 650 | # ifdef UINT64_T 651 | typedef struct { 652 | uint64_T re, im; 653 | } cuint64_T; 654 | # define CUINT64_T cuint64_T 655 | # endif 656 | #endif 657 | 658 | /*=======================================================================* 659 | * Min and Max: * 660 | * int8_T, int16_T, int32_T - signed 8, 16, or 32 bit integers * 661 | * uint8_T, uint16_T, uint32_T - unsigned 8, 16, or 32 bit integers * 662 | *=======================================================================*/ 663 | 664 | #define MAX_int8_T ((int8_T)(127)) /* 127 */ 665 | #define MIN_int8_T ((int8_T)(-128)) /* -128 */ 666 | #define MAX_uint8_T ((uint8_T)(255)) /* 255 */ 667 | #define MIN_uint8_T ((uint8_T)(0)) 668 | 669 | #define MAX_int16_T ((int16_T)(32767)) /* 32767 */ 670 | #define MIN_int16_T ((int16_T)(-32768)) /* -32768 */ 671 | #define MAX_uint16_T ((uint16_T)(65535)) /* 65535 */ 672 | #define MIN_uint16_T ((uint16_T)(0)) 673 | 674 | #define MAX_int32_T ((int32_T)(2147483647)) /* 2147483647 */ 675 | #define MIN_int32_T ((int32_T)(-2147483647-1)) /* -2147483648 */ 676 | #define MAX_uint32_T ((uint32_T)(0xFFFFFFFFU)) /* 4294967295 */ 677 | #define MIN_uint32_T ((uint32_T)(0)) 678 | 679 | #if defined(_MSC_VER) || (defined(__BORLANDC__) && __BORLANDC__ >= 0x530) \ 680 | || (defined(__WATCOMC__) && __WATCOMC__ >= 1100) \ 681 | || defined(__LCC64__) 682 | # ifdef INT64_T 683 | # define MAX_int64_T ((int64_T)(9223372036854775807LL)) 684 | # define MIN_int64_T ((int64_T)(-9223372036854775807LL-1LL)) 685 | # endif 686 | # ifdef UINT64_T 687 | # define MAX_uint64_T ((uint64_T)(0xFFFFFFFFFFFFFFFFULL)) 688 | # define MIN_uint64_T ((uint64_T)(0)) 689 | # endif 690 | #else 691 | # ifdef INT64_T 692 | # ifdef INT_TYPE_64_IS_LONG 693 | # define MAX_int64_T ((int64_T)(9223372036854775807L)) 694 | # define MIN_int64_T ((int64_T)(-9223372036854775807L-1L)) 695 | # else 696 | # define MAX_int64_T ((int64_T)(9223372036854775807LL)) 697 | # define MIN_int64_T ((int64_T)(-9223372036854775807LL-1LL)) 698 | # endif 699 | # endif 700 | # ifdef UINT64_T 701 | # ifdef INT_TYPE_64_IS_LONG 702 | # define MAX_uint64_T ((uint64_T)(0xFFFFFFFFFFFFFFFFUL)) 703 | # define MIN_uint64_T ((uint64_T)(0)) 704 | # else 705 | # define MAX_uint64_T ((uint64_T)(0xFFFFFFFFFFFFFFFFULL)) 706 | # define MIN_uint64_T ((uint64_T)(0)) 707 | # endif 708 | # endif 709 | #endif 710 | 711 | #ifdef _MSC_VER 712 | /* Conversion from unsigned __int64 to double is not implemented in windows 713 | * and results in a compile error, thus the value must first be cast to 714 | * signed __int64, and then to double. 715 | * 716 | * If the 64 bit int value is greater than 2^63-1, which is the signed int64 max, 717 | * the macro below provides a workaround for casting a uint64 value to a double 718 | * in windows. 719 | */ 720 | # define uint64_to_double(u) ( ((u) > _I64_MAX) ? \ 721 | (double)(__int64)((u) - _I64_MAX - 1) + (double)_I64_MAX + 1: \ 722 | (double)(__int64)(u) ) 723 | 724 | /* The following inline function should only be used in the macro double_to_uint64, 725 | * as it only handles the specfic range of double between 2^63 and 2^64-1 */ 726 | __forceinline 727 | uint64_T double_to_uint64_helper(double d) { 728 | union double_to_uint64_union_type { 729 | double dd; 730 | uint64_T i64; 731 | } di; 732 | di.dd = d; 733 | return (((di.i64 & 0x000fffffffffffff) | 0x0010000000000000) << 11); 734 | } 735 | 736 | /* The largest double value that can be cast to uint64 in windows is the 737 | * signed int64 max, which is 2^63-1. The macro below provides 738 | * a workaround for casting large double values to uint64 in windows. 739 | */ 740 | /* The magic number 18446744073709551616.0 is 2^64 */ 741 | /* The magic number 9223372036854775808.0 is 2^63 */ 742 | # define double_to_uint64(d) ( ((d) >= 18446744073709551616.0) ? \ 743 | 0xffffffffffffffffULL : \ 744 | ((d) >= 0.0) ? \ 745 | ((d) >= 9223372036854775808.0) ? \ 746 | double_to_uint64_helper(d) : \ 747 | (unsigned __int64)(d) : \ 748 | 0ULL ) 749 | #else 750 | # define uint64_to_double(u) ((double)(u)) 751 | # if defined(__BORLANDC__) || defined(__WATCOMC__) || defined(__TICCSC__) 752 | /* double_to_uint64 defined only for MSVC and UNIX */ 753 | # else 754 | # define double_to_uint64(d) ( ((d) >= 18446744073709551616.0) ? \ 755 | (unsigned long long) 0xffffffffffffffffULL : \ 756 | ((d) >= 0) ? (unsigned long long)(d) : (unsigned long long) 0 ) 757 | # endif 758 | #endif 759 | 760 | #if !defined(__cplusplus) && !defined(__bool_true_false_are_defined) 761 | 762 | #ifndef _bool_T 763 | #define _bool_T 764 | 765 | typedef boolean_T bool; 766 | 767 | #ifndef false 768 | #define false (0) 769 | #endif 770 | #ifndef true 771 | #define true (1) 772 | #endif 773 | 774 | #endif /* _bool_T */ 775 | 776 | #endif /* !__cplusplus */ 777 | 778 | /* 779 | * This software assumes that the code is being compiled on a target using a 780 | * 2's complement representation for signed integer values. 781 | */ 782 | #if ((SCHAR_MIN + 1) != -SCHAR_MAX) 783 | #error "This code must be compiled using a 2's complement representation for signed integer values" 784 | #endif 785 | 786 | /* 787 | * Maximum length of a MATLAB identifier (function/variable/model) 788 | * including the null-termination character. 789 | */ 790 | #define TMW_NAME_LENGTH_MAX 64 791 | 792 | /* 793 | * Maximum values for indices and dimensions 794 | */ 795 | #include 796 | 797 | #ifdef MX_COMPAT_32 798 | typedef int mwSize; 799 | typedef int mwIndex; 800 | typedef int mwSignedIndex; 801 | #else 802 | typedef size_t mwSize; /* unsigned pointer-width integer */ 803 | typedef size_t mwIndex; /* unsigned pointer-width integer */ 804 | typedef ptrdiff_t mwSignedIndex; /* a signed pointer-width integer */ 805 | #endif 806 | 807 | /* for the individual dim */ 808 | #ifndef SLSIZE_SLINDEX 809 | #define SLSIZE_SLINDEX 810 | typedef int SLIndex; 811 | typedef int SLSize; 812 | #endif 813 | 814 | /* for the total size */ 815 | #define SLIndexType size_t 816 | #define INVALID_SIZET_VALUE (std::numeric_limits::max()) 817 | #define MAX_VALID_SIZET_VALUE (std::numeric_limits::max() -1) 818 | 819 | 820 | #if (defined(_LP64) || defined(_WIN64)) && !defined(MX_COMPAT_32) 821 | /* Currently 2^48 based on hardware limitations */ 822 | # define MWSIZE_MAX 281474976710655UL 823 | # define MWINDEX_MAX 281474976710655UL 824 | # define MWSINDEX_MAX 281474976710655L 825 | # define MWSINDEX_MIN -281474976710655L 826 | #else 827 | # define MWSIZE_MAX 2147483647UL 828 | # define MWINDEX_MAX 2147483647UL 829 | # define MWSINDEX_MAX 2147483647L 830 | # define MWSINDEX_MIN -2147483647L 831 | #endif 832 | #define MWSIZE_MIN 0UL 833 | #define MWINDEX_MIN 0UL 834 | 835 | /** UTF-16 character type */ 836 | 837 | #if (defined(__cplusplus) && (__cplusplus >= 201103L)) || (defined(_HAS_CHAR16_T_LANGUAGE_SUPPORT) && _HAS_CHAR16_T_LANGUAGE_SUPPORT) 838 | typedef char16_t CHAR16_T; 839 | #define U16_STRING_LITERAL_PREFIX u 840 | #elif defined(_MSC_VER) 841 | typedef wchar_t CHAR16_T; 842 | #define U16_STRING_LITERAL_PREFIX L 843 | #else 844 | typedef UINT16_T CHAR16_T; 845 | #endif 846 | 847 | #endif /* __TMWTYPES__ */ 848 | 849 | #endif /* tmwtypes_h */ 850 | -------------------------------------------------------------------------------- /bandpassFilter/validatestring.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // File: validatestring.cpp 3 | // 4 | // MATLAB Coder version : 4.3 5 | // C/C++ source code generated on : 17-Mar-2021 14:44:58 6 | // 7 | 8 | // Include Files 9 | #include "validatestring.h" 10 | #include "fir1.h" 11 | #include "rt_nonfinite.h" 12 | #include 13 | 14 | // Variable Definitions 15 | static const char cv[128] = { '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', 16 | '\x06', '\x07', '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f', 17 | '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', '\x18', '\x19', 18 | '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f', ' ', '!', '\"', '#', '$', '%', 19 | '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', 20 | '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'a', 'b', 'c', 'd', 21 | 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 22 | 'u', 'v', 'w', 'x', 'y', 'z', '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 23 | 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 24 | 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '\x7f' }; 25 | 26 | // Function Definitions 27 | 28 | // 29 | // Arguments : const char str_Value[5] 30 | // char out_data[] 31 | // int out_size[2] 32 | // Return Type : void 33 | // 34 | void b_validatestring(const char str_Value[5], char out_data[], int out_size[2]) 35 | { 36 | int partial_match_size_idx_1; 37 | boolean_T b_bool; 38 | int kstr; 39 | int exitg1; 40 | static const char b_cv[8] = { 'B', 'A', 'N', 'D', 'P', 'A', 'S', 'S' }; 41 | 42 | boolean_T matched; 43 | int nmatched; 44 | char partial_match_data[8]; 45 | static const char vstr[8] = { 'B', 'A', 'N', 'D', 'P', 'A', 'S', 'S' }; 46 | 47 | static const char cv1[7] = { 'N', 'O', 'S', 'C', 'A', 'L', 'E' }; 48 | 49 | static const char b_vstr[7] = { 'N', 'O', 'S', 'C', 'A', 'L', 'E' }; 50 | 51 | static const char cv2[5] = { 'S', 'C', 'A', 'L', 'E' }; 52 | 53 | static const char c_vstr[5] = { 'S', 'C', 'A', 'L', 'E' }; 54 | 55 | partial_match_size_idx_1 = 0; 56 | b_bool = false; 57 | kstr = 0; 58 | do { 59 | exitg1 = 0; 60 | if (kstr < 5) { 61 | if (cv[static_cast(str_Value[kstr]) & 127] != cv[ 62 | static_cast(b_cv[kstr])]) { 63 | exitg1 = 1; 64 | } else { 65 | kstr++; 66 | } 67 | } else { 68 | b_bool = true; 69 | exitg1 = 1; 70 | } 71 | } while (exitg1 == 0); 72 | 73 | if (b_bool) { 74 | partial_match_size_idx_1 = 8; 75 | for (kstr = 0; kstr < 8; kstr++) { 76 | partial_match_data[kstr] = vstr[kstr]; 77 | } 78 | 79 | matched = true; 80 | nmatched = 1; 81 | } else { 82 | matched = false; 83 | nmatched = 0; 84 | } 85 | 86 | b_bool = false; 87 | kstr = 0; 88 | do { 89 | exitg1 = 0; 90 | if (kstr < 5) { 91 | if (cv[static_cast(str_Value[kstr]) & 127] != cv[ 92 | static_cast(cv1[kstr])]) { 93 | exitg1 = 1; 94 | } else { 95 | kstr++; 96 | } 97 | } else { 98 | b_bool = true; 99 | exitg1 = 1; 100 | } 101 | } while (exitg1 == 0); 102 | 103 | if (b_bool) { 104 | if (!matched) { 105 | partial_match_size_idx_1 = 7; 106 | for (kstr = 0; kstr < 7; kstr++) { 107 | partial_match_data[kstr] = b_vstr[kstr]; 108 | } 109 | } 110 | 111 | nmatched++; 112 | } 113 | 114 | b_bool = false; 115 | kstr = 0; 116 | do { 117 | exitg1 = 0; 118 | if (kstr < 5) { 119 | if (cv[static_cast(str_Value[kstr]) & 127] != cv[ 120 | static_cast(cv2[kstr])]) { 121 | exitg1 = 1; 122 | } else { 123 | kstr++; 124 | } 125 | } else { 126 | b_bool = true; 127 | exitg1 = 1; 128 | } 129 | } while (exitg1 == 0); 130 | 131 | if (b_bool) { 132 | nmatched = 1; 133 | partial_match_size_idx_1 = 5; 134 | for (kstr = 0; kstr < 5; kstr++) { 135 | partial_match_data[kstr] = c_vstr[kstr]; 136 | } 137 | } else { 138 | if (nmatched == 0) { 139 | partial_match_size_idx_1 = 0; 140 | } 141 | } 142 | 143 | if ((nmatched == 0) || (partial_match_size_idx_1 == 0)) { 144 | out_size[0] = 1; 145 | out_size[1] = 0; 146 | } else { 147 | if (nmatched <= 1) { 148 | out_size[0] = 1; 149 | out_size[1] = partial_match_size_idx_1; 150 | if (0 <= partial_match_size_idx_1 - 1) { 151 | std::memcpy(&out_data[0], &partial_match_data[0], 152 | partial_match_size_idx_1 * sizeof(char)); 153 | } 154 | } 155 | } 156 | } 157 | 158 | // 159 | // Arguments : const char str_Value[8] 160 | // char out_data[] 161 | // int out_size[2] 162 | // Return Type : void 163 | // 164 | void validatestring(const char str_Value[8], char out_data[], int out_size[2]) 165 | { 166 | boolean_T b_bool; 167 | int kstr; 168 | int exitg1; 169 | static const char b_cv[8] = { 'B', 'A', 'N', 'D', 'P', 'A', 'S', 'S' }; 170 | 171 | int i; 172 | static const char vstr[8] = { 'B', 'A', 'N', 'D', 'P', 'A', 'S', 'S' }; 173 | 174 | b_bool = false; 175 | kstr = 0; 176 | do { 177 | exitg1 = 0; 178 | if (kstr < 8) { 179 | if (cv[static_cast(str_Value[kstr]) & 127] != cv[ 180 | static_cast(b_cv[kstr])]) { 181 | exitg1 = 1; 182 | } else { 183 | kstr++; 184 | } 185 | } else { 186 | b_bool = true; 187 | exitg1 = 1; 188 | } 189 | } while (exitg1 == 0); 190 | 191 | if (b_bool) { 192 | kstr = 1; 193 | out_size[0] = 1; 194 | out_size[1] = 8; 195 | for (i = 0; i < 8; i++) { 196 | out_data[i] = vstr[i]; 197 | } 198 | } else { 199 | kstr = 0; 200 | out_size[0] = 1; 201 | out_size[1] = 0; 202 | } 203 | 204 | if ((kstr == 0) || (out_size[1] == 0)) { 205 | out_size[0] = 1; 206 | out_size[1] = 0; 207 | } 208 | } 209 | 210 | // 211 | // File trailer for validatestring.cpp 212 | // 213 | // [EOF] 214 | // 215 | -------------------------------------------------------------------------------- /bandpassFilter/validatestring.h: -------------------------------------------------------------------------------- 1 | // 2 | // File: validatestring.h 3 | // 4 | // MATLAB Coder version : 4.3 5 | // C/C++ source code generated on : 17-Mar-2021 14:44:58 6 | // 7 | #ifndef VALIDATESTRING_H 8 | #define VALIDATESTRING_H 9 | 10 | // Include Files 11 | #include 12 | #include 13 | #include "rtwtypes.h" 14 | #include "fir1_types.h" 15 | 16 | // Function Declarations 17 | extern void b_validatestring(const char str_Value[5], char out_data[], int 18 | out_size[2]); 19 | extern void validatestring(const char str_Value[8], char out_data[], int 20 | out_size[2]); 21 | 22 | #endif 23 | 24 | // 25 | // File trailer for validatestring.h 26 | // 27 | // [EOF] 28 | // 29 | -------------------------------------------------------------------------------- /bandpassFilter/xnrm2.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // File: xnrm2.cpp 3 | // 4 | // MATLAB Coder version : 4.3 5 | // C/C++ source code generated on : 17-Mar-2021 14:44:58 6 | // 7 | 8 | // Include Files 9 | #include "xnrm2.h" 10 | #include "fir1.h" 11 | #include "rt_nonfinite.h" 12 | #include 13 | 14 | // Function Definitions 15 | 16 | // 17 | // Arguments : int n 18 | // const emxArray_real_T *x 19 | // int ix0 20 | // Return Type : double 21 | // 22 | double xnrm2(int n, const emxArray_real_T *x, int ix0) 23 | { 24 | double y; 25 | double scale; 26 | int kend; 27 | int k; 28 | double absxk; 29 | double t; 30 | y = 0.0; 31 | if (n >= 1) { 32 | if (n == 1) { 33 | y = std::abs(x->data[ix0 - 1]); 34 | } else { 35 | scale = 3.3121686421112381E-170; 36 | kend = (ix0 + n) - 1; 37 | for (k = ix0; k <= kend; k++) { 38 | absxk = std::abs(x->data[k - 1]); 39 | if (absxk > scale) { 40 | t = scale / absxk; 41 | y = y * t * t + 1.0; 42 | scale = absxk; 43 | } else { 44 | t = absxk / scale; 45 | y += t * t; 46 | } 47 | } 48 | 49 | y = scale * std::sqrt(y); 50 | } 51 | } 52 | 53 | return y; 54 | } 55 | 56 | // 57 | // File trailer for xnrm2.cpp 58 | // 59 | // [EOF] 60 | // 61 | -------------------------------------------------------------------------------- /bandpassFilter/xnrm2.h: -------------------------------------------------------------------------------- 1 | // 2 | // File: xnrm2.h 3 | // 4 | // MATLAB Coder version : 4.3 5 | // C/C++ source code generated on : 17-Mar-2021 14:44:58 6 | // 7 | #ifndef XNRM2_H 8 | #define XNRM2_H 9 | 10 | // Include Files 11 | #include 12 | #include 13 | #include "rtwtypes.h" 14 | #include "fir1_types.h" 15 | 16 | // Function Declarations 17 | extern double xnrm2(int n, const emxArray_real_T *x, int ix0); 18 | 19 | #endif 20 | 21 | // 22 | // File trailer for xnrm2.h 23 | // 24 | // [EOF] 25 | // 26 | -------------------------------------------------------------------------------- /bandpassFilter/xzgeqp3.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // File: xzgeqp3.cpp 3 | // 4 | // MATLAB Coder version : 4.3 5 | // C/C++ source code generated on : 17-Mar-2021 14:44:58 6 | // 7 | 8 | // Include Files 9 | #include "xzgeqp3.h" 10 | #include "fir1.h" 11 | #include "fir1_emxutil.h" 12 | #include "fir1_rtwutil.h" 13 | #include "rt_nonfinite.h" 14 | #include "xnrm2.h" 15 | #include 16 | 17 | // Function Definitions 18 | 19 | // 20 | // Arguments : emxArray_real_T *A 21 | // int m 22 | // int n 23 | // emxArray_real_T *tau 24 | // emxArray_int32_T *jpvt 25 | // Return Type : void 26 | // 27 | void qrpf(emxArray_real_T *A, int m, int n, emxArray_real_T *tau, 28 | emxArray_int32_T *jpvt) 29 | { 30 | emxArray_real_T *work; 31 | int ma; 32 | int minmn; 33 | int i; 34 | int itemp; 35 | emxArray_real_T *vn1; 36 | emxArray_real_T *vn2; 37 | int j; 38 | int b_i; 39 | double smax; 40 | int ip1; 41 | int iy; 42 | int ii; 43 | int nmi; 44 | int mmi; 45 | int ix; 46 | int pvt; 47 | double temp2; 48 | double s; 49 | int jA; 50 | int lastv; 51 | boolean_T exitg2; 52 | int exitg1; 53 | emxInit_real_T(&work, 1); 54 | ma = A->size[0]; 55 | if (m < n) { 56 | minmn = m; 57 | } else { 58 | minmn = n; 59 | } 60 | 61 | i = work->size[0]; 62 | work->size[0] = A->size[1]; 63 | emxEnsureCapacity_real_T(work, i); 64 | itemp = A->size[1]; 65 | for (i = 0; i < itemp; i++) { 66 | work->data[i] = 0.0; 67 | } 68 | 69 | emxInit_real_T(&vn1, 1); 70 | i = vn1->size[0]; 71 | vn1->size[0] = A->size[1]; 72 | emxEnsureCapacity_real_T(vn1, i); 73 | itemp = A->size[1]; 74 | for (i = 0; i < itemp; i++) { 75 | vn1->data[i] = 0.0; 76 | } 77 | 78 | emxInit_real_T(&vn2, 1); 79 | i = vn2->size[0]; 80 | vn2->size[0] = A->size[1]; 81 | emxEnsureCapacity_real_T(vn2, i); 82 | itemp = A->size[1]; 83 | for (i = 0; i < itemp; i++) { 84 | vn2->data[i] = 0.0; 85 | } 86 | 87 | for (j = 0; j < n; j++) { 88 | smax = xnrm2(m, A, j * ma + 1); 89 | vn1->data[j] = smax; 90 | vn2->data[j] = smax; 91 | } 92 | 93 | for (b_i = 0; b_i < minmn; b_i++) { 94 | ip1 = b_i + 2; 95 | iy = b_i * ma; 96 | ii = iy + b_i; 97 | nmi = n - b_i; 98 | mmi = m - b_i; 99 | if (nmi < 1) { 100 | itemp = -1; 101 | } else { 102 | itemp = 0; 103 | if (nmi > 1) { 104 | ix = b_i; 105 | smax = std::abs(vn1->data[b_i]); 106 | for (j = 2; j <= nmi; j++) { 107 | ix++; 108 | s = std::abs(vn1->data[ix]); 109 | if (s > smax) { 110 | itemp = j - 1; 111 | smax = s; 112 | } 113 | } 114 | } 115 | } 116 | 117 | pvt = b_i + itemp; 118 | if (pvt + 1 != b_i + 1) { 119 | ix = pvt * ma; 120 | for (j = 0; j < m; j++) { 121 | smax = A->data[ix]; 122 | A->data[ix] = A->data[iy]; 123 | A->data[iy] = smax; 124 | ix++; 125 | iy++; 126 | } 127 | 128 | itemp = jpvt->data[pvt]; 129 | jpvt->data[pvt] = jpvt->data[b_i]; 130 | jpvt->data[b_i] = itemp; 131 | vn1->data[pvt] = vn1->data[b_i]; 132 | vn2->data[pvt] = vn2->data[b_i]; 133 | } 134 | 135 | if (b_i + 1 < m) { 136 | temp2 = A->data[ii]; 137 | itemp = ii + 2; 138 | tau->data[b_i] = 0.0; 139 | if (mmi > 0) { 140 | smax = xnrm2(mmi - 1, A, ii + 2); 141 | if (smax != 0.0) { 142 | s = rt_hypotd_snf(A->data[ii], smax); 143 | if (A->data[ii] >= 0.0) { 144 | s = -s; 145 | } 146 | 147 | if (std::abs(s) < 1.0020841800044864E-292) { 148 | pvt = -1; 149 | i = ii + mmi; 150 | do { 151 | pvt++; 152 | for (j = itemp; j <= i; j++) { 153 | A->data[j - 1] *= 9.9792015476736E+291; 154 | } 155 | 156 | s *= 9.9792015476736E+291; 157 | temp2 *= 9.9792015476736E+291; 158 | } while (!(std::abs(s) >= 1.0020841800044864E-292)); 159 | 160 | s = rt_hypotd_snf(temp2, xnrm2(mmi - 1, A, ii + 2)); 161 | if (temp2 >= 0.0) { 162 | s = -s; 163 | } 164 | 165 | tau->data[b_i] = (s - temp2) / s; 166 | smax = 1.0 / (temp2 - s); 167 | for (j = itemp; j <= i; j++) { 168 | A->data[j - 1] *= smax; 169 | } 170 | 171 | for (j = 0; j <= pvt; j++) { 172 | s *= 1.0020841800044864E-292; 173 | } 174 | 175 | temp2 = s; 176 | } else { 177 | tau->data[b_i] = (s - A->data[ii]) / s; 178 | smax = 1.0 / (A->data[ii] - s); 179 | i = ii + mmi; 180 | for (j = itemp; j <= i; j++) { 181 | A->data[j - 1] *= smax; 182 | } 183 | 184 | temp2 = s; 185 | } 186 | } 187 | } 188 | 189 | A->data[ii] = temp2; 190 | } else { 191 | tau->data[b_i] = 0.0; 192 | } 193 | 194 | if (b_i + 1 < n) { 195 | temp2 = A->data[ii]; 196 | A->data[ii] = 1.0; 197 | jA = (ii + ma) + 1; 198 | if (tau->data[b_i] != 0.0) { 199 | lastv = mmi - 1; 200 | itemp = (ii + mmi) - 1; 201 | while ((lastv + 1 > 0) && (A->data[itemp] == 0.0)) { 202 | lastv--; 203 | itemp--; 204 | } 205 | 206 | nmi -= 2; 207 | exitg2 = false; 208 | while ((!exitg2) && (nmi + 1 > 0)) { 209 | itemp = jA + nmi * ma; 210 | j = itemp; 211 | do { 212 | exitg1 = 0; 213 | if (j <= itemp + lastv) { 214 | if (A->data[j - 1] != 0.0) { 215 | exitg1 = 1; 216 | } else { 217 | j++; 218 | } 219 | } else { 220 | nmi--; 221 | exitg1 = 2; 222 | } 223 | } while (exitg1 == 0); 224 | 225 | if (exitg1 == 1) { 226 | exitg2 = true; 227 | } 228 | } 229 | } else { 230 | lastv = -1; 231 | nmi = -1; 232 | } 233 | 234 | if (lastv + 1 > 0) { 235 | if (nmi + 1 != 0) { 236 | for (iy = 0; iy <= nmi; iy++) { 237 | work->data[iy] = 0.0; 238 | } 239 | 240 | iy = 0; 241 | i = jA + ma * nmi; 242 | for (itemp = jA; ma < 0 ? itemp >= i : itemp <= i; itemp += ma) { 243 | ix = ii; 244 | smax = 0.0; 245 | pvt = itemp + lastv; 246 | for (j = itemp; j <= pvt; j++) { 247 | smax += A->data[j - 1] * A->data[ix]; 248 | ix++; 249 | } 250 | 251 | work->data[iy] += smax; 252 | iy++; 253 | } 254 | } 255 | 256 | if (!(-tau->data[b_i] == 0.0)) { 257 | itemp = 0; 258 | for (j = 0; j <= nmi; j++) { 259 | if (work->data[itemp] != 0.0) { 260 | smax = work->data[itemp] * -tau->data[b_i]; 261 | ix = ii; 262 | i = lastv + jA; 263 | for (pvt = jA; pvt <= i; pvt++) { 264 | A->data[pvt - 1] += A->data[ix] * smax; 265 | ix++; 266 | } 267 | } 268 | 269 | itemp++; 270 | jA += ma; 271 | } 272 | } 273 | } 274 | 275 | A->data[ii] = temp2; 276 | } 277 | 278 | for (j = ip1; j <= n; j++) { 279 | itemp = b_i + (j - 1) * ma; 280 | smax = vn1->data[j - 1]; 281 | if (smax != 0.0) { 282 | s = std::abs(A->data[itemp]) / smax; 283 | s = 1.0 - s * s; 284 | if (s < 0.0) { 285 | s = 0.0; 286 | } 287 | 288 | temp2 = smax / vn2->data[j - 1]; 289 | temp2 = s * (temp2 * temp2); 290 | if (temp2 <= 1.4901161193847656E-8) { 291 | if (b_i + 1 < m) { 292 | smax = xnrm2(mmi - 1, A, itemp + 2); 293 | vn1->data[j - 1] = smax; 294 | vn2->data[j - 1] = smax; 295 | } else { 296 | vn1->data[j - 1] = 0.0; 297 | vn2->data[j - 1] = 0.0; 298 | } 299 | } else { 300 | vn1->data[j - 1] = smax * std::sqrt(s); 301 | } 302 | } 303 | } 304 | } 305 | 306 | emxFree_real_T(&vn2); 307 | emxFree_real_T(&vn1); 308 | emxFree_real_T(&work); 309 | } 310 | 311 | // 312 | // File trailer for xzgeqp3.cpp 313 | // 314 | // [EOF] 315 | // 316 | -------------------------------------------------------------------------------- /bandpassFilter/xzgeqp3.h: -------------------------------------------------------------------------------- 1 | // 2 | // File: xzgeqp3.h 3 | // 4 | // MATLAB Coder version : 4.3 5 | // C/C++ source code generated on : 17-Mar-2021 14:44:58 6 | // 7 | #ifndef XZGEQP3_H 8 | #define XZGEQP3_H 9 | 10 | // Include Files 11 | #include 12 | #include 13 | #include "rtwtypes.h" 14 | #include "fir1_types.h" 15 | 16 | // Function Declarations 17 | extern void qrpf(emxArray_real_T *A, int m, int n, emxArray_real_T *tau, 18 | emxArray_int32_T *jpvt); 19 | 20 | #endif 21 | 22 | // 23 | // File trailer for xzgeqp3.h 24 | // 25 | // [EOF] 26 | // 27 | -------------------------------------------------------------------------------- /fdacoefs.h: -------------------------------------------------------------------------------- 1 | #ifndef FDACOEFS_H 2 | #define FDACOEFS_H 3 | 4 | /*----------------------------滤波器系数----------------------------------------*/ 5 | 6 | static float FC_HZ_32[100] = {0}; 7 | 8 | static float FC_HZ_63[100] = {0}; 9 | 10 | static float FC_HZ_125[100] = {0}; 11 | 12 | static float FC_HZ_250[100] = {0}; 13 | 14 | static float FC_HZ_500[100] = {0}; 15 | 16 | static float FC_HZ_1000[100] = {0}; 17 | 18 | static float FC_HZ_2000[100] = {0}; 19 | 20 | static float FC_HZ_4000[100] = {0}; 21 | 22 | static float FC_HZ_8000[100] = {0}; 23 | 24 | static float FC_HZ_16000[100] = {0}; 25 | 26 | /*----------------------------------------------------------------------------------*/ 27 | 28 | 29 | #endif // FDACOEFS_H 30 | -------------------------------------------------------------------------------- /frequency.md: -------------------------------------------------------------------------------- 1 | 2 | 3 |

频率响应

4 | 5 | ### 频率特性 6 | 7 | ​ 音频设备的频率响应是指将一个以恒电压输出的音频信号与系统相连接时,音频功率放大器产生的声压随频率的变化而发生增大或衰减、相位随频率而发生变化的现象。其是否平坦直接影响音色、音场表现等音质效果,是音频设备最主要的参数之一。音频功率放大电路中总是含有电抗元件,它的增益与频率有关,正常工作的频率范围是有限的,一旦超出这个范围,输出信号将不能按原有增益放大,从而导致失真。 音频功率放大电路的幅值和频率之间的关系,称为幅频特性,在额定的频率范围内,输出电压幅度的最大值与最小值之比,以分贝数(dB)来表示其不均匀度。增益频率函数在中频段增益根本不随频率而变化,我们称中频段的增益为中频增益。在中频增益段的左、右两边,随着频率的减小或增加,增益都要下降,分别称为低频增益段和高频增益段。通常把增益下降到中频增益的0.707倍(即`3dB`)处所对应的下限频率和上限频率,称为功率放大的带宽,如图1所示。 8 | 9 | ![](附件/频率响应.png) 10 | 11 |
图-1 频率响应
12 | 13 | ​ 音频设备的频率响应特性直接影响音色、音场等听觉效果。如果频率响应特性不平坦,有某段频率下陷的地方,则这一频段就会听不太清楚,而突出的频段则又会把较弱的频段遮盖掉,如图2所示。为了获取更好的听觉效果,需要改善音频设备的频响特性,进行频率响应补偿。图示均衡器使用模拟信号处理方法,对预先设置的 8 或 10 个频点进行提升或衰减,以获得所需的平坦频响。 14 | ​ ![](附件/频率响应特性.png) 15 | 16 |
图-2 频率响应曲线图
17 | 18 | ### 模拟与数字信号 19 | 20 | ​ 我们本身生活在一个模拟量的世界里,所谓模拟量,即连续变化量,屋里的温度是连续变化的,时间是连续变化的,诸如此类。而计算机是数字系统,他不能处理模拟量,而只能处理离散量,这意味着我们要把连续的模拟量进行采样,得到一系列离散的数字量。模拟量和数字量可以相互转换,模/数转换(A/D)和数/模转换(D/A) 。A/D转换通常使用`PCM`(脉冲编码调制)技术来实现,未经过数据压缩,直接量化进行传输则被称为`PCM`(脉冲编码调制)。A/D转换过程包括三个阶段,即取样、量化、编码。模数转换是将模拟信号转换成数字信号的系统,是一个滤波、采样保持和编码的过程。 21 | 22 | ​ 采样是指将时间轴上连续的信号每隔一定的时间间隔抽取出一个信号的幅度样本,把连续的模拟量用一个个离散的点来表示,称为时间上离散的脉冲序列。每秒钟采样的次数称为采样频率,用`ƒs`表示;样本之间的时间间隔称为取样周期,用T表示,`T=1/ƒs`。采样频率为`44.1kHz`,表示每秒钟采样44100次,如图3所示。常用的采样频率有`8kHz、22.05kHz、44.1kHz、48kHz`等。 23 | 24 | 25 | 26 | ![](附件/encod02.png) 27 | 28 | 29 | 30 |
图-3 数字信号和模拟信号
31 | 32 | ​ 量化就是把采集到的数值送到量化器(A/D转换器)编码成数字,每个数字代表一次采样所获得的声音信号的瞬间值。量化时,把整个幅度划分为几个量化级(量化数据位数),把落入同一级的样本值归为一类,并给定一个量化值,如图4所示。量化级数越多,量化误差就越小,声音质量就越好。 33 | 34 | ![](附件/encod04.png) 35 | 36 |
图-4 量化等级
37 | 38 | ​ 量化级对应的二进制位数称为量化位数,量化位数是每个采样点能够表示的数据范围,有时也称采样位数,量化位数(大小)决定了模拟信号数字化以后声音的动态范围。量化级是描述声音波形的数据是多少位的二进制数据,通常用bit做单位,如`16bit、24bit。16bit`量化级记录声音的数据是用16位的二进制数,因此,量化级也是数字声音质量的重要指标。 39 | 40 | ​ 编码是指采样、量化后的信号还不是数字信号,需要按一定的格式将离散的数字信号记录下来,并在数据的前、后加上同步、纠错等控制信号,再把它转换成数字编码脉冲,这一过程称为编码。编码有一定格式标准,最简单的编码方式是二进制编码。用这样方式组成的脉冲串的频率等于采样频率与量化比特数的积,称为所传输数字信号的数码率(音频:数据率、视频:码率)。显然,采样频率越高,量化比特数越大,数码率就越高,所需要的传输带宽就越宽。计算公式如下: 41 | 42 |
数码率(bps)=采样频率(Hz)×量化位数(bit)×声道数(bit/s)
43 | 44 | 45 | 46 | ​ 自然界的信号都不是很干净的,都会有噪声。信号和噪声混叠在一起的,图5是一个更接近于真实的模拟信号强度随时间变化的数据集,图6是真实信号采样图。 47 | 48 | ![](附件/M03.jpg) 49 | 50 |
图-5 模拟信号源
51 | 52 | ![](附件/M04.jpg) 53 | 54 |
图-6 真实信号采样
55 | 56 | 57 | 58 | ​ 用一条线把采样点连接起来,采集的到的数字波形可以看出明显的上下振动。由于高频噪声和原来的低频真实信号相叠加,最后采集出来的数据和原来的数据相比不一致,如图7所示。这是因为采样的频率远低于噪声信号的频率,发生了信号和噪声混叠在一起。 59 | 60 | ![](附件/M05.jpg) 61 | 62 |
图-7 信号和噪声混叠
63 | 64 | ​ 混叠通常是有害但又不可能100%避免,由奈奎斯特定理可知想要完整采集某个频率的信号,那么你至少要用2倍于该信号的最高频率的采样率来采集,否则混叠就会发生。除了提高采样率,另外一种避免混叠的方法是使用抗混叠滤波器. 通常在数字化之前使用一个低通滤波器把噪声滤掉即可。例如采样之前安装一个低通滤波器,截止频率为`10Hz` 那么你只需要一个`20Hz`的采样率就可以把你感兴趣的信号采集进来。高频噪声在采样之前就被模拟低通滤波器干掉了。当然,如果你采样频率够高,那么采样进来后才进行数字低通滤波也可以进行噪声过滤,而且绝大多数应用就是用的这种方法。 65 | 66 | ### `FFT` 傅里叶变换 67 | 68 | ​ 傅里叶变换是指任何连续周期信号可以由一组适当的正弦曲线组合而成,换言之,满足一定条件的连续函数(周期函数)都可以表示成一系列三角函数(正弦和/或余弦函数)或者它们的积分的线性组合形式,这个转换就称为傅里叶转换。离散傅里叶变换其实可以看作是“离散时间傅里叶变换”(`DTFT`)的一个特例,离散时间傅里叶变换在时域是离散的,但是在频域是连续的,而离散傅里叶变换则在时域和频域都以离散的形式呈现,因此,离散傅里叶变换更适用于所有使用计算机处理数据的场合。 69 | 70 | ​ 离散傅里叶变换的原理,首先要从连续傅里叶变换开始。因为工程中用的最广泛的是非周期信号,所以我们只关注非周期信号的处理方式。非周期信号傅里叶变换的基本思想就是:把非周期信号当成一个周期无限大的周期信号,然后研究这个无限大周期信号的傅里叶转换的极限特征。换句话说,就是把你要处理的非周期信号看作是一个只有一个周期的周期信号,所有的数据是周期性的,只不过只有一个周期而已。 71 | 72 | ​ 下面使用`MATLAB`函数生成正弦信号加上白噪声的叠加信号,绘制时域数据窗口显示,如图9所示。 73 | 74 | ```matlab 75 | %指定信号的参数,采样频率为 1 kHz,信号持续时间为 1.5 秒。 76 | Fs = 1000; % Sampling frequency 77 | T = 1/Fs; % Sampling period 78 | L = 1500; % Length of signal 79 | t = (0:L-1)*T; % Time vector 80 | 81 | %构造一个信号,其中包含幅值为 0.7 的 50 Hz 正弦量和幅值为 1 的 120 Hz 正弦量。 82 | S = 0.7*sin(2*pi*50*t) + sin(2*pi*120*t); 83 | 84 | %用均值为零、方差为4的白噪声扰乱该信号。 85 | X = S + 2*randn(size(t)); 86 | 87 | %在时域中绘制含噪信号。通过查看信号 X(t) 很难确定频率分量。 88 | subplot(2,1,1) %1st subplot 89 | plot(1000*t(1:50),S(1:50)); 90 | title('Raw Data') 91 | ylabel('X(t)') 92 | 93 | subplot(2,1,2) %2nd subplot 94 | plot(1000*t(1:50),X(1:50)); 95 | title('Signal Corrupted with Zero-Mean Random Noise'); 96 | xlabel('t (milliseconds)') 97 | ylabel('X(t)') 98 | ``` 99 | 100 | 101 | 102 | ![](附件/fft01.png) 103 | 104 |
图-9 零均值随机噪声破坏信号
105 | 106 | ​ 下面使用`MATLAB`的`fft`函数进行快速傅里叶变换,绘制频域数据窗口显示,如图10所示。 107 | 108 | ```matlab 109 | %计算原始信号的傅里叶变换。 110 | Y = fft(S); 111 | P2 = abs(Y/L); 112 | P1 = P2(1:L/2+1); 113 | P1(2:end-1) = 2*P1(2:end-1); 114 | f = Fs*(0:(L/2))/L; 115 | subplot(2,1,1) %1st subplot 116 | plot(f,P1) 117 | title('Single-Sided Amplitude Spectrum of S(t)') 118 | xlabel('f (Hz)') 119 | ylabel('|P1(f)|') 120 | 121 | %计算混叠信号的傅里叶变换。 122 | Y = fft(X); 123 | 124 | %计算双侧频谱 P2。然后基于 P2 和偶数信号长度 L 计算单侧频谱 P1。 125 | P2 = abs(Y/L); 126 | P1 = P2(1:L/2+1); 127 | P1(2:end-1) = 2*P1(2:end-1); 128 | 129 | %定义频域 f 并绘制单侧幅值频谱 P1。与预期相符,由于增加了噪声,幅值并不精确等于 0.7 和 1。 130 | %一般情况下,较长的信号会产生更好的频率近似值。 131 | f = Fs*(0:(L/2))/L; 132 | subplot(2,1,2) %2st subplot 133 | plot(f,P1) 134 | title('Single-Sided Amplitude Spectrum of X(t)') 135 | xlabel('f (Hz)') 136 | ylabel('|P1(f)|') 137 | ``` 138 | 139 | 140 | 141 | ![](附件/fft02.png) 142 | 143 |
图-10 单端振幅谱
144 | 145 | 146 | 147 | ### 数字滤波器 148 | 149 | ​ 滤波是信号处理中的一种基本而重要的技术,利用滤波技术可以在形形色色的信号中提取所需的信号,抑制不需要的干扰信号。按处理信号不同,滤波器可分为模拟滤波器与数字滤波器两大类。模拟滤波器是用来处理模拟信号或连续时间信号,数字滤波器是用来处理离散的数字信号。与模拟滤波器相比,数字滤波器具有诸多优点:可以用软件编程;稳定性高,可预测;不会因温度、湿度的影响产生误差,不需要高精度元件;很高的性能价格比。 150 | 151 |   滤波器是频率选择电路,只允许输入信号中的一定频率成分通过,与模拟滤波器相同,按通带来划分可将数字滤波器分为4种类型: 152 | 153 | (1)低通滤波器(`Lowpass filter`) :通过低频,滤除高频。 154 | (2)高通滤波器(`Highpass filter`):通过高频,滤除低频。 155 | (3)带通滤波器(`Bandpass filter`):通过固定范围的频率。 156 | (4)带阻滤波器(`Bandstop filter`):滤除固定范围的频率。 157 | 158 | 以上 4 种滤波器的理想频率响应,如图11所示。 159 | 160 | 161 | 162 | ![](附件/filter01.png) 163 | 164 |
图-11 数字滤波器类型
165 | 166 | ​ 滤波器允许通过的频率范围为通频带,理想滤波器通频带的增益为1,所以信号的幅值不变。截止频带是滤波器不允许通过的频率范围。理论上滤波器在通带应有单位增益(0 dB),在阻带有0增益(-∞ dB),然而在实际中通阻带之间有一个过渡范围,如下图所示。在这一范围,增益在0~1之间。在应用中,允许增益在单位增益上下轻微变化,即允许有通带纹波,如图12所示。这一点也是实际滤波器与理想滤波器的区别。阻带衰减在实际中不是无限的,通带纹波与阻带衰减可表示为: 167 | 168 | ![](附件/filter03.png) 169 | 170 | 其中`A0(f)、Ai(f)`分别是一定频率f下的输出和输入振幅,通带波纹的单位为分贝(dB)。 171 | 172 | 173 | 174 | ![](附件/filter02.png) 175 | 176 |
图-12 数字滤波通带纹波
177 | 178 | ​ 例如对于`-0.02dB`的波纹![](附件/math01.png)这表明,输出和输入的幅值之比近似为1。当阻带有`-60dB`的衰减,![](附件/math02.png),表明输出的幅度是输入的1/1000,如图13所示。 179 | 180 | ![](附件/filter04.png) 181 | 182 |
图-13 数字滤波增益
183 | 184 | ### `FIR(有限冲击响应滤波器)` 185 | 186 | ​ FIR(Finite Impulse Response)滤波器是指有限长单位冲激响应滤波器,又称为非递归型滤波器,是数字信号处理系统中最基本的元件,它可以在保证任意幅频特性的同时具有严格的线性相频特性,同时其单位抽样响应是有限长的,因而滤波器是稳定的系统。滑动平均滤波器就是FIR滤波器的一种。在一些应用中,有一个窗口,每一次新的数据进来都在窗口进行一次平局然后输出,如图14所示。 187 | 188 | ![](附件/FIR filter01.png) 189 | 190 |
图-14 3点滑动平均滤波器
191 | 192 | ​ 在这个滤波器中,可以看到每次把前三个数据进行平均(分别乘以0.33333)然后输出。 这三个系数的不同组合(0.3333, 0.333, 0.3333)就组成了各种FIR滤波器。这些系数叫做滤波系数。 在`matlab`中,他们叫做 b,滤波系数。 193 | 194 | ​ 下面是一个移动平均滤波器的例子,使用plot函数绘制图形显示,如图15所示。 195 | 196 | ```matlab 197 | npts=1000; 198 | b=[.2 .2 .2 .2 .2]; % create filter coefficients for 5- point moving average 199 | 200 | x=(rand(npts,1)*2)-1; % raw data from -1 to +1 201 | filtered_data=filter(b,1,x); % filter using 'b' coefficients 202 | 203 | subplot(2,2,1); % 1st subplot 204 | plot(x); % plot raw data 205 | title('Raw Data'); 206 | subplot(2,2,3); % 2nd subplot 207 | plot(filtered_data); %plot filtered data 208 | title('Filtered Data'); 209 | xlabel('Time') 210 | 211 | % Perform FFT on original and filtered signal 212 | fftpts=npts; % number points in FFT 213 | hpts=fftpts/2; % half number of FFT points 214 | x_fft=abs(fft(x))/hpts; %scaled FFT of original signal 215 | filtered_fft=abs(fft(filtered_data))/hpts; %scaled FFT of filtered signal 216 | 217 | subplot(2,2,2) %1st subplot 218 | plot(x_fft(1:hpts)); %plot first half of data points 219 | title('Raw Data'); 220 | subplot(2,2,4) %2nd subplot 221 | plot(filtered_fft(1:hpts));%plot first half data points 222 | title('Filtered Data'); 223 | xlabel('Frequency'); 224 | ``` 225 | 226 | 227 | 228 | ![](附件/FIR filter02.png) 229 | 230 |
图-15 FIR低通滤波器
231 | 232 | ​ 滑动动平均滤波器 一开始滤波的时候没有之前的数据做平均, `matlab`的 filter函数是这样计算的 233 | 234 |
filtered_data(2) = x(1)*0.2 + x(2)*0.2
235 | 236 | ​ 5点滑动滤波的计算公式是: 237 | 238 |
filtered_data(n) = b(1)*x(n) + b(2)*x(n-1) + b(3)*x(n-2) + b(4)*x(n-3) + b(5)*x(n-4)
239 | 240 | 241 | 242 | ![](附件/FIR filter03.png) 243 | 244 |
图-16 FIR滤波器基本结构
245 | 246 | ​ 如果滤波器的阶数很大(N) 那么滤波后的数据要比原始信号"迟缓" 很多。这叫做相位延时可以看出,5点滑动平均滤波器会使高频分量衰减。这是一种低通滤波器, 通低频,阻高频。FIR滤波器基本结构,如图16所示。 247 | 248 | 249 | 250 | ### `IIR(无限冲击响应滤波器)` 251 | 252 | ​ `IIR`数字滤波器采用递归型结构,即结构上带有反馈环路。`IIR`和`FIR`类似,不过进入了反馈机制。即下一次的滤波输出不仅仅和上几次的输入信号有关,还和上几次的输出信号有关。`IIR`比`FIR`"效率"更高,通常用更少的系数就可以达到很好的滤波结果,但是`IIR`也有缺点,由于引入了反馈机制,一些特定的系数组成的`IIR`滤波器可能不稳定,造成输出结果崩溃。。根据`IIR`滤波器的不同系数 有很多经典的`IIR`滤波器,例如`Butterworth`, `Chebyshew`, Bessel等。 253 | 254 | ​ 下面例子使用巴特沃斯滤波器(`butterworth`),使用plot函数绘制图形显示,如图17所示。 255 | 256 | ```matlab 257 | % Butterworth IIR Filter 258 | %先产生一个采样频率1000Hz, 2000个采样点的随机信号,然后用butter滤一波 259 | srate=1000; % sample rate 260 | npts=2000; %npts in signal 261 | Nyquist=srate/2; %Nyquist frequency 262 | lpf=300; %low-pass frequency 263 | order=5; %filter order 264 | t=[0:npts-1]/srate; %time scale for plot 265 | x=(rand(npts,1)*2)-1; % raw data from -1 to +1 266 | 267 | [b,a]=butter(order,lpf/Nyquist); %create filter coefficients 268 | 269 | filtered_data=filter(b,a,x); % filter using 'b' and 'a' coefficients 270 | 271 | % Calculate FFT 272 | fftpts=npts; % number points in FFT 273 | hpts=fftpts/2; % half number of FFT points 274 | binwidth=srate/fftpts; 275 | f=[0:binwidth:srate-binwidth]; 276 | x_fft=abs(fft(x))/hpts; %scaled FFT of original signal 277 | filtered_fft=abs(fft(filtered_data))/hpts; %scaled FFT of filtered signal 278 | 279 | subplot(2,2,1) 280 | plot(t,x); 281 | title('Raw Time Series'); 282 | subplot(2,2,3) 283 | plot(t,filtered_data); 284 | title('Filtered Time Series'); 285 | xlabel('Time (s)'); 286 | subplot(2,2,2) 287 | plot(f(1:hpts),x_fft(1:hpts)); 288 | title('Raw FFT'); 289 | subplot(2,2,4) 290 | plot(f(1:hpts),filtered_fft(1:hpts)); 291 | title('Filtered FFT'); 292 | xlabel('Frequency (Hz)'); 293 | ``` 294 | 295 | ​ butter 函数是`matlab`内置函数,输入截止频率和阶数,返回滤波器系数,b, a。 b 就跟FIR 一样的b(前馈系数), a指的是后馈系数。 296 | 297 | ![](附件/FIR filter02.png) 298 | 299 |
图-17 IIR低通滤波器
300 | 301 | 302 | 303 | ​ 我们可以看出同样是5阶滤波,`IIR `滤波类型的巴特沃斯滤波器的滤波效果单从幅频响应来说 比滑动平均滤波器好了不少。`IIR `滤波器原理是输入信号为x(m). 对应的乘以每一个b系数。 在5点滑动平均滤波器的例子中,这个b 就是 0.2,0.2,0.2,0.2,0.2. 输出为y(m). 这样每一个x(m)乘上对应的系数然后再加在一起 组成了 `y.IIR `滤波器引入了'a' 系数反馈环节,如图18所示。 每一次滤波,上一次的输出也要程序对应的系数a 然后减到本次输出中,计算公式如下: 304 | 305 |
y(n)=b(1)*x(n)+b(2)*x(n-1)+ ... + b(n)*x(n) - a(2)y(n-1) - a(3)*y(n-2)...
306 | 307 | ![](附件/IIR filter02.png) 308 | 309 |
图-18 IIR滤波器基本结构
310 | 311 | ​ 数字滤波器设计是一个复杂的数学运算,可以使用`Matlab filterDesigner` 工具生成FIR滤波器函数,在`matlab`命令窗口输入:`filterDesigner`命令,即可打开`filterDesigner`设计工具。下图设计的是采样频率`100Hz`,截止频率`10Hz`的7阶FIR低通数字滤波器,如图19所示。 312 | 313 | ![](附件/EQ02.png) 314 | 315 |
图-19 Matlab filterDesigner
316 | 317 | 完成滤波器设计后,您可以通过点击工具栏上的任意按钮,在显示窗口中查看以下滤波器分析: 318 | 319 | ​ ![](附件/FDAToolExample_04.png) 320 | 321 | ​ 按从左到右的顺序,按钮排列如下,幅值响应、相位响应、幅值响应和相位响应、群延迟响应、相位延迟响应、脉冲响应、阶跃响应、极点-零点图、滤波器系数、滤波器信息。 322 | 323 | -------------------------------------------------------------------------------- /icon.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | icon/eq.png 4 | 5 | 6 | -------------------------------------------------------------------------------- /icon/eq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusaProject/Parametric-equalizer/71ecd2f6f3d42d0b9191044aecff188f76bd5dc2/icon/eq.png -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "AudioPlayer.h" 11 | #include "widget.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | QApplication a(argc, argv); 16 | Widget app; 17 | QDesktopWidget *desktop = QApplication::desktop(); 18 | app.setWindowIcon(QIcon(":/icon/eq.png")); 19 | app.move((desktop->width() - app.width()) / 2, (desktop->height() - app.height()) / 2); 20 | app.show(); 21 | return a.exec(); 22 | } 23 | -------------------------------------------------------------------------------- /widget.cpp: -------------------------------------------------------------------------------- 1 | #include "widget.h" 2 | #include "ui_widget.h" 3 | 4 | #include "EQFilterGroup.h" 5 | #include 6 | 7 | Widget::Widget(QWidget *parent) 8 | : QWidget(parent) 9 | , ui(new Ui::Widget) 10 | { 11 | ui->setupUi(this); 12 | 13 | setBandpassFrequency(1); 14 | 15 | _player = new AudioPlayer(this); 16 | 17 | on_verticalSlider_valueChanged(100); 18 | on_verticalSlider_2_valueChanged(100); 19 | on_verticalSlider_3_valueChanged(100); 20 | on_verticalSlider_4_valueChanged(100); 21 | on_verticalSlider_5_valueChanged(100); 22 | on_verticalSlider_6_valueChanged(100); 23 | on_verticalSlider_7_valueChanged(100); 24 | on_verticalSlider_8_valueChanged(100); 25 | on_verticalSlider_9_valueChanged(100); 26 | on_verticalSlider_10_valueChanged(100); 27 | } 28 | 29 | Widget::~Widget() 30 | { 31 | delete ui; 32 | } 33 | 34 | void Widget::setMusicStyle(QList &style) 35 | { 36 | if (!style.isEmpty()) { 37 | 38 | ui->verticalSlider->setValue(style[0]); 39 | 40 | ui->verticalSlider_2->setValue(style[1]); 41 | 42 | ui->verticalSlider_3->setValue(style[2]); 43 | 44 | ui->verticalSlider_4->setValue(style[3]); 45 | 46 | ui->verticalSlider_5->setValue(style[4]); 47 | 48 | ui->verticalSlider_6->setValue(style[5]); 49 | 50 | ui->verticalSlider_7->setValue(style[6]); 51 | 52 | ui->verticalSlider_8->setValue(style[7]); 53 | 54 | ui->verticalSlider_9->setValue(style[8]); 55 | 56 | ui->verticalSlider_10->setValue(style[9]); 57 | } 58 | } 59 | 60 | void Widget::clearFdacoefs() 61 | { 62 | _player->reset(); 63 | 64 | EQFilterGroup::clearFdacoefs(); 65 | } 66 | 67 | void Widget::setBandpassFrequency(int status) 68 | { 69 | if (status == 1) { 70 | EQFilterGroup::updateCoefficient(21, 42, 1); 71 | EQFilterGroup::updateCoefficient(42, 85, 2); 72 | EQFilterGroup::updateCoefficient(85, 170, 3); 73 | EQFilterGroup::updateCoefficient(170, 339, 4); 74 | EQFilterGroup::updateCoefficient(339, 679, 5); 75 | EQFilterGroup::updateCoefficient(679, 1385, 6); 76 | EQFilterGroup::updateCoefficient(1385, 2715, 7); 77 | EQFilterGroup::updateCoefficient(2715, 5431, 8); 78 | EQFilterGroup::updateCoefficient(5431, 10861, 9); 79 | EQFilterGroup::updateCoefficient(10861, 21722, 10); 80 | 81 | bandwidthStatus = 1; 82 | 83 | } else if (status == 2) { 84 | 85 | EQFilterGroup::updateCoefficient(60, 100, 1); 86 | EQFilterGroup::updateCoefficient(100, 200, 2); 87 | EQFilterGroup::updateCoefficient(200, 500, 3); 88 | EQFilterGroup::updateCoefficient(500, 1000, 4); 89 | EQFilterGroup::updateCoefficient(1000, 2000, 5); 90 | EQFilterGroup::updateCoefficient(2000, 4000, 6); 91 | EQFilterGroup::updateCoefficient(4000, 8000, 7); 92 | EQFilterGroup::updateCoefficient(8000, 12000, 8); 93 | EQFilterGroup::updateCoefficient(12000, 16000, 9); 94 | EQFilterGroup::updateCoefficient(16000, 20000, 10); 95 | 96 | bandwidthStatus = 2; 97 | } 98 | } 99 | 100 | 101 | void Widget::on_verticalSlider_valueChanged(int value) 102 | { 103 | float gain = float(value) / 100; 104 | 105 | float coeff = 1.0; 106 | if (bandwidthStatus == 1) { 107 | coeff = 0.1; 108 | } else if (bandwidthStatus == 2) { 109 | coeff = 0.5; 110 | } 111 | 112 | _player->set_FC_HZ_32(gain, coeff); 113 | } 114 | 115 | void Widget::on_verticalSlider_2_valueChanged(int value) 116 | { 117 | float gain = float(value) / 100; 118 | 119 | float coeff = 1.0; 120 | if (bandwidthStatus == 1) { 121 | coeff = 0.2; 122 | } else if (bandwidthStatus == 2) { 123 | coeff = 0.6; 124 | } 125 | 126 | _player->set_FC_HZ_63(gain, coeff); 127 | } 128 | 129 | void Widget::on_verticalSlider_3_valueChanged(int value) 130 | { 131 | float gain = float(value) / 100; 132 | 133 | float coeff = 1.0; 134 | if (bandwidthStatus == 1) { 135 | coeff = 0.4; 136 | } else if (bandwidthStatus == 2) { 137 | coeff = 0.7; 138 | } 139 | 140 | _player->set_FC_HZ_125(gain, coeff); 141 | } 142 | 143 | void Widget::on_verticalSlider_4_valueChanged(int value) 144 | { 145 | float gain = float(value) / 100; 146 | 147 | float coeff = 0.8; 148 | 149 | _player->set_FC_HZ_250(gain, coeff); 150 | } 151 | 152 | void Widget::on_verticalSlider_5_valueChanged(int value) 153 | { 154 | float gain = float(value) / 100; 155 | 156 | float coeff = 0.9; 157 | 158 | _player->set_FC_HZ_500(gain, coeff); 159 | } 160 | 161 | void Widget::on_verticalSlider_6_valueChanged(int value) 162 | { 163 | float gain = float(value) / 100; 164 | _player->set_FC_HZ_1000(gain); 165 | } 166 | 167 | void Widget::on_verticalSlider_7_valueChanged(int value) 168 | { 169 | float gain = float(value) / 100; 170 | _player->set_FC_HZ_2000(gain); 171 | } 172 | 173 | void Widget::on_verticalSlider_8_valueChanged(int value) 174 | { 175 | float gain = float(value) / 100; 176 | _player->set_FC_HZ_4000(gain); 177 | } 178 | 179 | void Widget::on_verticalSlider_9_valueChanged(int value) 180 | { 181 | float gain = float(value) / 100; 182 | _player->set_FC_HZ_8000(gain); 183 | } 184 | 185 | void Widget::on_verticalSlider_10_valueChanged(int value) 186 | { 187 | float gain = float(value) / 100; 188 | _player->set_FC_HZ_16000(gain); 189 | } 190 | 191 | void Widget::on_comboBox_currentIndexChanged(int index) 192 | { 193 | musicStyle.clear(); 194 | 195 | ui->comboBox_2->blockSignals(true); 196 | ui->comboBox_2->setCurrentIndex(-1); 197 | ui->comboBox_2->blockSignals(false); 198 | 199 | if (bandwidthStatus == 2) { 200 | setBandpassFrequency(1); 201 | } 202 | 203 | switch (index) { 204 | 205 | case 0: 206 | // 0,0,0, 0,0,0,0,0,0,0 207 | musicStyle << 100 << 100 << 100 << 100 << 100 208 | << 100 << 100 << 100 << 100 << 100; 209 | break; 210 | 211 | case 1: 212 | // 0,0,0, 1,2, 3,3,2, 1,0 213 | musicStyle << 100 << 100 << 100 << 110 << 120 214 | << 130 << 130 << 120 << 110 << 100; 215 | break; 216 | 217 | case 2: 218 | // 9,8,5,2, 1,0,-3,-4,-3, 0 219 | musicStyle << 190 << 180 << 150 << 120 << 110 220 | << 100 << 70 << 60 << 70 << 100; 221 | break; 222 | case 3: 223 | // 8,8,8, 7,4,0,-3,-5,-7,-9 224 | musicStyle << 180 << 180 << 180 << 170 << 140 225 | << 100 << 70 << 50 << 30 << 10; 226 | break; 227 | 228 | case 4: 229 | // -9,-8,-7,-6,-3,1,5,8,10, 12 230 | musicStyle << 10 << 20 << 30 << 40 << 70 231 | << 110 << 150 << 180 << 200 << 220; 232 | break; 233 | 234 | case 5: 235 | // -2,-1, 0,2,3, 2,0,-2,-2,-1 236 | musicStyle << 80 << 90 << 100 << 120 << 130 237 | << 120 << 100 << 80 << 80 << 90; 238 | break; 239 | 240 | case 6: 241 | // 6,5,2,-2,-5,-2,0,3,5, 6 242 | musicStyle << 160 << 150 << 120 << 80 << 50 243 | << 80 << 100 << 130 << 150 << 160; 244 | break; 245 | 246 | case 7: 247 | // 2,1,0,0,-1,0,1,2,3,4 248 | musicStyle << 120 << 110 << 100 << 100 << 90 249 | << 100 << 110 << 120 << 130 << 140; 250 | break; 251 | 252 | case 8: 253 | // 8,7,6,3,2, 0,-1,-2,-1,0 254 | musicStyle << 180 << 170 << 160 << 130 << 120 255 | << 100 << 90 << 80 << 90 << 100; 256 | break; 257 | 258 | case 9: 259 | //4,4,3,2, 0,0,0,0,0,4 260 | musicStyle << 140 << 140 << 130 << 120 << 100 261 | << 100 << 100 << 100 << 100 << 140; 262 | break; 263 | 264 | case 10: 265 | //4 2 0 -3 -6 -6 -3 0 1 3 266 | musicStyle << 140 << 120 << 100 << 70 << 40 267 | << 40 << 70 << 100 << 110 << 130; 268 | break; 269 | 270 | case 11: 271 | //7 6 3 0 0 -4 -6 -6 0 0 272 | musicStyle << 170 << 160 << 130 << 100 << 100 273 | << 60 << 40 << 40 << 100 << 100; 274 | break; 275 | case 12: 276 | //3 6 8 3 -2 0 4 7 9 10 277 | musicStyle << 130 << 160 << 180 << 130 << 80 278 | << 100 << 140 << 170 << 190 << 200; 279 | break; 280 | case 13: 281 | //0 0 0 0 0 0 -6 -6 -6 -8 282 | musicStyle << 100 << 100 << 100 << 100 << 100 283 | << 100 << 40 << 40 << 40 << 20; 284 | break; 285 | case 14: 286 | //0 0 1 4 4 4 0 1 3 3 287 | musicStyle << 100 << 100 << 110 << 140 << 140 288 | << 140 << 100 << 110 << 130 << 130; 289 | break; 290 | case 15: 291 | //5 4 2 0 -2 0 3 6 7 8 292 | musicStyle << 150 << 140 << 120 << 100 << 80 293 | << 100 << 130 << 160 << 170 << 180; 294 | break; 295 | case 16: 296 | //6 5 0 -5 -4 0 6 8 8 7 297 | musicStyle << 160 << 150 << 100 << 50 << 60 298 | << 100 << 160 << 180 << 180 << 170; 299 | break; 300 | case 17: 301 | //7 4 -4 7 -2 1 5 7 9 9 302 | musicStyle << 170 << 140 << 60 << 170 << 80 303 | << 100 << 150 << 170 << 190 << 190; 304 | break; 305 | case 18: 306 | //5 6 2 -5 1 1 -5 3 8 5 307 | musicStyle << 150 << 160 << 120 << 50 << 100 308 | << 100 << 50 << 130 << 180 << 150; 309 | break; 310 | case 19: 311 | //-2 -1 -1 0 3 4 3 0 0 1 312 | musicStyle << 80 << 90 << 90 << 100 << 130 313 | << 140 << 130 << 100 << 100 << 110; 314 | break; 315 | 316 | default: 317 | break; 318 | } 319 | 320 | setMusicStyle(musicStyle); 321 | } 322 | 323 | 324 | void Widget::on_pushButton_clicked() 325 | { 326 | QString fileName = QFileDialog::getOpenFileName(this, 327 | tr("文件对话框!"), 328 | "F:", 329 | tr("音乐文件(*mp3)")); 330 | 331 | 332 | qDebug() << "filename : " << fileName; 333 | 334 | setWindowTitle(fileName); 335 | 336 | _player->setSourceFilename(fileName); 337 | 338 | _player->play(); 339 | } 340 | 341 | 342 | void Widget::on_lineEdit_editingFinished() 343 | { 344 | this->setFocus(); 345 | 346 | int Fc1 = ui->lineEdit->text().toInt(); 347 | int Fc2 = ui->lineEdit_2->text().toInt(); 348 | 349 | EQFilterGroup::updateCoefficient(Fc1, Fc2, 1); 350 | } 351 | 352 | void Widget::on_lineEdit_2_editingFinished() 353 | { 354 | this->setFocus(); 355 | 356 | int Fc1 = ui->lineEdit->text().toInt(); 357 | int Fc2 = ui->lineEdit_2->text().toInt(); 358 | 359 | EQFilterGroup::updateCoefficient(Fc1, Fc2, 1); 360 | 361 | } 362 | 363 | void Widget::on_lineEdit_3_editingFinished() 364 | { 365 | this->setFocus(); 366 | 367 | int Fc1 = ui->lineEdit_3->text().toInt(); 368 | int Fc2 = ui->lineEdit_4->text().toInt(); 369 | 370 | EQFilterGroup::updateCoefficient(Fc1, Fc2, 2); 371 | 372 | } 373 | 374 | void Widget::on_lineEdit_4_editingFinished() 375 | { 376 | this->setFocus(); 377 | 378 | int Fc1 = ui->lineEdit_3->text().toInt(); 379 | int Fc2 = ui->lineEdit_4->text().toInt(); 380 | 381 | EQFilterGroup::updateCoefficient(Fc1, Fc2, 2); 382 | 383 | } 384 | 385 | void Widget::on_lineEdit_5_editingFinished() 386 | { 387 | this->setFocus(); 388 | 389 | int Fc1 = ui->lineEdit_5->text().toInt(); 390 | int Fc2 = ui->lineEdit_6->text().toInt(); 391 | 392 | EQFilterGroup::updateCoefficient(Fc1, Fc2, 3); 393 | } 394 | 395 | void Widget::on_lineEdit_6_editingFinished() 396 | { 397 | this->setFocus(); 398 | 399 | int Fc1 = ui->lineEdit_5->text().toInt(); 400 | int Fc2 = ui->lineEdit_6->text().toInt(); 401 | 402 | EQFilterGroup::updateCoefficient(Fc1, Fc2, 3); 403 | 404 | } 405 | 406 | void Widget::on_lineEdit_7_editingFinished() 407 | { 408 | this->setFocus(); 409 | 410 | int Fc1 = ui->lineEdit_7->text().toInt(); 411 | int Fc2 = ui->lineEdit_8->text().toInt(); 412 | 413 | EQFilterGroup::updateCoefficient(Fc1, Fc2, 4); 414 | } 415 | 416 | void Widget::on_lineEdit_8_editingFinished() 417 | { 418 | this->setFocus(); 419 | 420 | int Fc1 = ui->lineEdit_7->text().toInt(); 421 | int Fc2 = ui->lineEdit_8->text().toInt(); 422 | 423 | EQFilterGroup::updateCoefficient(Fc1, Fc2, 4); 424 | } 425 | 426 | void Widget::on_lineEdit_9_editingFinished() 427 | { 428 | this->setFocus(); 429 | 430 | int Fc1 = ui->lineEdit_9->text().toInt(); 431 | int Fc2 = ui->lineEdit_10->text().toInt(); 432 | 433 | EQFilterGroup::updateCoefficient(Fc1, Fc2, 5); 434 | } 435 | 436 | void Widget::on_lineEdit_10_editingFinished() 437 | { 438 | this->setFocus(); 439 | 440 | int Fc1 = ui->lineEdit_9->text().toInt(); 441 | int Fc2 = ui->lineEdit_10->text().toInt(); 442 | 443 | EQFilterGroup::updateCoefficient(Fc1, Fc2, 5); 444 | } 445 | 446 | void Widget::on_lineEdit_11_editingFinished() 447 | { 448 | this->setFocus(); 449 | 450 | int Fc1 = ui->lineEdit_11->text().toInt(); 451 | int Fc2 = ui->lineEdit_12->text().toInt(); 452 | 453 | EQFilterGroup::updateCoefficient(Fc1, Fc2, 6); 454 | } 455 | 456 | void Widget::on_lineEdit_12_editingFinished() 457 | { 458 | this->setFocus(); 459 | 460 | int Fc1 = ui->lineEdit_11->text().toInt(); 461 | int Fc2 = ui->lineEdit_12->text().toInt(); 462 | 463 | EQFilterGroup::updateCoefficient(Fc1, Fc2, 6); 464 | } 465 | 466 | void Widget::on_lineEdit_13_editingFinished() 467 | { 468 | this->setFocus(); 469 | 470 | int Fc1 = ui->lineEdit_13->text().toInt(); 471 | int Fc2 = ui->lineEdit_14->text().toInt(); 472 | 473 | EQFilterGroup::updateCoefficient(Fc1, Fc2, 7); 474 | } 475 | 476 | void Widget::on_lineEdit_14_editingFinished() 477 | { 478 | this->setFocus(); 479 | 480 | int Fc1 = ui->lineEdit_13->text().toInt(); 481 | int Fc2 = ui->lineEdit_14->text().toInt(); 482 | 483 | EQFilterGroup::updateCoefficient(Fc1, Fc2, 7); 484 | } 485 | 486 | void Widget::on_lineEdit_15_editingFinished() 487 | { 488 | this->setFocus(); 489 | 490 | int Fc1 = ui->lineEdit_15->text().toInt(); 491 | int Fc2 = ui->lineEdit_16->text().toInt(); 492 | 493 | EQFilterGroup::updateCoefficient(Fc1, Fc2, 8); 494 | } 495 | 496 | void Widget::on_lineEdit_16_editingFinished() 497 | { 498 | this->setFocus(); 499 | 500 | int Fc1 = ui->lineEdit_15->text().toInt(); 501 | int Fc2 = ui->lineEdit_16->text().toInt(); 502 | 503 | EQFilterGroup::updateCoefficient(Fc1, Fc2, 8); 504 | } 505 | 506 | void Widget::on_lineEdit_17_editingFinished() 507 | { 508 | this->setFocus(); 509 | 510 | int Fc1 = ui->lineEdit_17->text().toInt(); 511 | int Fc2 = ui->lineEdit_18->text().toInt(); 512 | 513 | EQFilterGroup::updateCoefficient(Fc1, Fc2, 9); 514 | } 515 | 516 | void Widget::on_lineEdit_18_editingFinished() 517 | { 518 | this->setFocus(); 519 | 520 | int Fc1 = ui->lineEdit_17->text().toInt(); 521 | int Fc2 = ui->lineEdit_18->text().toInt(); 522 | 523 | EQFilterGroup::updateCoefficient(Fc1, Fc2, 9); 524 | } 525 | 526 | void Widget::on_lineEdit_19_editingFinished() 527 | { 528 | this->setFocus(); 529 | 530 | int Fc1 = ui->lineEdit_19->text().toInt(); 531 | int Fc2 = ui->lineEdit_20->text().toInt(); 532 | 533 | EQFilterGroup::updateCoefficient(Fc1, Fc2, 10); 534 | } 535 | 536 | void Widget::on_lineEdit_20_editingFinished() 537 | { 538 | this->setFocus(); 539 | 540 | int Fc1 = ui->lineEdit_19->text().toInt(); 541 | int Fc2 = ui->lineEdit_20->text().toInt(); 542 | 543 | EQFilterGroup::updateCoefficient(Fc1, Fc2, 10); 544 | } 545 | 546 | void Widget::on_comboBox_2_currentIndexChanged(int index) 547 | { 548 | musicStyle.clear(); 549 | 550 | // blockSignals 551 | ui->comboBox->blockSignals(true); 552 | ui->comboBox->setCurrentIndex(-1); 553 | ui->comboBox->blockSignals(false); 554 | 555 | if (bandwidthStatus == 1) { 556 | setBandpassFrequency(2); 557 | } 558 | 559 | switch (index) { 560 | case 0: 561 | // 0,0,0, 0,0,0,0,0,0,0 562 | musicStyle << 100 << 100 << 100 << 100 << 100 563 | << 100 << 100 << 100 << 100 << 100; 564 | break; 565 | 566 | case 1: 567 | //0, 0, 0, 0, 0, 0, -7, -7, -7, -9 568 | musicStyle << 100 << 100 << 100 << 100 << 100 569 | << 100 << 30 << 30 << 30 << 10; 570 | break; 571 | 572 | case 2: 573 | //0, 0, 8, 5, 5, 5, 3, 0, 0, 0 574 | musicStyle << 100 << 100 << 180 << 150 << 150 575 | << 150 << 130 << 100 << 100 << 100; 576 | break; 577 | case 3: 578 | //9, 7, 2, 0, 0, -5, -7, -7, 0, 0 579 | musicStyle << 190 << 170 << 120 << 100 << 100 580 | << 50 << 30 << 30 << 100 << 100; 581 | break; 582 | 583 | case 4: 584 | //-8, 9, 9, 5, 1, -4, -8, -10, -11, -11 585 | musicStyle << 20 << 190 << 190 << 150 << 110 586 | << 60 << 20 << 8 << 6 << 6; 587 | break; 588 | 589 | case 5: 590 | //-9, -9, -9, -4, 2, 11, 16, 16, 16, 16 591 | musicStyle << 10 << 10 << 10 << 60 << 120 592 | << 200 << 200 << 200 << 200 << 200; 593 | break; 594 | 595 | case 6: 596 | //4, 11, 5, -3, -2, 1, 4, 9, 12, 14 597 | musicStyle << 140 << 200 << 150 << 70 << 80 598 | << 110 << 140 << 190 << 200 << 200; 599 | break; 600 | 601 | case 7: 602 | //10, 10, 5, 5, 0, -4, -4, -4, 0, 0 603 | musicStyle << 200 << 200 << 150 << 150 << 100 604 | << 60 << 60 << 60 << 100 << 100; 605 | break; 606 | 607 | case 8: 608 | //-4, 0, 4, 5, 5, 5, 4, 2, 2, 2 609 | musicStyle << 60 << 100 << 140 << 150 << 150 610 | << 150 << 140 << 120 << 120 << 120; 611 | break; 612 | 613 | case 9: 614 | //7, 7, 0, 0, 0, 0, 0, 0, 7, 7 615 | musicStyle << 170 << 170 << 100 << 100 << 100 616 | << 100 << 100 << 100 << 170 << 170; 617 | break; 618 | 619 | case 10: 620 | //-1, 4, 7, 8, 5, 0, -2, -2, -1, -1 621 | musicStyle << 90 << 140 << 170 << 180 << 150 622 | << 100 << 80 << 80 << 90 << 90; 623 | break; 624 | 625 | case 11: 626 | //0, 0, 0, -5, 0, 6, 6, 0, 0, 0 627 | musicStyle << 100 << 100 << 100 << 50 << 100 628 | << 160 << 160 << 100 << 100 << 100; 629 | break; 630 | 631 | case 12: 632 | //8, 4, -5, -8, -3, 4, 8, 11, 11, 11 633 | musicStyle << 180 << 140 << 50 << 20 << 70 634 | << 140 << 180 << 200 << 200 << 200; 635 | break; 636 | 637 | case 13: 638 | //-2, -4, -4, 0, 4, 5, 8, 9, 11, 9 639 | musicStyle << 80 << 60 << 60 << 100 << 140 640 | << 150 << 180 << 190 << 200 << 190; 641 | break; 642 | 643 | case 14: 644 | //4, 1, 0, -2, 0, 4, 8, 9, 11, 12 645 | musicStyle << 140 << 110 << 100 << 80 << 100 646 | << 140 << 180 << 190 << 200 << 200; 647 | break; 648 | 649 | case 15: 650 | //4, 4, 2, 0, -4, -5, -3, 0, 2, 8 651 | musicStyle << 140 << 140 << 120 << 100 << 60 652 | << 50 << 70 << 100 << 120 << 180; 653 | break; 654 | 655 | case 16: 656 | //8, 5, 0, -5, -4, 0, 8, 9, 9, 8 657 | musicStyle << 180 << 150 << 100 << 50 << 60 658 | << 100 << 180 << 190 << 190 << 180; 659 | break; 660 | 661 | default: 662 | break; 663 | } 664 | 665 | setMusicStyle(musicStyle); 666 | } 667 | 668 | void Widget::on_pushButton_2_clicked() 669 | { 670 | clearFdacoefs(); 671 | } 672 | -------------------------------------------------------------------------------- /widget.h: -------------------------------------------------------------------------------- 1 | #ifndef WIDGET_H 2 | #define WIDGET_H 3 | 4 | #include "AudioPlayer.h" 5 | #include 6 | 7 | QT_BEGIN_NAMESPACE 8 | namespace Ui { class Widget; } 9 | QT_END_NAMESPACE 10 | 11 | class Widget : public QWidget 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | Widget(QWidget *parent = nullptr); 17 | ~Widget(); 18 | 19 | // 设置音乐风格 20 | void setMusicStyle(QList &style); 21 | 22 | void clearFdacoefs(); 23 | 24 | void setBandpassFrequency(int status); 25 | 26 | private slots: 27 | void on_verticalSlider_valueChanged(int value); 28 | 29 | void on_verticalSlider_2_valueChanged(int value); 30 | 31 | void on_verticalSlider_3_valueChanged(int value); 32 | 33 | void on_verticalSlider_4_valueChanged(int value); 34 | 35 | void on_verticalSlider_5_valueChanged(int value); 36 | 37 | void on_verticalSlider_6_valueChanged(int value); 38 | 39 | void on_verticalSlider_7_valueChanged(int value); 40 | 41 | void on_verticalSlider_8_valueChanged(int value); 42 | 43 | void on_verticalSlider_9_valueChanged(int value); 44 | 45 | void on_verticalSlider_10_valueChanged(int value); 46 | 47 | void on_comboBox_currentIndexChanged(int index); 48 | 49 | void on_pushButton_clicked(); 50 | 51 | void on_lineEdit_editingFinished(); 52 | 53 | void on_lineEdit_2_editingFinished(); 54 | 55 | void on_lineEdit_3_editingFinished(); 56 | 57 | void on_lineEdit_4_editingFinished(); 58 | 59 | void on_lineEdit_5_editingFinished(); 60 | 61 | void on_lineEdit_6_editingFinished(); 62 | 63 | void on_lineEdit_7_editingFinished(); 64 | 65 | void on_lineEdit_8_editingFinished(); 66 | 67 | void on_lineEdit_9_editingFinished(); 68 | 69 | void on_lineEdit_10_editingFinished(); 70 | 71 | void on_lineEdit_11_editingFinished(); 72 | 73 | void on_lineEdit_12_editingFinished(); 74 | 75 | void on_lineEdit_13_editingFinished(); 76 | 77 | void on_lineEdit_14_editingFinished(); 78 | 79 | void on_lineEdit_15_editingFinished(); 80 | 81 | void on_lineEdit_16_editingFinished(); 82 | 83 | void on_lineEdit_17_editingFinished(); 84 | 85 | void on_lineEdit_18_editingFinished(); 86 | 87 | void on_lineEdit_19_editingFinished(); 88 | 89 | void on_lineEdit_20_editingFinished(); 90 | 91 | void on_comboBox_2_currentIndexChanged(int index); 92 | 93 | void on_pushButton_2_clicked(); 94 | 95 | private: 96 | Ui::Widget *ui; 97 | 98 | int bandwidthStatus = 0; 99 | 100 | AudioPlayer *_player; 101 | 102 | QList musicStyle; 103 | }; 104 | #endif // WIDGET_H 105 | -------------------------------------------------------------------------------- /附件/EQ02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusaProject/Parametric-equalizer/71ecd2f6f3d42d0b9191044aecff188f76bd5dc2/附件/EQ02.png -------------------------------------------------------------------------------- /附件/EQFIR.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusaProject/Parametric-equalizer/71ecd2f6f3d42d0b9191044aecff188f76bd5dc2/附件/EQFIR.png -------------------------------------------------------------------------------- /附件/EQFilterGroup01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusaProject/Parametric-equalizer/71ecd2f6f3d42d0b9191044aecff188f76bd5dc2/附件/EQFilterGroup01.png -------------------------------------------------------------------------------- /附件/EQSS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusaProject/Parametric-equalizer/71ecd2f6f3d42d0b9191044aecff188f76bd5dc2/附件/EQSS.png -------------------------------------------------------------------------------- /附件/EQYX.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusaProject/Parametric-equalizer/71ecd2f6f3d42d0b9191044aecff188f76bd5dc2/附件/EQYX.jpg -------------------------------------------------------------------------------- /附件/FDAToolExample_04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusaProject/Parametric-equalizer/71ecd2f6f3d42d0b9191044aecff188f76bd5dc2/附件/FDAToolExample_04.png -------------------------------------------------------------------------------- /附件/FIR filter01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusaProject/Parametric-equalizer/71ecd2f6f3d42d0b9191044aecff188f76bd5dc2/附件/FIR filter01.png -------------------------------------------------------------------------------- /附件/FIR filter02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusaProject/Parametric-equalizer/71ecd2f6f3d42d0b9191044aecff188f76bd5dc2/附件/FIR filter02.png -------------------------------------------------------------------------------- /附件/FIR filter03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusaProject/Parametric-equalizer/71ecd2f6f3d42d0b9191044aecff188f76bd5dc2/附件/FIR filter03.png -------------------------------------------------------------------------------- /附件/FIRSJ01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusaProject/Parametric-equalizer/71ecd2f6f3d42d0b9191044aecff188f76bd5dc2/附件/FIRSJ01.png -------------------------------------------------------------------------------- /附件/FIRSJ02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusaProject/Parametric-equalizer/71ecd2f6f3d42d0b9191044aecff188f76bd5dc2/附件/FIRSJ02.png -------------------------------------------------------------------------------- /附件/FIRfilter01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusaProject/Parametric-equalizer/71ecd2f6f3d42d0b9191044aecff188f76bd5dc2/附件/FIRfilter01.png -------------------------------------------------------------------------------- /附件/FIRfilter02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusaProject/Parametric-equalizer/71ecd2f6f3d42d0b9191044aecff188f76bd5dc2/附件/FIRfilter02.png -------------------------------------------------------------------------------- /附件/FIRfilter03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusaProject/Parametric-equalizer/71ecd2f6f3d42d0b9191044aecff188f76bd5dc2/附件/FIRfilter03.png -------------------------------------------------------------------------------- /附件/IIR filter01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusaProject/Parametric-equalizer/71ecd2f6f3d42d0b9191044aecff188f76bd5dc2/附件/IIR filter01.png -------------------------------------------------------------------------------- /附件/IIR filter02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusaProject/Parametric-equalizer/71ecd2f6f3d42d0b9191044aecff188f76bd5dc2/附件/IIR filter02.png -------------------------------------------------------------------------------- /附件/M03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusaProject/Parametric-equalizer/71ecd2f6f3d42d0b9191044aecff188f76bd5dc2/附件/M03.jpg -------------------------------------------------------------------------------- /附件/M04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusaProject/Parametric-equalizer/71ecd2f6f3d42d0b9191044aecff188f76bd5dc2/附件/M04.jpg -------------------------------------------------------------------------------- /附件/M05.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusaProject/Parametric-equalizer/71ecd2f6f3d42d0b9191044aecff188f76bd5dc2/附件/M05.jpg -------------------------------------------------------------------------------- /附件/encod02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusaProject/Parametric-equalizer/71ecd2f6f3d42d0b9191044aecff188f76bd5dc2/附件/encod02.png -------------------------------------------------------------------------------- /附件/encod04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusaProject/Parametric-equalizer/71ecd2f6f3d42d0b9191044aecff188f76bd5dc2/附件/encod04.png -------------------------------------------------------------------------------- /附件/fft01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusaProject/Parametric-equalizer/71ecd2f6f3d42d0b9191044aecff188f76bd5dc2/附件/fft01.png -------------------------------------------------------------------------------- /附件/fft02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusaProject/Parametric-equalizer/71ecd2f6f3d42d0b9191044aecff188f76bd5dc2/附件/fft02.png -------------------------------------------------------------------------------- /附件/filter01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusaProject/Parametric-equalizer/71ecd2f6f3d42d0b9191044aecff188f76bd5dc2/附件/filter01.png -------------------------------------------------------------------------------- /附件/filter02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusaProject/Parametric-equalizer/71ecd2f6f3d42d0b9191044aecff188f76bd5dc2/附件/filter02.png -------------------------------------------------------------------------------- /附件/filter03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusaProject/Parametric-equalizer/71ecd2f6f3d42d0b9191044aecff188f76bd5dc2/附件/filter03.png -------------------------------------------------------------------------------- /附件/filter04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusaProject/Parametric-equalizer/71ecd2f6f3d42d0b9191044aecff188f76bd5dc2/附件/filter04.png -------------------------------------------------------------------------------- /附件/math01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusaProject/Parametric-equalizer/71ecd2f6f3d42d0b9191044aecff188f76bd5dc2/附件/math01.png -------------------------------------------------------------------------------- /附件/math02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusaProject/Parametric-equalizer/71ecd2f6f3d42d0b9191044aecff188f76bd5dc2/附件/math02.png -------------------------------------------------------------------------------- /附件/频率响应.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusaProject/Parametric-equalizer/71ecd2f6f3d42d0b9191044aecff188f76bd5dc2/附件/频率响应.png -------------------------------------------------------------------------------- /附件/频率响应特性.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lusaProject/Parametric-equalizer/71ecd2f6f3d42d0b9191044aecff188f76bd5dc2/附件/频率响应特性.png --------------------------------------------------------------------------------