Skip to content

Commit

Permalink
v7.20
Browse files Browse the repository at this point in the history
  • Loading branch information
llinkz committed Jan 14, 2024
1 parent b215743 commit 7f01623
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 59 deletions.
88 changes: 42 additions & 46 deletions README.md
@@ -1,93 +1,87 @@
# directTDoA v7.10
# directTDoA v7.20

>### Hmmm latest KiwiSDR software broke directTDoA (no GNSS/GPS detected), let's see if I can figure out what's the problem or simply wait. (03-Jan-2024) - Happy New Year ?
---
>### RESTRICTION BECAUSE OF MAPBOX ABUSE (11-aug-2023)
>### directTDoA code is now running in degraded mode as the Mapbox token is no longer valid (solution below)
>I knew it was a bad idea to share this in code but today I got a bill because some bad guys made **too many unrelated** requests using the Mapbox token.
>
>![mapbox abuse](http://linkz.ddns.net/mapbox-abuse.png)
![mapbox abuse](http://linkz.ddns.net/mapbox-abuse2.png)
####
### Here's your solution to fix it (it seems not possible to restrict the token to Static Images API only)
>1/ Create your own [Mapbox.com](https://account.mapbox.com/auth/signup/) account
>
>2/ Go to account and get/create a default public token
>
>3/ Edit [getmap.py](https://github.com/llinkz/directTDoA/blob/master/getmap.py#L30) and modify `MAP_TOK` variable with your default public token
>
>### directTDoA use [Static Images API](https://docs.mapbox.com/api/maps/static-images/) and you'll get 50000 free monthly requests
>### 03 Jan 2024 - KiwiSDR software version > v1.647 broke directTDoA (no GNSS/GPS detected because of IQ wav incompatibility)
>### 12 Jan 2024 - Good news! Christoph, our TDoA master fixed the issue (was a bug in kiwirecorder.py)
>#### FIX : https://github.com/jks-prv/kiwiclient/commit/bc189087cf503820d56ddcc0f8781d7eed1b6337
>#### The fix is simple and can be done by hand, just edit your kiwiclient/kiwirecorder.py file if you want a quick one !
---
![directTDoA picture](http://linkz.ddns.net/directTDoA.png)

This software is JUST a python 2/3 GUI designed to compute TDoA runs on shortwave radio transmissions using remote (GPS enabled) KiwiSDR receivers around the World.

> TDoA = Time Difference of Arrival .. (in this case: the Arrival of shortwave radio transmissions)
> # Linux users : GNU Octave version < 8 only !
> because read_kiwi_iq_wav.cc will not compile - fix in progress...
>## Linux users : GNU Octave version < 8 only !
> else, read_kiwi_iq_wav.cc will not compile - fix in progress...
## KNOWN ISSUES:

#### 1/ If you plan to use the software on a machine without a sound card then you must comment out lines 15 & 16 in `/directTDoA/kiwiclient/kiwirecorder.py`
`#stream = sounddevice.OutputStream(12000, 2048, channels=1, dtype='int16')`
`#stream = sounddevice.OutputStream(48000, 2048, channels=1, dtype='int16')`

`#stream.start()`

#### 2/ On recent versions of Octave the handling of the font size has been changed (pixels Vs points) and you may find that they are too large in the final file, you can reduce the fontsize values on lines 41, 42 & 154 in `/directTDoA/TDoA/m/tdoa_plot_map.m`

## INSTALL AND RUN (on WINDOWS)
---
## WINDOWS

##### The decision was made not to support installation from the repository.

Download [directTDoA-windows.zip](https://github.com/llinkz/directTDoA/releases), unzip and extract it
1/ Download the latest [directTDoA-windows.zip](https://github.com/llinkz/directTDoA/releases), unzip and extract it

Then double-click on `directTDoA.bat`
2/ Create your own [Mapbox.com](https://account.mapbox.com/auth/signup/) account, go to account and get/create a default public token then edit [getmap.py](https://github.com/llinkz/directTDoA/blob/master/getmap.py#L30) and modify `MAP_TOK` variable with your default public token
> NOTE: directTDoA use [Static Images API](https://docs.mapbox.com/api/maps/static-images/) and you'll get 50000 free monthly requests
#### IMPORTANT: You must use only this method to launch the program to avoid file path issues.
3/ double-click on `directTDoA.bat`

> Info: this archive contains all the necessary files already patched and compiled and also includes light versions of GNU Octave and python, so no need to install the full versions of the last two on your machine. The unzipped archive is 272 MB, compared to ~2 GB in the other installer way.
>#### IMPORTANT: You must use only this method to launch the program to avoid file path issues.
#### This .zip archive contains all the necessary files already patched and compiled and also includes light versions of GNU Octave and python, so no need to install the full versions of the last two on your machine. The unzipped archive is 272 MB, compared to ~2 GB in the other installer way.

## INSTALL AND RUN (on LINUX)
---
## LINUX

Install python 3 and python3-pip using your package manager
1/ Install python 3 and python3-pip using your package manager

Install GNU octave (important: only versions < 8)
2/ Install GNU octave (important: only versions < 8)

Install git, patch, gcc, base-devel, ttf-dejavu, gcc-fortran, tk, portaudio, xdg-utils, epdfview, fltk
3/ Install git, patch, gcc, base-devel, ttf-dejavu, gcc-fortran, tk, portaudio, xdg-utils, epdfview, fltk, liboctave-dev

`git clone --recursive https://github.com/llinkz/directTDoA`
4/ `git clone --recursive https://github.com/llinkz/directTDoA && cd directTDoA`

`cd directTDoA`
5/ `./setup.sh`
> ####This setup script will install python modules, compile the necessary .oct file and apply some files patchs
> ####IMPORTANT: The octave files compilation process takes a lot of time, be patient, ignore warnings and don't stop the script
`./setup.sh` (this script will install python modules, compile the necessary .oct file and apply some files patchs)
#### IMPORTANT: The octave files compilation process takes a lot of time, be patient, ignore warnings and don't stop the script
`./directTDoA.py`
6/ Create your own [Mapbox.com](https://account.mapbox.com/auth/signup/) account, go to account and get/create a default public token then edit file named [getmap.py](https://github.com/llinkz/directTDoA/blob/master/getmap.py#L30) and modify `MAP_TOK` variable with your default public token (directTDoA use [Static Images API](https://docs.mapbox.com/api/maps/static-images/) and you'll get 50000 free monthly requests)

> NOTE: on some distros you may need to install liboctave-dev
7/ `./directTDoA.py`

## INSTALL AND RUN (on MAC OS X)
---
## MAC OS X

* REQUIREMENT Xcode + Homebrew (https://brew.sh/index_fr)

Install Homebrew, in terminal : `/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"`
1/ Install Homebrew, in terminal : `/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"`

Install Python, in terminal : `brew install python@2` or `brew install python@3`
2/ Install Python, in terminal : `brew install python@2` or `brew install python@3`

Install GNU Octave in Terminal : `brew install octave`
3/ Install GNU Octave in Terminal : `brew install octave`

`git clone --recursive https://github.com/llinkz/directTDoA`
4/ `git clone --recursive https://github.com/llinkz/directTDoA && cd directTDoA`

`cd directTDoA`
5/ `./setup.sh`
> ####This setup script will install python modules, compile the necessary .oct file and apply some files patchs
> ####IMPORTANT: The octave files compilation process takes a lot of time, be patient, ignore warnings and don't stop the script
`./setup.sh` (this script will install python modules, compile the necessary .oct file and apply patches to some files. Check errors but Ignore warnings)
6/ Create your own [Mapbox.com](https://account.mapbox.com/auth/signup/) account, go to account and get/create a default public token then edit file named [getmap.py](https://github.com/llinkz/directTDoA/blob/master/getmap.py#L30) and modify `MAP_TOK` variable with your default public token (directTDoA use [Static Images API](https://docs.mapbox.com/api/maps/static-images/) and you'll get 50000 free monthly requests)

`./directTDoA.py`
7/ `./directTDoA.py`

---
## LICENSE
* This python GUI code has been written and released under the "do what the f$ck you want with it" license

---
## CHANGE LOG
* v1.00-1.50 : first working version, basic, static map, manual host adding, hardcoded coordinates, manual octave code run etc...
* v2.00 : current work, update & dynamic maps full of GPS enabled nodes, auto octave code run, easier to use
Expand Down Expand Up @@ -134,6 +128,8 @@ Install GNU Octave in Terminal : `brew install octave`
* v7.01: Bug fix on map update because of a single KiwiSDR node using https (ofc it just happened after the v7.00 release - haha)
* v7.02: Small but important fix
* v7.10: Bug fix on Start/Stop Listen function + TKinter exception at start fixed + modified patches for wavreader.py & tdoa_plot_map.m + more map POIs + more recording mode choices + legend showing current TDoA algo + files directories shortcut menu + some ultimateTDoA interface improvements
* v7.20: TDoA broken because of early 2024 software mods, a bug was fixed in kiwirecorder.py (credit: Christoph Mayer, Thanks !) - only kiwirecorder_patch.diff has been modified (we will still use an old kiwiclient version) - apparently Listen mode is not working anymore - this version is only for bug correction.
---
## Thanks
* Christoph Mayer @ https://github.com/hcab14/TDoA for the main TDoA code, excellent work and thanks for the public release !
* John Seamons, KiwiSDR developper @ https://github.com/jks-prv
Expand Down
2 changes: 1 addition & 1 deletion directTDoA.py
Expand Up @@ -47,7 +47,7 @@
from tkinter.simpledialog import askstring, askinteger
from tkinter.font import Font

VERSION = "directTDoA v7.10"
VERSION = "directTDoA v7.20"


class ReadKnownPointFile(object):
Expand Down
2 changes: 1 addition & 1 deletion getmap.py
Expand Up @@ -27,7 +27,7 @@
# navigation-preview-day-v4 / navigation-preview-night-v4
# navigation-guidance-day-v4 / navigation-guidance-night-v4

MAP_TOK = "pk.eyJ1IjoibGxpbmt6IiwiYSI6ImNrM3JzMzE4ZTBlY3gzZXM1MnR5ODZrcnAifQ.fdqW8wmA7qhPYzFsGufZXg"
MAP_TOK = "Your_Mapbox_token_here"
DATA_L = []
MAPBOX_ZOOM = {'2': [0, 0], '4': [900, 0], '6': [0, 600], '8': [900, 600]}
NB_OF_NODES = len(glob.glob1(sys.argv[6].rsplit(os.sep, 1)[0], "*.wav"))
Expand Down
40 changes: 29 additions & 11 deletions kiwirecorder_patch.diff
@@ -1,17 +1,31 @@
--- kiwirecorder.py 2020-04-19 22:07:10.613484893 +0000
+++ kiwirecorder.py 2020-04-19 22:05:07.786030210 +0000
--- kiwirecorder.py 2024-01-14 09:48:45.338711534 +0100
+++ kiwirecorder.py 2024-01-14 09:36:05.647684241 +0100
@@ -10,6 +10,10 @@
from kiwi import KiwiSDRStream, KiwiWorker
from optparse import OptionParser
from optparse import OptionGroup
+import sounddevice
+
+stream = sounddevice.OutputStream(12000, 2048, channels=1, dtype='int16')
+stream = sounddevice.OutputStream(48000, 2048, channels=1, dtype='int16')
+stream.start()

HAS_RESAMPLER = True
try:
@@ -151,8 +155,10 @@
@@ -21,11 +25,12 @@


def _write_wav_header(fp, filesize, samplerate, num_channels, is_kiwi_wav):
+ samplerate = int(samplerate+0.5);
fp.write(struct.pack('<4sI4s', b'RIFF', filesize - 8, b'WAVE'))
bits_per_sample = 16
byte_rate = samplerate * num_channels * bits_per_sample // 8
block_align = num_channels * bits_per_sample // 8
- fp.write(struct.pack('<4sIHHIIHH', b'fmt ', 16, 1, num_channels, int(samplerate+0.5), byte_rate, block_align, bits_per_sample))
+ fp.write(struct.pack('<4sIHHIIHH', b'fmt ', 16, 1, num_channels, samplerate, byte_rate, block_align, bits_per_sample))
if not is_kiwi_wav:
fp.write(struct.pack('<4sI', b'data', filesize - 12 - 8 - 16 - 8))

@@ -151,8 +156,10 @@
# For AM, ignore the low pass filter cutoff
lp_cut = -hp_cut if hp_cut is not None else hp_cut
self.set_mod(mod, lp_cut, hp_cut, self._freq)
Expand All @@ -24,8 +38,12 @@
else:
self.set_agc(on=True)
if self._options.compression is False:
@@ -270,31 +276,34 @@
_write_wav_header(fp, filesize, int(self._output_sample_rate), self._num_channels, self._options.is_kiwi_wav)
@@ -267,34 +274,37 @@

# fp.tell() sometimes returns zero. _write_wav_header writes filesize - 8
if filesize >= 8:
- _write_wav_header(fp, filesize, int(self._output_sample_rate), self._num_channels, self._options.is_kiwi_wav)
+ _write_wav_header(fp, filesize, self._output_sample_rate, self._num_channels, self._options.is_kiwi_wav)

def _write_samples(self, samples, *args):
- """Output to a file on the disk."""
Expand Down Expand Up @@ -65,7 +83,7 @@
+ self._start_time = time.time()
+ # Write a static WAV header
+ with open(self._get_output_filename(), 'wb') as fp:
+ _write_wav_header(fp, 100, int(self._output_sample_rate), self._num_channels, self._options.is_kiwi_wav)
+ _write_wav_header(fp, 100, self._output_sample_rate, self._num_channels, self._options.is_kiwi_wav)
+ if self._options.is_kiwi_tdoa:
+ # NB: MUST be a print (i.e. not a logging.info)
+ print("file=%d %s" % (self._options.idx, self._get_output_filename()))
Expand All @@ -84,7 +102,7 @@

def _on_gnss_position(self, pos):
pos_record = False
@@ -371,9 +380,9 @@
@@ -371,9 +381,9 @@
opt_single.server_host = s
opt_single.status = 0

Expand All @@ -96,7 +114,7 @@
opt_single.__dict__[x] = _sel_entry(i, opt_single.__dict__[x])
l.append(opt_single)
multiple_connections = i
@@ -567,6 +576,11 @@
@@ -567,6 +577,11 @@
default=False,
action='store_true',
help='Also process sound data when in waterfall or S-meter mode (sound connection options above apply)')
Expand All @@ -108,7 +126,7 @@
parser.add_option_group(group)

group = OptionGroup(parser, "S-meter mode options", "")
@@ -635,7 +649,7 @@
@@ -635,7 +650,7 @@
if opt.launch_delay != 0 and i != 0 and options[i-1].server_host == options[i].server_host:
time.sleep(opt.launch_delay)
r.start()
Expand All @@ -117,7 +135,7 @@
logging.info("started sound recorder %d" % i)

for i,r in enumerate(wf_recorders):
@@ -664,6 +678,7 @@
@@ -664,6 +679,7 @@

logging.debug('gc %s' % gc.garbage)

Expand Down

0 comments on commit 7f01623

Please sign in to comment.