Merge branch 'jketterl:develop' into tuning_step
This commit is contained in:
		@@ -1,5 +1,9 @@
 | 
				
			|||||||
**unreleased**
 | 
					**unreleased**
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**1.2.1**
 | 
				
			||||||
 | 
					- FifiSDR support fixed (pipeline formats now line up correctly)
 | 
				
			||||||
 | 
					- Added "Device" input for FifiSDR devices for sound card selection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
**1.2.0**
 | 
					**1.2.0**
 | 
				
			||||||
- Major rewrite of all demodulation components to make use of the new csdr/pycsdr and digiham/pydigiham demodulator
 | 
					- Major rewrite of all demodulation components to make use of the new csdr/pycsdr and digiham/pydigiham demodulator
 | 
				
			||||||
  modules
 | 
					  modules
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										9
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
								
							@@ -1,6 +1,13 @@
 | 
				
			|||||||
openwebrx (1.3.0) UNRELEASED; urgency=low
 | 
					openwebrx (1.3.0) UNRELEASED; urgency=low
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 -- Jakob Ketterl <jakob.ketterl@gmx.de>  Thu, 16 Jun 2022 21:47:00 +0000
 | 
					 -- Jakob Ketterl <jakob.ketterl@gmx.de>  Fri, 30 Sep 2022 16:47:00 +0000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					openwebrx (1.2.1) bullseye jammy; urgency=low
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  * FifiSDR support fixed (pipeline formats now line up correctly)
 | 
				
			||||||
 | 
					  * Added "Device" input for FifiSDR devices for sound card selection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 -- Jakob Ketterl <jakob.ketterl@gmx.de>  Tue, 20 Sep 2022 16:01:00 +0000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
openwebrx (1.2.0) bullseye jammy; urgency=low
 | 
					openwebrx (1.2.0) bullseye jammy; urgency=low
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,7 +24,7 @@ apt-get update
 | 
				
			|||||||
apt-get -y install --no-install-recommends $BUILD_PACKAGES
 | 
					apt-get -y install --no-install-recommends $BUILD_PACKAGES
 | 
				
			||||||
 | 
					
 | 
				
			||||||
git clone https://github.com/jketterl/owrx_connector.git
 | 
					git clone https://github.com/jketterl/owrx_connector.git
 | 
				
			||||||
cmakebuild owrx_connector 0.6.0
 | 
					cmakebuild owrx_connector 0.6.1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
apt-get -y purge --autoremove $BUILD_PACKAGES
 | 
					apt-get -y purge --autoremove $BUILD_PACKAGES
 | 
				
			||||||
apt-get clean
 | 
					apt-get clean
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,7 +25,7 @@ apt-get update
 | 
				
			|||||||
apt-get -y install --no-install-recommends $STATIC_PACKAGES $BUILD_PACKAGES
 | 
					apt-get -y install --no-install-recommends $STATIC_PACKAGES $BUILD_PACKAGES
 | 
				
			||||||
 | 
					
 | 
				
			||||||
git clone https://github.com/jketterl/runds_connector.git
 | 
					git clone https://github.com/jketterl/runds_connector.git
 | 
				
			||||||
cmakebuild runds_connector 0.2.1
 | 
					cmakebuild runds_connector 0.2.2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
apt-get -y purge --autoremove $BUILD_PACKAGES
 | 
					apt-get -y purge --autoremove $BUILD_PACKAGES
 | 
				
			||||||
apt-get clean
 | 
					apt-get clean
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,11 +31,11 @@ popd
 | 
				
			|||||||
rm -rf js8py
 | 
					rm -rf js8py
 | 
				
			||||||
 | 
					
 | 
				
			||||||
git clone https://github.com/jketterl/csdr.git
 | 
					git clone https://github.com/jketterl/csdr.git
 | 
				
			||||||
cmakebuild csdr 0.18.0
 | 
					cmakebuild csdr 0.18.1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
git clone https://github.com/jketterl/pycsdr.git
 | 
					git clone https://github.com/jketterl/pycsdr.git
 | 
				
			||||||
