Make a Sound Recorder

What You'll Do

In this project you'll write a program to record sound from your computer microphone, play it back, and draw a picture of the recorded sound. You can then process your recording to add effects such as pitch-shift, reverse, or echo.

What You Should Know

This project is ideal for those who are comfortable coding in Scratch, GP Blocks, or a similar blocks language. You should be familiar with loops, if-statements, and variables.

If you've never used GP Blocks, you may want to watch this one-minute video before you get started.

As you work, periodically click the button to download and save a copy of your project. To resume work on a saved project, launch GP, then drag and drop the saved .gpp file onto the GP browser window.

Step 1: Sound Input and Output

Click here to start this project in a new browser tab or window. You'll be going back and forth between these instructions and the project, so set up your windows or tabs to make that easy.

Click on the "Sound" category and drag out the "sound input" block:

Click on this block. You'll see a "talk bubble" with a bunch of numbers:

You may need to grant the browser permission to use your computer's microphone. If you see all zeros the first time you click on the "sound input" block, click it a few times. If you continue to see all zeros, check your computer's sound settings and make sure the microphone is enabled.

The numbers you see are the first hundred sound samples of the 1024 samples captured by the "sound input" block.You can use the "play samples" block to play them back:

If you listen carefully, you might hear a tiny sound. It's easier if you put this in a "forever" loop:

However, even with the "forever" loop, you'll just hear an incomprehensible sequence of tiny sound snippets. That's because the "sound input" block only records 1024 samples at a time, which is only about 1/20th of a second since GP records 22050 sound samples per second. To make a useful sound recorder, you'll need to collect a bunch of these tiny sound snippets and stick them together.

How it Works: Sound from Numbers
As you saw, the "sound input" block produces a sequence of numbers. Each number is the microphone sound level at one moment in time. The "play samples" block tells your computer to convert those numbers into an electrical signal that moves the speaker in your computer, recreating the sound waves that were originally picked up by the microphone. This trick of representing sound as a sequence of numbers, or digital audio, is the basis for all sorts of useful applications, from cell phones and voice mail to portable music players and digital recording studios.

Step 2: Use a List to Capture Sound

GP lists can store many things, including sound data. The list blocks are in the "Data" category. Drag out a "list" block and click it:

This block makes a list. In this case, it made a list with only one item, the number 1. You can expand the "list" block by clicking on the right-arrow on the right side of the block to make a longer list:

Lists can store things other than numbers, such as words:

The "count" block reports how many things are in a list:

The sound recorder will use a list to collect sound samples. The list will be stored in a variable named "recording". To create that variable, go to the "Variables" category and click the "Add an instance variable" button:

MicroBlocks will ask for the name of the variable. Enter "recording" and click the "OK" button:

New "recording" blocks will appear in the "Variables" to get and change the new variable:

To collect sound data, we'll start by making empty list and storing it in the "recording" variable:

Note: Be sure to click on the left-arrow of the "list" block until it has no input slots.

Now you can use a "repeat" loop to record a few seconds of sound into the list:

Note: Be sure you use the "to add all" list block (the third block in the "Data" category that starts with "to"), not the similar-looking "to add" block.

Each iteration of the "repeat" loop adds another 1024 sound samples to the recording. How much time is that?

Sampling Rate
GP records and plays exactly 22050 sound samples every second. This sampling rate is half the sampling rate used for CD quality audio. While this lower sampling rate results in slightly lower fidelity, the quality is still quite high. Most people who aren't audiophiles will barely notice any difference. The lower sampling rate means that GP has only half as much data to record or process, allowing programs that process sound to run faster and store more sound in a given amount of memory.

Knowing the number of samples and the sampling rate, you can compute how long your recording is:

Use the "play samples" block to play back the recording:

It works! You've implemented the essential parts of sound recording and playback, but it would be nice to add keys to control recording and playback.

Step 3: Add Controls

Add a "when space key pressed" hat to the record script. Then replace the "repeat" loop with a "while" loop:

This script clears the recording (by setting the recording to an empty list) when the space key is pressed. The "while" loop repeatedly adds sound samples from the "sound input" block to the recording as long as the space key is held down. This allows the user to record sound for as long as they want.

It would be nice to provide an indication that sound is being recorded. One way to do that is to use the "say" block:

We can also use a key to play back the recording, again using the "say" block to provide feedback to the user:

Step 4: Draw a Picture of the Sound

To draw a picture of the recorded sound, first add an "x" instance variable, then build this script:

This script uses the "computeLevels" block, a pre-built block that came with the initial project. The "computeLevels" block scans the recording and makes a list of volume levels over time. Each volume level in the list gives the peak (loudest) sample value within its time interval. Each time interval is 1/750th of the total recording, so there are 750 volume levels in the resulting list.

The "for" loop in the "show recording" script iterates through those levels drawing a one-pixel wide rectangle whose height is proportional to the level for each interval, and advancing "x" by one pixel at every step. The result is a picture of the sound's loudness over time.

Add a "broadcast" block to the recording script to update the sound picture every time you make a new recording:

Make a recording with several short, loud sounds (e.g. clapping your hands). Can you see the peaks in the sound picture that correspond to those sounds?

Summary: All the Scripts

Remix 1: Change the Playback Speed

You can make yourself sound like a chipmunk or a giant by playing back the recording faster or slower. Duplicate the playback script by right-clicking on the top block of the script and selecting "...all" (short for "duplicate all") from the menu:

Use the menu in the "when key pressed" block to change the key to "f" (for fast). Then click on the right-arrow on the "play samples" block and set the playback rate to 200:

Record yourself saying something, then play it back faster using the "f" key. Try some different rates.

Make another copy of the playback script to be triggered by the "s" key (for slower). Set the playback rate to a number between 10 and 100.

Pitch Shifting
The rate in the "play samples" block gives the playback speed as a percent of normal speed. "100" is the original speed, "200" is double speed, and "50" is half speed.

Changing the playback rate is called pitch shifting. In another GP activity, "Duck Piano", pitch shifting is used to turn a duck quack recording into a musical instrument that can play tunes.

Remix 2: Reverse the Sound

Playing the recording backward gives a strange effect. People talking backs sounds especially funny.

Make another copy of the playback script to be triggered by the "r" key, and use the "reversed" block from the "Data" category to reverse the samples before playing them:

In the days of vinyl records, people sometimes played records backward looking for hidden messages.

Remix 3: Echo Effect

Create a script to play the recording after a short delay ("wait 0.1 milliseconds") when the "echo" message is received:

Make two duplicates of that script with other delays:

Now make a script triggered by the "e" key that broadcasts the "echo" message, then plays the sound:

Actual echoes are softer than the original sound. Perhaps you can figure out how to reduce the volume of the echo. Hint: Start with a new, empty list and use a "for" loop to create a modified copy of the original recording where every sample is multiplied by a number between 0 and 1, such as 0.2.

Concurrency and Echos
The echo effect is the result of four scripts playing back the recording with different, but overlapping, time delays. That's possible because GP, like Scratch, supports concurrency, meaning that many scripts can run at once. When you press the "e" key, the "broadcast" block in that script starts the three "echo" scripts, but it doesn't wait for them to finish. Instead, it moves on to the "play samples" block. Since that sound is heard without any delay, it sounds like the original sound that generates the echoes.

Each of the echo scripts waits a different amount of time before it starts playing the sound, making it sound as though the sound is bouncing off walls at various distances. Since sound travels at about 1000 feet per second, in 0.1 seconds it can travel 100 feet. If you clap your hands, the sound could travel 50 feet out, reflect off a wall, and come back 50 feet, and you'd hear the echo 0.1 seconds later. Thus, an "echo" effect with a 0.1 second delay simulates an echo from a wall 50 feet away.

Going Further

If you enjoyed this activity, you might be interested in these other GP Blocks Hour of Code activities:

You may also want to check out: