27 #include <QApplication> 29 #include <QFutureSynchronizer> 31 #include <QMutexLocker> 33 #include <QtConcurrentRun> 59 #define REPAINT_INTERVAL 500 63 const QVariantList &args)
65 m_sonagram_window(Q_NULLPTR),
66 m_selection(Q_NULLPTR),
67 m_slices(0), m_fft_points(0),
69 m_track_changes(true), m_follow_selection(false), m_image(),
70 m_overview_cache(Q_NULLPTR), m_slice_pool(), m_valid(
MAX_SLICES, false),
71 m_pending_jobs(), m_lock_job_list(QMutex::Recursive), m_future(),
79 Qt::QueuedConnection);
101 QStringList *result = Q_NULLPTR;
108 if (!dlg)
return Q_NULLPTR;
115 if (dlg->exec() == QDialog::Accepted) {
116 result =
new QStringList();
132 if (params.count() != 5)
return -EINVAL;
136 if (!ok)
return -EINVAL;
141 if (!ok)
return -EINVAL;
144 m_color = (param.toUInt(&ok) != 0);
145 if (!ok)
return -EINVAL;
149 if (!ok)
return -EINVAL;
153 if (!ok)
return -EINVAL;
173 if (result)
return result;
186 QList<unsigned int> selected_channels;
189 length =
selection(&selected_channels, &offset, Q_NULLPTR,
true);
192 if (!length || selected_channels.isEmpty())
203 i18n(
"File or selection too large"));
209 &sig_mgr, offset, length, &selected_channels);
259 SIGNAL(sigSignalNameChanged(QString)),
273 unsigned int fft_points;
279 QList<unsigned int> track_list;
297 if (selected_tracks.contains(
signalManager().uuidOfTrack(track)))
298 track_list.append(track);
300 const unsigned int tracks = track_list.count();
303 const QVector<double> windowfunction = func.
points(fft_points);
304 Q_ASSERT(windowfunction.count() ==
Kwave::toInt(fft_points));
305 if (windowfunction.count() !=
Kwave::toInt(fft_points))
return;
313 QFutureSynchronizer<void> synchronizer;
314 for (
unsigned int slice_nr = 0; slice_nr < slices; slice_nr++) {
318 if (valid[slice_nr])
continue;
327 slice->m_index = slice_nr;
328 memset(slice->m_input, 0x00,
sizeof(slice->m_input));
329 memset(slice->m_output, 0x00,
sizeof(slice->m_output));
331 if ((pos <= last_sample) && (tracks)) {
333 memset(slice->m_result, 0x00,
sizeof(slice->m_result));
339 double *in = slice->m_input;
340 for (
unsigned int j = 0; j < fft_points; j++) {
342 if (!(source.
eof())) {
343 for (
unsigned int t = 0; t < tracks; t++) {
347 if (reader) *reader >> s;
352 in[j] = value * windowfunction[j];
360 synchronizer.addFuture(QtConcurrent::run(
365 memset(slice->m_result, 0xFF,
sizeof(slice->m_result));
376 synchronizer.waitForFinished();
388 qDebug(
"SonagramPlugin::run()");
406 p = fftw_plan_dft_r2c_1d(
421 const double scale =
static_cast<double>(
m_fft_points) / 254.0;
426 double a = ((rea * rea) + (ima * ima)) / scale;
428 slice->
m_result[j] =
static_cast<unsigned char>(qMin(a,
double(254.0)));
434 fftw_destroy_plan(p);
447 Q_ASSERT(this->thread() == QThread::currentThread());
448 Q_ASSERT(this->thread() == qApp->thread());
454 result.setRawData(reinterpret_cast<char *>(&(slice->
m_result[0])),
456 unsigned int nr = slice->
m_index;
470 const unsigned int height)
479 if (!width || !height)
return;
482 Q_ASSERT(width <= 32767);
483 Q_ASSERT(height <= 32767);
484 if ((width >= 32767) || (height >= 32767))
return;
487 m_image = QImage(width, height, QImage::Format_Indexed8);
493 for (
int i = 0; i < 256; i++) {
494 m_image.setColor(i, 0x00000000);
585 Q_ASSERT(first >= offset);
586 Q_ASSERT(last >= offset);
587 Q_ASSERT(last >= first);
592 unsigned int last_idx;
598 static_cast<sample_index_t>(
m_slices - 1))
601 m_valid.fill(
false, first_idx, last_idx + 1);
622 #include "SonagramPlugin.moc" unsigned int m_fft_points
virtual QImage getOverView(int width, int height, const QColor &fg, const QColor &bg, double gain=1.0)
sample_index_t offset() const
sample_index_t first() const
void parameters(QStringList &list)
void slotTrackDeleted(const QUuid &track_id)
int interpreteParameters(QStringList ¶ms)
Kwave::FixedPool< MAX_FFT_JOBS, Slice > m_slice_pool
void sliceAvailable(Kwave::SonagramPlugin::Slice *slice)
QWidget * parentWidget() const
#define SONAGRAM_OVERVIEW_HEIGHT
Kwave::SignalManager & signalManager()
void insertSlice(const unsigned int slice_nr, const QByteArray &slice)
QList< QUuid > allTracks()
unsigned char m_result[MAX_FFT_POINTS]
Kwave::PluginManager & manager() const
bool connect(Kwave::StreamObject &source, const char *output, Kwave::StreamObject &sink, const char *input)
void setColorMode(int color)
T round_up(T x, const T s)
void setTrackChanges(bool track_changes)
void setPoints(unsigned int points)
SonagramPlugin(QObject *parent, const QVariantList &args)
static int error(QWidget *widget, QString message, QString caption=QString())
QReadWriteLock m_pending_jobs
void setRate(double rate)
virtual ~SonagramPlugin() Q_DECL_OVERRIDE
Kwave::SonagramWindow * m_sonagram_window
void setFollowSelection(bool follow_selection)
void sigClosed(Kwave::Plugin *p)
sample_index_t last() const
static window_function_t findFromName(const QString &name)
virtual void run(QStringList params) Q_DECL_OVERRIDE
const QList< unsigned int > allTracks()
static double sample2double(const sample_t s)
Kwave::window_function_t m_window_type
void setOverView(const QImage &image)
virtual int start(QStringList ¶ms) Q_DECL_OVERRIDE
virtual double signalRate()
QVector< double > points(unsigned int len) const
#define KWAVE_PLUGIN(name, class)
void calculateSlice(Kwave::SonagramPlugin::Slice *slice)
void slotTrackInserted(const QUuid &track_id)
fftw_complex m_output[MAX_FFT_POINTS]
double m_input[MAX_FFT_POINTS]
virtual void seek(sample_index_t pos)
void setImage(QImage image)
void slotInvalidated(const QUuid *track_id, sample_index_t first, sample_index_t last)
Kwave::SelectionTracker * m_selection
Kwave::OverViewCache * m_overview_cache
void createNewImage(const unsigned int width, const unsigned int height)
virtual QStringList * setup(QStringList &previous_params) Q_DECL_OVERRIDE
sample_index_t length() const
void insertSlice(Kwave::SonagramPlugin::Slice *slice)
virtual sample_index_t selection(QList< unsigned int > *tracks=Q_NULLPTR, sample_index_t *left=Q_NULLPTR, sample_index_t *right=Q_NULLPTR, bool expand_if_empty=false)
void setColorMode(int mode)
void setWindowFunction(Kwave::window_function_t type)