mirror of
https://github.com/AlexandreRouma/SDRPlusPlus.git
synced 2024-12-26 19:08:30 +01:00
Finished RtAudio sink
This commit is contained in:
parent
49cf3af769
commit
72bd3e9cc1
@ -7,6 +7,8 @@
|
|||||||
#include <dsp/processing.h>
|
#include <dsp/processing.h>
|
||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
#include <RtAudio.h>
|
#include <RtAudio.h>
|
||||||
|
#include <config.h>
|
||||||
|
#include <options.h>
|
||||||
|
|
||||||
#define CONCAT(a, b) ((std::string(a) + b).c_str())
|
#define CONCAT(a, b) ((std::string(a) + b).c_str())
|
||||||
|
|
||||||
@ -18,6 +20,8 @@ SDRPP_MOD_INFO {
|
|||||||
/* Max instances */ 1
|
/* Max instances */ 1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ConfigManager config;
|
||||||
|
|
||||||
class AudioSink : SinkManager::Sink {
|
class AudioSink : SinkManager::Sink {
|
||||||
public:
|
public:
|
||||||
AudioSink(SinkManager::Stream* stream, std::string streamName) {
|
AudioSink(SinkManager::Stream* stream, std::string streamName) {
|
||||||
@ -27,9 +31,16 @@ public:
|
|||||||
monoPacker.init(&s2m.out, 512);
|
monoPacker.init(&s2m.out, 512);
|
||||||
stereoPacker.init(_stream->sinkOut, 512);
|
stereoPacker.init(_stream->sinkOut, 512);
|
||||||
|
|
||||||
stream->setSampleRate(48000);
|
bool created = false;
|
||||||
|
std::string device = "";
|
||||||
RtAudio::StreamParameters parameters;
|
config.aquire();
|
||||||
|
if (!config.conf.contains(_streamName)) {
|
||||||
|
created = true;
|
||||||
|
config.conf[_streamName]["device"] = "";
|
||||||
|
config.conf[_streamName]["devices"] = json({});
|
||||||
|
}
|
||||||
|
device = config.conf[_streamName]["device"];
|
||||||
|
config.release(created);
|
||||||
|
|
||||||
int count = audio.getDeviceCount();
|
int count = audio.getDeviceCount();
|
||||||
RtAudio::DeviceInfo info;
|
RtAudio::DeviceInfo info;
|
||||||
@ -37,12 +48,14 @@ public:
|
|||||||
info = audio.getDeviceInfo(i);
|
info = audio.getDeviceInfo(i);
|
||||||
if (!info.probed) { continue; }
|
if (!info.probed) { continue; }
|
||||||
if (info.outputChannels == 0) { continue; }
|
if (info.outputChannels == 0) { continue; }
|
||||||
if (info.isDefaultOutput) { devId = devList.size(); }
|
if (info.isDefaultOutput) { defaultDevId = devList.size(); }
|
||||||
devList.push_back(info);
|
devList.push_back(info);
|
||||||
deviceIds.push_back(i);
|
deviceIds.push_back(i);
|
||||||
txtDevList += info.name;
|
txtDevList += info.name;
|
||||||
txtDevList += '\0';
|
txtDevList += '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
selectByName(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
~AudioSink() {
|
~AudioSink() {
|
||||||
@ -65,30 +78,83 @@ public:
|
|||||||
running = false;
|
running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void selectFirst() {
|
||||||
|
selectById(defaultDevId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void selectByName(std::string name) {
|
||||||
|
for (int i = 0; i < devList.size(); i++) {
|
||||||
|
if (devList[i].name == name) {
|
||||||
|
selectById(i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
selectFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
void selectById(int id) {
|
||||||
|
devId = id;
|
||||||
|
bool created = false;
|
||||||
|
config.aquire();
|
||||||
|
if (!config.conf[_streamName]["devices"].contains(devList[id].name)) {
|
||||||
|
created = true;
|
||||||
|
config.conf[_streamName]["devices"][devList[id].name] = devList[id].preferredSampleRate;
|
||||||
|
}
|
||||||
|
sampleRate = config.conf[_streamName]["devices"][devList[id].name];
|
||||||
|
config.release(created);
|
||||||
|
|
||||||
|
sampleRates = devList[id].sampleRates;
|
||||||
|
sampleRatesTxt = "";
|
||||||
|
char buf[256];
|
||||||
|
bool found = false;
|
||||||
|
unsigned int defaultId = 0;
|
||||||
|
unsigned int defaultSr = devList[id].preferredSampleRate;
|
||||||
|
for (int i = 0; i < sampleRates.size(); i++) {
|
||||||
|
if (sampleRates[i] == sampleRate) {
|
||||||
|
found = true;
|
||||||
|
srId = i;
|
||||||
|
}
|
||||||
|
if (sampleRates[i] == defaultSr) {
|
||||||
|
defaultId = i;
|
||||||
|
}
|
||||||
|
sprintf(buf, "%d", sampleRates[i]);
|
||||||
|
sampleRatesTxt += buf;
|
||||||
|
sampleRatesTxt += '\0';
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
sampleRate = defaultSr;
|
||||||
|
srId = defaultId;
|
||||||
|
}
|
||||||
|
|
||||||
|
_stream->setSampleRate(sampleRate);
|
||||||
|
|
||||||
|
if (running) { doStop(); }
|
||||||
|
if (running) { doStart(); }
|
||||||
|
}
|
||||||
|
|
||||||
void menuHandler() {
|
void menuHandler() {
|
||||||
float menuWidth = ImGui::GetContentRegionAvailWidth();
|
float menuWidth = ImGui::GetContentRegionAvailWidth();
|
||||||
|
|
||||||
ImGui::SetNextItemWidth(menuWidth);
|
ImGui::SetNextItemWidth(menuWidth);
|
||||||
if (ImGui::Combo(("##_rtaudio_sink_dev_"+_streamName).c_str(), &devId, txtDevList.c_str())) {
|
if (ImGui::Combo(("##_rtaudio_sink_dev_"+_streamName).c_str(), &devId, txtDevList.c_str())) {
|
||||||
// TODO: Load SR from config
|
selectById(devId);
|
||||||
|
config.aquire();
|
||||||
|
config.conf[_streamName]["device"] = devList[devId].name;
|
||||||
|
config.release(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SetNextItemWidth(menuWidth);
|
||||||
|
if (ImGui::Combo(("##_rtaudio_sink_sr_"+_streamName).c_str(), &srId, sampleRatesTxt.c_str())) {
|
||||||
|
sampleRate = sampleRates[srId];
|
||||||
|
_stream->setSampleRate(sampleRate);
|
||||||
if (running) {
|
if (running) {
|
||||||
doStop();
|
doStop();
|
||||||
doStart();
|
doStart();
|
||||||
}
|
}
|
||||||
// TODO: Save to config
|
config.aquire();
|
||||||
|
config.conf[_streamName]["devices"][devList[devId].name] = sampleRate;
|
||||||
|
config.release(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// AudioDevice_t* dev = devices[devListId];
|
|
||||||
|
|
||||||
// ImGui::SetNextItemWidth(menuWidth);
|
|
||||||
// if (ImGui::Combo(("##_rtaudio_sink_sr_"+_streamName).c_str(), &dev->srId, dev->txtSampleRates.c_str())) {
|
|
||||||
// _stream->setSampleRate(dev->sampleRates[dev->srId]);
|
|
||||||
// if (running) {
|
|
||||||
// doStop();
|
|
||||||
// doStart();
|
|
||||||
// }
|
|
||||||
// // TODO: Save to config
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -96,7 +162,6 @@ private:
|
|||||||
RtAudio::StreamParameters parameters;
|
RtAudio::StreamParameters parameters;
|
||||||
parameters.deviceId = deviceIds[devId];
|
parameters.deviceId = deviceIds[devId];
|
||||||
parameters.nChannels = 2;
|
parameters.nChannels = 2;
|
||||||
unsigned int sampleRate = 48000;
|
|
||||||
unsigned int bufferFrames = sampleRate / 60;
|
unsigned int bufferFrames = sampleRate / 60;
|
||||||
RtAudio::StreamOptions opts;
|
RtAudio::StreamOptions opts;
|
||||||
opts.flags = RTAUDIO_MINIMIZE_LATENCY;
|
opts.flags = RTAUDIO_MINIMIZE_LATENCY;
|
||||||
@ -149,20 +214,16 @@ private:
|
|||||||
int devId = 0;
|
int devId = 0;
|
||||||
bool running = false;
|
bool running = false;
|
||||||
|
|
||||||
const double POSSIBLE_SAMP_RATE[6] = {
|
unsigned int defaultDevId = 0;
|
||||||
48000.0f,
|
|
||||||
44100.0f,
|
|
||||||
24000.0f,
|
|
||||||
22050.0f,
|
|
||||||
12000.0f,
|
|
||||||
11025.0f
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
std::vector<RtAudio::DeviceInfo> devList;
|
std::vector<RtAudio::DeviceInfo> devList;
|
||||||
std::vector<unsigned int> deviceIds;
|
std::vector<unsigned int> deviceIds;
|
||||||
std::string txtDevList;
|
std::string txtDevList;
|
||||||
|
|
||||||
|
std::vector<unsigned int> sampleRates;
|
||||||
|
std::string sampleRatesTxt;
|
||||||
|
unsigned int sampleRate = 48000;
|
||||||
|
|
||||||
RtAudio audio;
|
RtAudio audio;
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -205,8 +266,10 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
MOD_EXPORT void _INIT_() {
|
MOD_EXPORT void _INIT_() {
|
||||||
// Nothing here
|
json def = json({});
|
||||||
// TODO: Do instancing here (in source modules as well) to prevent multiple loads
|
config.setPath(options::opts.root + "/audio_sink_config.json");
|
||||||
|
config.load(def);
|
||||||
|
config.enableAutoSave();
|
||||||
}
|
}
|
||||||
|
|
||||||
MOD_EXPORT void* _CREATE_INSTANCE_(std::string name) {
|
MOD_EXPORT void* _CREATE_INSTANCE_(std::string name) {
|
||||||
@ -215,7 +278,8 @@ MOD_EXPORT void* _CREATE_INSTANCE_(std::string name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MOD_EXPORT void _DELETE_INSTANCE_() {
|
MOD_EXPORT void _DELETE_INSTANCE_() {
|
||||||
|
config.disableAutoSave();
|
||||||
|
config.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
MOD_EXPORT void _END_() {
|
MOD_EXPORT void _END_() {
|
||||||
|
Loading…
Reference in New Issue
Block a user