Commit 40cae6ec authored by Leander Schulten's avatar Leander Schulten
Browse files

Audio: Remove Support for the Capture_Windows_SoundOutput library. See...

Audio: Remove Support for the Capture_Windows_SoundOutput library. See leander.schulten/Capture_Windows_SoundOutput>
parent f069e055
Pipeline #190891 passed with stage
in 9 minutes and 45 seconds
......@@ -32,9 +32,6 @@ Die Lichtsteuerung hängt von ein paar anderen Projekten ab.
#### [Boost](https://www.boost.org/)
Boost wird benötigt, um bei Modules nicht lineare Codeausführung zu ermöglichen (Corotines) und wird genutzt, um Stacktraces auszugeben.
#### [Capture_Windows_SoundOutput](https://git.rwth-aachen.de/leander.schulten/Capture_Windows_SoundOutput)
Dieses Project ermöglicht das abfangen des Windows Audioausgangs. Für andere Plattformen ligen keine implementierungen vor, diese sind aber herzlich willkommen. Die kompilierte Version ist hier im git vorhanden.
#### [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.
......
......@@ -112,16 +112,6 @@ void AudioCaptureManager::dataCallback(float* data, unsigned int frames, bool*do
}
}
void AudioCaptureManager::startCapturingFromCaptureLibrary(AudioCaptureManager::CaptureLibEntry func) {
captureAudioThread = std::thread([this, func]() {
run = true;
emit this->capturingStatusChanged();
func(&AudioCaptureManager::staticInitCallback, &AudioCaptureManager::staticDataCallback);
run = false;
emit this->capturingStatusChanged();
});
}
bool AudioCaptureManager::startCapturingFromInput(unsigned input) {
if (input >= rtAudio.getDeviceCount()) {
return false;
......@@ -165,30 +155,7 @@ bool AudioCaptureManager::startCapturingFromInput(unsigned input) {
return true;
}
bool AudioCaptureManager::loadCaptureLibrary(const QString &name, const QString &filePathToCaptureLibrary) {
auto func = reinterpret_cast<CaptureLibEntry>(QLibrary::resolve(filePathToCaptureLibrary, "captureAudio"));
if (func) {
// replace if name is already there
auto res = captureLibraries.emplace(name, func);
if (res.second) {
auto pos = std::distance(captureLibraries.begin(), res.first);
captureDeviceNames.insert(static_cast<int>(pos), name);
if (currentCaptureDevice >= pos) {
currentCaptureDevice++;
emit currentCaptureDeviceChanged();
}
}
}
return func;
}
bool AudioCaptureManager::startCapturingFromDevice(const QString &name) {
for (const auto &c : captureLibraries) {
if (c.first == name) {
startCapturingFromCaptureLibrary(c.second);
return true;
}
}
for (unsigned i = 0; i < rtAudio.getDeviceCount(); ++i) {
if (auto di = rtAudio.getDeviceInfo(i); di.name.c_str() == name) {
return startCapturingFromInput(i);
......@@ -197,18 +164,7 @@ bool AudioCaptureManager::startCapturingFromDevice(const QString &name) {
return false;
}
bool AudioCaptureManager::startCapturingFromCaptureLibrary() {
if (captureLibraries.empty()) {
return false;
}
stopCapturingAndWait();
startCapturingFromCaptureLibrary(captureLibraries.begin()->second);
currentCaptureDevice = 0;
emit currentCaptureDeviceChanged();
return true;
}
bool AudioCaptureManager::startCapturingFromDefaultInput() {
bool AudioCaptureManager::startCapturingFromDefaultInput() {
stopCapturingAndWait();
#ifdef Q_OS_WIN
// check if default output is availible
......@@ -258,19 +214,14 @@ void AudioCaptureManager::stopCapturing() {
void AudioCaptureManager::stopCapturingAndWait() {
try {
if (captureAudioThread.joinable()) {
run = false;
captureAudioThread.join();
} else {
if (rtAudio.isStreamOpen()) {
rtAudio.closeStream();
std::this_thread::yield();
while (rtAudio.isStreamRunning()) {
std::this_thread::sleep_for(std::chrono::microseconds(500));
}
if (rtAudio.isStreamOpen()) {
rtAudio.closeStream();
std::this_thread::yield();
while (rtAudio.isStreamRunning()) {
std::this_thread::sleep_for(std::chrono::microseconds(500));
}
run = false;
}
run = false;
} catch (const RtAudioError &e) {
ErrorNotifier::showError("Error while stopping audio stream: " + QString(e.what()));
}
......@@ -287,10 +238,6 @@ void AudioCaptureManager::updateCaptureDeviceList() {
name = captureDeviceNames[currentCaptureDevice];
}
captureDeviceNames.clear();
for (const auto &i : captureLibraries) {
captureDeviceNames.push_back(i.first);
}
for (unsigned i = 0; i < rtAudio.getDeviceCount(); ++i) {
if (auto di = rtAudio.getDeviceInfo(i); di.inputChannels > 0 AUDIO_IF_WIN(|| di.outputChannels > 0)) {
captureDeviceNames.emplace_back(QString::fromStdString(di.name.c_str()));
......
......@@ -35,18 +35,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::thread captureAudioThread;
std::array<float, 2048> fftoutput;
std::atomic_bool run;
int currentCaptureDevice = -1;
RtAudio rtAudio;
AudioFFT audiofft;
ModelVector<QString> captureDeviceNames;
using CaptureLibEntry = int (*)(void(int, int), void(float *, unsigned int, bool *));
/**
* @brief captureLibraries all libraries loaded with loadCaptureLibrary. The string contains the name and the CaptureLibEntry the entry funciton
*/
std::map<QString, CaptureLibEntry> captureLibraries;
int channels = -1;
int samplesPerSecond = -1;
......@@ -62,25 +56,11 @@ class AudioCaptureManager : public QObject
private:
AudioCaptureManager();
~AudioCaptureManager(){
if(captureAudioThread.joinable()){
run.store(false);
captureAudioThread.join();
}
}
private:
static int rtAudioCallback(void *outputBuffer, void *inputBuffer, unsigned int nFrames, double streamTime, RtAudioStreamStatus status, void *userData);
static void staticInitCallback(int channels, int samplesPerSecond) { get().initCallback(channels, samplesPerSecond); }
static void staticDataCallback(float* data, unsigned int frames, bool*done){get().dataCallback(data,frames,done);}
void initCallback(int channels, int samplesPerSecond);
void dataCallback(float *data, unsigned int frames, bool *done);
/**
* @brief startCapturingFromCaptureLibrary starts the audio capturing with the given function
* @param func The entry function of the audio capture lib
*/
void startCapturingFromCaptureLibrary(CaptureLibEntry func);
/**
* @brief startCapturingFromInput starts the captuing from an input device
* @param inputIndex The index of the input device from rtAudio.getDeviceInfo(...)
......@@ -97,25 +77,12 @@ private:
int getIndexForDeviceName(const String &name);
public:
/**
* @brief loadCaptureLibrary loads the library located at the given path with a given name, with this name you can start capturing. The list can be updated with updateCaptureDeviceList()
* @param name the name that the capture device should have, if there is already a device with the name, replace this
* @param filePathToCaptureLibrary The path to the capture lib
* @return true, if the loading was successfull, false otherwise
*/
bool loadCaptureLibrary(const QString &name, const QString &filePathToCaptureLibrary);
/**
* @brief startCapturingFromDevice starts the capturing with a capture device with the given name. For the names, see getCaptureDeviceNames()
* @param name the name of the capture device
* @return true, if the capturing stats successfully, false otherwise
*/
Q_INVOKABLE bool startCapturingFromDevice(const QString &name);
/**
* @brief startCapturingFromCaptureLibrary starts the capturing from one capture library that was loaded with loadCaptureLibrary(...), which one is undefined
* @return true, if the capturing stats successfully, false otherwise
*/
bool startCapturingFromCaptureLibrary();
/**
* @brief startCapturingFromDefaultInput starts the capturing from the default input device. On windows from the default output.
* @return true, if the capturing stats successfully, false otherwise
......
#ifndef CAPTURE_WINDOWS_SOUNDOUTPUT_GLOBAL_H
#define CAPTURE_WINDOWS_SOUNDOUTPUT_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(CAPTURE_WINDOWS_SOUNDOUTPUT_LIBRARY)
# define CAPTURE_WINDOWS_SOUNDOUTPUTSHARED_EXPORT Q_DECL_EXPORT
#else
# define CAPTURE_WINDOWS_SOUNDOUTPUTSHARED_EXPORT Q_DECL_IMPORT
#endif
extern "C" CAPTURE_WINDOWS_SOUNDOUTPUTSHARED_EXPORT int captureAudio(void(*init)(int channels),void(*callback)(float * data, unsigned int numFramesAvailable, bool * done));
#endif // CAPTURE_WINDOWS_SOUNDOUTPUT_GLOBAL_H
......@@ -259,15 +259,6 @@ int main(int argc, char *argv[]) {
Settings::connect(&settings,&Settings::driverFilePathChanged,[&](){
Driver::loadAndStartDriver(settings.getDriverFilePath());
});
Settings::connect(&settings, &Settings::audioCaptureFilePathChanged, [&]() {
if (Audio::AudioCaptureManager::get().loadCaptureLibrary("Windows Output", settings.getAudioCaptureFilePath())) {
if (!Audio::AudioCaptureManager::get().startCapturingFromDevice("Windows Output")) {
ErrorNotifier::get()->newError(QStringLiteral("Failed to start capturing with Audio Capture Library"));
}
} else {
ErrorNotifier::get()->newError(QStringLiteral("Failed to load Audio Capture Library"));
}
});
Settings::connect(&settings,&Settings::updatePauseInMsChanged,[&](){
if(Driver::getCurrentDriver()){
Driver::getCurrentDriver()->setWaitTime(std::chrono::milliseconds(settings.getUpdatePauseInMs()));
......@@ -335,11 +326,8 @@ int main(int argc, char *argv[]) {
#endif
auto &audioManager = Audio::AudioCaptureManager::get();
audioManager.loadCaptureLibrary("Windows Output", settings.getAudioCaptureFilePath());
if (!audioManager.startCapturingFromCaptureLibrary()) {
if (!audioManager.startCapturingFromDefaultInput()) {
ErrorNotifier::showError("Audio capturing not possible");
}
if (!audioManager.startCapturingFromDefaultInput()) {
ErrorNotifier::showError("Audio capturing not possible");
}
Modules::ModuleManager::singletone()->controller().start();
......
......@@ -101,17 +101,6 @@ Pane{
onAccepted: Settings.compilerLibraryFlags = text;
}
Label{
Layout.fillWidth: true
text: "AudioCaptureLib:"
}
TextFieldFileChooser{
Layout.fillWidth: true
folder: false
path: Settings.audioCaptureFilePath
onPathChanged: {Settings.audioCaptureFilePath = path;path = Settings.audioCaptureFilePath;}
fileChooser: fileDialog
}
Label{
Layout.fillWidth: true
text: "Audio Capture Device:"
......
......@@ -20,7 +20,6 @@ class Settings : public QObject
Q_PROPERTY(QString compilerFlags READ getCompilerFlags WRITE setCompilerFlags NOTIFY compilerFlagsChanged)
Q_PROPERTY(QString compilerLibraryFlags READ getCompilerLibraryFlags WRITE setCompilerLibraryFlags NOTIFY compilerLibraryFlagsChanged)
Q_PROPERTY(QString includePath READ getIncludePath WRITE setIncludePath NOTIFY includePathChanged)
Q_PROPERTY(QString audioCaptureFilePath READ getAudioCaptureFilePath WRITE setAudioCaptureFilePath NOTIFY audioCaptureFilePathChanged)
Q_PROPERTY(unsigned int updatePauseInMs READ getUpdatePauseInMs WRITE setUpdatePauseInMs NOTIFY updatePauseInMsChanged)
static inline QFileInfo localSettingsFile;
public:
......@@ -58,17 +57,6 @@ public:
}
QString getDriverFilePath()const{return value(QStringLiteral("driverFilePath")).toString();}
void setAudioCaptureFilePath(const QString& file){
if(file == getAudioCaptureFilePath()){
return;
}
if(QFile::exists(file)){
setValue(QStringLiteral("audioCaptureFilePath"),file);
emit audioCaptureFilePathChanged();
}
}
QString getAudioCaptureFilePath()const{return value(QStringLiteral("audioCaptureFilePath")).toString();}
void setUpdatePauseInMs(unsigned int pause){setValue(QStringLiteral("updatePauseInMs"),pause);emit updatePauseInMsChanged();}
unsigned int getUpdatePauseInMs()const{return value(QStringLiteral("updatePauseInMs")).toUInt();}
void setModuleDirPath( const QString &_moduleDirPath){
......@@ -136,7 +124,6 @@ signals:
void compilerFlagsChanged();
void compilerLibraryFlagsChanged();
void includePathChanged();
void audioCaptureFilePathChanged();
public slots:
};
......
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