Becoming a dad does not only completely change your life but also changes the scope of your hobby projects (If time still permits :)) My first self-made project made especially for my newborn baby boy Felix is called pifon and is an audio baby monitor realized with two Raspberry Pi devices.
The hardware setup is fairly simple: one Pi, the pifon server, has a USB web cam attached. I use its internal microphone to record the voice of my little boy. The other Pi is the pifon monitor and has a set of analog speakers attached for the output. Additionaly, the mon device has an Adafruit RGB LCD Plate attached and I use the LCD on this little plate as output device and its 5 keys as user input. I did not mount the plate directly on the Pi but used a ribbon cable to detach it: This allows me to package the plate in its own housing (As it is easier to find a case for the plate alone):
To get started quickly, I tried to use as many off-the-shelve components for the software as I could: For the audio recording and streaming I opted for the Icecast audio streaming server that gets its input stream recorded from the webcam microphone with the darkice live audio streamer. This setup is proven to be stable and already documented in various projects – also on the Pi.
What’s missing is some kind on status messaging I wanted to have: The pifon server shall analyse the recorded audio stream and when something special (e.g. baby crying) happens it sends an event to the monitor client. So the client can start streaming the live audio only when something interesting is happening. Then the audio stream will stay live until the event is over and then stop streaming.
For the messaging between the server and the monitor I decided to use XMPP, the well known standard for Internet instant messaging. The pifon server and the monitor will then be two “bots” sitting in a chat room and exchanging events by “typing” messages. The advantage of this approach is that you can simply join the chat as a user and also watch for incoming events for the server – that’s also really helpful for debugging 🙂
I run my own XMPP server on the pifon server Pi and use the prosody server implementation. My code contribution in the project is the bot code and that is written in Python using the SleekXMPP for the XMPP communication. Additionally, I use Adafruit’s Python Code for accessing the LCD and reading the 5 buttons via the I2C bus.
Audio recording is done on the server with SoX‘s rec tool and using an ALSA dsnoop device that allows mutliple applications to share an input device (here the USB cam’s mic).
For audio playback on the pifon mon Pi I use the well known MPD that is controlled by my scripts with the MPC command line tool. It directly supports streaming by adding the stream server URL in the play list.
The pifon project is now in daily production use and has the following list of features:
- pifon audio server
- Stream baby’s audio via standard MP3 stream server to any streaming capable device
- Constantly analyse the audio signal and watch out for loudness periods
- Provides local XMPP chat server with private chat room for pifon eventing
- Send events as XMPP chat messages whenever something happens on the audio channel
- Listen on chat messages that allow to control the parameters of the analyse algorithm
- pifon monitor
- Automatically joins the XMPP chat and watches out for events from the server
- Can stream the audio to your local audio out with mpd
- LCD displays current state of the server including
- audio detector state: idle, attack, active, sustain, respite
- connection: is mon connected to XMPP server?
- server ping: does the audio server reply my pings?
- shows peak and current RMS audio level during active phase
- The LCD has an RGB backlight. It is used to display the server state:
- BLUE: mon is running but server is not connected yet
- WHITE: mon is running and server is connected. no audio event happened
- RED: audio is active (loud) but playback is not enabled
- GREEN: audio is active (load) and playback is enabled
- YELLOW: blanking is disabled otherwise similar to WHITE
- 5 Keys allow to directly toggle:
- Listen: toggle direct streaming from server. This allows to listen into baby’s room without the audio detector triggering the playback
- Mute: do not start audio streaming even if an audio event occurred. Use this if you want to watch out for audio events but do not start streaming the audio stream. You will then see the audio event with the LCD backlight only.
- Chime: the mon client plays a short signal sound before starting or stopping the streaming playback. You can disable playback of these sound icons with this button.
- Blank: if no audio event occurrs then the LCD is automatically blanked after 10s if no button is pressed. If you want to see the display permanently then toggle this button.
- Menu: open the parameter menu. Press the button again to leave the menu. Inside the menu the four directional keys allow you to navigate through the menu items and alter the values. See the description of the detector parameters for details below.
- Both devices are more or less portable if your network technology allows this (I use PowerLAN, but WLAN works as well)
- Use your Mac/PC or mobile phone as an alternate client: Use an XMPP chat client (I use Adium) to watch for server events and an internet stream player (e.g. VLC) to listen to the audio stream. Talk with the server to alter parameters.
Audio Detector Parameters
The audio detector used in pifon’s audio server has several parameters that allow you to adjust the responsitivity of the detector.
The audio detecter is modeled as a state machine that analyses the max RMS value of the samples recorded in a given period and uses this value to decide on state traversal.
The following states are defined:
- Idle: nothing special happens on audio
- Attack: audio level peaks and it might be the begin of a loudness phase if its long enough
- Active: attack period was long enough, we enter active mode and start streaming audio
- Sustain: if audio is silent during the active phase for a longer time then the sustain phase is entered and will lead to end of playback if its long enough
- Respite: This phase enforces a quiet period right after the end of an active phase. Even if audio events occur in this phase they are ignored. This phase was introduced to avoid very frequent start/stop playback cycles.
The mon displays some additonal states in the LCD, but they are not audio related:
- Connect: initial connect to XMPP server
- Online: mon is in chat room and gets pings from audio server
- Offline: no ping and disconnected from XMPP server
- No Ping: mon is connected to XMPP server but audio server does not reply on pings
The following audio detector parameters can be adjusted:
- trace (boolean): allows to show the audio RMS value all the time. This is useful for debugging and adjusting the other parameters
- alevel (int, 0-100): level of audio signal must be higher than this value to enter attack state
- slevel (int, 0-100): level of audio signal muse be lower than this value to enter sustain state
- update (int, 1-..): update interval of audio state in 100 ms
- attack (int, 0-..): duration in [s] of peak audio values that must be audible so that active state is entered
- sustain (int, 1-..): duration in [s] of silence so that active state is left
- respite (int, 0-..): duration in [s] after an active period where no new active period is started
You can alter these parameters in the XMPP chat with the following commands:
get audio * set audio trace False set audio alevel 10 set audio slevel 5 set audio update 5 set audio attack 0 set audio sustain 5 set audio respite 10
The ‘*’ allows to get all values available.
Build your own pifon!
Yes you can build your own clone of the pifon if you like. Everything you need is freely available: all used tools and my code.
The source of my code contributions are found on GitHub: cnvogelg/raspi. Just clone the repository and use it.
Now hack on and build your own uber-geeky baby monitor!