Access internal microphone input level via Terminal

applescriptaudiomicrophoneterminal

I am interested in using my old MacBook as an audio baby monitor. My imagined workflow is to set a noise threshold for the internal microphone in the MacBook when baby is stirring or whining and to use Messages to text me or my wife when the threshold is reached.

When I'm looking in System Preferences, I can see the Input level for the microphone is picking up noise, but how can I get a quantifiable number in Terminal?

I've seen online about osascript -e "get volume settings" to access a numeric value for how sensitive the microphone should be set, but I can't find a way to access how loud of an input is coming in at any given time.

Any ideas out there?

Best Answer

Using command line tools you can do the following:

  • Install brew
  • Update and doctor brew
  • Install portaudio, ffmpeg and all dependencies with brew

    brew install portaudio
    brew install ffmpeg
    
  • Install pip by downloading get-pip.py (direct link) and executing

    sudo python ~/Downloads/get-pip.py
    
  • Install soundmeter

    sudo pip install soundmeter
    
  • Run soundmeter. To get help use the -h switch:

    soundmeter -h
    optional arguments:
      -h, --help            show this help message and exit
      -c, --collect         collect RMS values to determine thresholds
      -s SECONDS, --seconds SECONDS
                            time in seconds to run the meter (default forever)
      -a {stop,exec-stop,exec}, --action {stop,exec-stop,exec}
                            triggered action
      -t [+|-]THRESHOLD [NUM ...], --trigger [+|-]THRESHOLD [NUM ...]
                            trigger condition (threshold RMS and number of times)
      -e SCRIPT, --exec SCRIPT
                            shell script to execute upon trigger
      -d, --daemonize       run the meter in the background
      --log [LOGFILE]       log the meter (default to ~/.soundmeter/log)
      -v, --verbose         verbose mode
      --segment SECONDS     audio segment length recorded in seconds (defaults to
                            0.5)
    

Simply running soundmeter will output an RMS value. After defining a threshold you can trigger a shell script action (which may itself trigger an AppleScript script) with the -e switch.

Entering soundmeter --segment 0.1 --log watching online TV (climate change and coffee farming in Colombia - the end of Arabica beans) will show something like:

2017-01-25 18:16:02,289 24
2017-01-25 18:16:02,665 24
2017-01-25 18:16:03,037 31
2017-01-25 18:16:03,399 3
2017-01-25 18:16:03,769 15
2017-01-25 18:16:04,142 11
2017-01-25 18:16:04,524 9
2017-01-25 18:16:04,891 7
2017-01-25 18:16:05,257 7
2017-01-25 18:16:05,632 0
2017-01-25 18:16:06,001 7
2017-01-25 18:16:06,384 0
2017-01-25 18:16:06,745 2
2017-01-25 18:16:07,113 10
2017-01-25 18:16:07,491 14
2017-01-25 18:16:07,860 6
2017-01-25 18:16:08,223 0
2017-01-25 18:16:08,609 13
2017-01-25 18:16:08,973 16
2017-01-25 18:16:09,347 7
2017-01-25 18:16:09,720 26
2017-01-25 18:16:10,091 1
2017-01-25 18:16:10,464 38 ← an Arabica bean died here
2017-01-25 18:16:10,835 13
2017-01-25 18:16:11,204 Stopped

Just to confirm: that's the microphone input level and not the sound level of the TV stream because the above installation runs in a VM guest and the TV stream on the hosting Mac - tested but not logged with some clapping which will increase the RMS to values above 200!


To send a message after a triggering event do the following - change <user_name> to your OS X short username and <telephone_number> to an appropriate telephone number below:

  • Create a dir and change to it:

    mkdir ~/.soundmeter
    cd ~/.soundmeter
    
  • Create an AppleScript:

    nano sendMessage.applescript
    

    with the content:

    on run {targetBuddyPhone, targetMessage}
        tell application "Messages"
            set targetService to 1st service whose service type = iMessage
            set targetBuddy to buddy targetBuddyPhone of targetService
            send targetMessage to targetBuddy
        end tell
    end run
    
  • Create a shell script:

    nano sendMessage.sh
    

    with the content:

    #!/bin/bash
    
    osascript /Users/<user_name>/.soundmeter/sendMessage.applescript <telephone_number> "Another Arabica bean died"
    

    and change the permissions:

    chmod 755 sendMessage.sh
    
  • Now start soundmeter with a command like this:

    soundmeter -t +38 -a exec -e /Users/<user_name>/.soundmeter/sendMessage.sh
    

    This should send a message to your (iPhone) telephone number. Please note that you can't send an iMessage to yourself. Sending it to an alias may work. Other similar (Apple)scripts are available here: How to send an imessage text with applescript, only in provided service?