Skip to content

Instantly share code, notes, and snippets.

@aaronmauro
Last active April 9, 2024 08:12
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aaronmauro/e87a2b59262a23c548d32fa3e73ecfad to your computer and use it in GitHub Desktop.
Save aaronmauro/e87a2b59262a23c548d32fa3e73ecfad to your computer and use it in GitHub Desktop.
Detects ultrasonic beacons commonly used in advertising and online advertising
#!/usr/bin/python
"""
Warning: This software is for research and educational purposes only.
Please do not violate any local or international laws. Please do not break terms of
service with other entities. Please read and understand the code before using it.
This code listens to the surrounding environment for ultrasonic beacons commonly used to track
individuals for advertising purposes. If an ultrasonic beacon is discovered, this code will
save a sample audio file as well as display a warning dialogue box.
To learn more about ultrasonic beacons, feel free to read this short article:
https://hackaday.com/2017/05/04/ultrasonic-tracking-beacons/
Please install pyaudio using the project documentation found here:
https://people.csail.mit.edu/hubert/pyaudio/docs/
Please install aubio using the project documentation found here:
https://aubio.readthedocs.io/en/latest/index.html
Please install tkinter using the project documentation found here:
https://tkdocs.com/tutorial/install.html
Please install wave using the instructions on PyPI: pip install wave
To test and calibrate for your hardware and noise environment, download a dog whistle
app for a smartphone and test setting the whistle to at least 20,000 hertz.
"""
__author__ = "Aaron Mauro"
__role__ = "researcher"
__institution__ = "Brock University"
__email__ = "amauro@brocku.ca"
__status__ = "prototype/experiment"
__version__ = "0.1"
import aubio
import pyaudio
import wave
import sys
import numpy as num
from tkinter import messagebox
from tkinter import Tk
HERTZ = 20000 # if greater than 20kHz or in ultrasound range, calibrate as needed
CHUNK = 1024
FORMAT = pyaudio.paFloat32
METHOD = "default"
SHORT_NORMALIZE = (1.0/32768.0)
CHANNELS = 1
RATE = 44100
HOP_SIZE = CHUNK
PERIOD_SIZE_IN_FRAME = HOP_SIZE
RECORD_SECONDS = 5
WAVE_OUTPUT_FILENAME = "output.wav"
def alert(title, message, kind='info', hidemain=True):
if kind not in ('error', 'warning', 'info'):
raise ValueError('Unsupported alert kind.')
show_method = getattr(messagebox, 'show{}'.format(kind))
show_method(title,message)
def get_hz(block):
ultrasonic_detection = aubio.pitch(METHOD, CHUNK,
HOP_SIZE, RATE)
ultrasonic_detection.set_unit("Hz")
ultrasonic_detection.set_silence(-40)
samples = num.frombuffer(block,
dtype=aubio.float_type)
pitch = ultrasonic_detection(samples)[0]
volume = num.sum(samples**2)/len(samples)
volume = "{:6f}".format(volume)
return pitch
def main():
Tk().withdraw()
ultra_sonic = False
while ultra_sonic == False:
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK)
print("* listening")
frames = []
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
data = stream.read(CHUNK)
frames.append(data)
print(get_hz(data))
if get_hz(data) > HERTZ:
alert("Beacon Warning","There is an ultrasonic beacon nearby!", kind='warning')
ultra_sonic = True
print("* done listening")
wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()
break
stream.stop_stream()
stream.close()
p.terminate()
if __name__ == "__main__":
try:
main()
except Exception as e:
print(str(e))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment