Skip to content

Commit

Permalink
Merged branch 'period-option'
Browse files Browse the repository at this point in the history
  • Loading branch information
phlash committed Jul 22, 2021
2 parents 7e968c5 + f3d562e commit c982af5
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 9 deletions.
46 changes: 38 additions & 8 deletions SoapyFCDPP/SoapyFCDPP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
SoapyFCDPP::SoapyFCDPP(const std::string &hid_path, const std::string &alsa_device, const bool is_plus, const uint32_t override_period) :
is_pro_plus(is_plus),
d_pcm_handle(nullptr),
d_running_size(0),
d_mmap_valid(false),
d_frequency(0),
d_lna_gain(0),
d_bias_tee(false),
Expand All @@ -28,10 +30,6 @@ SoapyFCDPP::SoapyFCDPP(const std::string &hid_path, const std::string &alsa_devi
if (d_handle == nullptr) {
throw std::runtime_error("hid_open_path failed to open: " + d_hid_path);
}
// Sample buffer x 2 because complex data.
d_buff.resize(2 * d_period_size);
// No mmap buffer (yet)
d_mmap_valid = false;
}

SoapyFCDPP::~SoapyFCDPP()
Expand Down Expand Up @@ -89,6 +87,9 @@ SoapySDR::ArgInfoList SoapyFCDPP::getStreamArgsInfo(const int direction, const s
SoapySDR::Stream *SoapyFCDPP::setupStream(const int direction, const std::string &format, const std::vector<size_t> &channels, const SoapySDR::Kwargs &args)
{
SoapySDR_log(SOAPY_SDR_INFO, "setup stream");
if (d_pcm_handle!=nullptr) {
throw std::runtime_error("setupStream only one stream at a time");
}
if (direction != SOAPY_SDR_RX) {
throw std::runtime_error("setupStream only RX supported");
}
Expand All @@ -113,6 +114,10 @@ SoapySDR::Stream *SoapyFCDPP::setupStream(const int direction, const std::string
d_pcm_handle = alsa_pcm_handle(d_alsa_device.c_str(), (unsigned int)d_sample_rate, d_period_size, SND_PCM_STREAM_CAPTURE);
assert(d_pcm_handle != nullptr);

// Save ALSA period size & adjust sample buffer (x 2 because complex data).
d_running_size = d_period_size;
d_buff.resize(2 * d_running_size);

return (SoapySDR::Stream *) this;
}

Expand Down Expand Up @@ -221,10 +226,11 @@ int SoapyFCDPP::readStream(SoapySDR::Stream *stream,
n_err = snd_pcm_avail_update(d_pcm_handle);
if (n_err > 0) {
// map up to one alsa period of data
snd_pcm_uframes_t offset, frames = std::min<snd_pcm_uframes_t>(std::min<size_t>(d_period_size, numElems), n_err);
snd_pcm_uframes_t offset, frames = std::min<snd_pcm_uframes_t>(std::min<size_t>(d_running_size, numElems), n_err);
const snd_pcm_channel_area_t *area;
n_err = snd_pcm_mmap_begin(d_pcm_handle, &area, &offset, &frames);
if (n_err >= 0) {
if(n_err >= 0) {
// map ok, convert and return.
#if SOAPY_SDR_API_VERSION >= 0x00070000
d_converter_func(((char *)area->addr)+(offset*4), buffs[0], frames, 1.0);
#else
Expand All @@ -234,12 +240,15 @@ int SoapyFCDPP::readStream(SoapySDR::Stream *stream,
memcpy(buffs[0], ((char *)area->addr)+(offset*4), frames*4);
#endif
snd_pcm_mmap_commit(d_pcm_handle, offset, frames);
n_err = (int) frames;
n_err = (int) frames;
}
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
if (n_err >= 0)
return (int) n_err;
// error, fallthrough
#pragma GCC diagnostic pop
case SND_PCM_STATE_XRUN:
err = (int) n_err;
// try to recover from error.
Expand Down Expand Up @@ -654,18 +663,39 @@ SoapySDR::ArgInfoList SoapyFCDPP::getSettingInfo(void) const
SoapySDR::ArgInfoList settings;

SoapySDR_log(SOAPY_SDR_DEBUG, "getSettingInfo");


SoapySDR::ArgInfo setting;
setting.key = "period";
setting.value = "0";
setting.type = SoapySDR::ArgInfo::Type::INT;
// Empirical testing shows ALSA supports periods in this range...
setting.range = SoapySDR::Range(d_sample_rate/1000, d_sample_rate/2, d_sample_rate/100);
settings.push_back(setting);

return settings;
}

void SoapyFCDPP::writeSetting(const std::string &key, const std::string &value)
{
SoapySDR_log(SOAPY_SDR_DEBUG, "writeSetting");
if (d_pcm_handle!=nullptr)
SoapySDR_log(SOAPY_SDR_WARNING, "writeSetting, will not affect currently open stream");
if ("period"==key) {
uint32_t period;
sscanf(value.c_str(), "%u", &period);
if (period<d_sample_rate/1000 || period>d_sample_rate/2) {
SoapySDR_logf(SOAPY_SDR_ERROR, "writeSetting: unsupported period value (%u)", period);
return;
}
d_period_size = period;
}
}

std::string SoapyFCDPP::readSetting(const std::string &key) const
{
SoapySDR_log(SOAPY_SDR_DEBUG, "readSetting");
if ("period"==key)
return std::to_string(d_period_size);
return "empty";
}

Expand Down
1 change: 1 addition & 0 deletions SoapyFCDPP/SoapyFCDPP.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class SoapyFCDPP : public SoapySDR::Device
const bool is_pro_plus;
snd_pcm_t* d_pcm_handle;
uint32_t d_period_size;
uint32_t d_running_size;
std::vector<int32_t> d_buff;
std::string d_out_format;
bool d_mmap_valid;
Expand Down
2 changes: 1 addition & 1 deletion fcddirect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ void trap(int sig)
int main(int argc, char **argv)
{
// find our device
char *config = "driver=fcdpp";
const char *config = "driver=fcdpp";
if (argc>1)
config = argv[1];
SoapySDR::loadModules();
Expand Down

0 comments on commit c982af5

Please sign in to comment.