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.
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.
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.
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?
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.
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:
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?
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.
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.
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.
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: