kids · lessons · nodejs · programming · raspberry pi

Lessons on PI 6: Playing Audio on a Raspberry PI

pimusic

There are lots of ways to get audio out of your little Raspberry PI.  The first, and easiest way to get started playing MP3 Files is this: omxplayer

The PI Foundation Way

The Raspberry PI foundation wrote up a little article to it here.  I wont repeat their advice, so if you want to just get something playing start here:

Raspberry PI Foundation: omxplayer

The trouble with that method is, currently, the audio output from the Raspberry PI over HDMI has a bit of a lag, so you lose the first couple of seconds while the audio software gets going.

Note these commands are expected to be run from the terminal.  The other thing to note is that you can send them out the A/V plug if you like.

What about the lag? Using External Hardware

You might have noticed this in the Lessons on PI: Lesson 5 Make your PI Speak! to avoid that problem, I use an external piece of hardware that plugs into the USB.  Like this:

usbaudio

That little guy is a sound card, that will be automatically recognized by Linux Drivers, so its easy to use.  And cheap!  These can be had from Ebay for around a dollar.  Adafruit is more reputable though, and you can be sure you’ll get a decent one from them.

Here is the catch though.  By default, the Raspberry PI only expects the audio to go out the HDMI or the A/V jack.  To force it you need to:

sudo vim /etc/asound.conf

And add this to the file:

pcm.!default { 
 type hw card 1 
} 
ctl.!default { 
 type hw card 1 
}

Then reboot.

If you have trouble. There is a lot more detail available here:

Adafruit Learn Article: USB Audio for Raspberry PI

OMXPlayer doesn’t take…

Now… if you use this external hardware AND you want to play mp3 files.  You need to use a new piece of software to do it.  Sadly, omxplayer does not use the Alsa sofware suite.  So those awesome configs you just made, wont help that bit.

Install mpg123…

MPG123 is another bit of free software that will use the Alsa Software.  To install that:

sudo apt-get install -y mpg123

Now you can play audio through your new shiny card:

mpg123 mysong.mp3

Done!  You can now play all the mp3s you like… but what if you want to do it programmatically!

The NodeJS way!

Lets write a little program that will now use all this work you’ve done.  Before we do, lets make it easy to run the mpg123 player but sitting on the shoulders of giants.

screen-shot-2017-02-19-at-8-28-32-am

Make the project…

Before we begin, lets create a new NodeJS project.  If you haven’t installed node, be sure to checkout my article here:

Installing NodeJS on a Raspberry PI

Then create a directory to do your playing in:

mkdir playing

Get into the directory:

cd playing

Setup the project:

npm init

Press enter a bunch of times, until that step completes…. ok, you now have the beginnings of a beautiful music player.

So, we need to install the play-sound npm module like this:

npm install --save play-sound

Finally… write some software.

Start editing index.js

vim index.js

Now tell node you’d like to use the play-sound module:

var player = require('play-sound')(opts = {});
var filename = "mysong.mp3";
player.play(filename);

Save that file out (in VIM its :wq)

Make sure the mysong.mp3 file is in the same directory as the index.js file and run it!

node index.js

That’s it!  You’ve now, programmattically played music!  Imagine what else you might be able to do…. you could make your own juke box!  Or combine it with:

Raspberry PI3 NodeJS GPIO Control: rpi-gpio

To make a spooky Halloween sound-effects box!  Really, now that you wield sound, you can rock out, or create ambience like never before.

Maybe make a digital grandfather clock!!!

Check out the code here: Weasley That git repository has the “gong” audio files and the code below watches the time and plays out the gongs – just like you might hear from an antique clock of old… and it respects your sleeping hours. 😉

var gDuration = 4000;
function playGongOnce(timeout) {
  if (!timeout) { timeout = gDuration; }
  player.play("/home/pi/weasley/gong.mp3", { timeout: timeout });
}

let curPlaying = false;
async function playFile(filename) {
  return new Promise((res, rej) => {
    if (curPlaying) {
      res();
      return;
    }

    curPlaying = true;

    player.play(filename, (err) => {
      if (err) { rej(err); curPlaying = false; }
      else {
        console.log("waiting for audio to be done...");
        setTimeout(() => {
          curPlaying = false;
          res();
        }, 20000);
      }
    });
  });
}

async function playGongForHour(hour) {
  console.log("Playing file: ", hour);
  return playFile("/home/pi/weasley/gongs" + hour + ".mp3");
}

setInterval(async () => {
  var now = new Date();
  var hours = now.getHours();

  if (isDst(now) && false) {
    hours -= 1;
  }

  // Might have wrapped.
  if (hours < 0) {
    hours += 24;
  }

  console.log("Hours: ", hours, now.getMinutes(), now.getSeconds());

  if (hours > 7 && hours < 22) {
    if (now.getMinutes() == 0 && now.getSeconds() <= 10) {
      if (hours > 12) {
        hours = hours - 12;
      }
      await playGongForHour(hours);
    }
    if (now.getMinutes() == 30 && now.getSeconds() <= 10) {
      await playFile("/home/pi/weasley/halfgong.mp3");
    }
  }
}, 10000);

(Stable diffusion’s idea of a “grand father clock”)

Advertisement

2 thoughts on “Lessons on PI 6: Playing Audio on a Raspberry PI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.