Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libquiet ctypes binding #1

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include quiet/*
104 changes: 101 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,102 @@
# quiet.py
Python bindings for libquiet
quiet.py
========

[![](https://img.shields.io/pypi/v/quiet.py.svg)](https://pypi.org/project/quiet.py/)


Python ctypes bindings for libquiet to transmit data with sound.

## Requirements
+ numpy

## Install

+ For ARM platform, binary package is available on pypi, just use `pip` to install it:

```
sudo apt install python-numpy
pip install --no-deps quiet.py
```

We install `numpy` separately, as installing `numpy` via pip requires compiling numpy from source.

+ For x86/amd64

```
sudo apt install cmake
git clone https://github.com/xiongyihui/quiet.py && cd quiet.py
./scripts/libs.sh
pip install .
```


## Usage
1. Encode a message, and then decode it
```
from quiet import Encode, Decoder

def test():
encoder = Encoder()
decoder = Decoder()

for chunk in encoder.encode('hello, world'):
message = decoder.decode(chunk)
if message is not None:
print(message)


test()
```

2. decode messages from recording in realtime

```
import sys
import numpy
import pyaudio
from quiet import Encode, Decoder

def decode():
if sys.version_info[0] < 3:
import Queue as queue
else:
import queue

FORMAT = pyaudio.paFloat32
CHANNELS = 1
RATE = 44100
CHUNK = 16384 # int(RATE / 100)

p = pyaudio.PyAudio()
q = queue.Queue()

def callback(in_data, frame_count, time_info, status):
q.put(in_data)
return (None, pyaudio.paContinue)

stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK,
stream_callback=callback)

count = 0
with Decoder(profile_name='ultrasonic-experimental') as decoder:
while True:
try:
audio = q.get()
audio = numpy.fromstring(audio, dtype='float32')
# audio = audio[::CHANNELS]
code = decoder.decode(audio)
if code is not None:
count += 1
print(code.tostring().decode('utf-8', 'ignore'))
except KeyboardInterrupt:
break


decode()
```


This repo is not yet ready. It is a work in progress.
4 changes: 4 additions & 0 deletions quiet/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# -*- coding:utf-8 -*-

from .quiet import Decoder, Encoder

270 changes: 270 additions & 0 deletions quiet/quiet-profiles.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
{
"audible": {
"mod_scheme": "gmsk",
"checksum_scheme": "crc32",
"inner_fec_scheme": "v27",
"outer_fec_scheme": "none",
"frame_length": 100,
"modulation": {
"center_frequency": 4200,
"gain": 0.1
},
"interpolation": {
"shape": "kaiser",
"samples_per_symbol": 10,
"symbol_delay": 4,
"excess_bandwidth": 0.35
},
"encoder_filters": {
"dc_filter_alpha": 0.01
},
"resampler": {
"delay": 13,
"bandwidth": 0.45,
"attenuation": 60,
"filter_bank_size": 64
}
},
"audible-7k-channel-0": {
"mod_scheme": "arb16opt",
"checksum_scheme": "crc32",
"inner_fec_scheme": "rs8",
"outer_fec_scheme": "v29",
"frame_length": 600,
"modulation": {
"center_frequency": 9200,
"gain": 0.1
},
"interpolation": {
"shape": "kaiser",
"samples_per_symbol": 6,
"symbol_delay": 4,
"excess_bandwidth": 0.31
},
"encoder_filters": {
"dc_filter_alpha": 0.01
},
"resampler": {
"delay": 13,
"bandwidth": 0.45,
"attenuation": 60,
"filter_bank_size": 64
},
"ofdm": {
"num_subcarriers": 48,
"cyclic_prefix_length": 8,
"taper_length": 4,
"left_band": 0,
"right_band": 0
}
},
"audible-7k-channel-1": {
"mod_scheme": "arb16opt",
"checksum_scheme": "crc32",
"inner_fec_scheme": "rs8",
"outer_fec_scheme": "v29",
"frame_length": 600,
"modulation": {
"center_frequency": 15500,
"gain": 0.1
},
"interpolation": {
"shape": "kaiser",
"samples_per_symbol": 6,
"symbol_delay": 4,
"excess_bandwidth": 0.31
},
"encoder_filters": {
"dc_filter_alpha": 0.01
},
"resampler": {
"delay": 13,
"bandwidth": 0.45,
"attenuation": 60,
"filter_bank_size": 64
},
"ofdm": {
"num_subcarriers": 48,
"cyclic_prefix_length": 8,
"taper_length": 4,
"left_band": 0,
"right_band": 0
}
},
"cable-64k": {
"mod_scheme": "qam1024",
"checksum_scheme": "crc32",
"inner_fec_scheme": "v27p23",
"outer_fec_scheme": "rs8",
"frame_length": 7500,
"modulation": {
"center_frequency": 10200,
"gain": 0.09
},
"interpolation": {
"shape": "kaiser",
"samples_per_symbol": 2,
"symbol_delay": 4,
"excess_bandwidth": 0.35
},
"encoder_filters": {
"dc_filter_alpha": 0.03
},
"resampler": {
"delay": 13,
"bandwidth": 0.45,
"attenuation": 60,
"filter_bank_size": 64
},
"ofdm": {
"num_subcarriers": 128,
"cyclic_prefix_length": 16,
"taper_length": 8,
"left_band": 6,
"right_band": 12
}
},
"hello-world": {
"mod_scheme": "gmsk",
"checksum_scheme": "crc32",
"inner_fec_scheme": "v27",
"outer_fec_scheme": "none",
"frame_length": 25,
"modulation": {
"center_frequency": 4400,
"gain": 0.08
},
"interpolation": {
"shape": "kaiser",
"samples_per_symbol": 20,
"symbol_delay": 4,
"excess_bandwidth": 0.38
},
"encoder_filters": {
"dc_filter_alpha": 0.01
},
"resampler": {
"delay": 13,
"bandwidth": 0.45,
"attenuation": 60,
"filter_bank_size": 64
}
},
"ultrasonic": {
"mod_scheme": "gmsk",
"checksum_scheme": "crc32",
"inner_fec_scheme": "v27",
"outer_fec_scheme": "none",
"frame_length": 75,
"modulation": {
"center_frequency": 19000,
"gain": 0.1
},
"interpolation": {
"shape": "rrcos",
"samples_per_symbol": 14,
"symbol_delay": 4,
"excess_bandwidth": 0.35
},
"encoder_filters": {
"dc_filter_alpha": 0.01
},
"resampler": {
"delay": 13,
"bandwidth": 0.45,
"attenuation": 60,
"filter_bank_size": 64
}
},
"ultrasonic-3600": {
"ofdm": {
"num_subcarriers": 64,
"cyclic_prefix_length": 20,
"taper_length": 8,
"left_band": 4,
"right_band": 13
},
"mod_scheme": "V29",
"checksum_scheme": "crc8",
"inner_fec_scheme": "v27",
"outer_fec_scheme": "none",
"frame_length": 550,
"modulation": {
"center_frequency": 18500,
"gain": 0.1
},
"interpolation": {
"shape": "kaiser",
"samples_per_symbol": 7,
"symbol_delay": 4,
"excess_bandwidth": 0.33
},
"encoder_filters": {
"dc_filter_alpha": 0.01
},
"resampler": {
"delay": 13,
"bandwidth": 0.45,
"attenuation": 60,
"filter_bank_size": 64
}
},
"ultrasonic-whisper": {
"mod_scheme": "gmsk",
"checksum_scheme": "crc32",
"inner_fec_scheme": "v27",
"outer_fec_scheme": "none",
"frame_length": 16,
"modulation": {
"center_frequency": 19500,
"gain": 0.1
},
"interpolation": {
"shape": "rrcos",
"samples_per_symbol": 30,
"symbol_delay": 4,
"excess_bandwidth": 0.35
},
"encoder_filters": {
"dc_filter_alpha": 0.01
},
"resampler": {
"delay": 13,
"bandwidth": 0.45,
"attenuation": 60,
"filter_bank_size": 64
}
},
"ultrasonic-experimental": {
"mod_scheme": "bpsk",
"checksum_scheme": "crc32",
"inner_fec_scheme": "rs8",
"outer_fec_scheme": "v29",
"frame_length": 100,
"modulation": {
"center_frequency": 19000,
"gain": 0.2
},
"interpolation": {
"shape": "kaiser",
"samples_per_symbol": 10,
"symbol_delay": 4,
"excess_bandwidth": 0.31
},
"encoder_filters": {
"dc_filter_alpha": 0.01
},
"resampler": {
"delay": 13,
"bandwidth": 0.45,
"attenuation": 60,
"filter_bank_size": 64
},
"header": {
"checksum_scheme": "crc32",
"inner_fec_scheme": "secded7264",
"outer_fec_scheme": "v29",
"mod_scheme": "bpsk"
}
}
}
Loading