LAB 4 F. A. Q.
Updated on 6-Feb-2000
0. Some of these questions don’t seem to make sense with respect to this semester’s lab.
ANSWER: Correct. The FAQs are based on the labs from Fall-99. Refer to that lab description when certain section numbers are cited.
(4) In airgnotes.m, does tnotes have the correct number of notes in their correct order? Looking at the sheet music, it appears to me that the F# (key 46) is repeated 3 times at the beginning of the piece. Also, why are there arrays called b2notes and b2dur? What does it mean to put the second treble note in an open bass array slot? When there are two treble notes, does the 2nd treble note shift into the bnotes array and then the bass note shift into the b2notes array? Finally, if the durations are already given to us in the airnotes.m file, why do we need to set a base duration such as q_dur=0.25?
ANSWER: 1) The notes and durations are correct. The third F# key is, in fact, tied to the second and its duration is accounted for. 2) b2notes are a supplementary set of bass notes not actually on the musical score that add a fullness to the air when played through MATLAB. If you look through this vector you will see that each note is an octave below the bass notes of b1notes and changes accordingly. 3)q_dur enables you to calculate the duration of each note respective to a set duration. My advice would be to start coding and you will soon see that this is helpful.
(4) As suggested in the lab writeup, I defined my quarter note has having a duration of 0.25 seconds, and based all other calculations on that. When I play this measure, however, it plays extremely fast. Any suggestions?
ANSWER: Use the debugger to put a breakpoint in the loop where you are making notes. Use the debugger and size to figure out length of notes that you are creating. Check this versus a hand calculation of the length of a (quarter) note when sampled at fs.
(4) I’m trying to store all notes (from the onenote.m) in one single matrix and play this matrix. It should be the right way to do this lab; however, I am not sure exactly how to do it. There is an “example” in the lab warm up (a file called play_scale), but when I substitute the modified version of tnotes and tdur into play_scale, it either crashes my computer or plays the short version for ONE time, and then locks up. Suggestions?
ANSWER: Use the debugger. (You may have to make play_scale into a function.) Put a breakpoint in the loop, so that every time through the loop where you insert a note, you can check how long it is. Then do a calculation by hand of what you expect the length to be. Check the frequencies also. If you have errors that say “OUT OF MEMORY," do a whos and see how much memory MATLAB is using.
(4) Is doing more than just playing the song optional?
ANSWER: Read the “sound evaluation criteria” at the bottom of the instructor verification page. If I were grading, getting the song right would merit about 80-85%; this leaves some room for those who implement the tweaks. Of course, you still have to write a report and that affects your grade.
(4) I created a q_dur constant of 0.25 as suggested in the lab. The problem is that when I try to create a vector of zeros to hold the sinusoids I get an error because the use of 0.25 (or any number as a multiplier) gives me decimal answers for tdur and does not allow me to create the correct size vector; how can I correct this error?
ANSWER: Use round() or fix() to get an integer.
(4) How long should our script take to synthesize the song? (obviously dependent on specs of your system) I’m just looking for a ballpark figure 10 secs to 30 secs etc…
ANSWER: It took about 15 secs on my Mac—300 MHz G3. So, 10 to 30 is about right, including applying an ADSR envelope and adding 2nd and 3rd harmonics.
(4) Sometimes when I try to play the short or long version of my song I get the following error:
soundsc(total_tnotes,fs) ??? Unable to open sound device. Error in ==> C:MATLABR11 toolboxmatlabdatafunplaysnd.dll Error in ==> C:MATLABR11toolboxmatlabdatafunsound.m On line 31 ==> playsnd(y,fs,bits);
The problem appears to be totally random and I haven’t identified a pattern yet. This problem is not isolated to my home computer only, it happens at the CoC-309 lab also.
ANSWER: This error is generated whenever the sound device is in use by another program. So if you’ve got ICQ open and a message comes in just as you are about to play your signal, you’ll get the error, because ICQ grabs the soundcard to play the “Uh oh!” If you’re trying to play your song signal again while it is still playing from a previous soundsc(), you’ll get this also. My advice is to close any applications that use the soundcard. Then soundsc() should always work unless your song is already playing. Other things to consider:
- When you place the call for sound() in more than one function (more than one place) in your whole program, then this problem appears.
- length of your total_tnotes vector, to the nearest 10,000. I assume fs = 11025.
- OS version.
- MATLAB version. It looks like you’re running 5.3 Have you checked www.mathworks.com for FAQs ?
(4) For the conclusion, we basically sum up our lab. What specifics should be included?
ANSWER: Often a conclusion to a research paper has “suggestions for future work." I’d suggest the following: What are the limits of your synthesis? If you wanted to make it better what else could be done? Discuss problems encountered and how you solved them; this should help you to discuss the “hard” part of the lab. Finally, there is the ever-popular “what did you learn?”
(4) My file works fine with the shortened version, but when I try to play the full version, my computer locks up, and if I am lucky, I get a message that I am out of memory. Any suggestions?
ANSWER: Try using a sampling rate of 8000 Hz; also, do whos and see how many “extra” vectors you might be creating. If you find some big ones that you don’t need, use clear to get rid of them.
(4) I can’t play the song immediately after I’ve just gotten done playing it before.
ANSWER: If you have a line of code that initializes the song array with zeroes then you may be putting too many zeroes in that array. If you use the whos command and see that your song array is longer than about 207,000, then you’ve got problems with your initialization code. Using the debugger and some testing code, you can figure out how long your initialization array must be. Pseudo-code might look like:
song = zeroes(1,fs*time_length_of_song);
Don’t forget those semicolons!! ( Remember, all those zeros at the end would have to be “played;” 1,000 seconds is about 17 minutes. ) NOTE: You can always hit control_C to stop all the zeros from scrolling by if you forget the semicolon.
(4) I don’t understand how I am supposed to combine 3 sets of vectors with different numbers of elements when each element has a different time duration. Once a vector of chords (3 X 1 matrix) has been created, how are you supposed to come up with a time duration for each chord?
ANSWER: Let’s say you had the following:
x1 = [ 1 2 3 4 ]; x2 = [ 4 5 6 ];
If you wanted to add them, the most logical result would probably be:
xsum = [ 5 7 9 4 ]; xsum = [ (1+4) (2+5) 3+6) 4 ];
Can you think of an easy way to add only the first three elements, and leave the fourth element of the first vector out of the computation? Then all you have to do is generalize it to fit the needs of your song vectors. It’s probably easier to handle each vector (treble, bass1, bass2) separately right up until you have to sum them together into the complete piece of music. Alternatively, you could determine which vector had the longest time duration and make all three the same length based on that length and initialize them to zero. Then when you start putting in values for your vectors, the last few of the short ones will be zero, having no effect on the addition of the three vectors.
(4) When I use the play_scale format to create 3 vectors of the clefs, the lengths are different by a significant amount. When I trim the vectors to add them, the music quality is diminished. Why is this happening?
ANSWER: The lengths should probably differ by less than 5 or 10 out of a total length that is certainly more than 100,000. If not, you have a bug in how you are handling DURATIONS. Also, use round() when you compute lengths of note vectors.
(4) I’m still not sure how to incorporate the durations into the code. I tried what I thought was correct, and the error I received was as follows:
??? Index exceeds matrix dimensions. Error in ==> c:matlabece2025labplay_gnotes.m On line 19 ==> xx(n1:n2) = xx(n1:n2) + tone;
Also, for the envelope, I understand that the best thing to do is use the interp1, but for this project, I’m uncertain what would be considered x and y, the function to use for x and y, and where to put e(t), i.e., in my play_gnotes file? onenote file?
ANSWER: Use the debugger to stop at this line. Examine the values of n1 and n2, and the length of tone. Also the length of xx() (which must be too short given the error message). How are you allocating xx? For your second question, envelope should be done on a per note basis, so it has to be put into the low-level function. In the example, x is the horizontal axis, y is the vertical axis, and e(t) vs t is what you want, so you should be able to make the connection.
(4) If you add both of the vectors together, then wouldn’t you be adding the frequencies together?
ANSWER: The spectrum is the ADDITION of frequency components.
(4) This is a general question concerning lab 4. It has been noted that “for” loops are unwise to use and inefficient in Matlab; however, I was wondering if the use of “for” loops is completely banned in lab 4?
ANSWER: “For” loops are NOT banned. We are trying to get you to use vectorization as much as possible. But the music synthesis is one place where a "for" loop makes sense. In other places it would be a very bad choice. When you need speed, vectorize !
(4) I understand the individual files we’ve been working with (onenote, play_scale, vsinus), but I’m having trouble tying it all together to synthesize the music.
ANSWER: Calling order: play_scale calls onenote which calls vsinus. Now replace play_scale with “play_song” Study how play_scale uses a list of keynums and durations; then adapt to the file format information given.
(4) I do not understand how we are supposed to play three vectors of keys at the same time.
ANSWER: How did you play the “chord” in lab #3, section 4.1? What operation did you use to play the 4 notes of the chord simultaneously?
(4) Is there any way to save the sound produced by soundsc() into a file (.wav or other format)?
ANSWER: A search of the MATLAB docs would turn up: wavwrite() and also wavread(). Make sure to obey the NORMALIZATION restriction in wavwrite().
(4) I’m having trouble getting a nice looking frequency spectrogram from plotspec(). Since plotspec() shows frequencies up to half the sampling rate, all the musical notes are concentrated near the bottom of the graph. I’m still not quite sure what the Lwindow parameter does.
ANSWER: If you want to resolve the frequencies, make Lwindow bigger, but keep Lwindow as a power of two. This is important when the frequencies are close together. Power of two is important because the underlying algorithm is the FFT, which is super-efficient for those lengths.
(4) When I run my play_scale file, it says "index exceeds matrix." Why would that happen?
ANSWER: You may not be using or computing the durations correctly. Use dbstop if error and snoop around for the durations and the lengths. Make sure that you know that your note function is making signals of the correct length for quarter notes, or eighth notes. Also, the length of xx(n1:n2) is n2-n1+1; check to be sure that is the length of your tone output.
(4) In play_scale, one line says, “length(tone);" since tone is a sinusoid not a matrix, how can you measure it’s length?
ANSWER: Tone is a vector containing “sample values” of a sinusoid. Therefore, as a vector it contains a certain number of elements. The number of elements is its length.
(4) I’m storing the treble and two bass parts of the song in three different matrices, but they are different sizes. This means that I can’t add them together, but I can play each one separately. Any suggestions?
ANSWER: They should be almost the same length (within a few samples). If so, just use the colon operator to chop the longer ones off (or add a few zeros to the other ones, which is probably a better solution than chopping) to make them all the same length. Then add.
(4.1) When I tried to do the summation with vsinus, I got an error reporting low memory; what could be the reason for this?
ANSWER: I suspect a bug. You should not run out of memory doing this, unless you’re working on an old computer with very little RAM. See the posts on debugging. Put a dbstop in your vsinus function and inspect the sizes of all the variables with whos. Also consult help debug.
(4.3) I have no idea how to envelope the musical passage that was created in Lab 4. I read through the lab instructions on enveloping, but I don’t know where to start.
ANSWER: You need to multiply two signals together. Create an envelope signal that follows the ADSR diagram. Call the result e(t), and make a MATLAB vector ee containing the values. Create one note as before: call it v(t) and store it in a vector called vv. Then multiply: e(t)v(t) which in MATLAB is ee.*vv. This has to be done for each and every note. Also, the lengths of the notes are different, so the length of the envelope function has to change. Finally, use linspace() or interp1() to generate an envelope that consists of straight line segments.
(4.3) We are asked to plot a few periods of two or three sinusoids to illustrate we have the correct frequency. Does this mean we just zoom in on three random sections of our wave plot and add the graphs into our report?
ANSWER: YES, but for this song it’s going to be hard because there are no isolated notes. If you choose a “random” section, the waveform might be very complex—no isolated sinusoids. You should be doing a spectrogram of some portion of the signal. This will cover a small time segment but many notes. Then you could pick out some notes that are visible in the spectrogram and show the time waveform over a few periods for those notes. Try to find some part of the waveform so that you can “justify” that you have the correct period in the signal.
(4.4(d)) We are asked to plot a few periods of two or three of the sinusoids. I’m assuming this means two or three different notes, but do you want pure sinusoids, or those with the second harmonic, or those enveloped in ADSR? Also, should we plot the notes individually, or plot a combination of two notes?
ANSWER: YES, plot 2 or 3 notes. Try to find a place where you can use the time-domain plot to verify that you’ve synthesized the correct frequency. This will probably be difficult once all the tweaks have been applied. Try to plot an individual note so that you can show that it has the right frequency.
(4.3) I have created an ADSR, but it has resulted in a static popping noise in between each note. Is there anyway to get rid of this popping? What exactly causes this?
ANSWER: This shouldn’t happen. ADSR smoothes the ends of each note. Make a plot of your ADSR to verify that it is correct. It has to change with the note duration. Make a plot of the ADSR times the sinusoid to verify that it starts slowly from zero and ends slowly going down to zero. Pops are caused by abrupt jumps in the signal value.