more work

This commit is contained in:
AlexandreRouma
2023-07-10 03:48:59 +02:00
parent 2e80882ab5
commit 25bc9f60ed
9 changed files with 259 additions and 114 deletions

View File

@ -16,6 +16,7 @@ namespace icons {
ImTextureID UNMUTED;
ImTextureID NORMAL_TUNING;
ImTextureID CENTER_TUNING;
ImTextureID ALIGN_CENTER;
GLuint loadTexture(std::string path) {
int w, h, n;
@ -45,6 +46,7 @@ namespace icons {
UNMUTED = (ImTextureID)(uintptr_t)loadTexture(resDir + "/icons/unmuted.png");
NORMAL_TUNING = (ImTextureID)(uintptr_t)loadTexture(resDir + "/icons/normal_tuning.png");
CENTER_TUNING = (ImTextureID)(uintptr_t)loadTexture(resDir + "/icons/center_tuning.png");
ALIGN_CENTER = (ImTextureID)(uintptr_t)loadTexture(resDir + "/icons/align_center.png");
return true;
}

View File

@ -13,7 +13,8 @@ namespace icons {
extern ImTextureID UNMUTED;
extern ImTextureID NORMAL_TUNING;
extern ImTextureID CENTER_TUNING;
extern ImTextureID ALIGN_CENTER;
GLuint loadTexture(std::string path);
bool load(std::string resDir);
}

View File

@ -3,20 +3,57 @@
#include <imgui.h>
#include <utils/flog.h>
#include <gui/style.h>
#include <gui/icons.h>
#include <utils/optionlist.h>
#define CONCAT(a, b) ((std::string(a) + b).c_str())
namespace streamsmenu {
std::vector<SinkID> sinksToBeRemoved;
std::recursive_mutex sinkTypesMtx;
OptionList<std::string, std::string> sinkTypes;
std::map<std::string, int> selectedSinkTypeId;
std::map<std::string, int> addSinkTypeId;
void updateSinkTypeList(const std::string& removed = "") {
std::lock_guard<std::recursive_mutex> lck1(sinkTypesMtx);
auto lck2 = sigpath::streamManager.getSinkTypesLock();
const auto& types = sigpath::streamManager.getSinkTypes();
sinkTypes.clear();
for (const auto& type : types) {
if (type == removed) { continue; }
sinkTypes.define(type, type, type);
}
}
void onSinkProviderRegistered(const std::string& type) {
// Update the list
updateSinkTypeList();
// Update the selected ID of each drop down
// TODO
}
void onSinkProviderUnregister(const std::string& type) {
// Update the list
updateSinkTypeList(type);
// Update the selected ID of each drop down
// TODO
}
void init() {
sigpath::streamManager.onSinkProviderRegistered.bind(onSinkProviderRegistered);
sigpath::streamManager.onSinkProviderUnregister.bind(onSinkProviderUnregister);
updateSinkTypeList();
}
void draw(void* ctx) {
float menuWidth = ImGui::GetContentRegionAvail().x;
auto lck = sigpath::streamManager.getStreamsLock();
auto streams = sigpath::streamManager.getStreams();
const auto& streams = sigpath::streamManager.getStreams();
int count = 0;
int maxCount = streams.size();
@ -26,35 +63,88 @@ namespace streamsmenu {
ImGui::Text("%s", name.c_str());
// Display ever sink
if (ImGui::BeginTable(CONCAT("sdrpp_streams_tbl_", name), 1, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) {
if (ImGui::BeginTable(CONCAT("sdrpp_streams_tbl_", name), 1, ImGuiTableFlags_Borders)) {
auto lck2 = stream->getSinksLock();
auto sinks = stream->getSinks();
for (auto& [id, sink] : sinks) {
std::string sid = sink->getStringID();
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
float tableWidth = ImGui::GetContentRegionAvail().x;
ImGui::Spacing();
// Sink type
sink->showMenu();
float vol = sink->getVolume();
bool muted = sink->getMuted();
float pan = sink->getPanning();
bool linked = true;
// Volume slider + mute button
float height = ImGui::GetTextLineHeightWithSpacing() + 2;
ImGui::PushID(ImGui::GetID(("sdrpp_streams_center_btn_" + sid).c_str()));
if (ImGui::ImageButton(icons::ALIGN_CENTER, ImVec2(height, height), ImVec2(0, 0), ImVec2(1, 1), 0, ImVec4(0, 0, 0, 0), ImGui::GetStyleColorVec4(ImGuiCol_Text))) {
sink->setPanning(0.0f);
}
ImGui::PopID();
ImGui::SameLine();
ImGui::FillWidth();
if (ImGui::Button(CONCAT("Remove##sdrpp_streams_remove_type_", name))) {
if (ImGui::SliderFloat(CONCAT("##sdrpp_streams_pan_", sid), &pan, -1, 1, "")) {
sink->setPanning(pan);
}
if (muted) {
ImGui::PushID(ImGui::GetID(("sdrpp_unmute_btn_" + sid).c_str()));
if (ImGui::ImageButton(icons::MUTED, ImVec2(height, height), ImVec2(0, 0), ImVec2(1, 1), 0, ImVec4(0, 0, 0, 0), ImGui::GetStyleColorVec4(ImGuiCol_Text))) {
sink->setMuted(false);
}
ImGui::PopID();
}
else {
ImGui::PushID(ImGui::GetID(("sdrpp_mute_btn_" + sid).c_str()));
if (ImGui::ImageButton(icons::UNMUTED, ImVec2(height, height), ImVec2(0, 0), ImVec2(1, 1), 0, ImVec4(0, 0, 0, 0), ImGui::GetStyleColorVec4(ImGuiCol_Text))) {
sink->setMuted(true);
}
ImGui::PopID();
}
ImGui::SameLine();
ImGui::FillWidth();
if (ImGui::SliderFloat(CONCAT("##sdrpp_streams_vol_", sid), &vol, 0, 1, "")) {
sink->setVolume(vol);
}
int startCur = ImGui::GetCursorPosX();
if (ImGui::Checkbox(CONCAT("Link volume##sdrpp_streams_vol_", sid), &linked)) {
// TODO
}
ImGui::SameLine();
if (ImGui::Button(CONCAT("Remove##sdrpp_streams_remove_type_", sid), ImVec2(tableWidth - (ImGui::GetCursorPosX() - startCur), 0))) {
sinksToBeRemoved.push_back(id);
}
ImGui::Spacing();
}
lck2.unlock();
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
float tableWidth = ImGui::GetContentRegionAvail().x;
ImGui::Spacing();
int ssds = 0;
ImGui::Combo(CONCAT("##sdrpp_streams_add_type_", name), &ssds, "Test 1\0Test 2\0");
int startCur = ImGui::GetCursorPosX();
{
std::lock_guard<std::recursive_mutex> lck(sinkTypesMtx);
ImGui::Combo(CONCAT("##sdrpp_streams_add_type_", name), &ssds, sinkTypes.txt);
}
ImGui::SameLine();
ImGui::FillWidth();
if (ImGui::Button(CONCAT("Add##sdrpp_streams_add_btn_", name))) {
if (ImGui::Button(CONCAT("Add##sdrpp_streams_add_btn_", name), ImVec2(tableWidth - (ImGui::GetCursorPosX() - startCur), 0))) {
stream->addSink("Audio");
}
ImGui::Spacing();
ImGui::EndTable();

View File

@ -1,11 +1,12 @@
#include "stream.h"
#include <utils/flog.h>
Sink::Sink(SinkEntry* entry, dsp::stream<dsp::stereo_t>* stream, const std::string& name, SinkID id) :
Sink::Sink(SinkEntry* entry, dsp::stream<dsp::stereo_t>* stream, const std::string& name, SinkID id, const std::string& stringId) :
entry(entry),
stream(stream),
streamName(name),
id(id)
id(id),
stringId(stringId)
{}
void Sink::showMenu() {}
@ -17,6 +18,12 @@ SinkEntry::SinkEntry(StreamManager* manager, AudioStream* parentStream, const st
{
this->type = type;
this->inputSamplerate = inputSamplerate;
// Generate string ID
stringId = parentStream->getName();
char buf[16];
sprintf(buf, "%d", (int)id);
stringId += buf;
// Initialize DSP
resamp.init(&input, inputSamplerate, inputSamplerate);
@ -44,7 +51,7 @@ void SinkEntry::setType(const std::string& type) {
auto lck2 = manager->getSinkTypesLock();
// Get the provider or throw error
auto types = manager->getSinkTypes();
const auto& types = manager->getSinkTypes();
if (std::find(types.begin(), types.end(), type) == types.end()) {
this->type.clear();
throw SinkEntryCreateException("Invalid sink type");
@ -53,7 +60,7 @@ void SinkEntry::setType(const std::string& type) {
// Create sink
this->type = type;
provider = manager->providers[type];
sink = provider->createSink(this, &volumeAdjust.out, parentStream->getName(), id);
sink = provider->createSink(this, &volumeAdjust.out, parentStream->getName(), id, stringId);
}
SinkID SinkEntry::getID() const {
@ -111,6 +118,15 @@ void SinkEntry::stopSink() {
sink->stop();
}
std::lock_guard<std::recursive_mutex> SinkEntry::getLock() {
return std::lock_guard<std::recursive_mutex>(mtx);
}
void SinkEntry::setSamplerate(double samplerate) {
std::lock_guard<std::recursive_mutex> lck(mtx);
resamp.setOutSamplerate(samplerate);
}
void SinkEntry::startDSP() {
std::lock_guard<std::recursive_mutex> lck(mtx);
resamp.start();
@ -136,6 +152,10 @@ void SinkEntry::setInputSamplerate(double samplerate) {
resamp.setInSamplerate(samplerate);
}
std::string SinkEntry::getStringID() {
return stringId;
}
AudioStream::AudioStream(StreamManager* manager, const std::string& name, dsp::stream<dsp::stereo_t>* stream, double samplerate) :
manager(manager),
name(name)
@ -449,7 +469,7 @@ void StreamManager::unregisterSinkProvider(SinkProvider* provider) {
for (auto& [name, stream] : streams) {
// Aquire lock on sink list
auto sLock = stream->getSinksLock();
auto sinks = stream->getSinks();
const auto& sinks = stream->getSinks();
// Find all sinks with the type that is about to be removed
std::vector<SinkID> toRemove;

View File

@ -19,7 +19,7 @@ class SinkEntry;
class Sink {
public:
Sink(SinkEntry* entry, dsp::stream<dsp::stereo_t>* stream, const std::string& name, SinkID id);
Sink(SinkEntry* entry, dsp::stream<dsp::stereo_t>* stream, const std::string& name, SinkID id, const std::string& stringId);
virtual ~Sink() {}
virtual void start() = 0;
@ -31,6 +31,7 @@ protected:
dsp::stream<dsp::stereo_t>* const stream;
const std::string streamName;
const SinkID id;
const std::string stringId;
};
class SinkProvider {
@ -41,7 +42,7 @@ public:
* @param name Name of the audio stream.
* @param index Index of the sink in the menu. Should be use to keep settings.
*/
virtual std::unique_ptr<Sink> createSink(SinkEntry* entry, dsp::stream<dsp::stereo_t>* stream, const std::string& name, SinkID index) = 0;
virtual std::unique_ptr<Sink> createSink(SinkEntry* entry, dsp::stream<dsp::stereo_t>* stream, const std::string& name, SinkID id, const std::string& stringId) = 0;
/**
* Destroy a sink instance. This function is so that the provide knows at all times how many instances there are.
@ -62,6 +63,7 @@ class StreamManager;
// TODO: Would be cool to have data and audio sinks instead of just audio.
class SinkEntry {
friend AudioStream;
friend Sink;
public:
SinkEntry(StreamManager* manager, AudioStream* parentStream, const std::string& type, SinkID id, double inputSamplerate);
@ -124,6 +126,12 @@ public:
*/
void showMenu();
/**
* Get the string form ID unique to both the sink and stream. Be used to reference settings.
* @return Unique string ID.
*/
std::string getStringID();
// Emitted when the type of the sink was changed
NewEvent<const std::string&> onTypeChanged;
// Emmited when volume of the sink was changed
@ -133,11 +141,17 @@ public:
// Emitted when the panning of the sink was changed
NewEvent<float> onPanningChanged;
// TODO: Need to allow the sink to change the entry samplerate and start/stop the DSP
// This will also require allowing it to get a lock on the sink so others don't attempt to mess with it.
std::lock_guard<std::recursive_mutex> getLock();
void startDSP();
void stopDSP();
void setSamplerate(double samplerate);
private:
void startSink();
void stopSink();
void startDSP();
void stopDSP();
void destroy(bool forgetSettings);
void setInputSamplerate(double samplerate);
@ -153,6 +167,8 @@ private:
double inputSamplerate;
AudioStream* const parentStream;
StreamManager* const manager;
std::string stringId;
float volume = 1.0f;
bool muted = false;