diff --git a/AudioOutput.cpp b/AudioOutput.cpp index 7c6d61e..6ce32f3 100644 --- a/AudioOutput.cpp +++ b/AudioOutput.cpp @@ -90,6 +90,8 @@ HifiBerryAudioOutputput::HifiBerryAudioOutputput(int pcmrate, SoapyHifiBerryData parameters.nChannels = 2; parameters.firstChannel = 0; parameters.deviceId = 0; + DigitalPlaybackMin = 0; + DigitalPlaybackMax = 100; } /* @@ -123,6 +125,7 @@ bool HifiBerryAudioOutputput::open(std::string device) printf("Cannot open audio output stream\n"); return false; } + get_alsa_range(1, "Digital Playback Volume"); this->startStream(); return true; } @@ -251,6 +254,49 @@ int HifiBerryAudioOutputput::controle_alsa(int element, int ivalue) return 0; } +int HifiBerryAudioOutputput::get_alsa_range(int element, std::string name) +{ + char str[80]; + snd_ctl_t *ctl; + snd_ctl_elem_id_t *id; + snd_ctl_elem_info_t *info; + snd_ctl_elem_value_t *control; + int err; + + snd_ctl_elem_id_alloca(&id); + snd_ctl_elem_info_alloca(&info); + snd_ctl_elem_value_alloca(&control); + + // Open the control interface for the specified sound card + sprintf(str, "hw:%d", alsa_device); + if ((err = snd_ctl_open(&ctl, str, 0)) < 0) + { + printf("Error opening control interface: %s\n", snd_strerror(err)); + return err; + } + + // Set the ID of the element we want to retrieve information for + snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); + snd_ctl_elem_id_set_name(id, name.c_str()); + + // Retrieve the element information + snd_ctl_elem_info_set_id(info, id); + if ((err = snd_ctl_elem_info(ctl, info)) < 0) + { + printf("Error retrieving element info: %s\n", snd_strerror(err)); + snd_ctl_close(ctl); + return err; + } + + // Retrieve the element range + DigitalPlaybackMin = snd_ctl_elem_info_get_min(info); + DigitalPlaybackMax = snd_ctl_elem_info_get_max(info); + printf("Digital Playback Volume range: [%ld, %ld]\n", DigitalPlaybackMin, DigitalPlaybackMax); + + snd_ctl_close(ctl); + return 0; +} + /* pi@pi3:~$ amixer --debug - c 3 controls numid = 22, iface = MIXER, name = 'Headphone Playback Volume' diff --git a/AudioOutput.h b/AudioOutput.h index d7b6688..87483aa 100644 --- a/AudioOutput.h +++ b/AudioOutput.h @@ -37,6 +37,8 @@ class HifiBerryAudioOutputput : unsigned int get_device() { return parameters.deviceId;} int controle_alsa(int element, int ivalue); int lookup_id(snd_ctl_elem_id_t *id, snd_ctl_t *handle); + int get_alsa_range(int element, std::string name); + int get_max_volume() { return DigitalPlaybackMax; } protected: void samplesToInt16(const SampleVector& samples, @@ -53,4 +55,5 @@ class HifiBerryAudioOutputput : atomic underrun; int alsa_device; map device_map; + long DigitalPlaybackMin, DigitalPlaybackMax; }; \ No newline at end of file diff --git a/SoapyHifiBerrySettings.cpp b/SoapyHifiBerrySettings.cpp index 88b9460..2e340c0 100644 --- a/SoapyHifiBerrySettings.cpp +++ b/SoapyHifiBerrySettings.cpp @@ -5,7 +5,7 @@ * Device interface **********************************************************************/ const cfg::File::ConfigMap defaultOptions = { - {"si5351", {{"correction", cfg::makeOption("0")}, {"rxdrive", cfg::makeOption("2")}, {"txdrive", cfg::makeOption("2")}}}, + {"si5351", {{"correction", cfg::makeOption("0")}, {"rxdrive", cfg::makeOption("2")}, {"t.xdrive", cfg::makeOption("2")}}}, {"sound", {{"device", cfg::makeOption("snd_rpi_hifiberry_dacplusadcpro")}, {"samplerate", cfg::makeOption("192000")}}} }; @@ -267,12 +267,25 @@ SoapySDR::Range SoapyHifiBerry::getGainRange(const int direction, const size_t c void SoapyHifiBerry::setGain(const int direction, const size_t channel, const double value) { - - SoapySDR_log(SOAPY_SDR_INFO, "SoapyHifiBerry::setGain called"); + char str[80]; + sprintf(str, "SoapyHifiBerry::setGain called %f", value * 2.4); + SoapySDR_log(SOAPY_SDR_INFO, str); if (direction == SOAPY_SDR_RX) uptr_HifiBerryAudioOutputput->controle_alsa(21, (int) value); // numid = 21, iface = MIXER, name = 'ADC Capture Volume' + if (direction == SOAPY_SDR_TX) + { + if (value < 99.9) + { + float factor = uptr_HifiBerryAudioOutputput->get_max_volume() / 100.0; + uptr_HifiBerryAudioOutputput->controle_alsa(1, (int)(value * factor)); //numid = 1, iface = MIXER, name = 'Digital Playback Volume' + } + else + { + uptr_HifiBerryAudioOutputput->controle_alsa(1, uptr_HifiBerryAudioOutputput->get_max_volume()); //numid = 1, iface = MIXER, name = 'Digital Playback Volume' + } + } } /*******************************************************************