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)