Commit 09e902e2 authored by Leander Schulten's avatar Leander Schulten

Merge branch 'master' into windows-release

parents b2615758 8efcb3e1
Pipeline #204684 canceled with stages
in 4 minutes and 56 seconds
......@@ -22,6 +22,9 @@ Features:
* Qt Network Authorization (egal welches OS)
5. Drücke _Next_ und beende die Installation.
6. Nun Qt Creator wie [hier](documentation/QtCreator.md) beschrieben einrichten
7. Dann git wie [hier](documentation/git.md) beschrieben einrichten
8. Linux only: Die folgenden Pakete werden zum Bauen der Lichtsteuerung benötigt: `gcc make cmake autoconf libtool automake libasound2-dev libgl1-mesa-dev mesa-common-dev`. Man kann sie z.B. durch den Befehl `sudo apt install gcc make cmake ...` installieren.
9. Im Ordner `src/lib` das Script `build_libs.sh` ausführen.
## Docker/GitlabCI/Cross-Compilation
Siehe [hier](Docker.md).
......@@ -33,10 +36,7 @@ Die Lichtsteuerung hängt von ein paar anderen Projekten ab.
Boost wird benötigt, um bei Modules nicht lineare Codeausführung zu ermöglichen (Corotines) und wird genutzt, um Stacktraces auszugeben.
#### [RtAudio](https://github.com/thestk/rtaudio)
RtAudio (Realtime Audio) ist eine Bibliothek, mit welcher auf jedem Betriebsystem alle Audioeingänge aufgenommen werden können. Unter Windows ist es auch möglich den Audio Ausgang aufzunehmen. Vor RtAudio wurde diese Aufgabe von der [Capture_Windows_SoundOutput](https://git.rwth-aachen.de/leander.schulten/Capture_Windows_SoundOutput) lib übernommen (Diese konnte nur unter Windows den Standardausgang aufnehmen).
#### [AudioFFT](https://git.rwth-aachen.de/leander.schulten/FFT_for_Audio)
Dieses Projekt ermöglicht es, den abgefangenen Sound auf Frequenzbereiche aufzuspalten, wobei jedem Frequenzbereich eine "Energie"/Stärke zugeordnet wird. Dieses Projekt hängt wiederum von [fftw](http://www.fftw.org/) ab. Diese Abhängigkeiten befinden sich auch hier als kompilierte lib im git.
RtAudio (Realtime Audio) ist eine Bibliothek, mit welcher auf jedem Betriebsystem alle Audioeingänge aufgenommen werden können. Unter Windows ist es auch möglich den Audio Ausgang aufzunehmen. Vor RtAudio wurde diese Aufgabe von der [Capture_Windows_SoundOutput](https://git.rwth-aachen.de/leander.schulten/Capture_Windows_SoundOutput) lib übernommen (Diese konnte nur unter Windows den Standardausgang aufnehmen).
#### [SusbDmx-Driver](https://git.rwth-aachen.de/leander.schulten/SusbDMX-Driver)
Dieses Projekt enthält den aktuellen Treiber, der es ermöglicht, den USB zu DMX Konverter anzusteuern. Dieser Treiber befindet sich nicht als lib hier im git.
......
......@@ -55,12 +55,6 @@ fi
# copy aubio
cp "src/lib/aubio/lib/libaubio-5.dll" "$target_folder"
#copy AudioFFT
cp "src/lib/AudioFFT/dll/win${bit}/AudioFFT.dll" "$target_folder"
cp "src/lib/AudioFFT/dll/win${bit}/libfftw3-3.dll" "$target_folder"
cp "src/lib/AudioFFT/dll/win${bit}/libfftw3f-3.dll" "$target_folder"
cp "src/lib/AudioFFT/dll/win${bit}/libfftw3l-3.dll" "$target_folder"
#copy DrMinGw
if [[ $bit == "64" ]]; then
for file in src/lib/DrMinGW/bin/*; do cp "$file" "$target_folder";done
......
......@@ -3,7 +3,7 @@ Die IDE mit der die Lichtsteuerung entwickelt wird.
### Einrichten
1. Mac: open Qt Creator -> About Plugins...
Windows: open Help -> About Plugins...
Windows/Linux: open Help -> About Plugins...
2. Enable:
- C++ -> ClangCodeModel
- C++ -> ClangFormat
......@@ -12,12 +12,23 @@ Die IDE mit der die Lichtsteuerung entwickelt wird.
- Utilities -> Todo
Click 'Close' and restart Qt Creator
3. Open the settings (Mac: Qt Creator -> Preferences..., Windows: Tools -> Options...)
3. Open the settings (Mac: Qt Creator -> Preferences..., Windows/Linux: Tools -> Options...)
4. You can choose under Environment -> Interface -> Theme the 'Dark' Theme ;)
5. Check C++ -> Code Style -> Format instead of indenting
Check C++ -> Code Style -> Format while typing
Check C++ -> Code Style -> Format edited code on file save
6. Check Qt Quick -> QML/JS Editing -> Enable auto format on file save if [this](https://bugreports.qt.io/browse/QTCREATORBUG-23019) is fixed
6. Check Qt Quick -> QML/JS Editing -> Enable auto format on file save, **if [this](https://bugreports.qt.io/browse/QTCREATORBUG-23019) is fixed**
7. Close the settings
8. You can select File -> Sessions -> Manage... -> Restore last session on startup
9. If you have changed the theme, restart Qt Creator
### Compiler
Unter **Windows** wird der Compiler von Qt mitgeliefert.
Unter **Linux** kann gcc mittels `sudo apt install gcc` installiert werden. Gcc sollte mindestens version 7 haben (überprüfen mit `gcc --version`). Außerdem muss make installiert werden: `sudo apt install make`.
Unter **Mac**: XCode im AppStore installieren.
### Cpp-Check installieren
[Cppcheck](http://cppcheck.sourceforge.net/) ist ein Tool zur statischen Analyse, um Fehler zu finden.
* Windows: Auf die Webseite von [Cppcheck](http://cppcheck.sourceforge.net/) gehen, den Installer runterladen und installieren.
* Mac: `brew install cppcheck` (vorrausgesetzt [brew](https://brew.sh/) ist installiert)
* Linux: `sudo apt install cppcheck`
\ No newline at end of file
# Git
Git ist eine Software zur verteilten Versionsverwaltung von Dateien. Wenn man noch keine Ahnung von Git hat, kann [ich](@Leander.Schulten) das [Git Book](https://git-scm.com/book/en/v2) empfehlen, zumindest die Kapitel [Recording Changes to the Repository](https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository), [Branches in a Nutshell](https://git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell) und [Basic Branching and Merging](https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging). Man kann natürlich auch jedes andere Turoial im Internet lesen.
### Git installieren
*Linux:* `sudo apt install git`
*Mac:* Wenn XCode installiert ist: `sudo xcode-select --install`, wenn [brew](https://brew.sh/) installiert ist: `brew install git`, sonst von der [Git Webseite](https://git-scm.com/downloads)
*Windows:* Von der [Git Webseite](https://git-scm.com/downloads). Bei der Installation alle voreingestellten Einstellungen so lassen.
### SHH-Key auf git.rwth-aachen.de registrieren
Um ein git repository klonen, sowie pullen und pushen zu können, muss ein lokaler SSH-Key auf git.rwth-aachen.de registriert werden.
Gehe dafür auf https://git.rwth-aachen.de/profile/keys und befolge die dort oben verlinkte Anleitung, die sehr genau ist.
Unter **Windows** kann es zu Problemen kommen, wenn man mit den Key in SmartGit importieren möchte. Erfahrungsgemäß funktionieren Keys, die mit [Putty](https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html) erzeugt wurde (bis zum Download von *puttygen.exe* runterscrollen). In puttygen.exe dann einfach einen Key generieren und privaten und öffentlichen Schlüssel speichern.
### SmartGit installieren
Git bietet von sich aus nur ein Kommandozeilenprogram an. Wenn man eine grafische Oberfläche haben möchte, kann man z.B. [SmartGit](https://www.syntevo.com/smartgit/) installieren.
1. Download SmartGit from [here](https://www.syntevo.com/smartgit/download/). Linux: Use the *Debian Bundle*
2. Start the installer
3. Choose *Non-commercial use only (most features, no support)* and press *Next*
4. Wait 10 seconds, check the boxes and click *OK*
5. Enter your real name and a real email. The name is used in the commits and the email is used to send you a mail when you commit broken code. *Next*
6. Select *Use SmartGit as SSH client*. *Next*
7. Select *File Manager*. *Next*
8. Press *Finish*
9. Select *Clone existing repository*. *OK*
10. Repository URL: `git@git.rwth-aachen.de:leander.schulten/Lichtsteuerung.git`. *Next*
11. If a dialog opens: Select the file that you have created in the step *SHH-Key auf git.rwth-aachen.de registrieren*
12. *Next*. *Finish*
\ No newline at end of file
......@@ -20,6 +20,7 @@ SOURCES += \
applicationdata.cpp \
audio/aubio/aubiocapi.cpp \
audio/aubio/onsetanalysis.cpp \
audio/aubio/spectrumanalysis.cpp \
audio/aubio/tempoanalysis.cpp \
audio/audioeventdata.cpp \
audio/remotevolume.cpp \
......@@ -107,6 +108,7 @@ DEFINES += _USE_MATH_DEFINES
HEADERS += \
audio/aubio/aubiocapi.h \
audio/aubio/onsetanalysis.h \
audio/aubio/spectrumanalysis.h \
audio/aubio/tempoanalysis.h \
audio/audioeventdata.h \
audio/remotevolume.h \
......@@ -209,9 +211,9 @@ DISTFILES +=
# QMAKE_CXXFLAGS += -lasan
# LIBS += -lasan
win32-g++{
win32-g++ | linux{
# boost
CONFIG(debug, debug|release){
win32-g++:CONFIG(debug, debug|release){
DEBUG = d-
} else {
DEBUG =
......@@ -220,29 +222,12 @@ win32-g++{
INCLUDEPATH += $$PWD/'lib/boost/include'
}
unix{
macx{
#installed with brew install boost
LIBS += -L/usr/local/lib -lboost_coroutine -lboost_context-mt
INCLUDEPATH += /usr/local/include
}
macx{
#AudioFFT
LIBS += -L$$PWD/'lib/AudioFFT/dll' -lAudioFFT
INCLUDEPATH += $$PWD/lib/AudioFFT/include
}
win32-g++{
#AudioFFT
#LIBS += -L$$PWD/'lib/AudioFFT/dll' -lAudioFFT
contains(QT_ARCH, i386){ # 32 bit
LIBS += -L$$PWD/'lib/AudioFFT/dll/win32/' -lAudioFFT
} else { # 64 bit
LIBS += -L$$PWD/'lib/AudioFFT/dll/win64' -lAudioFFT
}
INCLUDEPATH += $$PWD/'lib/AudioFFT/include'
}
win32-g++{
#DrMinGW
#LIBS += -L$$PWD/'lib/AudioFFT/dll' -lAudioFFT
......@@ -279,12 +264,6 @@ macx{
DEFINES += _GNU_SOURCE
}
win32-msvc{
#AudioFFT
LIBS += -L$$PWD/'lib/AudioFFT/dll/AudioFFT.dll'
INCLUDEPATH += $$PWD/'lib/AudioFFT/include'
}
# RTAudio
INCLUDEPATH += $$PWD/lib/RtAudio/include
LIBS += -L$$PWD/lib/RtAudio/lib -lrtaudio
......@@ -294,3 +273,10 @@ macx{
# Needed by the SystemVolume class
LIBS += -framework CoreAudio
}
linux{
# needed for dynamic libs
LIBS += -ldl
# needed for the SystemVolume class
LIBS += -lasound
}
#include "spectrumanalysis.h"
namespace Audio::Aubio {
using namespace C_API;
SpectrumAnalysis::SpectrumAnalysis(C_API::uint_t spectrumSize, C_API::uint_t stepSize) : spectrumAnalyser(new_aubio_pvoc(spectrumSize * 2, stepSize), del_aubio_pvoc), fftOutputData(new_cvec(spectrumSize * 2), del_cvec), inputData{stepSize, nullptr} {}
void SpectrumAnalysis::processNewSamples(float *newSamples) {
inputData.data = newSamples;
aubio_pvoc_do(spectrumAnalyser.get(), &inputData, fftOutputData.get());
}
boost::beast::span<float> SpectrumAnalysis::getSpectrum() const {
return {fftOutputData->norm, fftOutputData->length};
}
float *SpectrumAnalysis::getPointerToSpectrum() const {
return fftOutputData->norm;
}
} // namespace Audio::Aubio
#ifndef SPECTRUMANALYSIS_H
#define SPECTRUMANALYSIS_H
#include "aubiocapi.h"
#include <boost/beast/core/span.hpp> // TODO use std::span in c++20
#include <memory>
namespace Audio::Aubio {
/**
* @brief The SpectrumAnalysis class computes a spectrum (energy for every frequency) for the audio data.
*/
class SpectrumAnalysis {
std::unique_ptr<C_API::aubio_pvoc_t, decltype(&C_API::del_aubio_pvoc)> spectrumAnalyser;
std::unique_ptr<C_API::cvec_t, decltype(&C_API::del_cvec)> fftOutputData;
C_API::fvec_t inputData;
public:
/**
* @brief SpectrumAnalysis Creates a spectrum analysis.
* @param spectrumSize The size of blocks in the spectrum from 0 to sampleRate/2. Must be a power of 2.
* @param stepSize The size of a new block that gets passed to this->processNewSamples().
*/
SpectrumAnalysis(C_API::uint_t spectrumSize, C_API::uint_t stepSize);
/**
* @brief processNewSamples process and analyse new samples
* @param newSamples A pointer to the new samples, the length of the array must be minimun the step size from the constructor
*/
void processNewSamples(float *newSamples);
/**
* @brief getSpectrum returns the spectrum (the enery for every block)
* @return the spectrum
*/
[[nodiscard]] boost::beast::span<float> getSpectrum() const;
/**
* @brief getPointerToSpectrum See getSpectrum().
* @return A pointer to the spectrum. You can modify the values. They will be overwritten in the processNewSamples(float*) method
*/
[[nodiscard]] float *getPointerToSpectrum() const; // remove when using std::span in c++20
};
} // namespace Audio::Aubio
#endif // SPECTRUMANALYSIS_H
......@@ -16,8 +16,8 @@
#endif
namespace Audio {
AudioCaptureManager::AudioCaptureManager():audiofft(sample.size())
{
AudioCaptureManager::AudioCaptureManager() {
rtAudio.showWarnings();
updateCaptureDeviceList();
}
......@@ -35,6 +35,7 @@ void AudioCaptureManager::initCallback(int channels, int samplesPerSecond) {
if (GUI::Colorplot::getLast()) {
GUI::Colorplot::getLast()->setBlockSize(512);
}
spectrumAnalysis.emplace(2048, samplesPerFrame);
}
void AudioCaptureManager::dataCallback(float* data, unsigned int frames, bool*done){
......@@ -58,7 +59,6 @@ void AudioCaptureManager::dataCallback(float* data, unsigned int frames, bool*do
sample.addData(data,data+frames*static_cast<unsigned>(channels),channels-1,firstIndex);
audiofft.analyse(sample.data(),1,fftoutput.data());
{
// feed the *analysis classes with new samples
int restFrames = static_cast<int>(frames);
......@@ -75,6 +75,7 @@ void AudioCaptureManager::dataCallback(float* data, unsigned int frames, bool*do
restFrames -= samplesPerFrame;
continue;
}
spectrumAnalysis->processNewSamples(sample.data() + sample.size() - restFrames);
for (auto &[onsetFunction, pair] : onsetAnalyzes) {
bool wasOnset = pair.first.processNewSamples(sample.data() + sample.size() - restFrames);
pair.second.addOnsetData(pair.second.getNewestSample(), pair.first.getOnsetValue(), 0);
......@@ -95,15 +96,16 @@ void AudioCaptureManager::dataCallback(float* data, unsigned int frames, bool*do
}
}
// db scale
std::transform(fftoutput.begin(), fftoutput.end(), fftoutput.begin(), [](auto i) { return 10 * std::log10(1 + i); });
auto spectrum = spectrumAnalysis->getSpectrum();
std::transform(spectrum.cbegin(), spectrum.cend(), spectrumAnalysis->getPointerToSpectrum(), [](auto i) { return 10 * std::log10(1 + i); });
if (GUI::Graph::getLast() && run) {
GUI::Graph::getLast()->showData(fftoutput.data(), fftoutput.size());
GUI::Graph::getLast()->showData(spectrumAnalysis->getPointerToSpectrum(), spectrum.size());
}
if (GUI::Colorplot::getLast() && run) {
GUI::Colorplot::getLast()->startBlock();
for (int i = 0; i < 512; ++i) {
GUI::Colorplot::getLast()->pushDataToBlock(fftoutput.at(i));
GUI::Colorplot::getLast()->pushDataToBlock(spectrum.begin()[i]);
}
GUI::Colorplot::getLast()->endBlock();
}
......@@ -112,6 +114,12 @@ void AudioCaptureManager::dataCallback(float* data, unsigned int frames, bool*do
}
}
void AudioCaptureManager::rtAudioErrorCallback(RtAudioError::Type /*type*/, const std::string &errorText) {
get().currentCaptureDevice = -1;
emit get().currentCaptureDeviceChanged();
ErrorNotifier::showError("Error while capturing from capture device. Capturing stopped.\nError: " + QString::fromStdString(errorText) + "\nPlease select a new audio capture device the settings tab.");
}
bool AudioCaptureManager::startCapturingFromInput(unsigned input) {
if (input >= rtAudio.getDeviceCount()) {
return false;
......@@ -138,7 +146,7 @@ bool AudioCaptureManager::startCapturingFromInput(unsigned input) {
isp.firstChannel = 0;
unsigned samplesPerFrame = static_cast<unsigned>(this->samplesPerFrame);
try {
rtAudio.openStream(nullptr, &isp, RTAUDIO_FLOAT32, static_cast<unsigned>(this->samplesPerSecond), &samplesPerFrame, rtAudioCallback, nullptr, nullptr, nullptr);
rtAudio.openStream(nullptr, &isp, RTAUDIO_FLOAT32, static_cast<unsigned>(this->samplesPerSecond), &samplesPerFrame, rtAudioCallback, nullptr, nullptr, rtAudioErrorCallback);
if (static_cast<int>(samplesPerFrame) != this->samplesPerFrame) {
rtAudio.closeStream();
return false;
......
......@@ -5,9 +5,10 @@
#include "modelvector.h"
#include "sample.h"
#include "aubio/onsetanalysis.h"
#include "aubio/spectrumanalysis.h"
#include "aubio/tempoanalysis.h"
#include "audio_fft.h"
#include <RtAudio.h>
#include <boost/beast/core/span.hpp> // TODO use std::span in c++20
#include <map>
#include <thread>
......@@ -35,12 +36,12 @@ class AudioCaptureManager : public QObject
Q_PROPERTY(int currentCaptureDevice READ getCurrentCaptureDevice WRITE setCurrentCaptureDevice NOTIFY currentCaptureDeviceChanged)
Q_PROPERTY(QAbstractItemModel *captureDeviceNames READ getCaptureDeviceNamesModel CONSTANT)
Sample<float,4096> sample;
std::array<float, 2048> fftoutput;
std::atomic_bool run;
int currentCaptureDevice = -1;
RtAudio rtAudio;
AudioFFT audiofft;
ModelVector<QString> captureDeviceNames;
// we use a optional to delay the creation of the object until we know the samplesPerFrame value
std::optional<Aubio::SpectrumAnalysis> spectrumAnalysis;
int channels = -1;
int samplesPerSecond = -1;
......@@ -57,6 +58,7 @@ class AudioCaptureManager : public QObject
private:
AudioCaptureManager();
private:
static void rtAudioErrorCallback(RtAudioError::Type type, const std::string &errorText);
static int rtAudioCallback(void *outputBuffer, void *inputBuffer, unsigned int nFrames, double streamTime, RtAudioStreamStatus status, void *userData);
void initCallback(int channels, int samplesPerSecond);
void dataCallback(float *data, unsigned int frames, bool *done);
......@@ -105,7 +107,7 @@ public:
*/
const std::vector<QString> &getCaptureDeviceNames() const { return captureDeviceNames.getVector(); }
const std::array<float, 2048> &getFFTOutput() { return fftoutput; }
boost::beast::span<float> getFFTOutput() { return (spectrumAnalysis ? spectrumAnalysis->getSpectrum() : boost::beast::span<float>{nullptr, 0}); }
/**
* @brief requestTempoAnalysis requests the data series from a tempo analysis that uses a spezific onset detection function
* You can call the function with the same parameters multiple times, the result will be the same
......
......@@ -104,7 +104,85 @@ SystemVolume::SystemVolume() {
emit volumeChanged();
}
#endif
#ifdef Q_OS_LINUX
snd_mixer_selem_id_alloca(&sid);
// sets simple-mixer index and name
snd_mixer_selem_id_set_index(sid, mix_index);
snd_mixer_selem_id_set_name(sid, mix_name);
if ((snd_mixer_open(&handle, 0)) < 0) {
qWarning() << "SystemVolume: Failed to open the mixer";
return;
}
if ((snd_mixer_attach(handle, card)) < 0) {
snd_mixer_close(handle);
handle = nullptr;
qWarning() << "SystemVolume: Failed to attach the card 'default'";
return;
}
if ((snd_mixer_selem_register(handle, nullptr, nullptr)) < 0) {
snd_mixer_close(handle);
handle = nullptr;
qWarning() << "SystemVolume: Failed to register the mixer";
return;
}
if (snd_mixer_load(handle) < 0) {
snd_mixer_close(handle);
handle = nullptr;
qWarning() << "SystemVolume: Failed to load the mixer";
return;
}
elem = snd_mixer_find_selem(handle, sid);
if (!elem) {
snd_mixer_close(handle);
handle = nullptr;
qWarning() << "SystemVolume: Failed to find a mixer element";
return;
}
if (snd_mixer_selem_get_playback_volume_range(elem, &minv, &maxv) < 0) {
snd_mixer_close(handle);
handle = nullptr;
qWarning() << "SystemVolume: Failed to get the mixer playback volume range";
return;
}
snd_mixer_elem_set_callback(elem, snd_mixer_elem_callback);
startTimer(16);
long volume;
if (snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_MONO, &volume) < 0) {
snd_mixer_close(handle);
handle = nullptr;
qWarning() << "SystemVolume: Failed to get the volume";
return;
}
this->volume = (volume - minv) / static_cast<double>(maxv - minv);
emit volumeChanged();
#endif
}
#ifdef Q_OS_LINUX
void SystemVolume::timerEvent(QTimerEvent * /*event*/) {
if (handle) {
snd_mixer_handle_events(handle);
}
}
int SystemVolume::snd_mixer_elem_callback(snd_mixer_elem_t *elem, unsigned int mask) {
// testet, don't know why value 1, but only mask == 1 works
if (mask == 1) {
long volume;
if (snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_MONO, &volume) >= 0) {
get().volume = (volume - get().minv) / static_cast<double>(get().maxv - get().minv);
emit get().volumeChanged();
} else {
qWarning() << "SystemVolume: Failed to get the volume";
}
}
return 0;
}
#endif
SystemVolume::~SystemVolume() {
#ifdef Q_OS_WIN
......@@ -123,6 +201,11 @@ SystemVolume::~SystemVolume() {
}
CoUninitialize();
#endif
#ifdef Q_OS_LINUX
if (handle) {
snd_mixer_close(handle);
}
#endif
}
void SystemVolume::setVolume(double volume) {
......@@ -154,6 +237,14 @@ void SystemVolume::setVolume(double volume) {
}
}
}
#endif
#ifdef Q_OS_LINUX
if (handle) {
long outvol = static_cast<long>(volume * (maxv - minv)) + minv;
if (snd_mixer_selem_set_playback_volume_all(elem, outvol) < 0) {
qWarning() << "SystemVolume: Can not set system volume for all channels";
}
}
#endif
}
}
......@@ -18,6 +18,10 @@
#include <CoreAudio/CoreAudio.h>
#endif
#ifdef Q_OS_LINUX
#include <alsa/asoundlib.h>
#endif
#ifdef Q_OS_WIN
class Callback : public IAudioEndpointVolumeCallback {
......@@ -45,12 +49,31 @@ class SystemVolume : public QObject {
#endif
#ifdef Q_OS_MAC
AudioDeviceID defaultOutputDeviceID = kAudioDeviceUnknown;
#endif
#ifdef Q_OS_LINUX
// code from here: https://stackoverflow.com/questions/7657624/get-master-sound-volume-in-c-in-linux
snd_mixer_t *handle = nullptr;
snd_mixer_elem_t *elem = nullptr;
snd_mixer_selem_id_t *sid = nullptr;
long minv, maxv;
static constexpr const char *mix_name = "Master";
static constexpr const char *card = "default";
static constexpr int mix_index = 0;
#endif
double volume = -1;
Q_PROPERTY(double volume READ getVolume WRITE setVolume NOTIFY volumeChanged)
SystemVolume();
#ifdef Q_OS_LINUX
protected:
void timerEvent(QTimerEvent *event) override;
private:
static int snd_mixer_elem_callback(snd_mixer_elem_t *elem, unsigned int mask);
#endif
public:
static SystemVolume &get() {
static SystemVolume sv;
......
......@@ -456,6 +456,15 @@ void transferData(Modules::Property & p, GUI::detail::PropertyInformation &pi){
pi.setMaxValue(p.asNumeric<SourceType>()->getMax());
}
// see https://stackoverflow.com/questions/4160945/long-long-int-vs-long-int-vs-int64-t-in-c
template <>
void transferData<int64_t>(Modules::Property &p, GUI::detail::PropertyInformation &pi) {
static_assert(sizeof(qint64) == sizeof(int64_t), "qint64 and int64_t must have the same size");
pi.setValue(static_cast<qint64>(p.asNumeric<int64_t>()->getValue()));
pi.setMinValue(static_cast<qint64>(p.asNumeric<int64_t>()->getMin()));
pi.setMaxValue(static_cast<qint64>(p.asNumeric<int64_t>()->getMax()));
}
QQuickItem * ProgramBlockEditor::getItemWithPropertyBase(QMouseEvent *event){
auto comp = childAt(event->x(),event->y());
if(!comp){
......
libAudioFFT.1.0.0.dylib
\ No newline at end of file
libAudioFFT.1.0.0.dylib
\ No newline at end of file
libAudioFFT.1.0.0.dylib
\ No newline at end of file
#ifndef AUDIO_FFT_H
#define AUDIO_FFT_H
#include "audio_fft_global.h"
#include "fftw3.h"
class AUDIO_FFT_SHARED_EXPORT AudioFFT
{
fftw_plan plan;
fftw_complex *in, *out;
const unsigned int size;
public:
AudioFFT(const unsigned int size);
void execute();
void analyse(float* floatData,const int stepsToNext, float*output);
void fillInputData(float* floatData,const int stepsToNext);
void fillInputDataAndApplyHannWindow(float* floatData,const int stepsToNext);
fftw_complex * getInput(){return in;}
fftw_complex * getOutput(){return out;}
/**
* @brief fillOutput füllt size/2 mem positionen mit dem Ergebnis der Analyse in log db scale
* @param mem Ein size/2 langer float array der mit dem Ergebnis gefüllt wird
*/
void fillOutput(float * mem);
unsigned int getSize(){return size;}
~AudioFFT();
private:
void createPlan();
inline float hann(int n);
};
#endif // AUDIO_FFT_H
#ifndef AUDIO_FFT_GLOBAL_H
#define AUDIO_FFT_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(AUDIO_FFT_LIBRARY)
# define AUDIO_FFT_SHARED_EXPORT Q_DECL_EXPORT
#else
# define AUDIO_FFT_SHARED_EXPORT Q_DECL_IMPORT
#endif
#endif // AUDIO_FFT_GLOBAL_H
This diff is collapsed.
......@@ -20,8 +20,12 @@ elif [[ "$OSTYPE" == "darwin"* ]]; then
FILES_TO_COPY="librtaudio.dylib librtaudio.6.dylib"
else
#linux
if ! dpkg -s libasound2-dev autoconf libtool automake >/dev/null 2>&1; then
echo "You have to install the packages libasound2-dev autoconf libtool automake! Run 'sudo apt install libasound2-dev autoconf libtool automake'"
exit 1
fi
./autogen.sh --with-alsa
FILES_TO_COPY="librtaudio.so librtaudio.6.so"
FILES_TO_COPY="librtaudio.so*"
fi
make
cd ..
......
......@@ -63,7 +63,22 @@ elif [[ "$OSTYPE" == "msys" ]] || ! [[ -z "$GITLAB_CI" ]]; then
./b2$EXE --prefix=../ -q --layout=tagged --with-coroutine --with-context abi=ms architecture=x86 binary-format=pe target-os=windows toolset=$TOOLSET link=shared threading=multi runtime-link=shared address-model=64 install
echo "Boost build is finished"
else
# linux?
echo "You are on Linux"
echo "Linux is currently not supported (no mashine to test). You must install boost yourself. Maybe look at the windows version in this file."
echo "We do not use the boost package from the package manager, because this package is very outdated"
# copied from windows
GIT_DIR="boost.git"
if ! [ -d "$GIT_DIR" ]; then
echo "We have to clone the repo, this will take approximately 6.5 minutes"
git clone --depth 1 --shallow-submodules --recurse-submodules --jobs 32 https://github.com/boostorg/boost.git "$GIT_DIR"
cd "$GIT_DIR"
echo "Init the build"
# configure the build
./bootstrap.sh
else
cd "$GIT_DIR"
git pull
fi
echo "Build boost, this will take approximately 3 minutes, if boost is not already build."
./b2 --prefix=../ -q --layout=tagged --with-coroutine --with-context link=shared install
echo "Boost build is finished"
fi
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment