Assignment 6

Due: Friday, April ***, at 10:00am

You can turn in your assignment up until 10:00am on 4/**/18. You should hand in both a hardcopy and electronic copy of your solutions (it is ok to hand in your hardcopy during your lab on Friday, but the electronic copy should be submitted by 10:00am). Your hardcopy submission should include printouts of two code files, drawGUI.m and musicGUI.m, and a hardcopy of a picture created with the GUI sketchpad that you construct for Problem 1. Your electronic submission is described in the section Uploading your saved work. (If you'd like to save paper, you can cut and paste all of your code files into one file, but your electronic submission should contain the two separate files.)

Reading

The following material is especially useful to review for this assignment: notes and examples from Lectures #13-16 and Lab #8. There is also extensive online documentation on the creation of graphical user interfaces with the GUIDE program available through the MATLAB Help facility.

Getting Started: Download assign6_problems

Use Cyberduck to connect to the CS server and download a copy of the assign6_problems folder onto your Desktop. The assign6_problems folder contains one code file for Problem 1, setupCoords.m and six code files for Problem 2: testMusic.m, emptySong.m, addNote.m, displayNotes.m, displaySignal.m, and playSong.m.

Uploading your completed work

When you are done with this assignment, you should have 11 files stored in your assign6_problems folder: two .fig files, drawGUI.fig and musicGUI.fig, and eight M-Files, drawGUI.m, setupCoords.m, musicGUI.m, testMusic.m, emptySong.m, addNote.m, displayNotes.m, displaySignal.m, and playSong.m.

Use Cyberduck to connect to the CS file server and navigate to your cs112/drop/assign6 folder. Drag your assign6_problems folder to this drop folder. More details about this process can be found on the webpage on Managing Assignment Work.

Problem 1: Create a GUI sketchpad

In this problem, you will build a GUI sketchpad that might look something like this when complete:

Part A: Using the Layout Editor to lay out your GUI

To begin, enter guide in the Command Window to start the Layout Editor for the MATLAB Graphical User Interface Development Environment. A GUIDE Quick Start window will appear with Blank GUI (Default) selected. Click the OK button. A Layout Editor window will appear (image shown below), titled untitled.fig (when you save your GUI for the first time, name it drawGUI). Select Preferences... from the File menu, and in the Preferences window, check the box labeled Show names in component palette and click the OK button. You are now ready to create your first GUI!

Guide layout window

First, you're going to design the physical layout of your sketchpad, using the components listed below. The GUI image above is just a sample -- you are free to layout your own GUI as you wish.

  • Axes: drawing window
  • Popup Menu: menu to select square, circle or triangle
  • Edit Text: text boxes with labels where the user can enter the following information:
    • x coordinate of position of new figure
    • y coordinate of position of new figure
    • size of new figure
    • line style for new figure, e.g. g:*
    • name of picture
  • Static Text: text label for picture name
  • Checkbox: to set linewidth to 1 (if not checked) or 2 (if checked)
  • Toggle Button: to specify hold on or hold off
  • Push Button: buttons for each of these actions:
    1. plot the new figure
    2. undo the last plot
    3. close the GUI
For each component, do the following:
  • drag and resize the component to the desired location and size
  • double-click on the component to open the Property Inspector to set the following properties for each component:
    • the String property specifies the text string that will appear on the component
    • the Tag property specifies a name that will be used to refer to this component in your GUI code
    • (optional) ForegroundColor, BackgroundColor, FontSize
General tips for working with GUIs

  • The .m file and .fig files are intertwined:
    When you add a new component to the .fig file, the .m is automatically updated to include the new component.
  • Resizing the whole GUI:
    The entire GUI window can be resized by dragging the lower right corners of the full Layout Editor window and the inner layout grid.
  • Saving your work so far:
    Click on the save icon (floppy disk) in the menu bar, or select Save from the File menu. Type drawGUI as the file name. MATLAB will also save the Layout Editor figure as a .fig file, e.g. drawGUI.fig.
  • Saving and running your GUI:
    Click on the green triangle (circled in red below) at the far right end of the menu bar.

  • Executing the current GUI file:
    Type drawGUI in the Command Window, or selecting Run from the Tools menu.
  • Revisiting this GUI later:
    To return to this GUI in the Layout Editor at a later time, enter guide drawGUI.fig in the Command Window

Part B: Writing MATLAB code to add functionality to your GUI components

Once you have your GUI components laid out, you can then modify the drawGUI.m code file to perform actions in response to each of the GUI components. Recall that MATLAB automatically generates code for each GUI component in your drawGUI.m file. First, modify the drawGUI_OpeningFcn function (executed when the GUI is first created) by constructing fields of the handles structure that store information that needs to be shared across GUI components:

  • matrix of x,y coordinates for a square with side length 1
  • matrix of x,y coordinates for a circle of diameter 1
  • matrix of x,y coordinates for an equilateral triangle with side length 1
  • vector to store the plots drawn so far (to support the undo operation)
To assist you with the matrices of coordinates for the three shapes, the function setupCoords is provided in the setupCoords.m file. This function returns three matrices that contain x,y coordinates for the square, circle, and triangle. The first row of each matrix contains the x coordinates and the second row contains the y coordinates. Examine the coordinates to understand how the user's specified position and size will affect their appearance. In the drawGUI_OpeningFcn function, the matrices returned by setupCoords can be placed directly into the handles structure, similar to the setup of variables in the energyGUI program discussed in lecture.

Your next step is to modify the Callback functions for the components that have an immediate visual effect in your GUI. For example, the plot button has an immediate effect when pressed in the GUI. For the other GUI components that do not have an immediate visual effect (e.g., x position, y position, etc), MATLAB automatically keeps track of the current values of the user-entered strings.

  • Edit Text component for picture name: modify the Static Text string that appears below the drawing area, using the text that the user entered in the Edit Text box. Remember that you have access to all of the GUI components through the input handles structure and can read and modify the state of these components with the set and get functions.
  • Toggle Button: set hold on or hold off, depending on the state of this button, and also adjust the text string that appears on this button in the GUI display (similar to the sourceToggle in the energyGUI program).
  • Push Button components: for the plot button, call the plot function to plot the selected figure (square, circle or triangle) in the drawing window, using the current settings for the x and y position, size, line style and linewidth. Note that the Value property for a checkbox is 0 when not checked and 1 when checked (the same is true of a toggle button). Also modify the field of the handles structure that stores the vector of plots in the current display, in order to support the undo operation. For the undo button, delete the last plot drawn and update the handles structure appropriately. For the close button, execute the following statement: delete(handles.figure1)
Notes:
  1. Remember that every function that modifies the value of a field of the handles structure must include the following statement at the end:

          guidata(hObject,handles)
    
  2. Many Callback functions will remain empty, that is, no action will be performed when the GUI components are used. The GUI component information (e.g. x position) is accessed by using the handles structure from within the Callback function for the plot button.
  3. You can also include printing statements by omitting the semi-colon at the end of any statement that produces a value, or adding calls to the disp function. These values will be printed in the Command Window.

Part C: I think my GUI is done, now what do I do?

Thoroughly test your GUI to make sure it really works.

Nothing to undo?

Check your GUI in the following scenario. If your hold on button is clicked and you plot something, and then click undo, what you just drew should go away. Now, if you click undo again, but there is nothing to undo, a well-designed GUI would handle this scenario gracefully (i.e. without generating MATLAB error messages). Your GUI should handle this scenario gracefully.

View the whole drawing from the beginning

MATLAB's tendency is to show just what you plot and no more. When drawing in a sketchpad, it is often desirable to view the entire drawing canvas for the session. One way to do this is to create a rectangle that has the dimensions of your desired drawing (e.g. 12.5 x 9.25 in the above GUI), and draw that rectangle in white so it is invisible. This will initialize the plotting area to the specified dimensions. Of course, if the user plots something out of that canvas, (e.g. a bird at coordinates (20,20)), then MATLAB will automatically expand the canvas to include the new object.

Design a picture and print a hardcopy

Fully test your GUI by experimenting with many settings. When testing, remember that you should hit the return key after editing any text field of your GUI. When you are convinced your GUI is working well, construct a final picture to submit with your assignment. Print a hard copy of your final picture (see instructions below) to turn in with your assignment.

How to print a hard copy of your final picture in your sketchpad

Electronic submission

Be sure to include both the drawGUI.m and drawGUI.fig files in the assign6_programs folder that you submit electronically.

Problem 2: Making Music with MATLAB   

In this problem, you'll create a GUI for a program that allows you to create, display and play a simple song in MATLAB. Much of the code for this program is provided for you. Your task is to create the GUI, which will contain some new GUI components: a listbox, radio buttons and a slider. Here is a sample GUI layout for the program:

music GUI layout

You're welcome to add your own style to the appearance of the GUI, which should contain the following components:

  • a Listbox that contains a list of notes for the user to select the next note to add to the song
  • Radio Buttons for the user to select a loudness and duration for each note, given three choices
  • two graphing Axes to display the note sequence and sound waveform for the user's song
  • a Slider that allows the user to shift the sound waveform to the left or right, to view different parts of the waveform
  • various Push Buttons to perform the following actions:
    • add a note to the song
    • clear the song
    • display the song (both the notes and waveform)
    • play the song
    • zoom in to see the waveform at a higher resolution
    • zoom out to see the waveform at a lower resolution
    • exit the program

There are six code files in the assign6_problems folder: a script file named testMusic.m and five function files, playSong.m, displaySong.m, displaySignal.m, addNote.m and emptySong.m. You do not need to make any changes to these files. The functions assume that the song is stored in a cell array that contains three vectors: the first vector stores the notes (integers from 1 to 13 that represent the 13 notes listed on the GUI), the second vector stores the loudness of each note (an integer from 1 to 3, representing soft, medium and loud) and the third vector stores the duration of each note (an integer from 1 to 3, representing short, medium and long). You do not need to write any code that refers to this cell array of vectors. Your GUI code will just call the five functions, described below:

function song = emptySong
% returns an initial empty song

function newsong = addNote (oldsong, note, loudness, duration)
% given an input song and input note (integer between 1 and 13), loudness
% and duration (both integers between 1 and 3), returns a new song with
% the new note added to the end of the old song

function displayNotes (song)
% displays the notes of the input song - time is shown on the horizontal
% axis and the notes (integers between 1 and 13) are shown on the vertical
% axis. Each note is displayed as a short segment whose length is the
% duration and width is the loudness of the note

function displaySignal (song, zoom, slider)
% displays the sound waveform for the input song, given an input zoom factor
% (integer greater than or equal to zero) that controls how stretched out the
% signal is on the horizontal time axis, and input slider value (number between
% 0 and 1) that controls which segment of the sound waveform is shown

function playSong (song)
% plays the input song

To illustrate how these functions are called, the script testMusic.m creates a song that consists of the 13 notes of the scale in ascending order with varying loudness and durations, displays the notes and the sound waveform for two different zoom factors 0 and 10, and then plays the song.

Tips on creating the GUI layout with GUIDE

  • Multiple strings for a Listbox can be entered in the Property Inspector in the same way as strings for a Pop-up Menu.
  • To create the radio buttons, first drag a Button Group onto the GUI and then drag the individual Radio Buttons to their location inside the Button Group box on the GUI. The Title property for the Button Group controls the string that appears at the top of the box on the GUI (e.g. "Select loudness" on the GUI displayed above). The radio buttons each have a Value property that is 0 or 1 depending on whether the button is selected. Be sure to specify a unique Tag name for each radio button.
  • A Slider has a Position property that is a vector of four values that specify (1) distance from the left edge of the GUI window, (2) distance from the bottom of the window, (3) width and (4) height. If the width is greater than the height, the slider will be oriented horizontally. The Slider has a Value property that is a number between 0 and 1, which can be provided directly as an input to the displaySignal function.
  • You do not need to create labels for the two graphing areas - these labels are displayed by the displayNotes and displaySignal functions using the title function.

In the GUI opening function, create two variables in the handles structure to store the current song (this can be initialized to the empty song that is returned by the emptySong function) and the zoom factor (initialized to 0).

Guidelines on the GUI behavior

  • When the "add note" button is pressed, a new note should be added to the current song using the user's selected note, loudness and duration. After getting this information from the GUI, the addNote function can be called to add the new note. The displays of the notes and sound waveform do not need to be updated at this point.
  • When the "display song" button is pressed, both the notes and sound waveform should be displayed. The axes function can be used to specify where to display the notes and signal.
  • When the "zoom in" button is pressed, the zoom factor should be incremented by 1, and when the "zoom out" button is pressed, the zoom factor should be decremented by 1 (be sure the zoom factor does not become negative). When the "zoom in" or "zoom out" buttons are pressed or the slider is modified, the display of the sound waveform should be updated by calling the displaySignal function. Note that when the sound waveform is displayed for a zoom factor of 0, the full waveform is displayed and the slider does not shift the waveform.
  • When the "play song" button is pressed, the user should hear their song played.
  • When the "clear song" button is pressed, the current song should be reset to an initial empty song.
  • Clicking on the "close" button should close the GUI window and terminate the program.