cd pycsdr
 | 
					cd pycsdr
 | 
				
			||||||
git checkout 0.18.0
 | 
					git checkout 0.18.1
 | 
				
			||||||
./setup.py install install_headers
 | 
					./setup.py install install_headers
 | 
				
			||||||
cd ..
 | 
					cd ..
 | 
				
			||||||
rm -rf pycsdr
 | 
					rm -rf pycsdr
 | 
				
			||||||
@@ -46,11 +46,11 @@ cp codecserver/conf/codecserver.conf /usr/local/etc/codecserver
 | 
				
			|||||||
cmakebuild codecserver 0.2.0
 | 
					cmakebuild codecserver 0.2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
git clone https://github.com/jketterl/digiham.git
 | 
					git clone https://github.com/jketterl/digiham.git
 | 
				
			||||||
cmakebuild digiham 0.6.0
 | 
					cmakebuild digiham 0.6.1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
git clone https://github.com/jketterl/pydigiham.git
 | 
					git clone https://github.com/jketterl/pydigiham.git
 | 
				
			||||||
cd pydigiham
 | 
					cd pydigiham
 | 
				
			||||||
git checkout 0.6.0
 | 
					git checkout 0.6.1
 | 
				
			||||||
./setup.py install
 | 
					./setup.py install
 | 
				
			||||||
cd ..
 | 
					cd ..
 | 
				
			||||||
