├── .gitignore ├── LICENSE ├── README.md ├── ask_modulate_radio_signal.py ├── audio_signal_generation.ipynb ├── auto_crop.ipynb ├── auto_crop_signal.py ├── fsk_modem_research.ipynb ├── fsk_modem_research2.ipynb ├── images ├── aprs_close.png ├── generated_wave_superwave.png ├── generated_wave_zoomedin.png ├── generated_wave_zoomedin2.png ├── original_radio_signal.png ├── original_wave_superwave.png ├── original_wave_zoomedin.png ├── preamble_audacity.png ├── recorded_vs_generated.png └── remodulated_aprs_signal_phase_good.png ├── radio_signal_generation.ipynb ├── raw_data ├── Sine_curve_drawing_animation.gif ├── a440.wav ├── aprs_pocket_packet.wav ├── aprs_pocket_packet2.wav ├── c_major_scale.wav ├── c_major_scale_harmonics.wav ├── generated_sig1.pcm ├── generated_sig2.pcm ├── generated_sig3.pcm ├── outlet_c1_off.json ├── outlet_c1_on.json ├── outlet_c2_off.json ├── outlet_c2_on.json ├── preamble_part_2.wav ├── remodulated_test_44100.wav └── remote_1_on_raw.pcm └── raw_signal_to_crop.pcm /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | local_settings.py 55 | 56 | # Flask stuff: 57 | instance/ 58 | .webassets-cache 59 | 60 | # Scrapy stuff: 61 | .scrapy 62 | 63 | # Sphinx documentation 64 | docs/_build/ 65 | 66 | # PyBuilder 67 | target/ 68 | 69 | # IPython Notebook 70 | .ipynb_checkpoints 71 | 72 | # pyenv 73 | .python-version 74 | 75 | # celery beat schedule file 76 | celerybeat-schedule 77 | 78 | # dotenv 79 | .env 80 | 81 | # virtualenv 82 | venv/ 83 | ENV/ 84 | 85 | # Spyder project settings 86 | .spyderproject 87 | 88 | # Rope project settings 89 | .ropeproject 90 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Caleb Madrigal 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # radio-hacking-scripts 2 | Scripts to aid in the manipulation of electromagnetic radiation (in conjunction with gnu_radio and SDR). 3 | -------------------------------------------------------------------------------- /ask_modulate_radio_signal.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import json 3 | import argparse 4 | import numpy as np 5 | 6 | SAMPLE_BITSIZE = 16 7 | MAX_AMP_16BIT = int(2**SAMPLE_BITSIZE/2 - 1) 8 | 9 | DEFAULT_RATIOS = { 10 | '_': 1, 11 | '0': 1, 12 | '1': 3 13 | } 14 | 15 | DEFAULT_AMP_MAP = { 16 | 'LOW': MAX_AMP_16BIT * .02, 17 | 'HIGH': MAX_AMP_16BIT 18 | } 19 | 20 | 21 | def get_modulation_array(binary_data, sample_rate, baud, sig_ratios, amp_map, dtype=np.int16): 22 | data_points_in_bit = int(sample_rate * 1/baud) 23 | modulation_array = np.array([], dtype=dtype) 24 | 25 | # To describe this general algorithms, I'll use the specific concrete pulse ratios: 26 | # '_': 1, 27 | # '0': 1, 28 | # '1': 3 29 | # Meaning that a "1" should be 3x longer than a "0" or a "space" pulse. Now since we need a space 30 | # between "1"s (as well as "0"), we can calculate that the pulse for a "1" should be 3/4 of the bit 31 | # and the pulse for a "0" should be 1/4 of the bit (since for the 1, it's 3 parts "1" and 1 part "space") 32 | one_pulse_len = int((sig_ratios['1'] / (sig_ratios['1'] + sig_ratios['_'])) * data_points_in_bit) 33 | one_space_len = data_points_in_bit - one_pulse_len 34 | zero_pulse_len = int((sig_ratios['0'] / (sig_ratios['1'] + sig_ratios['_'])) * data_points_in_bit) 35 | zero_space_len = data_points_in_bit - zero_pulse_len 36 | 37 | modulated_one_bit = np.append(np.full(one_pulse_len, amp_map['HIGH'], dtype=dtype), 38 | np.full(one_space_len, amp_map['LOW'], dtype=dtype)) 39 | modulated_zero_bit = np.append(np.full(zero_pulse_len, amp_map['HIGH'], dtype=dtype), 40 | np.full(zero_space_len, amp_map['LOW'], dtype=dtype)) 41 | 42 | for bit in binary_data: 43 | modulated_bit = modulated_one_bit if bit == '1' else modulated_zero_bit 44 | modulation_array = np.append(modulation_array, modulated_bit) 45 | return modulation_array 46 | 47 | def generate_on_off_key_signal(binary_data, carrier_wave_freq, sample_rate, 48 | baud, sig_ratios=DEFAULT_RATIOS, amp_map=DEFAULT_AMP_MAP, dtype=np.int16): 49 | signal_len_secs = len(binary_data) * (1/baud) 50 | t = np.linspace(0, signal_len_secs, sample_rate * signal_len_secs) 51 | 52 | # Using Euler's formula to generate a complex sinusoidal wave 53 | carrier_wave = 1 * np.e**(carrier_wave_freq * 2 * np.pi * (0+1j) * t) 54 | modulation_array = get_modulation_array(binary_data, sample_rate, baud, sig_ratios, amp_map, dtype) 55 | 56 | # Pad (or trim) the modulation array to match the length of the carrier wave 57 | if len(carrier_wave) > len(modulation_array): 58 | pad_len = len(carrier_wave) - len(modulation_array) 59 | modulation_array = np.append(modulation_array, np.full(pad_len, amp_map['LOW'], dtype=dtype)) 60 | elif len(carrier_wave) < len(modulation_array): 61 | modulation_array = modulation_array[:len(carrier_wave)] 62 | 63 | # Modulate by superwave 64 | super_wave_freq = carrier_wave_freq / (160*2) 65 | super_wave = 1 * np.e**(super_wave_freq * 2 * np.pi * (0+1j) * t) 66 | 67 | return t, carrier_wave * modulation_array * super_wave 68 | 69 | 70 | def generate_pulse(bit_val, carrier_wave_freq, sample_rate, baud, multiple_of_bit_len, 71 | amp_map=DEFAULT_AMP_MAP, dtype=np.int16): 72 | signal_len_secs = multiple_of_bit_len * (1/baud) 73 | t = np.linspace(0, signal_len_secs, sample_rate * signal_len_secs) 74 | 75 | high_or_low = 'HIGH' if bit_val == '1' else 'LOW' 76 | pulse = amp_map[high_or_low] * np.e**(carrier_wave_freq * 2 * np.pi * (0+1j) * t) 77 | return t, pulse 78 | 79 | 80 | def join_all_arrays(array_list): 81 | joined = array_list[0] 82 | for a in array_list[1:]: 83 | joined = np.append(joined, a) 84 | return joined 85 | 86 | 87 | def write_pcm_file(signal_data, file_path, dtype='complex64'): 88 | np.array(signal_data).astype(dtype).tofile(file_path) 89 | 90 | 91 | def ask_modulate_radio_signal(bit_str, freq, baud, sample_rate, amp_map, repeat_times=12, header_len=4, header_value='1', space_len=4): 92 | t, complex_signal = generate_on_off_key_signal(bit_str, freq, sample_rate, baud, amp_map=amp_map, dtype='complex64') 93 | t2, signal_header = generate_pulse(header_value, freq, sample_rate, baud, header_len, amp_map=amp_map, dtype='complex64') 94 | t3, signal_spacer = generate_pulse('0', freq, sample_rate, baud, space_len, amp_map=amp_map, dtype='complex64') 95 | return join_all_arrays([signal_header] + ([complex_signal, signal_spacer] * repeat_times)) 96 | 97 | 98 | def parse_config_file(config_path): 99 | """ Loads config file like this: 100 | {'bit_str': '0110100000100000', 101 | 'freq': 315000000, 102 | 'baud': 410, 103 | 'sample_rate': 2000000, 104 | 'amp_map': {'LOW': 0.28, 'HIGH': 1.4}, 105 | 'header_len': 3.85, 106 | 'space_len': 3.78 107 | } 108 | """ 109 | with open(config_path, 'r') as f: 110 | config_dict = json.load(f) 111 | return config_dict 112 | 113 | 114 | if __name__ == '__main__': 115 | parser = argparse.ArgumentParser() 116 | parser.add_argument('-c', '--config', type=str, dest='config', required=True, help='Config file path') 117 | parser.add_argument('-o', '--out', type=str, dest='outfile', required=True, help='Output file path') 118 | args = parser.parse_args() 119 | 120 | config = parse_config_file(args.config) 121 | 122 | signal = ask_modulate_radio_signal(**config) 123 | write_pcm_file(signal, args.outfile, dtype='complex64') 124 | 125 | -------------------------------------------------------------------------------- /auto_crop.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Auto Crop signal\n", 8 | "\n", 9 | "Usually, when recording either radio waves or sound waves, you start recording, the signal comes, and then, as the slow human being that you are (slow relative to computers), you stop recording a while after the signal transmission completed.\n", 10 | "\n", 11 | "But usually, you just want the signal and don't care about the surrounding dead air/noise.\n", 12 | "\n", 13 | "To this end, let's develop an algorithm to auto-crop the signal of interest. We will do this by:\n", 14 | "* breaking the signal into 16 chunks\n", 15 | "* calculating the power in each chunk\n", 16 | "* finding where the largest increase in power happens\n", 17 | "* finding where the largest decrease in power happens\n", 18 | "* saving only the portion between the largest power increase in decrease\n", 19 | "\n", 20 | "Since this is mostly meant for use with radio signals, we will experiment with a radio signal in the [PCM](https://en.wikipedia.org/wiki/Pulse-code_modulation) [raw wave format](https://en.wikipedia.org/wiki/Raw_audio_format) - which is essentially the same as a [WAV](https://en.wikipedia.org/wiki/WAV) file without the headers.\n", 21 | "\n", 22 | "# Graphing boilerplate code" 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "execution_count": 1, 28 | "metadata": { 29 | "collapsed": true 30 | }, 31 | "outputs": [], 32 | "source": [ 33 | "%matplotlib inline\n", 34 | "import matplotlib.pyplot as plt\n", 35 | "import numpy as np\n", 36 | "import scipy\n", 37 | "#import scipy.io.wavfile\n", 38 | "\n", 39 | "def setup_graph(title='', x_label='', y_label='', fig_size=None):\n", 40 | " fig = plt.figure()\n", 41 | " if fig_size != None:\n", 42 | " fig.set_size_inches(fig_size[0], fig_size[1])\n", 43 | " ax = fig.add_subplot(111)\n", 44 | " ax.set_title(title)\n", 45 | " ax.set_xlabel(x_label)\n", 46 | " ax.set_ylabel(y_label)" 47 | ] 48 | }, 49 | { 50 | "cell_type": "markdown", 51 | "metadata": {}, 52 | "source": [ 53 | "# Auto crop algorithm" 54 | ] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "execution_count": 2, 59 | "metadata": { 60 | "collapsed": true 61 | }, 62 | "outputs": [], 63 | "source": [ 64 | "def auto_crop_signal(signal_data, margin_percent=1, num_chunks=16):\n", 65 | " \"\"\" Break the signal into chunks, and find the chunk there is the largest\n", 66 | " jump from quiet to loud (start index), and the largest jump from \n", 67 | " loud to quiet (stop index). \"\"\"\n", 68 | " chunk_size = int(len(signal_data) / num_chunks)\n", 69 | " largest_increase_index = 0\n", 70 | " largest_increase_size = -999999999\n", 71 | " largest_decrease_index = chunk_size * num_chunks\n", 72 | " largest_decrease_size = 999999999\n", 73 | " last_chunk_sum = sum([abs(i) for i in signal_data[0:chunk_size]])\n", 74 | " for chunk_start in range(0, len(signal_data), chunk_size):\n", 75 | " chunk = signal_data[chunk_start:chunk_start+chunk_size]\n", 76 | " # Don't consider the last chunk if it's not a full chunk,\n", 77 | " # since that will likely yield the smallest sum\n", 78 | " if len(chunk) < chunk_size:\n", 79 | " continue\n", 80 | " chunk_sum = sum([abs(i) for i in chunk])\n", 81 | " chunk_diff = chunk_sum - last_chunk_sum\n", 82 | " last_chunk_sum = chunk_sum\n", 83 | " if chunk_diff > largest_increase_size:\n", 84 | " largest_increase_size = chunk_diff\n", 85 | " largest_increase_index = chunk_start\n", 86 | " if chunk_diff < largest_decrease_size:\n", 87 | " largest_decrease_size = chunk_diff\n", 88 | " largest_decrease_index = chunk_start\n", 89 | " margin = int((largest_decrease_index - largest_increase_index) * (margin_percent / 100))\n", 90 | " return signal_data[largest_increase_index-margin:largest_decrease_index+margin]\n" 91 | ] 92 | }, 93 | { 94 | "cell_type": "markdown", 95 | "metadata": {}, 96 | "source": [ 97 | "# Read in PCM file" 98 | ] 99 | }, 100 | { 101 | "cell_type": "code", 102 | "execution_count": 3, 103 | "metadata": { 104 | "collapsed": false 105 | }, 106 | "outputs": [], 107 | "source": [ 108 | "in_signal = scipy.fromfile(open('raw_signal_to_crop.pcm'), dtype=scipy.complex64)" 109 | ] 110 | }, 111 | { 112 | "cell_type": "code", 113 | "execution_count": 4, 114 | "metadata": { 115 | "collapsed": false 116 | }, 117 | "outputs": [ 118 | { 119 | "name": "stderr", 120 | "output_type": "stream", 121 | "text": [ 122 | "/usr/local/lib/python3.5/site-packages/numpy/core/numeric.py:482: ComplexWarning: Casting complex values to real discards the imaginary part\n", 123 | " return array(a, dtype, copy=False, order=order)\n" 124 | ] 125 | }, 126 | { 127 | "data": { 128 | "text/plain": [ 129 | "[]" 130 | ] 131 | }, 132 | "execution_count": 4, 133 | "metadata": {}, 134 | "output_type": "execute_result" 135 | }, 136 | { 137 | "data": { 138 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAY8AAAEACAYAAABLfPrqAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAFVhJREFUeJzt3X+sHWWdx/HPtxSWiLH8iFwrhQItViVCl2VrSREvQrGw\nq/gTy5oUkFXE7e4S1ggkJi2RP0SzCRAVwa1Cm2hLCEurWAQCF1KyxabQpSItBRRKvZaCgkJXqOW7\nf8zc3nPPr3bOmTvPMzPvV3LSmefMzPPMc+c8n3Nm5pyauwsAgCwmhG4AAKB8CA8AQGaEBwAgM8ID\nAJAZ4QEAyIzwAABklkt4mNkSM9tuZo93WeYGM9tiZhvMbGYe9QIAwsjrk8ePJH2005Nmdrakae5+\nnKRLJH0/p3oBAAHkEh7uvkbSH7sscq6kpemyj0iaZGYDedQNACheUdc8jpC0tWF+W1oGACghLpgD\nADKbWFA92yQd2TA/JS1rYWb82BYAZOTuVmR9eX7ysPTRzipJCyTJzGZLesXdt3fakLvzcNeiRYuC\nt2FfH1JvD3fX+efvbblFLevMnp29nsmTs69zzjnZ1znzzOzrHH/8vi6/aM86J5+cvZ7TTsu+zsUX\nZ1/n85/vv54qvT7G//VXvFw+eZjZjyUNSjrMzJ5XcoQfIMnd/WZ3/7mZnWNmT0t6XdJFedQLAAgj\nl/Bw93/ah2UW5lEXACA8LphHbHBwMHQTIjEYugERGQzdgGjw+giL8IgYL44Rg6EbEJHB0A2IBq+P\nsAgPAEBmhAcAIDPCA8EFutMQQB8IDwS3enXoFgDIivBAcDt3hm4BgKwIDwBAZoQHACAzwgMAkBnh\nAQDIjPAAAGRGeAAAMiM8AACZER4AgMwIDwBAZoQHACAzwgO1wQ8wAvkhPAAAmREeCI5PBED5EB4A\ngMwIDwBAZoQHEAFO3aFsCA+UUlGDLYM60B7hgVJiUAfCIjwQXNWCoGr7A7RDeAA5izk8Ym4byoXw\nAGqE8EBeCA+gpHoJgqLWQfURHkAEYh7Uq1YP8kF4oDYYoHtDH6AdwgO1EfPgRNtQNoQHaoNBEMgP\n4YFSivlUCiFFH9QB4YHgYh6gY25bzOiD6iM8EFzVBuiY21YU+qD6CA8AQGaEB2qDd8P0AfJDeABd\nPPRQ6BaUEyFVfYQH0MVf/hK6BeVUtetYaEV4AIgC4VEuhAdQUgy2CInwQHAMgr2h3xAS4QEAyIzw\nAABkRngAADIjPAB0xbUVtJNLeJjZPDPbZGZPmdkVbZ7/sJm9YmaPpo+v51EvACCMif1uwMwmSPqO\npDMk/U7SOjNb6e6bmhZ9yN0/3m99QBXx7h5lk8cnj1mStrj7c+6+S9JySee2Wc5yqAsAEIE8wuMI\nSVsb5l9Iy5qdYmYbzOwuM3t/DvWixninDoTV92mrfbRe0lHuvtPMzpZ0p6T3dFp48eLFe6YHBwc1\nODg43u1DyRAexVm/PnQL0GxoaEhDQ0NB25BHeGyTdFTD/JS0bA93f61herWZfc/MDnX3P7TbYGN4\nAAhreDh0C9Cs+U311VdfXXgb8jhttU7SdDObamYHSJovaVXjAmY20DA9S5J1Cg4AQPz6/uTh7rvN\nbKGke5SE0RJ3f9LMLkme9pslfcbMLpW0S9L/Sfpcv/UCseKUGuogl2se7n63pBlNZTc1TH9X0nfz\nqAuIHeGBOuAb5kCNEGzIC+EB1AjhgbwQHqgNBk4gP4QHUCMEKPJCeAAlVVQQEDhoh/AASopBHSER\nHiilrVv3vkyZxBwEfMJBO4QHSumll0K3IF8MnK19QJ/EjfAA0BWDONohPFAbnH7pTdX2B/kgPFAb\nb71VTD1r1mRfhwG6FX0SN8IDAJAZ4QEAyIzwAJA7TjlVH+EBIEoEUNwIDwC5Y+CvPsIDQBQInHIh\nPABE4cEHx84TJnEjPIAIMFBKO3eGbgGyIDwA5I4wrD7CA0Du8vjVYwIoboQHgNxt3Bi6BRhvhAdq\ng3eyQH4ID6BGyhSgZWprHREeAHLHwF99hAeA3BEe1Ud4AAAyIzwARKH5P+vi00vcCA8AUSAsyoXw\nAABkRnigNor6P8xjVqZ392Vqax0RHqiNqg1GvexP1foA4RAeqA2z0C3IF0GAkAgPAFEiHONGeAAA\nMiM8gJIq6ppH1U73IR+EBxCBXgboJ57Ivg6ngpAXwgOIwDPPFFPPo48WU08eCLq4ER6ojTfeCN0C\noDoID9TGm2+GbkE5FXXNg08a5UJ4AOiqqEG9uR7CJG6EBwAgM8IDQFd8AkA7hAeArkKFB6EVN8Kj\nInbtktauDd0KxGzjxtAtQJWUIjyWLEnu+Gh+JzJ1qvSRj0h33DFa9swz0gMPjM5v2yadd550001j\n133zzWSbX/yi9OKLSdmNN0rLlrXWf8st0l//um9t/cEPpFNPHf3571WrpAcflNasGV3mxhulW28d\nu97q1dKll0qf/vRo2QsvSNdfL02bJn3jG9JrryXb/dSnkrY//PDositWSKecIg0Pj5a5J8tdccXY\nupYta73zaPdu6Uc/at1vM+mEE6Tnnhtd7itfkS67LNxPnDe3c7x88pPF1NN4vI6nE04opp5eDA21\nL1+7Vrr8cmnlSmnHjtHyCy9MXkfPPjtadscd0owZyfQPfzh6fG7eLF10UfvtX3ONdNddyfSf/iTd\ndpt0ySUE7T5x96gekjwZ9jo/Xn65tWznTvdvf3ts2dKlrcu5u3/hC63lt93WWnbnnWPnly1L1p85\nc2z5E0+4r1jRuv5VV42dnzs3Wb95udtvby2bP999zpzW8rVrx84vWdK+j559tv26H/jA6Pz++7v/\n9KfuX/3q2OW+9jX3++9v36YpU8aWXXaZ+8c/3v3v1e3x0ku9r5vl0fy3HK/HT35STD0LFhRTz5o1\nxdTT7vH8861l7u6vvz627LTT2r+uJPd588bOb9jgftRRrcu1e/22e7z+ukcpGcqLHastqbc/ZjZP\n0nVKPskscfdr2yxzg6SzJb0u6UJ339BhWy713yYAyNuZZ0r33hu6Fa3MTO5e6K+Q9R0eZjZB0lOS\nzpD0O0nrJM13900Ny5wtaaG7/4OZfVDS9e4+u8P2CA8A0crh/XbuQoRHHtc8Zkna4u7PufsuScsl\nndu0zLmSlkqSuz8iaZKZDeRQNwAggDzC4whJWxvmX0jLui2zrc0yAICSmBi6Ae0tbpgeTB8AAEka\nGhrSUKdb1AqSxzWP2ZIWu/u8dP5KJVf+r21Y5vuSHnD3Fen8JkkfdvftbbbHNQ8A0eKaRyKP01br\nJE03s6lmdoCk+ZJWNS2zStICaU/YvNIuOAAA5dD3aSt3321mCyXdo9FbdZ80s0uSp/1md/+5mZ1j\nZk8ruVW3w1d2ACBeH/tY6BbEI5dvmLv73e4+w92Pc/dvpmU3ufvNDcssdPfp7n6iu5fo/zPrzfHH\n97f+ddfl0469Wbq0v/U7fXMXCG122y8D9IfjvUHR30rc20NKvmE+PDz6jdJDDx39hueWLY3fqkwe\nO3a0lo2s21jWTHLfuHF0fu7cpOyYY0bLmr9RLbmfd15rPevXJ9Onntpax8jjjTday4eHx5ZdfPHo\n/PLlSdnu3e33R3L/9a+Tb9ePzH/rW2OXmz69c3tuuKF7vzWWL1yYzG/e3Lrc6afv27dz2z2a6x6v\nB/W433KL+zveUUz78tgfd/cPfWhs2UMPJeUjvzIx8u3yxvXvuy+Zf/rp1m0eeGDn4715vtvrIjbJ\nUF7wWF10hXttUIR/pbvu6v3gefjhZN0//znfNq1cmfxERS+uuSb5KZc8FTkIFrXOwEAx9Zx4YnF9\nMGlStnW+/OXs9Vx2WW9ta+7vRlOnuu+3X37H65e+lNTx8sv5bTOkEOGRy8+T5MnMPLY2Ye96/a9K\n3bOvyzrJOhMnJj9UmWWdgw+WXn11/NvWyzonnyytXz+2DPumrHdbASiJogbk444rph6EQ3gAyN2B\nB4ZuAcYb4QHk7OCDQ7cAGH+EB0qp12ssRSiqbTH3AaqP8ABqpJfA4ZMU2iE8gBrp5YL59OnZ1+FT\nUfURHgCAzAgPoIvDDgvdgs5ifnffyyecmPcHrQgPoAtuOS0O4VEuhAeArnoZ1PnkUX2EBwAgM8ID\nQBT4LatyITwA5K6oU10Ih/AAEAWueZQL4QEAyIzwAHLGb1uhDggPAEBmhAcAIDPCA6XEKRvuTkJY\nhAcAIDPCA0Du+GRYfYQHSolTNsUhCNAO4QHkrGqDbdX2B/kgPFBKEzhye0IQIC+8BFFK++0XugVA\nvREeQBe8UwfaIzwQXNVOQRE4qIOKvWxRRgMD2ddhgAbCIjwQHEHQm6r9ACPHQbkQHgjuwANDt6Az\nBjSgPcIDwcU8QMfcNiAkwgPB9TJAxzyox9w2IC+EB4KLebCNOdhi7jdUH+EB1AiBg7wQHgByR0hV\nH+EBIHeER/URHkCNxDyox9w2tCI8gJzFPAjG3DaUC+EBIHeEVPURHgCAzAgPoKSq9u6+avtTdYQH\ngK740iPaITwAAJkRHkAX7qFbAMRpYj8rm9khklZImirpt5LOc/dX2yz3W0mvSnpL0i53n9VPvQCA\nsPr95HGlpPvcfYak+yVd1WG5tyQNuvvfEhxAPrhGgJD6DY9zJd2aTt8q6RMdlrMc6gL2YOAEwup3\nQD/c3bdLkrv/XtLhHZZzSfea2Toz+2KfdQKERwXxNy2XvV7zMLN7JQ00FikJg6+3WbzT5cU57j5s\nZu9UEiJPuvuaTnUuXrx4z/Tg4KAGBwf31kyUGING9fA3HV9DQ0MaGhoK2oa9hoe7z+30nJltN7MB\nd99uZu+S9GKHbQyn/+4ws/+WNEvSPoUHUDYMnBhvzW+qr7766sLb0O9pq1WSLkynL5C0snkBM3ub\nmb09nT5I0lmSftVnvQB6QLAhL/2Gx7WS5prZZklnSPqmJJnZZDP7WbrMgKQ1ZvaYpLWSfuru9/RZ\nLwAgoL6+5+Huf5B0ZpvyYUn/mE7/RtLMfuoBAMSF22dRG9OmhW5BOXGqC+0QHqiNyZNDtyBfvQzq\nBAHyQngAADIjPIAuYn6nHnPbUH2EBwAgM8IDQO74VFR9hAcQgRNPDN2C8AicciE8gJz1Mggec0z+\n7QDGE+EBlFQvIXX66fm3A/VEeAARKOqUzUEHZV+H00loh/BAbcQ8CNI2lA3hgdqo2iA4ZUroFqDO\nCA+gi5gD56STQrcAdUZ4ILiYf6Mp5vCoGvq6XAgPBDch4qMw5mADQor4ZYu6qNoAHXPbgLwQHkCN\nEGzIC+EB1AjXipAXwgOoEcIDeSE8gJKqWhAQOOVCeKA2GJzixt+nXAgP1EbMg1PMbQPaITxQSlUb\nbKt2uzKqj/BAKTFwxo2/T/URHkDOYh44Y24byoXwAABkRngAJcUttAiJ8AC6iHngjLltqD7CA0Du\nuHus+ggPIGcMgqgDwgMAkBnhAQDIjPAAEAVO95UL4QEAyIzwAABkRngAADIjPAAAmREeAHI3aVLo\nFmC8ER4AcjdnTugWYLwRHgCicOyxoVuALAgPAFGYMSN0C5AF4QEAyIzwAABkRngAADIjPAAAmREe\nAIDM+goPM/uMmf3KzHab2UldlptnZpvM7Ckzu6KfOoHYcdcQ6qDfTx4bJX1S0oOdFjCzCZK+I+mj\nko6XdL6ZvbfPemthaGgodBMiMRS6AZm8733jufWh8dx4qfD6CKuv8HD3ze6+RVK3X+KfJWmLuz/n\n7rskLZd0bj/11gUvjhFDoRsQkaHQDYgGr4+wirjmcYSkrQ3zL6RlQM/mzQvdAqDe9hoeZnavmT3e\n8NiY/vuxIhqI6uvlZyne857s6xx9dPZ1pk3Lvs7kydnXOfLI7Osc0cNbsHe/O/s6vfTb4YdnX+ed\n78y+DsIxd+9/I2YPSPoPd3+0zXOzJS1293np/JWS3N2v7bCt/hsEADXj7oX+R74Tc9xWp4avkzTd\nzKZKGpY0X9L5nTZSdAcAALLr91bdT5jZVkmzJf3MzFan5ZPN7GeS5O67JS2UdI+kJyQtd/cn+2s2\nACCkXE5bAQDqJZpvmFfpi4Rm9lsz+18ze8zMfpmWHWJm95jZZjP7hZlNalj+KjPbYmZPmtlZDeUn\npTcnPGVm1zWUH2Bmy9N1/sfMjmp47oJ0+c1mtqCofW6of4mZbTezxxvKgu67mR1tZmvT535iZnme\nru2oQ18sMrMXzOzR9DGv4bkq98UUM7vfzJ5Ib7r5t7S8dsdGm77417S8XMeGuwd/KAmxpyVNlbS/\npA2S3hu6XX3sz7OSDmkqu1bS19LpKyR9M51+v6THlFx/Ojrth5FPhI9I+vt0+ueSPppOXyrpe+n0\n55ScCpSkQyQ9I2mSpINHpgve91MlzZT0eCz7LmmFpM+m0zdKuiRgXyySdHmbZd9X8b54l6SZ6fTb\nJW2W9N46Hhtd+qJUx0Zhg8peOnO2pNUN81dKuiJ0u/rYn99IOqypbJOkgYaDZ1O7fZW0WtIH02V+\n3VA+X9KN6fTdkj6YTu8n6cXmZRoOgM8F2P+pGjtgBt13STskTWg41u4O2BeLlNyZ2Lxc5fuiaX/v\nlHRmnY+Npr44o2zHRiynrar2RUKXdK+ZrTOzf07LBtx9uyS5++8ljdwJ37zv29KyI5T0w4jGPtmz\njic3JLxqZod22VZoh4fadzM7TNIf3f2thm318G2HXC00sw1m9l8Np2lq0xdmdrSST2RrFfB1EUN/\nNPTFI2lRaY6NWMKjaua4+0mSzpH0L2b2ISWB0ijPOxXKdntz0fseU/98T9Kx7j5T0u8l/WeO246+\nL8zs7ZJul/Tv7v6awr8ugvVHm74o1bERS3hsk3RUw/yUtKyU3H04/XeHko+ksyRtN7MBSTKzd0l6\nMV18m6TG7xeP7Hun8jHrmNl+kt7h7n9QvP0YbN/d/WVJkyz5gc7mbRXO3Xd4el5A0g+UHBtSDfoi\nvQB7u6Rl7r4yLa7lsdGuL8p2bMQSHnu+SGhmByg5L7cqcJt6YmZvS99RyMwOknSWkl8fXiXpwnSx\nCySNvHhWSZqf3h1xjKTpkn6ZfoR/1cxmmZlJWtC0zgXp9Gcl3Z9O/0LSXDObZGaHSJqblhXNNPZd\nTOh9fyBdtrn+Iozpi3SAHPEpSb9Kp+vQFz9Uco7++oayuh4bLX1RumOj6ItDXS4azVNy18EWSVeG\nbk8f+3GMkrvFHlMSGlem5YdKui/dx3skHdywzlVK7qB4UtJZDeV/l25ji6TrG8r/RtJtaflaSUc3\nPHdhWv6UpAUB9v/Hkn4n6Q1Jz0u6SMkdHsH2Pf2bPJKWr5C0f8C+WCrp8fQYuVPpxeIa9MUcSbsb\nXhuPpq/5oK+LEP3RpS9KdWzwJUEAQGaxnLYCAJQI4QEAyIzwAABkRngAADIjPAAAmREeAIDMCA8A\nQGaEBwAgs/8H0GvUjWYRfSMAAAAASUVORK5CYII=\n", 139 | "text/plain": [ 140 | "" 141 | ] 142 | }, 143 | "metadata": {}, 144 | "output_type": "display_data" 145 | } 146 | ], 147 | "source": [ 148 | "plt.plot(in_signal)" 149 | ] 150 | }, 151 | { 152 | "cell_type": "code", 153 | "execution_count": 5, 154 | "metadata": { 155 | "collapsed": false 156 | }, 157 | "outputs": [], 158 | "source": [ 159 | "cropped_sig = auto_crop_signal(in_signal)" 160 | ] 161 | }, 162 | { 163 | "cell_type": "code", 164 | "execution_count": 6, 165 | "metadata": { 166 | "collapsed": false 167 | }, 168 | "outputs": [ 169 | { 170 | "name": "stderr", 171 | "output_type": "stream", 172 | "text": [ 173 | "/usr/local/lib/python3.5/site-packages/numpy/core/numeric.py:482: ComplexWarning: Casting complex values to real discards the imaginary part\n", 174 | " return array(a, dtype, copy=False, order=order)\n" 175 | ] 176 | }, 177 | { 178 | "data": { 179 | "text/plain": [ 180 | "[]" 181 | ] 182 | }, 183 | "execution_count": 6, 184 | "metadata": {}, 185 | "output_type": "execute_result" 186 | }, 187 | { 188 | "data": { 189 | "image/png": "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\nZYaHJKmy/wd+CHixoF0R3wAAAABJRU5ErkJggg==\n", 190 | "text/plain": [ 191 | "" 192 | ] 193 | }, 194 | "metadata": {}, 195 | "output_type": "display_data" 196 | } 197 | ], 198 | "source": [ 199 | "plt.plot(cropped_sig)" 200 | ] 201 | }, 202 | { 203 | "cell_type": "markdown", 204 | "metadata": {}, 205 | "source": [ 206 | "# Write file" 207 | ] 208 | }, 209 | { 210 | "cell_type": "code", 211 | "execution_count": 7, 212 | "metadata": { 213 | "collapsed": true 214 | }, 215 | "outputs": [], 216 | "source": [ 217 | "def write_pcm_file(signal_data, file_path):\n", 218 | " np.array(signal_data).astype('complex64').tofile(file_path)\n" 219 | ] 220 | }, 221 | { 222 | "cell_type": "code", 223 | "execution_count": 8, 224 | "metadata": { 225 | "collapsed": false 226 | }, 227 | "outputs": [], 228 | "source": [ 229 | "write_pcm_file(cropped_sig, 'cropped_sig.pcm')" 230 | ] 231 | }, 232 | { 233 | "cell_type": "markdown", 234 | "metadata": {}, 235 | "source": [ 236 | "# Verify write worked by reading back in" 237 | ] 238 | }, 239 | { 240 | "cell_type": "code", 241 | "execution_count": 9, 242 | "metadata": { 243 | "collapsed": true 244 | }, 245 | "outputs": [], 246 | "source": [ 247 | "read_cropped = scipy.fromfile(open('cropped_sig.pcm'), dtype=scipy.complex64)" 248 | ] 249 | }, 250 | { 251 | "cell_type": "code", 252 | "execution_count": 10, 253 | "metadata": { 254 | "collapsed": false 255 | }, 256 | "outputs": [ 257 | { 258 | "name": "stderr", 259 | "output_type": "stream", 260 | "text": [ 261 | "/usr/local/lib/python3.5/site-packages/numpy/core/numeric.py:482: ComplexWarning: Casting complex values to real discards the imaginary part\n", 262 | " return array(a, dtype, copy=False, order=order)\n" 263 | ] 264 | }, 265 | { 266 | "data": { 267 | "text/plain": [ 268 | "[]" 269 | ] 270 | }, 271 | "execution_count": 10, 272 | "metadata": {}, 273 | "output_type": "execute_result" 274 | }, 275 | { 276 | "data": { 277 | "image/png": "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\nZYaHJKmy/wd+CHixoF0R3wAAAABJRU5ErkJggg==\n", 278 | "text/plain": [ 279 | "" 280 | ] 281 | }, 282 | "metadata": {}, 283 | "output_type": "display_data" 284 | } 285 | ], 286 | "source": [ 287 | "plt.plot(read_cropped)" 288 | ] 289 | } 290 | ], 291 | "metadata": { 292 | "kernelspec": { 293 | "display_name": "Python 3", 294 | "language": "python", 295 | "name": "python3" 296 | }, 297 | "language_info": { 298 | "codemirror_mode": { 299 | "name": "ipython", 300 | "version": 3 301 | }, 302 | "file_extension": ".py", 303 | "mimetype": "text/x-python", 304 | "name": "python", 305 | "nbconvert_exporter": "python", 306 | "pygments_lexer": "ipython3", 307 | "version": "3.5.1" 308 | } 309 | }, 310 | "nbformat": 4, 311 | "nbformat_minor": 0 312 | } 313 | -------------------------------------------------------------------------------- /auto_crop_signal.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import scipy 3 | import numpy as np 4 | 5 | def read_pcm_file(file_path, file_type=scipy.complex64): 6 | with open(file_path, 'rb') as f: 7 | return scipy.fromfile(f, dtype=file_type) 8 | 9 | def write_pcm_file(file_path, signal_data, file_type='complex64'): 10 | np.array(signal_data).astype('complex64').tofile(file_path) 11 | 12 | def auto_crop_signal(signal_data, margin_percent=5, num_chunks=16): 13 | """ Break the signal into chunks, and find the chunk there is the largest 14 | jump from quiet to loud (start index), and the largest jump from 15 | loud to quiet (stop index). """ 16 | chunk_size = int(len(signal_data) / num_chunks) 17 | largest_increase_index = 0 18 | largest_increase_size = -999999999 19 | largest_decrease_index = chunk_size * num_chunks 20 | largest_decrease_size = 999999999 21 | last_chunk_sum = sum([abs(i) for i in signal_data[0:chunk_size]]) 22 | for chunk_start in range(0, len(signal_data), chunk_size): 23 | chunk = signal_data[chunk_start:chunk_start+chunk_size] 24 | # Don't consider the last chunk if it's not a full chunk, 25 | # since that will likely yield the smallest sum 26 | if len(chunk) < chunk_size: 27 | continue 28 | chunk_sum = sum([abs(i) for i in chunk]) 29 | chunk_diff = chunk_sum - last_chunk_sum 30 | last_chunk_sum = chunk_sum 31 | if chunk_diff > largest_increase_size: 32 | largest_increase_size = chunk_diff 33 | largest_increase_index = chunk_start 34 | if chunk_diff < largest_decrease_size: 35 | largest_decrease_size = chunk_diff 36 | largest_decrease_index = chunk_start 37 | margin = int((largest_decrease_index - largest_increase_index) * (margin_percent / 100)) 38 | return signal_data[largest_increase_index-margin:largest_decrease_index+margin] 39 | 40 | if __name__ == '__main__': 41 | try: 42 | in_file_path = sys.argv[1] 43 | out_file_path = sys.argv[2] 44 | except IndexError: 45 | print('Usage: python auto_crop_signal.py ') 46 | sys.exit(1) 47 | signal_data = read_pcm_file(in_file_path) 48 | cropped_signal = auto_crop_signal(signal_data) 49 | write_pcm_file(out_file_path, cropped_signal) 50 | print('Wrote auto-cropped signal to:', out_file_path) 51 | 52 | -------------------------------------------------------------------------------- /images/aprs_close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calebmadrigal/radio-hacking-scripts/96dc2ea40781c47f73b363fcf8bf789f1faafef0/images/aprs_close.png -------------------------------------------------------------------------------- /images/generated_wave_superwave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calebmadrigal/radio-hacking-scripts/96dc2ea40781c47f73b363fcf8bf789f1faafef0/images/generated_wave_superwave.png -------------------------------------------------------------------------------- /images/generated_wave_zoomedin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calebmadrigal/radio-hacking-scripts/96dc2ea40781c47f73b363fcf8bf789f1faafef0/images/generated_wave_zoomedin.png -------------------------------------------------------------------------------- /images/generated_wave_zoomedin2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calebmadrigal/radio-hacking-scripts/96dc2ea40781c47f73b363fcf8bf789f1faafef0/images/generated_wave_zoomedin2.png -------------------------------------------------------------------------------- /images/original_radio_signal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calebmadrigal/radio-hacking-scripts/96dc2ea40781c47f73b363fcf8bf789f1faafef0/images/original_radio_signal.png -------------------------------------------------------------------------------- /images/original_wave_superwave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calebmadrigal/radio-hacking-scripts/96dc2ea40781c47f73b363fcf8bf789f1faafef0/images/original_wave_superwave.png -------------------------------------------------------------------------------- /images/original_wave_zoomedin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calebmadrigal/radio-hacking-scripts/96dc2ea40781c47f73b363fcf8bf789f1faafef0/images/original_wave_zoomedin.png -------------------------------------------------------------------------------- /images/preamble_audacity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calebmadrigal/radio-hacking-scripts/96dc2ea40781c47f73b363fcf8bf789f1faafef0/images/preamble_audacity.png -------------------------------------------------------------------------------- /images/recorded_vs_generated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calebmadrigal/radio-hacking-scripts/96dc2ea40781c47f73b363fcf8bf789f1faafef0/images/recorded_vs_generated.png -------------------------------------------------------------------------------- /images/remodulated_aprs_signal_phase_good.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calebmadrigal/radio-hacking-scripts/96dc2ea40781c47f73b363fcf8bf789f1faafef0/images/remodulated_aprs_signal_phase_good.png -------------------------------------------------------------------------------- /raw_data/Sine_curve_drawing_animation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calebmadrigal/radio-hacking-scripts/96dc2ea40781c47f73b363fcf8bf789f1faafef0/raw_data/Sine_curve_drawing_animation.gif -------------------------------------------------------------------------------- /raw_data/a440.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calebmadrigal/radio-hacking-scripts/96dc2ea40781c47f73b363fcf8bf789f1faafef0/raw_data/a440.wav -------------------------------------------------------------------------------- /raw_data/aprs_pocket_packet.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calebmadrigal/radio-hacking-scripts/96dc2ea40781c47f73b363fcf8bf789f1faafef0/raw_data/aprs_pocket_packet.wav -------------------------------------------------------------------------------- /raw_data/aprs_pocket_packet2.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calebmadrigal/radio-hacking-scripts/96dc2ea40781c47f73b363fcf8bf789f1faafef0/raw_data/aprs_pocket_packet2.wav -------------------------------------------------------------------------------- /raw_data/c_major_scale.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calebmadrigal/radio-hacking-scripts/96dc2ea40781c47f73b363fcf8bf789f1faafef0/raw_data/c_major_scale.wav -------------------------------------------------------------------------------- /raw_data/c_major_scale_harmonics.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calebmadrigal/radio-hacking-scripts/96dc2ea40781c47f73b363fcf8bf789f1faafef0/raw_data/c_major_scale_harmonics.wav -------------------------------------------------------------------------------- /raw_data/generated_sig1.pcm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calebmadrigal/radio-hacking-scripts/96dc2ea40781c47f73b363fcf8bf789f1faafef0/raw_data/generated_sig1.pcm -------------------------------------------------------------------------------- /raw_data/generated_sig2.pcm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calebmadrigal/radio-hacking-scripts/96dc2ea40781c47f73b363fcf8bf789f1faafef0/raw_data/generated_sig2.pcm -------------------------------------------------------------------------------- /raw_data/generated_sig3.pcm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calebmadrigal/radio-hacking-scripts/96dc2ea40781c47f73b363fcf8bf789f1faafef0/raw_data/generated_sig3.pcm -------------------------------------------------------------------------------- /raw_data/outlet_c1_off.json: -------------------------------------------------------------------------------- 1 | { 2 | 'bit_str': '0110100001000000', 3 | "freq": 315000000, 4 | "baud": 410, 5 | "sample_rate": 2000000, 6 | "header_len": 3.85, 7 | "space_len": 3.78, 8 | "amp_map": { 9 | "LOW": 0.28, 10 | "HIGH": 1.4 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /raw_data/outlet_c1_on.json: -------------------------------------------------------------------------------- 1 | { 2 | 'bit_str': '0110100010000000', 3 | "freq": 315000000, 4 | "baud": 410, 5 | "sample_rate": 2000000, 6 | "header_len": 3.85, 7 | "space_len": 3.78, 8 | "amp_map": { 9 | "LOW": 0.28, 10 | "HIGH": 1.4 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /raw_data/outlet_c2_off.json: -------------------------------------------------------------------------------- 1 | { 2 | "bit_str": "0110100000010000", 3 | "freq": 315000000, 4 | "baud": 410, 5 | "sample_rate": 2000000, 6 | "amp_map": { 7 | "LOW": 0.28, 8 | "HIGH": 1.4 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /raw_data/outlet_c2_on.json: -------------------------------------------------------------------------------- 1 | { 2 | "bit_str": "0110100000100000", 3 | "freq": 315000000, 4 | "baud": 410, 5 | "sample_rate": 2000000, 6 | "amp_map": { 7 | "LOW": 0.28, 8 | "HIGH": 1.4 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /raw_data/preamble_part_2.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calebmadrigal/radio-hacking-scripts/96dc2ea40781c47f73b363fcf8bf789f1faafef0/raw_data/preamble_part_2.wav -------------------------------------------------------------------------------- /raw_data/remodulated_test_44100.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calebmadrigal/radio-hacking-scripts/96dc2ea40781c47f73b363fcf8bf789f1faafef0/raw_data/remodulated_test_44100.wav -------------------------------------------------------------------------------- /raw_data/remote_1_on_raw.pcm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calebmadrigal/radio-hacking-scripts/96dc2ea40781c47f73b363fcf8bf789f1faafef0/raw_data/remote_1_on_raw.pcm -------------------------------------------------------------------------------- /raw_signal_to_crop.pcm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/calebmadrigal/radio-hacking-scripts/96dc2ea40781c47f73b363fcf8bf789f1faafef0/raw_signal_to_crop.pcm --------------------------------------------------------------------------------