mirror of
https://github.com/AlexandreRouma/SDRPlusPlus.git
synced 2025-07-12 20:15:37 +02:00
rewrote DSP
This commit is contained in:
75
src/io/audio.h
Normal file
75
src/io/audio.h
Normal file
@ -0,0 +1,75 @@
|
||||
#pragma once
|
||||
#include <thread>
|
||||
#include <dsp/stream.h>
|
||||
#include <dsp/types.h>
|
||||
#include <fstream>
|
||||
#include <portaudio.h>
|
||||
|
||||
namespace io {
|
||||
class AudioSink {
|
||||
public:
|
||||
AudioSink() {
|
||||
|
||||
}
|
||||
|
||||
AudioSink(dsp::stream<float>* in, 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];
|
||||
_volume = 1.0f;
|
||||
Pa_Initialize();
|
||||
}
|
||||
|
||||
void setVolume(float volume) {
|
||||
_volume = volume;
|
||||
}
|
||||
|
||||
void start() {
|
||||
PaStreamParameters outputParams;
|
||||
outputParams.channelCount = 2;
|
||||
outputParams.sampleFormat = paFloat32;
|
||||
outputParams.hostApiSpecificStreamInfo = NULL;
|
||||
outputParams.device = Pa_GetDefaultOutputDevice();
|
||||
outputParams.suggestedLatency = Pa_GetDeviceInfo(outputParams.device)->defaultLowOutputLatency;
|
||||
PaError err = Pa_OpenStream(&stream, NULL, &outputParams, 40000.0f, 320, paClipOff, _callback, this);
|
||||
printf("%s\n", Pa_GetErrorText(err));
|
||||
err = Pa_StartStream(stream);
|
||||
printf("%s\n", Pa_GetErrorText(err));
|
||||
}
|
||||
|
||||
void stop() {
|
||||
Pa_CloseStream(stream);
|
||||
}
|
||||
|
||||
private:
|
||||
static int _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);
|
||||
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;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _bufferSize;
|
||||
dsp::stream<float>* _input;
|
||||
float* buffer;
|
||||
float _volume;
|
||||
PaStream *stream;
|
||||
};
|
||||
};
|
106
src/io/soapy.h
Normal file
106
src/io/soapy.h
Normal file
@ -0,0 +1,106 @@
|
||||
#include <string>
|
||||
#include <SoapySDR/Device.hpp>
|
||||
#include <SoapySDR/Modules.hpp>
|
||||
#include <dsp/stream.h>
|
||||
#include <dsp/types.h>
|
||||
|
||||
namespace io {
|
||||
class SoapyWrapper {
|
||||
public:
|
||||
SoapyWrapper() {
|
||||
output.init(64000);
|
||||
refresh();
|
||||
setDevice(devList[0]);
|
||||
}
|
||||
|
||||
void start() {
|
||||
if (running) {
|
||||
return;
|
||||
}
|
||||
dev = SoapySDR::Device::make(args);
|
||||
_stream = dev->setupStream(SOAPY_SDR_RX, "CF32");
|
||||
dev->activateStream(_stream);
|
||||
running = true;
|
||||
_workerThread = std::thread(_worker, this);
|
||||
}
|
||||
|
||||
void stop() {
|
||||
if (!running) {
|
||||
return;
|
||||
}
|
||||
running = false;
|
||||
dev->deactivateStream(_stream);
|
||||
dev->closeStream(_stream);
|
||||
_workerThread.join();
|
||||
SoapySDR::Device::unmake(dev);
|
||||
}
|
||||
|
||||
void refresh() {
|
||||
if (running) {
|
||||
return;
|
||||
}
|
||||
|
||||
devList = SoapySDR::Device::enumerate();
|
||||
txtDevList = "";
|
||||
for (int i = 0; i < devList.size(); i++) {
|
||||
txtDevList += devList[i]["label"];
|
||||
txtDevList += '\0';
|
||||
}
|
||||
}
|
||||
|
||||
void setDevice(SoapySDR::Kwargs devArgs) {
|
||||
if (running) {
|
||||
return;
|
||||
}
|
||||
args = devArgs;
|
||||
dev = SoapySDR::Device::make(devArgs);
|
||||
txtSampleRateList = "";
|
||||
sampleRates = dev->listSampleRates(SOAPY_SDR_RX, 0);
|
||||
for (int i = 0; i < sampleRates.size(); i++) {
|
||||
txtSampleRateList += std::to_string((int)sampleRates[i]);
|
||||
txtSampleRateList += '\0';
|
||||
}
|
||||
}
|
||||
|
||||
void setSampleRate(float sampleRate) {
|
||||
if (running) {
|
||||
return;
|
||||
}
|
||||
dev->setSampleRate(SOAPY_SDR_RX, 0, sampleRate);
|
||||
}
|
||||
|
||||
void setFrequency(float freq) {
|
||||
dev->setFrequency(SOAPY_SDR_RX, 0, freq);
|
||||
}
|
||||
|
||||
bool isRunning() {
|
||||
return running;
|
||||
}
|
||||
|
||||
SoapySDR::KwargsList devList;
|
||||
std::string txtDevList;
|
||||
std::vector<double> sampleRates;
|
||||
std::string txtSampleRateList;
|
||||
|
||||
dsp::stream<dsp::complex_t> output;
|
||||
|
||||
private:
|
||||
static void _worker(SoapyWrapper* _this) {
|
||||
dsp::complex_t* buf = new dsp::complex_t[32000];
|
||||
int flags = 0;
|
||||
long long timeMs = 0;
|
||||
while (_this->running) {
|
||||
_this->dev->readStream(_this->_stream, (void**)&buf, 32000, flags, timeMs);
|
||||
_this->output.write(buf, 32000);
|
||||
}
|
||||
printf("Read worker terminated\n");
|
||||
delete[] buf;
|
||||
}
|
||||
|
||||
SoapySDR::Kwargs args;
|
||||
SoapySDR::Device* dev;
|
||||
SoapySDR::Stream* _stream;
|
||||
std::thread _workerThread;
|
||||
bool running = false;
|
||||
};
|
||||
};
|
Reference in New Issue
Block a user