rm -rf pydigiham
 | 
					rm -rf pydigiham
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -81,6 +81,12 @@ Envelope.prototype.draw = function(visible_range){
 | 
				
			|||||||
        scale_ctx.fill();
 | 
					        scale_ctx.fill();
 | 
				
			||||||
        scale_ctx.globalAlpha = 1;
 | 
					        scale_ctx.globalAlpha = 1;
 | 
				
			||||||
        scale_ctx.stroke();
 | 
					        scale_ctx.stroke();
 | 
				
			||||||
 | 
					        scale_ctx.lineWidth = 1;
 | 
				
			||||||
 | 
					        scale_ctx.textAlign = "left";
 | 
				
			||||||
 | 
					        scale_ctx.fillText(this.demodulator.high_cut.toString(), to_px + env_att_w, env_h2);
 | 
				
			||||||
 | 
					        scale_ctx.textAlign = "right";
 | 
				
			||||||
 | 
					        scale_ctx.fillText(this.demodulator.low_cut.toString(), from_px - env_att_w, env_h2);
 | 
				
			||||||
 | 
					        scale_ctx.lineWidth = 3;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (typeof line !== "undefined") // out of screen?
 | 
					    if (typeof line !== "undefined") // out of screen?
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,6 +37,7 @@ $(function(){
 | 
				
			|||||||
    var retention_time = 2 * 60 * 60 * 1000;
 | 
					    var retention_time = 2 * 60 * 60 * 1000;
 | 
				
			||||||
    var strokeOpacity = 0.8;
 | 
					    var strokeOpacity = 0.8;
 | 
				
			||||||
    var fillOpacity = 0.35;
 | 
					    var fillOpacity = 0.35;
 | 
				
			||||||
 | 
					    var callsign_url = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    var colorKeys = {};
 | 
					    var colorKeys = {};
 | 
				
			||||||
    var colorScale = chroma.scale(['red', 'blue', 'green']).mode('hsl');
 | 
					    var colorScale = chroma.scale(['red', 'blue', 'green']).mode('hsl');
 | 
				
			||||||
@@ -286,6 +287,9 @@ $(function(){
 | 
				
			|||||||
                        if ('map_position_retention_time' in config) {
 | 
					                        if ('map_position_retention_time' in config) {
 | 
				
			||||||
                            retention_time = config.map_position_retention_time * 1000;
 | 
					                            retention_time = config.map_position_retention_time * 1000;
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
 | 
					                        if ('callsign_url' in config) {
 | 
				
			||||||
 | 
					                            callsign_url = config['callsign_url'];
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
                    case "update":
 | 
					                    case "update":
 | 
				
			||||||
                        processUpdates(json.value);
 | 
					                        processUpdates(json.value);
 | 
				
			||||||
@@ -338,7 +342,33 @@ $(function(){
 | 
				
			|||||||
        delete infowindow.locator;
 | 
					        delete infowindow.locator;
 | 
				
			||||||
        delete infowindow.callsign;
 | 
					        delete infowindow.callsign;
 | 
				
			||||||
        return infowindow;
 | 
					        return infowindow;
 | 
				
			||||||
    }
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var linkifyCallsign = function(callsign) {
 | 
				
			||||||
 | 
					        if ((callsign_url == null) || (callsign_url == ''))
 | 
				
			||||||
 | 
					            return callsign;
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            return '<a target="callsign_info" href="' +
 | 
				
			||||||
 | 
					                callsign_url.replaceAll('{}', callsign.replace(new RegExp('-.*$'), '')) +
 | 
				
			||||||
 | 
					                '">' + callsign + '</a>';
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var distanceKm = function(p1, p2) {
 | 
				
			||||||
 | 
					        // Earth radius in km
 | 
				
			||||||
 | 
					        var R = 6371.0;
 | 
				
			||||||
 | 
					        // Convert degrees to radians
 | 
				
			||||||
 | 
					        var rlat1 = p1.lat() * (Math.PI/180);
 | 
				
			||||||
 | 
					        var rlat2 = p2.lat() * (Math.PI/180);
 | 
				
			||||||
 | 
					        // Compute difference in radians
 | 
				
			||||||
 | 
					        var difflat = rlat2-rlat1;
 | 
				
			||||||
 | 
					        var difflon = (p2.lng()-p1.lng()) * (Math.PI/180);
 | 
				
			||||||
 | 
					        // Compute distance
 | 
				
			||||||
 | 
					        d = 2 * R * Math.asin(Math.sqrt(
 | 
				
			||||||
 | 
					            Math.sin(difflat/2) * Math.sin(difflat/2) +
 | 
				
			||||||
 | 
					            Math.cos(rlat1) * Math.cos(rlat2) * Math.sin(difflon/2) * Math.sin(difflon/2)
 | 
				
			||||||
 | 
					        ));
 | 
				
			||||||
 | 
					        return Math.round(d);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    var infowindow;
 | 
					    var infowindow;
 | 
				
			||||||
    var showLocatorInfoWindow = function(locator, pos) {
 | 
					    var showLocatorInfoWindow = function(locator, pos) {
 | 
				
			||||||
@@ -351,13 +381,15 @@ $(function(){
 | 
				
			|||||||
        }).sort(function(a, b){
 | 
					        }).sort(function(a, b){
 | 
				
			||||||
            return b.lastseen - a.lastseen;
 | 
					            return b.lastseen - a.lastseen;
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					        var distance = receiverMarker?
 | 
				
			||||||
 | 
					            " at " + distanceKm(receiverMarker.position, pos) + " km" : "";
 | 
				
			||||||
        infowindow.setContent(
 | 
					        infowindow.setContent(
 | 
				
			||||||
            '<h3>Locator: ' + locator + '</h3>' +
 | 
					            '<h3>Locator: ' + locator + distance + '</h3>' +
 | 
				
			||||||
            '<div>Active Callsigns:</div>' +
 | 
					            '<div>Active Callsigns:</div>' +
 | 
				
			||||||
            '<ul>' +
 | 
					            '<ul>' +
 | 
				
			||||||
                inLocator.map(function(i){
 | 
					                inLocator.map(function(i){
 | 
				
			||||||
                    var timestring = moment(i.lastseen).fromNow();
 | 
					                    var timestring = moment(i.lastseen).fromNow();
 | 
				
			||||||
                    var message = i.callsign + ' (' + timestring + ' using ' + i.mode;
 | 
					                    var message = linkifyCallsign(i.callsign) + ' (' + timestring + ' using ' + i.mode;
 | 
				
			||||||
                    if (i.band) message += ' on ' + i.band;
 | 
					                    if (i.band) message += ' on ' + i.band;
 | 
				
			||||||
                    message += ')';
 | 
					                    message += ')';
 | 
				
			||||||
                    return '<li>' + message + '</li>'
 | 
					                    return '<li>' + message + '</li>'
 | 
				
			||||||
@@ -374,16 +406,20 @@ $(function(){
 | 
				
			|||||||
        var marker = markers[callsign];
 | 
					        var marker = markers[callsign];
 | 
				
			||||||
        var timestring = moment(marker.lastseen).fromNow();
 | 
					        var timestring = moment(marker.lastseen).fromNow();
 | 
				
			||||||
        var commentString = "";
 | 
					        var commentString = "";
 | 
				
			||||||
 | 
					        var distance = "";
 | 
				
			||||||
        if (marker.comment) {
 | 
					        if (marker.comment) {
 | 
				
			||||||
            commentString = '<div>' + marker.comment + '</div>';
 | 
					            commentString = '<div>' + marker.comment + '</div>';
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        if (receiverMarker) {
 | 
				
			||||||
 | 
					            distance = " at " + distanceKm(receiverMarker.position, marker.position) + " km";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        infowindow.setContent(
 | 
					        infowindow.setContent(
 | 
				
			||||||
            '<h3>' + callsign + '</h3>' +
 | 
					            '<h3>' + linkifyCallsign(callsign) + distance + '</h3>' +
 | 
				
			||||||
            '<div>' + timestring + ' using ' + marker.mode + ( marker.band ? ' on ' + marker.band : '' ) + '</div>' +
 | 
					            '<div>' + timestring + ' using ' + marker.mode + ( marker.band ? ' on ' + marker.band : '' ) + '</div>' +
 | 
				
			||||||
            commentString
 | 
					            commentString
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        infowindow.open(map, marker);
 | 
					        infowindow.open(map, marker);
 | 
				
			||||||
    }
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    var showReceiverInfoWindow = function(marker) {
 | 
					    var showReceiverInfoWindow = function(marker) {
 | 
				
			||||||
        var infowindow = getInfoWindow()
 | 
					        var infowindow = getInfoWindow()
 | 
				
			||||||
@@ -392,7 +428,7 @@ $(function(){
 | 
				
			|||||||
            '<div>Receiver location</div>'
 | 
					            '<div>Receiver location</div>'
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        infowindow.open(map, marker);
 | 
					        infowindow.open(map, marker);
 | 
				
			||||||
    }
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    var getScale = function(lastseen) {
 | 
					    var getScale = function(lastseen) {
 | 
				
			||||||
        var age = new Date().getTime() - lastseen;
 | 
					        var age = new Date().getTime() - lastseen;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -802,6 +802,7 @@ function on_ws_recv(evt) {
 | 
				
			|||||||
                            $('#openwebrx-sdr-profiles-listbox').val(currentprofile.toString());
 | 
					                            $('#openwebrx-sdr-profiles-listbox').val(currentprofile.toString());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                            waterfall_clear();
 | 
					                            waterfall_clear();
 | 
				
			||||||
 | 
					                            zoom_set(0);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        if ('tuning_precision' in config)
 | 
					                        if ('tuning_precision' in config)
 | 
				
			||||||
@@ -969,9 +970,15 @@ var waterfall_measure_minmax_now = false;
 | 
				
			|||||||
var waterfall_measure_minmax_continuous = false;
 | 
					var waterfall_measure_minmax_continuous = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function waterfall_measure_minmax_do(what) {
 | 
					function waterfall_measure_minmax_do(what) {
 | 
				
			||||||
 | 
					    // Get visible range
 | 
				
			||||||
 | 
					    var range = get_visible_freq_range();
 | 
				
			||||||
 | 
					    var start = center_freq - bandwidth / 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // this is based on an oversampling factor of about 1,25
 | 
					    // this is based on an oversampling factor of about 1,25
 | 
				
			||||||
    var ignored = .1 * what.length;
 | 
					    range.start = Math.max(0.1, (range.start - start) / bandwidth);
 | 
				
			||||||
    var data = what.slice(ignored, -ignored);
 | 
					    range.end   = Math.min(0.9, (range.end - start) / bandwidth);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var data = what.slice(range.start * what.length, range.end * what.length);
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
        min: Math.min.apply(Math, data),
 | 
					        min: Math.min.apply(Math, data),
 | 
				
			||||||
        max: Math.max.apply(Math, data)
 | 
					        max: Math.max.apply(Math, data)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -159,6 +159,7 @@ defaultConfig = PropertyLayer(
 | 
				
			|||||||
    squelch_auto_margin=10,
 | 
					    squelch_auto_margin=10,
 | 
				
			||||||
    google_maps_api_key="",
 | 
					    google_maps_api_key="",
 | 
				
			||||||
    map_position_retention_time=2 * 60 * 60,
 | 
					    map_position_retention_time=2 * 60 * 60,
 | 
				
			||||||
 | 
					    callsign_url="https://www.qrzcq.com/call/{}",
 | 
				
			||||||
    decoding_queue_workers=2,
 | 
					    decoding_queue_workers=2,
 | 
				
			||||||
    decoding_queue_length=10,
 | 
					    decoding_queue_length=10,
 | 
				
			||||||
    wsjt_decoding_depth=3,
 | 
					    wsjt_decoding_depth=3,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -457,6 +457,7 @@ class MapConnection(OpenWebRxClient):
 | 
				
			|||||||
            "google_maps_api_key",
 | 
					            "google_maps_api_key",
 | 
				
			||||||
            "receiver_gps",
 | 
					            "receiver_gps",
 | 
				
			||||||
            "map_position_retention_time",
 | 
					            "map_position_retention_time",
 | 
				
			||||||
 | 
					            "callsign_url",
 | 
				
			||||||
            "receiver_name",
 | 
					            "receiver_name",
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        filtered_config.wire(self.write_config)
 | 
					        filtered_config.wire(self.write_config)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -168,6 +168,13 @@ class GeneralSettingsController(SettingsFormController):
 | 
				
			|||||||
                    infotext="Specifies how log markers / grids will remain visible on the map",
 | 
					                    infotext="Specifies how log markers / grids will remain visible on the map",
 | 
				
			||||||
                    append="s",
 | 
					                    append="s",
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
 | 
					                TextInput(
 | 
				
			||||||
 | 
					                    "callsign_url",
 | 
				
			||||||
 | 
					                    "Callsign database URL",
 | 
				
			||||||
 | 
					                    infotext="Specifies callsign lookup URL, such as QRZ.COM "
 | 
				
			||||||
 | 
					                    + "or QRZCQ.COM. Place curly brackers ({}) where callsign "
 | 
				
			||||||
 | 
					                    + "is supposed to be.",
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -249,10 +249,13 @@ class SdrSource(ABC):
 | 
				
			|||||||
    def getPort(self):
 | 
					    def getPort(self):
 | 
				
			||||||
        return self.port
 | 
					        return self.port
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _getTcpSourceFormat(self):
 | 
				
			||||||
 | 
					        return Format.COMPLEX_FLOAT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _getTcpSource(self):
 | 
					    def _getTcpSource(self):
 | 
				
			||||||
        with self.modificationLock:
 | 
					        with self.modificationLock:
 | 
				
			||||||
            if self.tcpSource is None:
 | 
					            if self.tcpSource is None:
 | 
				
			||||||
                self.tcpSource = TcpSource(self.port, Format.COMPLEX_FLOAT)
 | 
					                self.tcpSource = TcpSource(self.port, self._getTcpSourceFormat())
 | 
				
			||||||
        return self.tcpSource
 | 
					        return self.tcpSource
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def getBuffer(self):
 | 
					    def getBuffer(self):
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,6 +11,10 @@ logger = logging.getLogger(__name__)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DirectSource(SdrSource, metaclass=ABCMeta):
 | 
					class DirectSource(SdrSource, metaclass=ABCMeta):
 | 
				
			||||||
 | 
					    def __init__(self, id, props):
 | 
				
			||||||
 | 
					        self._conversion = None
 | 
				
			||||||
 | 
					        super().__init__(id, props)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def onPropertyChange(self, changes):
 | 
					    def onPropertyChange(self, changes):
 | 
				
			||||||
        logger.debug("restarting sdr source due to property changes: {0}".format(changes))
 | 
					        logger.debug("restarting sdr source due to property changes: {0}".format(changes))
 | 
				
			||||||
        self.stop()
 | 
					        self.stop()
 | 
				
			||||||
@@ -48,6 +52,10 @@ class DirectSource(SdrSource, metaclass=ABCMeta):
 | 
				
			|||||||
    def getFormatConversion(self) -> Optional[Chain]:
 | 
					    def getFormatConversion(self) -> Optional[Chain]:
 | 
				
			||||||
        return None
 | 
					        return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _getTcpSourceFormat(self):
 | 
				
			||||||
 | 
					        conversion = self.getFormatConversion()
 | 
				
			||||||
 | 
					        return Format.COMPLEX_FLOAT if conversion is None else conversion.getInputFormat()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # override this in subclasses, if necessary
 | 
					    # override this in subclasses, if necessary
 | 
				
			||||||
    def sleepOnRestart(self):
 | 
					    def sleepOnRestart(self):
 | 
				
			||||||
        pass
 | 
					        pass
 | 
				
			||||||
@@ -57,12 +65,12 @@ class DirectSource(SdrSource, metaclass=ABCMeta):
 | 
				
			|||||||
            source = self._getTcpSource()
 | 
					            source = self._getTcpSource()
 | 
				
			||||||
            buffer = Buffer(source.getOutputFormat())
 | 
					            buffer = Buffer(source.getOutputFormat())
 | 
				
			||||||
            source.setWriter(buffer)
 | 
					            source.setWriter(buffer)
 | 
				
			||||||
            conversion = self.getFormatConversion()
 | 
					            self._conversion = self.getFormatConversion()
 | 
				
			||||||
            if conversion is not None:
 | 
					            if self._conversion is not None:
 | 
				
			||||||
                conversion.setReader(buffer.getReader())
 | 
					                self._conversion.setReader(buffer.getReader())
 | 
				
			||||||
                # this one must be COMPLEX_FLOAT
 | 
					                # this one must be COMPLEX_FLOAT
 | 
				
			||||||
                buffer = Buffer(Format.COMPLEX_FLOAT)
 | 
					                buffer = Buffer(Format.COMPLEX_FLOAT)
 | 
				
			||||||
                conversion.setWriter(buffer)
 | 
					                self._conversion.setWriter(buffer)
 | 
				
			||||||
            self.buffer = buffer
 | 
					            self.buffer = buffer
 | 
				
			||||||
        return self.buffer
 | 
					        return self.buffer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,8 @@ from subprocess import Popen
 | 
				
			|||||||
from csdr.chain import Chain
 | 
					from csdr.chain import Chain
 | 
				
			||||||
from pycsdr.modules import Convert, Gain
 | 
					from pycsdr.modules import Convert, Gain
 | 
				
			||||||
from pycsdr.types import Format
 | 
					from pycsdr.types import Format
 | 
				
			||||||
 | 
					from typing import List
 | 
				
			||||||
 | 
					from owrx.form.input import Input, TextInput
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import logging
 | 
					import logging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -49,3 +51,15 @@ class FifiSdrDeviceDescription(DirectSourceDeviceDescription):
 | 
				
			|||||||
    def supportsPpm(self):
 | 
					    def supportsPpm(self):
 | 
				
			||||||
        # not currently mapped, and it's unclear how this should be sent to the device
 | 
					        # not currently mapped, and it's unclear how this should be sent to the device
 | 
				
			||||||
        return False
 | 
					        return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def getInputs(self) -> List[Input]:
 | 
				
			||||||
 | 
					        return super().getInputs() + [
 | 
				
			||||||
 | 
					            TextInput(
 | 
				
			||||||
 | 
					                "device",
 | 
				
			||||||
 | 
					                "Device identifier",
 | 
				
			||||||
 | 
					                infotext="Alsa audio device identifier",
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def getDeviceOptionalKeys(self):
 | 
				
			||||||
 | 
					        return super().getDeviceOptionalKeys() + ["device"]
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user