mirror of
https://github.com/AlexandreRouma/SDRPlusPlus.git
synced 2024-12-26 02:48:31 +01:00
limit stream configuration to creator
This commit is contained in:
parent
75800e0ca2
commit
139f63ad25
@ -11,7 +11,7 @@ Sink::Sink(SinkEntry* entry, dsp::stream<dsp::stereo_t>* stream, const std::str
|
|||||||
|
|
||||||
void Sink::showMenu() {}
|
void Sink::showMenu() {}
|
||||||
|
|
||||||
SinkEntry::SinkEntry(StreamManager* manager, AudioStream* parentStream, const std::string& type, SinkID id, double inputSamplerate) :
|
SinkEntry::SinkEntry(StreamManager* manager, Stream* parentStream, const std::string& type, SinkID id, double inputSamplerate) :
|
||||||
manager(manager),
|
manager(manager),
|
||||||
parentStream(parentStream),
|
parentStream(parentStream),
|
||||||
id(id)
|
id(id)
|
||||||
@ -156,7 +156,7 @@ std::string SinkEntry::getStringID() const {
|
|||||||
return stringId;
|
return stringId;
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioStream::AudioStream(StreamManager* manager, const std::string& name, dsp::stream<dsp::stereo_t>* stream, double samplerate) :
|
Stream::Stream(StreamManager* manager, const std::string& name, dsp::stream<dsp::stereo_t>* stream, double samplerate) :
|
||||||
manager(manager),
|
manager(manager),
|
||||||
name(name)
|
name(name)
|
||||||
{
|
{
|
||||||
@ -166,7 +166,7 @@ AudioStream::AudioStream(StreamManager* manager, const std::string& name, dsp::s
|
|||||||
split.init(stream);
|
split.init(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioStream::~AudioStream() {
|
Stream::~Stream() {
|
||||||
// Copy sink IDs
|
// Copy sink IDs
|
||||||
std::vector<SinkID> ids;
|
std::vector<SinkID> ids;
|
||||||
for (auto& [id, sink] : sinks) {
|
for (auto& [id, sink] : sinks) {
|
||||||
@ -179,75 +179,11 @@ AudioStream::~AudioStream() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioStream::setInput(dsp::stream<dsp::stereo_t>* stream, double samplerate) {
|
const std::string& Stream::getName() const {
|
||||||
std::unique_lock<std::shared_mutex> lck(sinksMtx);
|
|
||||||
|
|
||||||
// If all that's needed is to set the input, do it and return
|
|
||||||
if (samplerate == 0.0) {
|
|
||||||
split.setInput(stream);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update samplerate
|
|
||||||
this->samplerate = samplerate;
|
|
||||||
|
|
||||||
// Stop DSP
|
|
||||||
if (running) {
|
|
||||||
split.stop();
|
|
||||||
for (auto& [id, sink] : sinks) {
|
|
||||||
sink->stopDSP();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Set input and samplerate
|
|
||||||
split.setInput(stream);
|
|
||||||
for (auto& [id, sink] : sinks) {
|
|
||||||
sink->setInputSamplerate(samplerate);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start DSP
|
|
||||||
if (running) {
|
|
||||||
for (auto& [id, sink] : sinks) {
|
|
||||||
sink->startDSP();
|
|
||||||
}
|
|
||||||
split.start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioStream::setSamplerate(double samplerate) {
|
|
||||||
std::unique_lock<std::shared_mutex> lck(sinksMtx);
|
|
||||||
|
|
||||||
// Update samplerate
|
|
||||||
this->samplerate = samplerate;
|
|
||||||
|
|
||||||
// Stop DSP
|
|
||||||
if (running) {
|
|
||||||
split.stop();
|
|
||||||
for (auto& [id, sink] : sinks) {
|
|
||||||
sink->stopDSP();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set samplerate
|
|
||||||
for (auto& [id, sink] : sinks) {
|
|
||||||
sink->setInputSamplerate(samplerate);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start DSP
|
|
||||||
if (running) {
|
|
||||||
for (auto& [id, sink] : sinks) {
|
|
||||||
sink->startDSP();
|
|
||||||
}
|
|
||||||
split.start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& AudioStream::getName() const {
|
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
SinkID AudioStream::addSink(const std::string& type, SinkID id) {
|
SinkID Stream::addSink(const std::string& type, SinkID id) {
|
||||||
std::unique_lock<std::shared_mutex> lck(sinksMtx);
|
std::unique_lock<std::shared_mutex> lck(sinksMtx);
|
||||||
|
|
||||||
// Find a free ID if not provided
|
// Find a free ID if not provided
|
||||||
@ -289,7 +225,7 @@ SinkID AudioStream::addSink(const std::string& type, SinkID id) {
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioStream::removeSink(SinkID id, bool forgetSettings) {
|
void Stream::removeSink(SinkID id, bool forgetSettings) {
|
||||||
// Acquire shared lock
|
// Acquire shared lock
|
||||||
std::shared_ptr<SinkEntry> sink;
|
std::shared_ptr<SinkEntry> sink;
|
||||||
{
|
{
|
||||||
@ -333,15 +269,85 @@ void AudioStream::removeSink(SinkID id, bool forgetSettings) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_lock<std::shared_mutex> AudioStream::getSinksLock() {
|
std::shared_lock<std::shared_mutex> Stream::getSinksLock() {
|
||||||
return std::shared_lock<std::shared_mutex>(sinksMtx);
|
return std::shared_lock<std::shared_mutex>(sinksMtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::map<SinkID, std::shared_ptr<SinkEntry>>& AudioStream::getSinks() const {
|
const std::map<SinkID, std::shared_ptr<SinkEntry>>& Stream::getSinks() const {
|
||||||
return sinks;
|
return sinks;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioStream::startDSP() {
|
MasterStream::MasterStream(StreamManager* manager, const std::string& name, dsp::stream<dsp::stereo_t>* stream, double samplerate) :
|
||||||
|
Stream(manager, name, stream, samplerate)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void MasterStream::setInput(dsp::stream<dsp::stereo_t>* stream, double samplerate) {
|
||||||
|
std::unique_lock<std::shared_mutex> lck(sinksMtx);
|
||||||
|
|
||||||
|
// If all that's needed is to set the input, do it and return
|
||||||
|
if (samplerate == 0.0) {
|
||||||
|
split.setInput(stream);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update samplerate
|
||||||
|
this->samplerate = samplerate;
|
||||||
|
|
||||||
|
// Stop DSP
|
||||||
|
if (running) {
|
||||||
|
split.stop();
|
||||||
|
for (auto& [id, sink] : sinks) {
|
||||||
|
sink->stopDSP();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Set input and samplerate
|
||||||
|
split.setInput(stream);
|
||||||
|
for (auto& [id, sink] : sinks) {
|
||||||
|
sink->setInputSamplerate(samplerate);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start DSP
|
||||||
|
if (running) {
|
||||||
|
for (auto& [id, sink] : sinks) {
|
||||||
|
sink->startDSP();
|
||||||
|
}
|
||||||
|
split.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MasterStream::setSamplerate(double samplerate) {
|
||||||
|
std::unique_lock<std::shared_mutex> lck(sinksMtx);
|
||||||
|
|
||||||
|
// Update samplerate
|
||||||
|
this->samplerate = samplerate;
|
||||||
|
|
||||||
|
// TODO: Maybe simply disallow while running?
|
||||||
|
|
||||||
|
// Stop DSP if it was running
|
||||||
|
if (running) {
|
||||||
|
split.stop();
|
||||||
|
for (auto& [id, sink] : sinks) {
|
||||||
|
sink->stopDSP();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set samplerate
|
||||||
|
for (auto& [id, sink] : sinks) {
|
||||||
|
sink->setInputSamplerate(samplerate);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start DSP if it was running
|
||||||
|
if (running) {
|
||||||
|
for (auto& [id, sink] : sinks) {
|
||||||
|
sink->startDSP();
|
||||||
|
}
|
||||||
|
split.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MasterStream::startDSP() {
|
||||||
// TODO: Maybe add a different mutex for the stream?
|
// TODO: Maybe add a different mutex for the stream?
|
||||||
std::unique_lock<std::shared_mutex> lck(sinksMtx);
|
std::unique_lock<std::shared_mutex> lck(sinksMtx);
|
||||||
|
|
||||||
@ -356,7 +362,7 @@ void AudioStream::startDSP() {
|
|||||||
running = true;
|
running = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioStream::stopDSP() {
|
void MasterStream::stopDSP() {
|
||||||
// TODO: Maybe add a different mutex for the stream?
|
// TODO: Maybe add a different mutex for the stream?
|
||||||
std::unique_lock<std::shared_mutex> lck(sinksMtx);
|
std::unique_lock<std::shared_mutex> lck(sinksMtx);
|
||||||
|
|
||||||
@ -371,7 +377,7 @@ void AudioStream::stopDSP() {
|
|||||||
running = false;
|
running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<AudioStream> StreamManager::createStream(const std::string& name, dsp::stream<dsp::stereo_t>* stream, double samplerate) {
|
std::shared_ptr<MasterStream> StreamManager::createStream(const std::string& name, dsp::stream<dsp::stereo_t>* stream, double samplerate) {
|
||||||
std::unique_lock<std::shared_mutex> lck(streamsMtx);
|
std::unique_lock<std::shared_mutex> lck(streamsMtx);
|
||||||
|
|
||||||
// Check that no stream with that name already exists
|
// Check that no stream with that name already exists
|
||||||
@ -381,7 +387,7 @@ std::shared_ptr<AudioStream> StreamManager::createStream(const std::string& name
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create and save stream
|
// Create and save stream
|
||||||
auto newStream = std::make_shared<AudioStream>(this, name, stream, samplerate);
|
std::shared_ptr<MasterStream> newStream(new MasterStream(this, name, stream, samplerate));
|
||||||
streams[name] = newStream;
|
streams[name] = newStream;
|
||||||
|
|
||||||
// Release lock and emit event
|
// Release lock and emit event
|
||||||
@ -391,7 +397,7 @@ std::shared_ptr<AudioStream> StreamManager::createStream(const std::string& name
|
|||||||
return newStream;
|
return newStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StreamManager::destroyStream(std::shared_ptr<AudioStream>& stream) {
|
void StreamManager::destroyStream(std::shared_ptr<MasterStream>& stream) {
|
||||||
// Emit event
|
// Emit event
|
||||||
onStreamDestroy(stream);
|
onStreamDestroy(stream);
|
||||||
|
|
||||||
@ -400,7 +406,7 @@ void StreamManager::destroyStream(std::shared_ptr<AudioStream>& stream) {
|
|||||||
std::unique_lock<std::shared_mutex> lck(streamsMtx);
|
std::unique_lock<std::shared_mutex> lck(streamsMtx);
|
||||||
|
|
||||||
// Get iterator of the stream
|
// Get iterator of the stream
|
||||||
auto it = std::find_if(streams.begin(), streams.end(), [&stream](std::pair<const std::string, std::shared_ptr<AudioStream>> e) {
|
auto it = std::find_if(streams.begin(), streams.end(), [&stream](std::pair<const std::string, std::shared_ptr<Stream>> e) {
|
||||||
return e.second == stream;
|
return e.second == stream;
|
||||||
});
|
});
|
||||||
if (it == streams.end()) {
|
if (it == streams.end()) {
|
||||||
@ -421,7 +427,7 @@ std::shared_lock<std::shared_mutex> StreamManager::getStreamsLock() {
|
|||||||
return std::shared_lock<std::shared_mutex>(streamsMtx);
|
return std::shared_lock<std::shared_mutex>(streamsMtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::map<std::string, std::shared_ptr<AudioStream>>& StreamManager::getStreams() const {
|
const std::map<std::string, std::shared_ptr<Stream>>& StreamManager::getStreams() const {
|
||||||
return streams;
|
return streams;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,12 +11,13 @@
|
|||||||
#include <shared_mutex>
|
#include <shared_mutex>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
class AudioStream;
|
class SinkEntry;
|
||||||
|
class Stream;
|
||||||
|
class MasterStream;
|
||||||
|
class StreamManager;
|
||||||
|
|
||||||
using SinkID = int;
|
using SinkID = int;
|
||||||
|
|
||||||
class SinkEntry;
|
|
||||||
|
|
||||||
class Sink {
|
class Sink {
|
||||||
public:
|
public:
|
||||||
Sink(SinkEntry* entry, dsp::stream<dsp::stereo_t>* stream, const std::string& name, SinkID id, const std::string& stringId);
|
Sink(SinkEntry* entry, dsp::stream<dsp::stereo_t>* stream, const std::string& name, SinkID id, const std::string& stringId);
|
||||||
@ -58,14 +59,13 @@ public:
|
|||||||
SinkEntryCreateException(const char* what) : std::runtime_error(what) {}
|
SinkEntryCreateException(const char* what) : std::runtime_error(what) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class StreamManager;
|
|
||||||
|
|
||||||
// TODO: Would be cool to have data and audio sinks instead of just audio.
|
// TODO: Would be cool to have data and audio sinks instead of just audio.
|
||||||
class SinkEntry {
|
class SinkEntry {
|
||||||
friend AudioStream;
|
|
||||||
friend Sink;
|
friend Sink;
|
||||||
|
friend Stream;
|
||||||
|
friend MasterStream;
|
||||||
public:
|
public:
|
||||||
SinkEntry(StreamManager* manager, AudioStream* parentStream, const std::string& type, SinkID id, double inputSamplerate);
|
SinkEntry(StreamManager* manager, Stream* parentStream, const std::string& type, SinkID id, double inputSamplerate);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the type of the sink.
|
* Get the type of the sink.
|
||||||
@ -165,7 +165,7 @@ private:
|
|||||||
std::string type;
|
std::string type;
|
||||||
const SinkID id;
|
const SinkID id;
|
||||||
double inputSamplerate;
|
double inputSamplerate;
|
||||||
AudioStream* const parentStream;
|
Stream* const parentStream;
|
||||||
StreamManager* const manager;
|
StreamManager* const manager;
|
||||||
|
|
||||||
std::string stringId;
|
std::string stringId;
|
||||||
@ -175,28 +175,11 @@ private:
|
|||||||
float panning = 0.0f;
|
float panning = 0.0f;
|
||||||
};
|
};
|
||||||
|
|
||||||
class StreamManager;
|
class Stream {
|
||||||
|
protected:
|
||||||
class AudioStream {
|
Stream(StreamManager* manager, const std::string& name, dsp::stream<dsp::stereo_t>* stream, double samplerate);
|
||||||
friend StreamManager;
|
|
||||||
public:
|
public:
|
||||||
AudioStream(StreamManager* manager, const std::string& name, dsp::stream<dsp::stereo_t>* stream, double samplerate);
|
~Stream();
|
||||||
~AudioStream();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set DSP stream input.
|
|
||||||
* @param stream DSP stream.
|
|
||||||
* @param samplerate New samplerate (optional, 0.0 if not used).
|
|
||||||
*/
|
|
||||||
void setInput(dsp::stream<dsp::stereo_t>* stream, double samplerate = 0.0);
|
|
||||||
|
|
||||||
// TODO: There must be a way to pre-stop things to avoid having weird shit happen
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the samplerate of the input stream.
|
|
||||||
* @param samplerate Samplerate in Hz.
|
|
||||||
*/
|
|
||||||
void setSamplerate(double samplerate);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the name of the stream.
|
* Get the name of the stream.
|
||||||
@ -231,7 +214,40 @@ public:
|
|||||||
*/
|
*/
|
||||||
const std::map<SinkID, std::shared_ptr<SinkEntry>>& getSinks() const;
|
const std::map<SinkID, std::shared_ptr<SinkEntry>>& getSinks() const;
|
||||||
|
|
||||||
// TODO: This should only be callable by the module that created the stream
|
// Emitted when the samplerate of the stream was changed
|
||||||
|
NewEvent<double> onSamplerateChanged;
|
||||||
|
// Emitted when a sink was added
|
||||||
|
NewEvent<std::shared_ptr<SinkEntry>> onSinkAdded;
|
||||||
|
// Emitted when a sink is being removed
|
||||||
|
NewEvent<std::shared_ptr<SinkEntry>> onSinkRemove;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
StreamManager* const manager;
|
||||||
|
const std::string name;
|
||||||
|
double samplerate;
|
||||||
|
dsp::routing::Splitter<dsp::stereo_t> split;
|
||||||
|
bool running = false;
|
||||||
|
|
||||||
|
std::map<SinkID, std::shared_ptr<SinkEntry>> sinks;
|
||||||
|
std::shared_mutex sinksMtx;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MasterStream : public Stream {
|
||||||
|
friend StreamManager;
|
||||||
|
MasterStream(StreamManager* manager, const std::string& name, dsp::stream<dsp::stereo_t>* stream, double samplerate);
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Set DSP stream input.
|
||||||
|
* @param stream DSP stream.
|
||||||
|
* @param samplerate New samplerate (optional, 0.0 if not used).
|
||||||
|
*/
|
||||||
|
void setInput(dsp::stream<dsp::stereo_t>* stream, double samplerate = 0.0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the samplerate of the input stream.
|
||||||
|
* @param samplerate Samplerate in Hz.
|
||||||
|
*/
|
||||||
|
void setSamplerate(double samplerate);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start the DSP.
|
* Start the DSP.
|
||||||
@ -242,23 +258,6 @@ public:
|
|||||||
* Stop the DSP.
|
* Stop the DSP.
|
||||||
*/
|
*/
|
||||||
void stopDSP();
|
void stopDSP();
|
||||||
|
|
||||||
// Emitted when the samplerate of the stream was changed
|
|
||||||
NewEvent<double> onSamplerateChanged;
|
|
||||||
// Emitted when a sink was added
|
|
||||||
NewEvent<std::shared_ptr<SinkEntry>> onSinkAdded;
|
|
||||||
// Emitted when a sink is being removed
|
|
||||||
NewEvent<std::shared_ptr<SinkEntry>> onSinkRemove;
|
|
||||||
|
|
||||||
private:
|
|
||||||
StreamManager* const manager;
|
|
||||||
const std::string name;
|
|
||||||
double samplerate;
|
|
||||||
dsp::routing::Splitter<dsp::stereo_t> split;
|
|
||||||
bool running = false;
|
|
||||||
|
|
||||||
std::map<SinkID, std::shared_ptr<SinkEntry>> sinks;
|
|
||||||
std::shared_mutex sinksMtx;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class StreamManager {
|
class StreamManager {
|
||||||
@ -271,13 +270,13 @@ public:
|
|||||||
* @param samplerate Samplerate of the audio data.
|
* @param samplerate Samplerate of the audio data.
|
||||||
* @return Audio stream instance.
|
* @return Audio stream instance.
|
||||||
*/
|
*/
|
||||||
std::shared_ptr<AudioStream> createStream(const std::string& name, dsp::stream<dsp::stereo_t>* stream, double samplerate);
|
std::shared_ptr<MasterStream> createStream(const std::string& name, dsp::stream<dsp::stereo_t>* stream, double samplerate);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy an audio stream.
|
* Destroy an audio stream.
|
||||||
* @param stream Stream to destroy. The passed shared pointer will be automatically reset.
|
* @param stream Stream to destroy. The passed shared pointer will be automatically reset.
|
||||||
*/
|
*/
|
||||||
void destroyStream(std::shared_ptr<AudioStream>& stream);
|
void destroyStream(std::shared_ptr<MasterStream>& stream);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Aquire a lock for the stream list.
|
* Aquire a lock for the stream list.
|
||||||
@ -289,7 +288,7 @@ public:
|
|||||||
* Get a list of streams and their associated names.
|
* Get a list of streams and their associated names.
|
||||||
* @return Map of names to stream instance.
|
* @return Map of names to stream instance.
|
||||||
*/
|
*/
|
||||||
const std::map<std::string, std::shared_ptr<AudioStream>>& getStreams() const;
|
const std::map<std::string, std::shared_ptr<Stream>>& getStreams() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a sink provider.
|
* Register a sink provider.
|
||||||
@ -317,16 +316,16 @@ public:
|
|||||||
const std::vector<std::string>& getSinkTypes() const;
|
const std::vector<std::string>& getSinkTypes() const;
|
||||||
|
|
||||||
// Emitted when a stream was created
|
// Emitted when a stream was created
|
||||||
NewEvent<std::shared_ptr<AudioStream>> onStreamCreated;
|
NewEvent<std::shared_ptr<Stream>> onStreamCreated;
|
||||||
// Emitted when a stream is about to be destroyed
|
// Emitted when a stream is about to be destroyed
|
||||||
NewEvent<std::shared_ptr<AudioStream>> onStreamDestroy;
|
NewEvent<std::shared_ptr<Stream>> onStreamDestroy;
|
||||||
// Emitted when a sink provider was registered
|
// Emitted when a sink provider was registered
|
||||||
NewEvent<const std::string&> onSinkProviderRegistered;
|
NewEvent<const std::string&> onSinkProviderRegistered;
|
||||||
// Emitted when a sink provider is about to be unregistered
|
// Emitted when a sink provider is about to be unregistered
|
||||||
NewEvent<const std::string&> onSinkProviderUnregister;
|
NewEvent<const std::string&> onSinkProviderUnregister;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<std::string, std::shared_ptr<AudioStream>> streams;
|
std::map<std::string, std::shared_ptr<Stream>> streams;
|
||||||
std::shared_mutex streamsMtx;
|
std::shared_mutex streamsMtx;
|
||||||
|
|
||||||
std::map<std::string, SinkProvider*> providers;
|
std::map<std::string, SinkProvider*> providers;
|
||||||
|
@ -634,7 +634,7 @@ private:
|
|||||||
dsp::chain<dsp::stereo_t> afChain;
|
dsp::chain<dsp::stereo_t> afChain;
|
||||||
dsp::filter::Deemphasis<dsp::stereo_t> deemp;
|
dsp::filter::Deemphasis<dsp::stereo_t> deemp;
|
||||||
|
|
||||||
std::shared_ptr<AudioStream> stream;
|
std::shared_ptr<MasterStream> stream;
|
||||||
|
|
||||||
demod::Demodulator* selectedDemod = NULL;
|
demod::Demodulator* selectedDemod = NULL;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user