a LOT of new stuff

This commit is contained in:
Ryzerth
2020-08-16 03:39:05 +02:00
parent 31a95031e4
commit eadaf3ce6b
34 changed files with 3988 additions and 203 deletions

View File

@ -9,34 +9,128 @@
namespace io {
class AudioSink {
public:
enum {
MONO,
STEREO,
_TYPE_COUNT
};
struct AudioDevice_t {
std::string name;
int index;
int channels;
std::vector<float> sampleRates;
std::string txtSampleRates;
};
AudioSink() {
}
AudioSink(dsp::stream<float>* in, int bufferSize) {
AudioSink(int bufferSize) {
_bufferSize = bufferSize;
_input = in;
buffer = new float[_bufferSize * 2];
_volume = 1.0f;
Pa_Initialize();
}
void init(dsp::stream<float>* in, int bufferSize) {
_bufferSize = bufferSize;
_input = in;
buffer = new float[_bufferSize * 2];
monoBuffer = new float[_bufferSize];
stereoBuffer = new dsp::StereoFloat_t[_bufferSize];
_volume = 1.0f;
Pa_Initialize();
devTxtList = "";
int devCount = Pa_GetDeviceCount();
devIndex = Pa_GetDefaultOutputDevice();
const PaDeviceInfo *deviceInfo;
PaStreamParameters outputParams;
outputParams.sampleFormat = paFloat32;
outputParams.hostApiSpecificStreamInfo = NULL;
for(int i = 0; i < devCount; i++) {
deviceInfo = Pa_GetDeviceInfo(i);
if (deviceInfo->maxOutputChannels < 1) {
continue;
}
AudioDevice_t dev;
dev.name = deviceInfo->name;
dev.index = i;
dev.channels = std::min<int>(deviceInfo->maxOutputChannels, 2);
dev.sampleRates.clear();
dev.txtSampleRates = "";
for (int j = 0; j < 6; j++) {
outputParams.channelCount = dev.channels;
outputParams.device = dev.index;
outputParams.suggestedLatency = deviceInfo->defaultLowOutputLatency;
PaError err = Pa_IsFormatSupported(NULL, &outputParams, POSSIBLE_SAMP_RATE[j]);
if (err != paFormatIsSupported) {
continue;
}
dev.sampleRates.push_back(POSSIBLE_SAMP_RATE[j]);
dev.txtSampleRates += std::to_string((int)POSSIBLE_SAMP_RATE[j]);
dev.txtSampleRates += '\0';
}
if (dev.sampleRates.size() == 0) {
continue;
}
if (i == devIndex) {
devListIndex = devices.size();
}
devices.push_back(dev);
devTxtList += deviceInfo->name;
devTxtList += '\0';
}
}
void init(int bufferSize) {
_bufferSize = bufferSize;
monoBuffer = new float[_bufferSize];
stereoBuffer = new dsp::StereoFloat_t[_bufferSize];
_volume = 1.0f;
Pa_Initialize();
devTxtList = "";
int devCount = Pa_GetDeviceCount();
devIndex = Pa_GetDefaultOutputDevice();
const PaDeviceInfo *deviceInfo;
PaStreamParameters outputParams;
outputParams.sampleFormat = paFloat32;
outputParams.hostApiSpecificStreamInfo = NULL;
for(int i = 0; i < devCount; i++) {
deviceInfo = Pa_GetDeviceInfo(i);
if (deviceInfo->maxOutputChannels < 1) {
continue;
}
AudioDevice_t dev;
dev.name = deviceInfo->name;
dev.index = i;
dev.channels = std::min<int>(deviceInfo->maxOutputChannels, 2);
dev.sampleRates.clear();
dev.txtSampleRates = "";
for (int j = 0; j < 6; j++) {
outputParams.channelCount = dev.channels;
outputParams.device = dev.index;
outputParams.suggestedLatency = deviceInfo->defaultLowOutputLatency;
PaError err = Pa_IsFormatSupported(NULL, &outputParams, POSSIBLE_SAMP_RATE[j]);
if (err != paFormatIsSupported) {
continue;
}
dev.sampleRates.push_back(POSSIBLE_SAMP_RATE[j]);
dev.txtSampleRates += std::to_string((int)POSSIBLE_SAMP_RATE[j]);
dev.txtSampleRates += '\0';
}
if (dev.sampleRates.size() == 0) {
continue;
}
if (i == devIndex) {
devListIndex = devices.size();
}
devices.push_back(dev);
devTxtList += deviceInfo->name;
devTxtList += '\0';
}
}
void setMonoInput(dsp::stream<float>* input) {
_monoInput = input;
}
void setStereoInput(dsp::stream<dsp::StereoFloat_t>* input) {
_stereoInput = input;
}
void setVolume(float volume) {
@ -47,13 +141,25 @@ namespace io {
if (running) {
return;
}
const PaDeviceInfo *deviceInfo;
AudioDevice_t dev = devices[devListIndex];
PaStreamParameters outputParams;
deviceInfo = Pa_GetDeviceInfo(dev.index);
outputParams.channelCount = 2;
outputParams.sampleFormat = paFloat32;
outputParams.hostApiSpecificStreamInfo = NULL;
outputParams.device = devIndex;
outputParams.device = dev.index;
outputParams.suggestedLatency = Pa_GetDeviceInfo(outputParams.device)->defaultLowOutputLatency;
PaError err = Pa_OpenStream(&stream, NULL, &outputParams, 48000.0f, _bufferSize, paClipOff, _callback, this);
PaError err;
if (streamType == MONO) {
err = Pa_OpenStream(&stream, NULL, &outputParams, _sampleRate, _bufferSize, NULL,
(dev.channels == 2) ? _mono_to_stereo_callback : _mono_to_mono_callback, this);
}
else {
err = Pa_OpenStream(&stream, NULL, &outputParams, _sampleRate, _bufferSize, NULL,
(dev.channels == 2) ? _stereo_to_stereo_callback : _stereo_to_mono_callback, this);
}
if (err != 0) {
spdlog::error("Error while opening audio stream: ({0}) => {1}", err, Pa_GetErrorText(err));
return;
@ -81,47 +187,128 @@ namespace io {
return;
}
_bufferSize = blockSize;
delete[] monoBuffer;
delete[] stereoBuffer;
monoBuffer = new float[_bufferSize];
stereoBuffer = new dsp::StereoFloat_t[_bufferSize];
}
void setSampleRate(float sampleRate) {
_sampleRate = sampleRate;
}
void setDevice(int id) {
if (devIndex == id) {
if (devListIndex == id) {
return;
}
if (running) {
return;
}
devIndex = id;
devListIndex = id;
devIndex = devices[id].index;
}
int getDeviceId() {
return devIndex;
return devListIndex;
}
void setStreamType(int type) {
streamType = type;
}
std::string devTxtList;
std::vector<AudioDevice_t> devices;
private:
static int _callback(const void *input,
static int _mono_to_mono_callback(const void *input,
void *output,
unsigned long frameCount,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags, void *userData ) {
AudioSink* _this = (AudioSink*)userData;
float* outbuf = (float*)output;
_this->_input->read(_this->buffer, frameCount);
_this->_monoInput->read(_this->monoBuffer, frameCount);
float vol = powf(_this->_volume, 2);
for (int i = 0; i < frameCount; i++) {
outbuf[(i * 2) + 0] = _this->buffer[i] * vol;
outbuf[(i * 2) + 1] = _this->buffer[i] * vol;
outbuf[i] = _this->monoBuffer[i] * vol;
}
return 0;
}
static int _stereo_to_stereo_callback(const void *input,
void *output,
unsigned long frameCount,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags, void *userData ) {
AudioSink* _this = (AudioSink*)userData;
dsp::StereoFloat_t* outbuf = (dsp::StereoFloat_t*)output;
_this->_stereoInput->read(_this->stereoBuffer, frameCount);
// Note: Calculate the power in the UI instead of here
float vol = powf(_this->_volume, 2);
for (int i = 0; i < frameCount; i++) {
outbuf[i].l = _this->stereoBuffer[i].l * vol;
outbuf[i].r = _this->stereoBuffer[i].r * vol;
}
return 0;
}
static int _mono_to_stereo_callback(const void *input,
void *output,
unsigned long frameCount,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags, void *userData ) {
AudioSink* _this = (AudioSink*)userData;
dsp::StereoFloat_t* outbuf = (dsp::StereoFloat_t*)output;
_this->_monoInput->read(_this->monoBuffer, frameCount);
float vol = powf(_this->_volume, 2);
for (int i = 0; i < frameCount; i++) {
outbuf[i].l = _this->monoBuffer[i] * vol;
outbuf[i].r = _this->monoBuffer[i] * vol;
}
return 0;
}
static int _stereo_to_mono_callback(const void *input,
void *output,
unsigned long frameCount,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags, void *userData ) {
AudioSink* _this = (AudioSink*)userData;
float* outbuf = (float*)output;
_this->_stereoInput->read(_this->stereoBuffer, frameCount);
// Note: Calculate the power in the UI instead of here
float vol = powf(_this->_volume, 2);
for (int i = 0; i < frameCount; i++) {
outbuf[i] = ((_this->stereoBuffer[i].l + _this->stereoBuffer[i].r) / 2.0f) * vol;
}
return 0;
}
float POSSIBLE_SAMP_RATE[6] = {
48000.0f,
44100.0f,
24000.0f,
22050.0f,
12000.0f,
11025.0f
};
int streamType;
int devIndex;
int devListIndex;
float _sampleRate;
int _bufferSize;
dsp::stream<float>* _input;
float* buffer;
float _volume;
dsp::stream<float>* _monoInput;
dsp::stream<dsp::StereoFloat_t>* _stereoInput;
float* monoBuffer;
dsp::StereoFloat_t* stereoBuffer;
float _volume = 1.0f;
PaStream *stream;
bool running = false;
};

View File

@ -52,6 +52,7 @@ namespace io {
devList = SoapySDR::Device::enumerate();
txtDevList = "";
devNameList.clear();
if (devList.size() == 0) {
txtDevList += '\0';
return;
@ -59,6 +60,7 @@ namespace io {
for (int i = 0; i < devList.size(); i++) {
txtDevList += devList[i]["label"];
txtDevList += '\0';
devNameList.push_back(devList[i]["label"]);
}
}
@ -74,6 +76,7 @@ namespace io {
txtSampleRateList += std::to_string((int)sampleRates[i]);
txtSampleRateList += '\0';
}
_sampleRate = sampleRates[0];
gainList = dev->listGains(SOAPY_SDR_RX, 0);
gainRanges.clear();
@ -84,7 +87,11 @@ namespace io {
currentGains = new float[gainList.size()];
for (int i = 0; i < gainList.size(); i++) {
gainRanges.push_back(dev->getGainRange(SOAPY_SDR_RX, 0, gainList[i]));
currentGains[i] = dev->getGain(SOAPY_SDR_RX, 0, gainList[i]);
SoapySDR::Range rng = dev->getGainRange(SOAPY_SDR_RX, 0, gainList[i]);
spdlog::info("{0}: {1} -> {2} (Step: {3})", gainList[i], rng.minimum(), rng.maximum(), rng.step());
currentGains[i] = rng.minimum();
}
}
@ -109,8 +116,14 @@ namespace io {
return running;
}
float getSampleRate() {
return _sampleRate;
}
SoapySDR::KwargsList devList;
std::vector<std::string> devNameList;
std::string txtDevList;
std::vector<double> sampleRates;
std::string txtSampleRateList;