mirror of
https://github.com/AlexandreRouma/SDRPlusPlus.git
synced 2024-11-14 14:32:52 +01:00
initial structure
This commit is contained in:
parent
800a8b22c7
commit
8851735cb8
136
core/src/signal_path/stream.cpp
Normal file
136
core/src/signal_path/stream.cpp
Normal file
@ -0,0 +1,136 @@
|
||||
#include "stream.h"
|
||||
#include <utils/flog.h>
|
||||
|
||||
void Sink::showMenu() {}
|
||||
|
||||
SinkEntry::SinkEntry(std::unique_ptr<Sink> sink) {
|
||||
this->sink = std::move(sink);
|
||||
}
|
||||
|
||||
float SinkEntry::getVolume() {
|
||||
return volume;
|
||||
}
|
||||
|
||||
void SinkEntry::setVolume(float volume) {
|
||||
this->volume = volume;
|
||||
volumeAdjust.setVolume(volume);
|
||||
}
|
||||
|
||||
bool SinkEntry::getMuted() {
|
||||
return muted;
|
||||
}
|
||||
|
||||
void SinkEntry::setMuted(bool muted) {
|
||||
this->muted = muted;
|
||||
volumeAdjust.setMuted(muted);
|
||||
}
|
||||
|
||||
float SinkEntry::getPanning() {
|
||||
return panning;
|
||||
}
|
||||
|
||||
void SinkEntry::setPanning(float panning) {
|
||||
this->panning = panning;
|
||||
// TODO: Update DSP
|
||||
}
|
||||
|
||||
AudioStream::AudioStream(StreamManager* manager, const std::string& name, dsp::stream<dsp::stereo_t>* stream, double samplerate) {
|
||||
this->manager = manager;
|
||||
this->name = name;
|
||||
this->samplerate = samplerate;
|
||||
|
||||
split.init(stream);
|
||||
}
|
||||
|
||||
void AudioStream::setInput(dsp::stream<dsp::stereo_t>* stream) {
|
||||
std::lock_guard<std::recursive_mutex> lck(mtx);
|
||||
split.setInput(stream);
|
||||
}
|
||||
|
||||
const std::string& AudioStream::getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
void AudioStream::bindStream(dsp::stream<dsp::stereo_t>* stream) {
|
||||
std::lock_guard<std::recursive_mutex> lck(mtx);
|
||||
split.bindStream(stream);
|
||||
}
|
||||
|
||||
void AudioStream::unbindStream(dsp::stream<dsp::stereo_t>* stream) {
|
||||
std::lock_guard<std::recursive_mutex> lck(mtx);
|
||||
split.unbindStream(stream);
|
||||
}
|
||||
|
||||
int AudioStream::addSink(const std::string& type) {
|
||||
std::lock_guard<std::recursive_mutex> lck(mtx);
|
||||
std::lock_guard<std::recursive_mutex> lck2(manager->mtx);
|
||||
|
||||
// Check that the sink provider is available
|
||||
if (manager->providers.find(type) == manager->providers.end()) {
|
||||
flog::error("Could not add sink of type '{}'. No provider is available for such a type.", type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Create sink instance
|
||||
int id = sinks.size();
|
||||
auto sink = manager->providers[type]->createSink(this);
|
||||
|
||||
// Check that the sink was created succesfully
|
||||
if (!sink) {
|
||||
flog::error("Could not create sink of type '{}'. Provider returned null.", type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Create and save entry
|
||||
sinks.push_back(SinkEntry(std::move(sink)));
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
void AudioStream::removeSink(int index) {
|
||||
std::lock_guard<std::recursive_mutex> lck(mtx);
|
||||
|
||||
// Check that the index exists
|
||||
if (index >= sinks.size()) {
|
||||
flog::error("Can't remove sink of index {} from stream '{}'. Index out of range.", index, name);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Free stuff
|
||||
|
||||
}
|
||||
|
||||
const std::vector<SinkEntry>& AudioStream::getSinks() {
|
||||
return sinks;
|
||||
}
|
||||
|
||||
std::shared_ptr<AudioStream> StreamManager::registerStream(const std::string& name, dsp::stream<dsp::stereo_t>* stream, double samplerate) {
|
||||
std::lock_guard<std::recursive_mutex> lck(mtx);
|
||||
|
||||
// Check that an audio stream that name doesn't already exist
|
||||
if (streams.find(name) != streams.end()) {
|
||||
flog::error("Could not register audio stream with name '{}', a stream with this name already exists.", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Create stream and add to list
|
||||
streams[name] = std::make_shared<AudioStream>(this, stream, samplerate);
|
||||
}
|
||||
|
||||
void StreamManager::unregisterStream(const std::string& name) {
|
||||
std::lock_guard<std::recursive_mutex> lck(mtx);
|
||||
|
||||
// Check that stream exists
|
||||
auto it = streams.find(name);
|
||||
if (it == streams.end()) {
|
||||
flog::error("Could not unregister audio stream with name '{}', no stream exists with that name.", name);
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove from list
|
||||
streams.erase(it);
|
||||
}
|
||||
|
||||
const std::map<std::string, std::shared_ptr<AudioStream>>& StreamManager::getStreams() {
|
||||
return streams;
|
||||
}
|
101
core/src/signal_path/stream.h
Normal file
101
core/src/signal_path/stream.h
Normal file
@ -0,0 +1,101 @@
|
||||
#pragma once
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <dsp/stream.h>
|
||||
#include <dsp/types.h>
|
||||
#include <dsp/routing/splitter.h>
|
||||
#include <dsp/multirate/rational_resampler.h>
|
||||
#include <dsp/audio/volume.h>
|
||||
|
||||
class AudioStream;
|
||||
|
||||
class Sink {
|
||||
public:
|
||||
virtual void start() = 0;
|
||||
virtual void stop() = 0;
|
||||
virtual void showMenu();
|
||||
|
||||
private:
|
||||
dsp::stream<dsp::stereo_t>* stream;
|
||||
AudioStream* audioStream = NULL;
|
||||
};
|
||||
|
||||
class SinkEntry {
|
||||
public:
|
||||
SinkEntry(std::unique_ptr<Sink> sink);
|
||||
|
||||
float getVolume();
|
||||
void setVolume(float volume);
|
||||
|
||||
bool getMuted();
|
||||
void setMuted(bool muted);
|
||||
|
||||
float getPanning();
|
||||
void setPanning(float panning);
|
||||
private:
|
||||
dsp::audio::Volume volumeAdjust;
|
||||
dsp::multirate::RationalResampler<dsp::stereo_t> resamp;
|
||||
|
||||
std::unique_ptr<Sink> sink;
|
||||
float volume = 1.0f;
|
||||
bool muted = false;
|
||||
float panning = 0.0f;
|
||||
};
|
||||
|
||||
class StreamManager;
|
||||
|
||||
class AudioStream {
|
||||
friend Sink;
|
||||
friend StreamManager;
|
||||
public:
|
||||
AudioStream(StreamManager* manager, const std::string& name, dsp::stream<dsp::stereo_t>* stream, double samplerate);
|
||||
|
||||
void setInput(dsp::stream<dsp::stereo_t>* stream);
|
||||
|
||||
const std::string& getName();
|
||||
|
||||
void bindStream(dsp::stream<dsp::stereo_t>* stream);
|
||||
void unbindStream(dsp::stream<dsp::stereo_t>* stream);
|
||||
|
||||
double getSamplerate();
|
||||
void setSamplerate(double samplerate);
|
||||
|
||||
int addSink(const std::string& type);
|
||||
void setSinkType(int index, const std::string& type);
|
||||
void removeSink(int index);
|
||||
const std::vector<SinkEntry>& getSinks();
|
||||
|
||||
private:
|
||||
void setSinkInputSamplerate(Sink* sink, double samplerate);
|
||||
|
||||
std::recursive_mutex mtx;
|
||||
StreamManager* manager;
|
||||
std::string name;
|
||||
double samplerate;
|
||||
dsp::routing::Splitter<dsp::stereo_t> split;
|
||||
std::vector<SinkEntry> sinks;
|
||||
};
|
||||
|
||||
class SinkProvider {
|
||||
public:
|
||||
std::unique_ptr<Sink> createSink(const std::string& name, int index);
|
||||
void destroySink(std::unique_ptr<Sink> sink);
|
||||
};
|
||||
|
||||
class StreamManager {
|
||||
friend AudioStream;
|
||||
public:
|
||||
std::shared_ptr<AudioStream> registerStream(const std::string& name, dsp::stream<dsp::stereo_t>* stream, double samplerate);
|
||||
void unregisterStream(const std::string& name);
|
||||
|
||||
void registerSinkProvider(const std::string& name, SinkProvider* provider);
|
||||
void unregisterSinkProvider(const std::string& name);
|
||||
|
||||
const std::map<std::string, std::shared_ptr<AudioStream>>& getStreams();
|
||||
|
||||
private:
|
||||
std::recursive_mutex mtx;
|
||||
std::map<std::string, std::shared_ptr<AudioStream>> streams;
|
||||
std::map<std::string, SinkProvider*> providers;
|
||||
};
|
Loading…
Reference in New Issue
Block a user