/music-habits

Tracking my heapdhone/speaker usage on my laptop.

Primary LanguageC

music-habits

Trying to monitor my speaker/headphone usage on my laptop.

GIF

Table of content

How does this work?

Step 1 Gather data to perform analytics.

Step 2 Perform analytics on the time-series data obtained.

Step 3 Create a summary and visualize it.

Step-1 Gather data

Linux machines using ALSA/Pulseaudio play sound using a client-server architecture. A C program based on pactl subscribes to events on output devices and applications playing sound, and logs them to a file in CSV-format.

See the diff to know the changes made

Sample dumps are available in examples.

Step-2 Analysis

This Go program reads the log file provided and dumps a summary on the console. Additionally, it can start a web server and let you pictorially view in your web browser. HTML is awesome 😎

Step-3 Create summary

A text summary is simple to print on terminal screen, but a pictorial view would have been more appealing. HTML/CSS/JS was the go-to choice here. I tried playing with gg, but gave up after trying hard to center align text. If you can invest that time, please let me know.

Usage

Build

git clone https://github.com/himanshub16/music-habits
cd music-habits
./setup.sh

start collecting data

cd pulseaudio/src
make pactl
./pactl

view data collected

cd pulseaudio/src
tail -f sink*

generate summary

# to print summary (notice the file path)
# duration can be today/yesterday/month/all
go run generate_report.go -logfile pulseaudio/src/sink_input-firefox.log -duration today

# to visualize in browser
go run generate_report.go -logfile pulseaudio/src/sink_input-firefox.log -interactive -port 5000

Why pulseaudio?

Pulseaudio provides a great API on Linux which provides

  • list of sound sinks (output devices),
  • list of sink-inputs (applications/services producing sound),
  • properties as volume, corked (is paused), mute, etc. and also
  • subscribe to events.

Why using pactl based C code?

pulseaudio Python drivers are a great choice to use the library. However, I couldn't find one which provides corked status for any sink-input. This is required to know that a sink-input (browser/music player) has paused playing, and there is nothing coming out of the speakers.

This is where C came to rescue. However, due to very tiring nature of C, and after dealing with many naive mistakes (coming back from Python/JavaScript/Golang), I went up to tweaking pactl.c to my use-case, and it works well.

Currently, I couldn't compile pactl.c directly because of incorrect compilation flags and missing shared libraries. In case you can help out with the right flags, or an awesome makefile to compile this without having to clone entire pulseaudio codebase from git, feel free to help me out. That also helps in fixing the filename from pactl.c to something more appropriate.

Why Golang for analysis?

It is just simple loops with some grouping and calculations. Python/NodeJS would be have been easier, but I just wanted to spend more time getting comfortable with Golang.

Additionally, it has a decent web server built in, and has everything you need (I miss you map and filter 😭).

Why HTML for viz?

Using an entirely Go based tool is something I would prefer. I gave a lot of try with gg, but after lot of hardwork required to fix and align the text, I gave up and moved to a simpler solution of using HTML and passing data from Golang via a web server.

If you are enthusiastic about giving this a try, feel free to let me know on this issue.