├── .gitignore ├── sweeper.py ├── get_frequency.py ├── common.py ├── play_wave.py ├── LICENSE.txt └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | -------------------------------------------------------------------------------- /sweeper.py: -------------------------------------------------------------------------------- 1 | from wavebender import * 2 | import sys 3 | from common import * 4 | 5 | def sweep(): 6 | return (val(i) for i in count(0)) 7 | 8 | channels = ((sweep(),),) 9 | samples = compute_samples(channels, 44100 * 60 * 1) 10 | write_wavefile(sys.stdout, samples, 44100 * 60 * 1, nchannels=1) 11 | -------------------------------------------------------------------------------- /get_frequency.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | from common import * 3 | 4 | parser = argparse.ArgumentParser(description='Get the hertz of the sound at a given time.') 5 | parser.add_argument('time', metavar='T', type=float, nargs='?', help='The time at which you found the resonant frequency') 6 | args = parser.parse_args() 7 | 8 | print freq_at_time(args.time) 9 | -------------------------------------------------------------------------------- /common.py: -------------------------------------------------------------------------------- 1 | import math 2 | 3 | start = 20 4 | final = 200 5 | 6 | end_time = 20 7 | k = (final - start) / end_time 8 | 9 | def val_at_time(time): 10 | return math.sin(2.0 * math.pi * (start * time + ((k * time * time) / 2))) 11 | 12 | def freq_at_time(time): 13 | return start + k * time 14 | 15 | def val(i): 16 | time = float(i) / 44100 17 | return val_at_time(time) 18 | -------------------------------------------------------------------------------- /play_wave.py: -------------------------------------------------------------------------------- 1 | from wavebender import * 2 | import sys 3 | from common import * 4 | 5 | parser = argparse.ArgumentParser(description='Play a sine wave at a given frequency.') 6 | parser.add_argument('freq', metavar='F', type=float, nargs='?', help='The resonant frequency') 7 | args = parser.parse_args() 8 | 9 | wave = sine_wave(args.freq, 44100, 1) 10 | 11 | channels = ((wave,),) 12 | samples = compute_samples(channels, 44100 * 60 * 1) 13 | write_wavefile(sys.stdout, samples, 44100 * 60 * 1, nchannels=1) 14 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The ISC License 2 | 3 | Copyright (c) 2015 Ian Macalinao 4 | 5 | Permission to use, copy, modify, and/or distribute this software for 6 | any purpose with or without fee is hereby granted, provided that the 7 | above copyright notice and this permission notice appear in all 8 | copies. 9 | 10 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 | WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 | WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 | AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 | DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 | PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 | TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 | PERFORMANCE OF THIS SOFTWARE. 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | resonance-finder 2 | ================ 3 | 4 | A tool to help you find the resonance of objects in your room. Make sure you have a subwoofer. 5 | 6 | ![Resonant Frequency](http://imgs.xkcd.com/comics/resonance.png) 7 | 8 | ## Setup 9 | 10 | You need to install the [Wavebender][wavebender] library before doing anything. 11 | 12 | ## Usage 13 | Playing the resonant frequency of an object is simple with these 3 steps: 14 | 15 | 1. **Find when the sweeper reaches resonance.** Run `python sweeper.py | aplay` and a stopwatch simultaneously. When you reach resonance, record the time on your stopwatch. 16 | 2. **Get the resonant frequency from this time.** Use the command `python get_frequency.py 3.4` replacing `3.4` with the number of seconds elapsed (the time you recorded on the stopwatch). 17 | 3. **Play the frequency.** Use `python play_wave.py 100.0 | aplay` where `100.0` is instead the frequency from `get_frequency.py` in Hz. 18 | 19 | Now you can troll people by shaking their desks/room/anything! 20 | 21 | [wavebender]: https://github.com/zacharydenton/wavebender 22 | 23 | ## License 24 | 25 | ISC 26 | --------------------------------------------------------------------------------