Skip to content

Commit

Permalink
examples: add vu meter filter
Browse files Browse the repository at this point in the history
  • Loading branch information
wang-bin committed Jul 19, 2017
1 parent e92757f commit fa27201
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 0 deletions.
54 changes: 54 additions & 0 deletions examples/qmlvumeter/VUMeterFilter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#include "VUMeterFilter.h"
#include <QtAV/AudioFrame.h>
#include <cmath>

VUMeterFilter::VUMeterFilter(QObject *parent)
: AudioFilter(parent)
, mLeft(0)
, mRight(0)
{
}

void VUMeterFilter::process(Statistics *statistics, AudioFrame *frame)
{
if (!frame)
return;
const uchar* data = frame->constBits();
const int s = frame->samplesPerChannel();
const int cn = frame->channelCount();
const int r = 1;
float level[2];
const AudioFormat& af = frame->format();
if (af.isFloat()) {
float max[2];
max[0] = max[1] = 0;
const float *p = (float*)data;
for (int i = 0; i < s; i+=cn) {
max[0] = qMax(max[0], qAbs(p[i]));
max[1] = qMax(max[1], qAbs(p[i+r]));
}
level[0] = 20.0f * log10(max[0]);
level[1] = 20.0f * log10(max[1]);
} else if (!af.isUnsigned()) {
const int b = af.sampleSize();
if (b == 2) {
qint16 max[2];
max[0] = max[1] = 0;
const qint16 *p = (qint16*)data;
for (int i = 0; i < s; i+=cn) {
max[0] = qMax(max[0], qAbs(p[i]));
max[1] = qMax(max[1], qAbs(p[i+r]));
}
level[0] = 20.0f * log10((double)max[0]/(double)INT16_MAX);
level[1] = 20.0f * log10((double)max[1]/(double)INT16_MAX);
}
}
if (!qFuzzyCompare(level[0], mLeft)) {
mLeft = level[0];
Q_EMIT leftLevelChanged(mLeft);
}
if (!qFuzzyCompare(level[1], mRight)) {
mRight = level[1];
Q_EMIT leftLevelChanged(mRight);
}
}
27 changes: 27 additions & 0 deletions examples/qmlvumeter/VUMeterFilter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#ifndef VUMeterFilter_H
#define VUMeterFilter_H
#include <QtAV/Filter.h>

using namespace QtAV;
class VUMeterFilter : public AudioFilter
{
Q_OBJECT
Q_PROPERTY(int leftLevel READ leftLevel WRITE setLeftLevel NOTIFY leftLevelChanged)
Q_PROPERTY(int rightLevel READ rightLevel WRITE setRightLevel NOTIFY rightLevelChanged)
public:
VUMeterFilter(QObject* parent = NULL);
int leftLevel() const {return mLeft;}
void setLeftLevel(int value) {mLeft = value;}
int rightLevel() const {return mRight;}
void setRightLevel(int value) {mRight = value;}
Q_SIGNALS:
void leftLevelChanged(int value);
void rightLevelChanged(int value);
protected:
void process(Statistics* statistics, AudioFrame* frame = 0) Q_DECL_OVERRIDE;
private:
int mLeft;
int mRight;
};

#endif // VUMeterFilter_H
17 changes: 17 additions & 0 deletions examples/qmlvumeter/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include "VUMeterFilter.h"

#include <QtGui/QGuiApplication>
#include <QQuickItem>
#include <QtQml/QQmlEngine>
#include <QtQml/QQmlContext>
#include <QtQml/QQmlApplicationEngine>
int main(int argc, char** argv)
{
qmlRegisterType<VUMeterFilter>("com.qtav.vumeter", 1, 0, "VUMeterFilter");
QGuiApplication app(argc, argv);

QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

return app.exec();
}
49 changes: 49 additions & 0 deletions examples/qmlvumeter/main.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.0
import QtAV 1.7
import com.qtav.vumeter 1.0
Window {
visible: true
width: 640
height: 480
title: qsTr("QtAV VU Meter Filter. Press key 'O' to open a file")

VUMeterFilter {
id: vu
}

AudioFilter {
id: afilter
type: AudioFilter.UserFilter
userFilter: vu
}

Video {
id: video
autoPlay: true
anchors.fill: parent
audioFilters: [afilter]
Text {
anchors.fill: parent
color: "white"
text: "dB left=" + vu.leftLevel + " right=" + vu.rightLevel
}
}

Item {
anchors.fill: parent
focus: true
Keys.onPressed: {
switch (event.key) {
case Qt.Key_O:
fileDialog.open()
break
}
}
}
FileDialog {
id: fileDialog
onAccepted: video.source = fileUrl
}
}
5 changes: 5 additions & 0 deletions examples/qmlvumeter/qml.qrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/">
<file>main.qml</file>
</qresource>
</RCC>
32 changes: 32 additions & 0 deletions examples/qmlvumeter/qmlvumeter.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
TEMPLATE = app
CONFIG -= app_bundle

QT += av qml quick
CONFIG += c++11

HEADERS = VUMeterFilter.h
SOURCES = main.cpp VUMeterFilter.cpp

RESOURCES += qml.qrc

# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =

# Additional import path used to resolve QML modules just for Qt Quick Designer
QML_DESIGNER_IMPORT_PATH =

# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

0 comments on commit fa27201

Please sign in to comment.