Commit 357d8fa6 authored by Leander Schulten's avatar Leander Schulten
Browse files

Make it possible for a module to access the fftOutput and make it default for the editor

parent 7d7590dc
......@@ -131,7 +131,8 @@ HEADERS += \
programblockeditor.h \
audio/sample.h \
test/testsampleclass.h \
audio/audiocapturemanager.h
audio/audiocapturemanager.h \
programms/fftoutput.hpp
# Default rules for deployment.
......
......@@ -88,6 +88,9 @@ Item{
enabled: listView.currentIndex !== -1
text: listView.currentItem ? listView.currentItem.itemData.name : "Select one Module"
onTextChanged: listView.currentItem.itemData.name = text;
validator: RegExpValidator{
regExp: /[^\s]+/
}
}
Label{
......
......@@ -59,7 +59,10 @@ bool AudioCaptureManager::startCapturing(QString filePathToCaptureLibrary){
if(func){
captureAudioThread = std::thread([this,func](){
run = true;
emit this->capturingStatusChanged();
func(&AudioCaptureManager::staticInitCallback,&AudioCaptureManager::staticDataCallback);
run = false;
emit this->capturingStatusChanged();
});
}
return func;
......
......@@ -10,8 +10,10 @@ namespace Audio {
/**
* @brief The AudioCaptureManager class gets the data from the captureWindowsSountoutput Project and analyse the data and give the data to the other components
*/
class AudioCaptureManager
class AudioCaptureManager : public QObject
{
Q_OBJECT
Q_PROPERTY(bool capturing READ isCapturing NOTIFY capturingStatusChanged)
Sample<float,4096> sample;
std::array<float,2048> fftoutput;
std::thread captureAudioThread;
......@@ -34,10 +36,14 @@ private:
void dataCallback(float* data, unsigned int frames, bool*done);
public:
bool startCapturing(QString filePathToCaptureLibrary);
bool isCapturing(){return run;}
const std::array<float,2048>& getFFTOutput(){return fftoutput;}
public:
AudioCaptureManager(AudioCaptureManager const&) = delete;
void operator=(AudioCaptureManager const&) = delete;
static AudioCaptureManager & get(){static AudioCaptureManager m;return m;}
signals:
void capturingStatusChanged();
};
}
......
......@@ -332,6 +332,7 @@ void CodeEditorHelper::compile(){
QString outputType = toName(module->getOutputType());
QTextStream stream( &file );
stream << "#define MODULE_LIBRARY" << endl;
stream << "#define HAVE_AUDIO" << endl;
switch (module->getType()) {
case Modules::Module::Filter:
stream << "#define HAVE_FILTER" << endl;
......
#ifndef FFTOUTPUT_H
#define FFTOUTPUT_H
#include <type_traits>
#include <iterator>
namespace Modules {
template<typename T>
class FFTOutputView{
// The view should never be empty to avoid issues with Bad code by users
T emptyValue = 0;
const T * data_ = &emptyValue;
std::size_t size_ = 1;
int sampleRate_ = 44100;
public:
// from https://github.com/boostorg/beast/blob/5abac8b380ffcd914126c5019c980366c5a53f68/include/boost/beast/core/span.hpp
/// The type of value, including cv qualifiers
using element_type = T;
/// The type of value of each span element
using value_type = typename std::remove_const<T>::type;
/// The type of integer used to index the span
using index_type = std::ptrdiff_t;
/// A pointer to a span element
using pointer = T*;
/// A reference to a span element
using reference = T&;
/// The iterator used by the container
using iterator = pointer;
/// The const pointer used by the container
using const_pointer = T const*;
/// The const reference used by the container
using const_reference = T const&;
/// The const iterator used by the container
using const_iterator = const_pointer;
/// Constructor
FFTOutputView() = default;
/// Constructor
FFTOutputView(FFTOutputView const&) = default;
/// Assignment
FFTOutputView& operator=(FFTOutputView const&) = default;
/** Constructor
@param data A pointer to the beginning of the range of elements
@param size The number of elements pointed to by `data`
*/
FFTOutputView(T* data, std::size_t size, int sampleRate)
: data_(data), size_(size), sampleRate_(sampleRate)
{
}
/** Constructor
@param container The container to construct from
*/
template<class ContiguousContainer>
explicit
FFTOutputView(ContiguousContainer&& container, int sampleRate)
: data_(container.data())
, size_(container.size())
, sampleRate_(sampleRate)
{
}
/// Assignment
template<class ContiguousContainer>
FFTOutputView& operator=(ContiguousContainer&& container){
data_ = container.data();
size_ = container.size();
return *this;
}
/// Returns `true` if the span is empty
bool
empty() const
{
return size_ == 0;
}
/// Returns a pointer to the beginning of the span
T*
data() const
{
return data_;
}
/// Returns the number of elements in the span
std::size_t
size() const
{
return size_;
}
/// Returns an iterator to the beginning of the span
const_iterator
begin() const
{
return data_;
}
/// Returns an iterator to the beginning of the span
const_iterator
cbegin() const
{
return data_;
}
/// Returns an iterator to one past the end of the span
const_iterator
end() const
{
return data_ + size_;
}
/// Returns an iterator to one past the end of the span
const_iterator
cend() const
{
return data_ + size_;
}
int getSampleRate() const{
return sampleRate_;
}
void setSampleRate(int sampleRate){
sampleRate_ = sampleRate;
}
int getMaxFrequency() const{
return sampleRate_/2;
}
/**
* @brief getBlockSize Der Fft output ist in size() Blöcke eingeteilt und
* die Maximal registrierte Frequenz ist getMaxFrequency(). Jeder Block
* enthält somit eine Frequenzspanne von getBlockSize() Herz.
* @return
*/
double getBlockSize()const{
return getMaxFrequency()/static_cast<double>(size_);
}
int getLowerBlockFrequency(const_iterator i){
return getMaxFrequency() * std::distance(cbegin(),i) / size();
}
int getUpperBlockFrequency(const_iterator i){
return getLowerBlockFrequency(++i);
}
/// Returns an iterator to the beginning of the span
const_iterator
begin(int frequency) const
{
return data_ + frequency * size_ / getMaxFrequency();
}
const_iterator
end(int frequency) const
{
return begin(frequency) + 1;
}
T atFrequency(int frequency)const{
return *begin(frequency);
}
};
}
#endif // FFTOUTPUT_H
......@@ -19,6 +19,10 @@
#include "consumer.hpp"
#endif
#ifdef HAVE_AUDIO
#include "fftoutput.hpp"
#endif
#include <string>
//disable Warning for char * as return type in extern "C" Block with clang
......@@ -35,7 +39,7 @@
#endif
extern "C" {
enum class MODUL_TYPE{Program, LoopProgram,Filter,Consumer};
enum class MODUL_TYPE{Program, LoopProgram,Filter,Consumer,Audio};
#ifdef MODULE_LIBRARY
......@@ -64,6 +68,12 @@ MODULE_EXPORT bool have(MODUL_TYPE t){
return true;
#else
return false;
#endif
case MODUL_TYPE::Audio:
#ifdef HAVE_AUDIO
return true;
#else
return false;
#endif
}
return false; // Vielleicht wird das enum in einer weiteren Version erweitert.
......@@ -92,6 +102,16 @@ MODULE_EXPORT char const * getDescriptionOfConsumer(unsigned int index);
MODULE_EXPORT Modules::Consumer * createConsumer(unsigned int index);
#endif
#ifdef HAVE_AUDIO
Modules::FFTOutputView<float> _emptyView;
Modules::FFTOutputView<float> * _fftOutputView = &_emptyView;
bool __supportAudio = false;
MODULE_EXPORT void _supportAudio(bool b){__supportAudio = b;}
MODULE_EXPORT void _setFFTOutputView(Modules::FFTOutputView<float> * fftOutputView){_fftOutputView = fftOutputView?fftOutputView:&_emptyView;}
const Modules::FFTOutputView<float> & getFFTOutput(){return *_fftOutputView;}
bool supportAudio(){return __supportAudio;}
#endif
}
#endif // MODULES_GLOBAL_H
......@@ -5,6 +5,7 @@
#include "settings.h"
#include <QJsonObject>
#include <QJsonArray>
#include "audio/audiocapturemanager.h"
namespace Modules {
......@@ -65,7 +66,14 @@ typedef Modules::Program* (*CreateProgramm)(unsigned int index);
ModuleManager::ModuleManager()
{
fftOutputView = Audio::AudioCaptureManager::get().getFFTOutput();
QObject::connect(&Audio::AudioCaptureManager::get(),&Audio::AudioCaptureManager::capturingStatusChanged,[this](){
for(const auto & info : loadedLibraryMap){
if(info.second.supportAudioFunc){
info.second.supportAudioFunc(Audio::AudioCaptureManager::get().isCapturing());
}
}
});
}
void ModuleManager::loadModules(const QJsonObject & o){
......@@ -81,13 +89,13 @@ typedef Modules::Program* (*CreateProgramm)(unsigned int index);
qDebug()<<e->first;
if(e->first == filePath){
filter.erase(std::remove_if(filter.begin(),filter.end(),[&](const auto &f){
return f.libraryIdentifier == e->second;
return f.libraryIdentifier == e->second.libraryIdentifier;
}),filter.cend());
programms.erase(std::remove_if(programms.begin(),programms.end(),[&](const auto &f){
return f.libraryIdentifier == e->second;
return f.libraryIdentifier == e->second.libraryIdentifier;
}),programms.cend());
consumer.erase(std::remove_if(consumer.begin(),consumer.end(),[&](const auto &f){
return f.libraryIdentifier == e->second;
return f.libraryIdentifier == e->second.libraryIdentifier;
}),consumer.cend());
QLibrary lib(filePath);
bool suc = lib.unload();
......@@ -135,8 +143,6 @@ typedef Modules::Program* (*CreateProgramm)(unsigned int index);
auto lastProgram = programms.size();
auto lastFilter = filter .size();
auto lastConsumer = consumer .size();
lastLibraryIdentifier++;
loadedLibraryMap.emplace_back(lib.fileName(),lastLibraryIdentifier);
if(f(MODUL_TYPE::Program)){
loadType(lib,programms,"Program",lastLibraryIdentifier);
}if(f(MODUL_TYPE::LoopProgram)){
......@@ -147,6 +153,13 @@ typedef Modules::Program* (*CreateProgramm)(unsigned int index);
qDebug()<< "Loading Consumer";
loadType(lib,consumer,"Consumer",lastLibraryIdentifier);
}
SupportAudioFunc supportAudioFunc = nullptr;
if(f(MODUL_TYPE::Audio)){
//qDebug()<< "Loading Audio";
supportAudioFunc = loadAudio(lib,&fftOutputView);
}
lastLibraryIdentifier++;
loadedLibraryMap.emplace_back(lib.fileName(),LibInfo{lastLibraryIdentifier,supportAudioFunc});
if(replaceNewInPBs){
for(const auto & pb : ProgramBlockManager::model){
for(;lastProgram<programms.size();lastProgram++){
......@@ -194,4 +207,23 @@ typedef Modules::Program* (*CreateProgramm)(unsigned int index);
}
ModuleManager::SupportAudioFunc ModuleManager::loadAudio(QLibrary & lib, Modules::FFTOutputView<float> * fftOutputView){
//typedef void (*SupportAudioFunc )(bool);
typedef void (*SetFFTOutputViewFunc )(Modules::FFTOutputView<float>*);
//using SupportAudioFunc = unsigned int (bool);
//using SetFFTOutputViewFunc = char const * (Modules::FFTOutputView<float>*);
auto supportAudioFunc = reinterpret_cast<SupportAudioFunc>(lib.resolve("_supportAudio"));
auto setFFTOutputViewFunc = reinterpret_cast<SetFFTOutputViewFunc>(lib.resolve("_setFFTOutputView"));
if (!supportAudioFunc || !setFFTOutputViewFunc) {
qDebug() << "Error loading audio functions : "<< supportAudioFunc << setFFTOutputViewFunc;
return nullptr;
}
setFFTOutputViewFunc(fftOutputView);
supportAudioFunc(Audio::AudioCaptureManager::get().isCapturing());
return supportAudioFunc;
}
}
......@@ -17,6 +17,7 @@
#include <memory>
#include "modelvector.h"
#include "controller.h"
#include "fftoutput.hpp"
namespace Modules {
......@@ -92,7 +93,7 @@ class Module : public QObject{
Q_PROPERTY(ValueType outputType READ getOutputType WRITE setOutputType NOTIFY outputTypeChanged)
Q_PROPERTY(QString code READ getCode WRITE setCode NOTIFY codeChanged)
Q_PROPERTY(PropertiesVector * properties READ getPropertiesP CONSTANT)
QString name = "No Name";
QString name = "No_Name";
QString description;
PropertiesVector properties;
QString code;
......@@ -233,7 +234,12 @@ signals:
typedef std::vector<detail::Entry<Program>> ProgrammModulContainer;
typedef std::vector<detail::Entry<Filter>> FilterModulContainer;
typedef std::vector<detail::Entry<Consumer>> ConsumerModulContainer;
std::vector<std::pair<QString,int>> loadedLibraryMap;
typedef void (*SupportAudioFunc)(bool);
struct LibInfo{
int libraryIdentifier = -1;
SupportAudioFunc supportAudioFunc = nullptr;
};
std::vector<std::pair<QString,LibInfo>> loadedLibraryMap;
int lastLibraryIdentifier = 0;
ModelVector<Module*> modules;
ProgrammModulContainer programms;
......@@ -241,9 +247,13 @@ signals:
FilterModulContainer filter;
ConsumerModulContainer consumer;
Controller controller_;
FFTOutputView<float> fftOutputView;
private:
template<typename Type, typename String>
static void loadType(QLibrary & lib, std::vector<detail::Entry<Type>> &c,String name, int libraryIdentifier);
static SupportAudioFunc loadAudio(QLibrary & lib,Modules::FFTOutputView<float> * fftOutputView);
public:
ModuleManager();
~ModuleManager(){for(auto m : modules)delete m;}
......
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