We will be using direct digital synthesis to generate the call of the northern cardinal. Specifically, this adult male northern cardinal recorded by Gerrit Vyn in 2006. This bird was recorded in Texas, but cardinals are also common in Ithaca and throughout the eastern United States. If you pay attention when you're walking through campus, you may hear one singing. The males are a very striking red. You can read more about the cardinal here.
Cardinals have a variety of songs and calls. We will be synthesizing on of its most common songs, which you can hear in the first ten seconds of the recording below:
Here is a screenshot of the spectrogram for the song that we'll be synthesizing. Cardinals and many other songbirds produce almost pure frequency-modulated tones. As can be seen in the spectrogram below, the cardinal sweeps through frequencies from ~2kHz to ~7kHz. We'll assume that the dominant tones (the darkest lines on the spectrogram) are significantly louder than all other frequencies (the lighter lines). We'll only synthesize these loudest frequencies. The generated song sounds quite realistic under this assumption. Your synthesizer will be controlled via a keypad.
Experience shows that students prefer these webpages short. For that reason, please see these external pages for additional information which will be critical to completing this particular lab.
- Direct digital synthesis (DDS): This is the algorithm that we will use for sound production. This is a powerful algorithm, a good one to understand deeply.
- Birdsong synthesis via DDS: This webpage deconstructs the Northern cardinal's song, and synthesizes it via DDS.
- Keypad: Your birdsong synthesizer will be cotrolled via a keypad. Please see this page for examples of and information about the the keypad that we will be using.
- Sound synthesis page: Generally speaking you want to make pleasant sounding synthesis. You may want to look at the sound synthesis page. I suggest starting with a linear attack of about 1000 samples, a decay of about 1000 samples, and a sustain as long as necessary for a 130ms chirp/swoop.
DAC datasheet: The SPI DAC you will use is the MCP4822. The DAC analog output is marked DACA or DACB on the SECABB. The SPI connections are supplied on the Big Board (SECABB), as long as you connect the DAC_CS jumper. Section 5.1 and 5.2 of the MCP4822 datasheet discussed the way the the DAC uses SPI. The edge connector pin marked DACA or DACB will go (optionally through a low pass filter) to an audio socket, to be connected to the green audio plug of the speakers. If you are going to design a lowpass filter for the DAC, then you need to know that the input impedance of the speakers is around 10 Kohm.
Hardware/Software setup for PIC32: This page describes the software/hardware required for configuring this lab.
I suggest that you organize the program as follows. If a different organization makes more sense to you, that's ok. This is just a suggestion.
- DDS of sine waves
- DAC output
- Sample count for precise timing of sounds
- Scans and debounces the keypad and any other buttons you may use
- Your state machine must debounce all 12 keys.
- Parses the command (if any) and updates state variables (play mode, sound list, etc.)
- Waits for 10-30 mSec using
PT_YIELD_TIME_msec(time)
, then repeats.
- Waits to be semaphore-signalled by a different thread
- Plays the sound associated with each button press recorded in the global array by setting up the DDS parameters associated with each sound
- Maintains playback timing using the sample count from the timer ISR
You may find some previous year's lectures useful. You may also find Bruce's lectures useful.
Timing of all functions in this lab, and every exercise in this course will be handled by interrupt-driven counters, (including the builtin functions in ProtoThreads) and not by software wait-loops. This will be enforced because wait-loops are hard to debug and tend to limit multitasking. You may not use any form of a delay(mSec) function.
If your program just sits there and does nothing:
YIELD
(or YIELD_UNTIL
, or YIELD_TIME_msec
) in the while(1)
loop?If your program reboots about 5 times/second:
If your thread state variables seem to change on their own:
The oscilloscope is essential for debugging this lab (and every lab). The oscilloscope is the only way of deciding if -- It doesn't work! -- results from hardware or software.
Note that these checkpoints are cumulative. In week 2, for example, you must have also completed all of the requirements from week 1.
By the end of lab session in week one you must have either built and tested your own board or tested a prebuilt board.
Timing of all functions in this lab, and in every exercise in this course will be handled by interrupt-driven counters, not by software wait-loops. ProtoThreads maintains an ISR driven timer for you. This will be enforced because wait-loops are hard to debug and tend to limit multitasking
Write a Protothreads C program which will:
- Upon power-up or reset the system should go into play mode and play a sound for each button press (swoop for key 1, chirp for key 2, and 130 ms of silence for key 3).
- Pressing and holding a separate button (not the keypad) or toggling a switch puts the system into record mode so that each button press is recorded for later playback. Recording continues until the record mode toggle is released. The duration of each button press does not affect the recording.
When you demonstrate the program to a staff member, you will be asked to play back a sequence of sounds which simulates the birdsong above, and to play back a random sequence of swoops/chirps/silences. At no time during the demo can you reset or reprogram the MCU.
In addition to the above, ECE 5730 students should synthesize another Northern Cardinal song, shown below. You may deconstruct this song into 4 sound primitives, as illustrated below. Fit these frequency sweeps to functions using similar analysis to that shown at the top of this document.
Each of these 4 sound primitives should be mapped to 4 additional keys on the keypad.
You may fit to any function that you like. 2 linear functions and a parabolic function sound nice.
You can also synthesize songs for other, more challenging birds like the Baltimore oriole. (If you're lucky, you can spot these in Ithaca too. They're gorgeous and have a very distinctive song).
Your written lab report should include the sections mentioned in the policy page, and:
By plugging the Pic into the microphone input of the PC, we can record the sound that it generates and create a spectrogram of the Pic-generated birdsong:
samplerate, data = wavfile.read('./Bird.wav')
frequencies, times, spectrogram = signal.spectrogram((data[80000:191000,0]+data[80000:191000,1])/2., samplerate)
plt.pcolormesh(times, frequencies, spectrogram, shading='gouraud')
plt.ylabel('Hz'); plt.xlabel('Time (sec)')
plt.title('Spectrogram of PIC-generated birdsong')
plt.ylim([0,10000])
plt.show()
import numpy
import matplotlib.pyplot as plt
from IPython.display import Audio
from IPython.display import Image
from scipy import signal
from scipy.fft import fftshift
from scipy.io import wavfile
plt.rcParams['figure.figsize'] = [12, 4]
from IPython.core.display import HTML
HTML("""
<style>
.output_png {
display: table-cell;
text-align: center;
vertical-align: middle;
}
</style>
""")