1 #include "audiospectrum.h"
2 #include "tools/kiss_fftr.h"
9 bool fileWritten = false;
11 AudioSpectrum::AudioSpectrum(Monitor *projMonitor, Monitor *clipMonitor, QWidget *parent) :
12 AbstractAudioScopeWidget(projMonitor, clipMonitor, true, parent)
14 ui = new Ui::AudioSpectrum_UI;
17 m_cfg = kiss_fftr_alloc(512, 0,0,0);
19 m_aAutoRefresh->setChecked(true); // TODO remove
21 m_aLin = new QAction(i18n("Linear scale"), this);
22 m_aLin->setCheckable(true);
23 m_aLog = new QAction(i18n("Logarithmic scale"), this);
24 m_aLog->setCheckable(true);
26 m_agScale = new QActionGroup(this);
27 m_agScale->addAction(m_aLin);
28 m_agScale->addAction(m_aLog);
30 m_menu->addSeparator()->setText(i18n("Scale"));;
31 m_menu->addAction(m_aLin);
32 m_menu->addAction(m_aLog);
36 AudioSpectrum::~AudioSpectrum()
44 void AudioSpectrum::readConfig()
46 AbstractAudioScopeWidget::readConfig();
48 KSharedConfigPtr config = KGlobal::config();
49 KConfigGroup scopeConfig(config, configName());
50 QString scale = scopeConfig.readEntry("scale");
52 m_aLin->setChecked(true);
54 m_aLog->setChecked(true);
58 void AudioSpectrum::writeConfig()
60 KSharedConfigPtr config = KGlobal::config();
61 KConfigGroup scopeConfig(config, configName());
63 if (m_aLin->isChecked()) {
68 scopeConfig.writeEntry("scale", scale);
72 QString AudioSpectrum::widgetName() const { return QString("audiospectrum"); }
74 bool AudioSpectrum::isBackgroundDependingOnInput() const { return false; }
75 bool AudioSpectrum::isScopeDependingOnInput() const { return true; }
76 bool AudioSpectrum::isHUDDependingOnInput() const { return false; }
78 QImage AudioSpectrum::renderBackground(uint) { return QImage(); }
79 QImage AudioSpectrum::renderScope(uint accelerationFactor, const QVector<int16_t> audioFrame, const int freq, const int num_channels, const int num_samples)
83 // The resulting FFT vector is only half as long
84 kiss_fft_cpx freqData[256];
86 // Copy the first channel's audio into a vector for the FFT display
87 for (int i = 0; i < 512; i++) {
88 data[i] = (float) audioFrame.data()[i*num_channels];
90 kiss_fftr(m_cfg, data, freqData);
91 // qDebug() << num_samples << " samples at " << freq << " Hz";
92 // qDebug() << "FFT Freq: " << freqData[0].r << " " << freqData[1].r << ", " << freqData[2].r;
93 // qDebug() << "FFT imag: " << freqData[0].i << " " << freqData[1].i << ", " << freqData[2].i;
95 qDebug() << QMetaObject::normalizedSignature("void audioSamplesSignal(const QVector<int16_t>&, int freq, int num_channels, int num_samples)");
100 for (int i = 0; i < 256; i++) {
101 if (m_aLin->isChecked()) {
102 val = pow(pow(fabs(freqData[i].r),2) + pow(fabs(freqData[i].i),2), .5);
104 val = log(pow(pow(fabs(freqData[i].r),2) + pow(fabs(freqData[i].i),2), .5));
106 max = (max > val) ? max : val;
107 min = (min < val) ? min : val;
109 qDebug() << "MAX: " << max << ", MIN: " << min;
111 float factor = 100./(max-min);
113 QImage spectrum(512, 100, QImage::Format_ARGB32);
114 spectrum.fill(qRgba(0,0,0,0));
115 for (int i = 0; i < 256; i++) {
116 if (m_aLin->isChecked()) {
117 val = pow(pow(fabs(freqData[i].r),2) + pow(fabs(freqData[i].i),2), .5);
119 val = log(pow(pow(fabs(freqData[i].r),2) + pow(fabs(freqData[i].i),2), .5));
122 val = factor * (val-min);
124 for (int y = 0; y < val && y < 100; y++) {
125 spectrum.setPixel(2*i, 99-y, qRgba(225, 182, 255, 255));
126 spectrum.setPixel(2*i+1, 99-y, qRgba(225, 182, 255, 255));
130 emit signalScopeRenderingFinished(0, 1);
133 if (!fileWritten || true) {
135 mFile.open("/tmp/freq.m");
137 qDebug() << "Opening file failed.";
141 for (int sample = 0; sample < 256; sample++) {
142 mFile << data[sample] << " ";
146 mFile << "freq = [ ";
147 for (int sample = 0; sample < 256; sample++) {
148 mFile << freqData[sample].r << "+" << freqData[sample].i << "*i ";
154 qDebug() << "File written.";
157 qDebug() << "File already written.";
163 QImage AudioSpectrum::renderHUD(uint) { return QImage(); }
165 QRect AudioSpectrum::scopeRect() {
166 return QRect(0,0,40,40);