--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2012 by Simon Andreas Eugster (simon.eu@gmail.com) *
+ * This file is part of kdenlive. See www.kdenlive.org. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+
+#include "audioEnvelope.h"
+
+#include "audioStreamInfo.h"
+#include <QImage>
+#include <QTime>
+#include <cmath>
+#include <iostream>
+
+AudioEnvelope::AudioEnvelope(Mlt::Producer *producer) :
+ m_envelope(NULL),
+ m_producer(producer),
+ m_envelopeStdDevCalculated(false)
+{
+ m_info = new AudioInfo(m_producer);
+}
+
+AudioEnvelope::~AudioEnvelope()
+{
+ if (m_envelope != NULL) {
+ delete m_envelope;
+ }
+ delete m_info;
+}
+
+
+void AudioEnvelope::loadEnvelope()
+{
+ Q_ASSERT(m_envelope == NULL);
+
+ std::cout << "Loading envelope ..." << std::endl;
+
+ m_envelopeSize = m_producer->get_length();
+
+ int samplingRate = m_info->info(0)->samplingRate();
+ mlt_audio_format format_s16 = mlt_audio_s16;
+ int channels = 1;
+
+ Mlt::Frame *frame;
+ int64_t position;
+ int samples;
+
+ m_envelope = new uint64_t[m_envelopeSize];
+ m_envelopeMax = 0;
+ m_envelopeMean = 0;
+
+ QTime t;
+ t.start();
+ for (int i = 0; i < m_envelopeSize; i++) {
+
+ frame = m_producer->get_frame(i);
+ position = mlt_frame_get_position(frame->get_frame());
+ samples = mlt_sample_calculator(m_producer->get_fps(), samplingRate, position);
+
+ int16_t *data = static_cast<int16_t*>(frame->get_audio(format_s16, samplingRate, channels, samples));
+
+ uint64_t sum = 0;
+ for (int k = 0; k < samples; k++) {
+ sum += fabs(data[k]);
+ }
+ m_envelope[i] = sum;
+
+ m_envelopeMean += sum;
+ if (sum > m_envelopeMax) {
+ m_envelopeMax = sum;
+ }
+ }
+ m_envelopeMean /= m_envelopeSize;
+ std::cout << "Calculating the envelope (" << m_envelopeSize << " frames) took "
+ << t.elapsed() << " ms." << std::endl;
+}
+
+int64_t AudioEnvelope::loadStdDev()
+{
+ if (m_envelopeStdDevCalculated) {
+ std::cout << "Standard deviation already calculated, not re-calculating." << std::endl;
+ } else {
+
+ if (m_envelope == NULL) {
+ loadEnvelope();
+ }
+
+ m_envelopeStdDev = 0;
+ for (int i = 0; i < m_envelopeSize; i++) {
+ m_envelopeStdDev += sqrt((m_envelope[i]-m_envelopeMean)*(m_envelope[i]-m_envelopeMean)/m_envelopeSize);
+ }
+ m_envelopeStdDevCalculated = true;
+
+ }
+ return m_envelopeStdDev;
+}
+
+QImage AudioEnvelope::drawEnvelope()
+{
+ if (m_envelope == NULL) {
+ loadEnvelope();
+ }
+
+ QImage img(m_envelopeSize, 400, QImage::Format_ARGB32);
+ img.fill(qRgb(255,255,255));
+ double fy;
+ for (int x = 0; x < img.width(); x++) {
+ fy = m_envelope[x]/double(m_envelopeMax) * img.height();
+ for (int y = img.height()-1; y > img.height()-1-fy; y--) {
+ img.setPixel(x,y, qRgb(50, 50, 50));
+ }
+ }
+ return img;
+}
+
+void AudioEnvelope::dumpInfo() const
+{
+ if (m_envelope == NULL) {
+ std::cout << "Envelope not generated, no information available." << std::endl;
+ } else {
+ std::cout << "Envelope info" << std::endl
+ << "* size = " << m_envelopeSize << std::endl
+ << "* max = " << m_envelopeMax << std::endl
+ << "* ยต = " << m_envelopeMean << std::endl
+ ;
+ if (m_envelopeStdDevCalculated) {
+ std::cout << "* s = " << m_envelopeStdDev << std::endl;
+ }
+ }
+}
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2012 by Simon Andreas Eugster (simon.eu@gmail.com) *
+ * This file is part of kdenlive. See www.kdenlive.org. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+
+#ifndef AUDIOENVELOPE_H
+#define AUDIOENVELOPE_H
+
+#include "audioInfo.h"
+#include <mlt++/Mlt.h>
+
+class QImage;
+class AudioEnvelope
+{
+public:
+ AudioEnvelope(Mlt::Producer *producer);
+ ~AudioEnvelope();
+
+ void loadEnvelope();
+ int64_t loadStdDev();
+
+ QImage drawEnvelope();
+
+ void dumpInfo() const;
+
+private:
+ uint64_t *m_envelope;
+ Mlt::Producer *m_producer;
+ AudioInfo *m_info;
+
+ int m_envelopeSize;
+ uint64_t m_envelopeMax;
+ uint64_t m_envelopeMean;
+ uint64_t m_envelopeStdDev;
+
+ bool m_envelopeStdDevCalculated;
+};
+
+#endif // AUDIOENVELOPE_H
#include "audioInfo.h"
#include "audioStreamInfo.h"
+#include "audioEnvelope.h"
int main(int argc, char *argv[])
{
framesToFetch = 5000;
}
- mlt_audio_format format_s16 = mlt_audio_s16;
- int samplingRate = infoMain.info(0)->samplingRate();
- int channels = 1;
+ AudioEnvelope envelopeMain(&prodMain);
+ envelopeMain.loadEnvelope();
+ envelopeMain.loadStdDev();
+ envelopeMain.dumpInfo();
- Mlt::Frame *frame;
- int64_t position;
- int samples;
-
- uint64_t envelope[framesToFetch];
- uint64_t max = 0;
-
- QTime t;
- t.start();
- for (int i = 0; i < framesToFetch; i++) {
-
- frame = prodMain.get_frame(i);
- position = mlt_frame_get_position(frame->get_frame());
- samples = mlt_sample_calculator(prodMain.get_fps(), infoMain.info(0)->samplingRate(), position);
-
- int16_t *data = static_cast<int16_t*>(frame->get_audio(format_s16, samplingRate, channels, samples));
-
- uint64_t sum = 0;
- for (int k = 0; k < samples; k++) {
- sum += fabs(data[k]);
- }
- envelope[i] = sum;
-
- if (sum > max) {
- max = sum;
- }
- }
- std::cout << "Calculating the envelope (" << framesToFetch << " frames) took "
- << t.elapsed() << " ms." << std::endl;
-
- QImage img(framesToFetch, 400, QImage::Format_ARGB32);
- img.fill(qRgb(255,255,255));
- double fy;
- for (int x = 0; x < img.width(); x++) {
- fy = envelope[x]/double(max) * img.height();
- for (int y = img.height()-1; y > img.height()-1-fy; y--) {
- img.setPixel(x,y, qRgb(50, 50, 50));
- }
- }
QString outImg = QString("envelope-%1.png")
.arg(QDateTime::currentDateTime().toString("yyyy-MM-dd-hh:mm:ss"));
- img.save(outImg);
+ envelopeMain.drawEnvelope().save(outImg);
std::cout << "Saved volume envelope as "
<< QFileInfo(outImg).absoluteFilePath().toStdString()
<< std::endl;
+
return 0;
}
+
+
+