I snore. I’m perfect in many most ways, but this is the one major defect I am aware of. Like any good engineer, upon learning of a defect I set out to correct or at least patch it. The name of this little project stems from Ivan Pavlov’s experiments with conditioning as well as Operation Sandman, a CIA program for sleep deprivation torture of detainees at Gitmo.
The naming convention is evident when one looks at the strategy I am taking to correct my unpleasant snoring habit. I have an app on my phone (Sleep as Android) that tracks my sleep, is a cool alarm, and among other things, tracks my snoring. From this app I know:
- It is possible to “detect” snoring.
- I don’t rip logs all night, but in bursts.
I have tried a number of things to correct this throughout the last year including mouth piece, a jaw strap, a shirt with a tennis ball sewn in the back, video recording myself sleeping to see if I can detect a position where snoring occurs, essential oils/other alternative medicines, etc. Failing all of these, I now begrudgingly turn to “Data Science” the form of mysticism reserved for the exceptionally desperate.
The plan of attack on this endeavor is as follows:
- Create a program that detects loud noises (preprocessing).
- Differentiate between snoring and other nighttime noises (dog, furnace, coughs, etc).
- When snoring is detected administer a small shock via a Bluetooth controlled shock collar for dogs which I will be wearing as an arm band.
- Video record results of me electrocuting myself while trying to sleep and post to YouTube, elevating me to stardom.
- Possibly train myself to stop snoring.
The title of this project should now be apparent, as I am hoping to “train” myself to not snore, and if I were developing this commercially, I’m fairly confident that any beta-testing I did would (rightly) classify me as a war criminal.
In part one of this series (I promise that all the time and have a bad habit of not following through), I present the code and methods I have developed for detecting loud noises / building my dataset.
In future parts, I hope to do some cool things with respect to signal processing and Bluetooth device hacking with Python.
Loud Noises
The first step is to record sounds. The code presented is fairly elegant and easy to follow (for now).
We have a class AudioHandler
which contains some variables and a few methods.
In addition to the alsaaudio
handler, we have:
rawData
a list for holding caching the audio recordedvolume
which will be used to create a csv of timestamp, volume data- and various thresholds to prevent getting multiple shocks in unison, a warm-up period, volume threshold for recording, etc.
The methods are:
setThreshold
This action listens to the mic for a number of seconds and attempts to dynamically set the threshold. It’s not great- for my first night of use I ended up doing it manually by observation and laying in bed and making some breathing / fake snoring sounds and seeing where it hit.
dumpData
This method writes the csv and audio to disk
executeAction
This is a place holder, and later will be used to call the “shock”
run
This is where all the fun happens. In short it
- Attempts to set a baseline threshold considering mic sensativity, background noise, etc.
- In a
while
loop it then- Listens to the mic
- If the volume is above the threshold:
- Set a
recordingActive
flag toTrue
if it wasn’t already - If it wasn’t already, timestamp when this recording started
- Determine how long the current recording has been going on.
- If it has been going on for some duration, call the
executeAction
method and dump the recording to disk.
- Set a
- If
recordingActive
is true, add the raw audio and volume levels torawData
andvolume
And that’s about it. Again, look at the code for specifics, but all in all pretty straight forward.
Last night I recorded.
Building a Training Set
As a priest of the mystic art of data science, the first part of any ceremonial ritual is to create a training / testing data set.
This was a very tedious part of my day. I went through the recordings and seperated them into two folders “snore” and “non-snore”. Well, I did this for about 30 minutes, and got approx 80 samples of each. Then I moved the rest into an “unlabled” folder… you know for testing purposes, not because I was super bored. Perhaps if I had an intern, this would have been a more robust set.
Finally I wrote a little python script that will copy the csvs over appropriately to all of the wav files you sorted out into the proper directories.
Stay tuned for part 2, where we’ll do some signal processing to differentiate the snores from the noises!
2 thoughts on “Pavlov’s Sandman pt. 1”