For this assignment you will develop a simple music player that can play three songs. In the centre of the screen a play button is displayed when no song is being played. Otherwise, a pause button is displayed there. At the bottom of the screen, an indicator shows how much of the song has been played.
More detail follows.
As with the previous assignment, you are provided with starter code. The code does the following:
- imports the minim library.
- declares a Minim variable by the name minim.
- declares an AudioPlayer variable by the name song.
- You will use the minim variable to load songs from disk, and the song variable will hold the song that is currently playing.
- A boolean variable called playing, whose usage is explained later in this section.
- The setup() function has been (mostly) implemented for you. It sets the size of the screen, sets playing to false, and loads the first song from disk. The function then initializes minim and loads the first song.
- The draw() function has been (mostly) implemented for you.
- The draw() function calls two functions drawSongList() and drawSongSlider(), and then either drawPause(), or drawPlay(), depending on the value of playing.
- Code to handle closing minim has been implemented. You do not need to worry about doing that in your code, but make sure that the exit() function at the bottom remains in your submission.
This assignment is marked out of 45. There are 10 bonus marks.
Before you start with the rest of the program, perform the following steps.
Place 3 mp3 files in your source code folder, under the names “song1.mp3”, “song2.mp3”, and “song3.mp3”.
Warning
name these files exactly as described. You will not be submitting them as part of your assignment.
(1 mark) Add a statement to draw the background as the first line of draw()
Done? Good. Now, you should start by implementing the following functions:
Implement the function loadAndPlaySong(int songNum) as follows:
(3 marks) songNum is guaranteed to be a number between 0 and 2, inclusive. if songNum is 0, loadAndPlaySong should use the minim variable to load “song1.mp3” into the variable song, and start to play it from the beginning. Similarly, songNum having value 1 results in “song2.mp3” being loaded and played, and songNum having value 2 results in “song3.mp3” being loaded and played.
See the notes for information on how to load a song.
After the song starts playing, you may want to update the playing variable.
(Bonus 2 marks) Do not use if-else-if to complete this function.
Implement the function drawSongList() so that calling it achieves the following:
(3 marks) The three songs are displayed on the screen. Do not use the actual song names. Use “Song 1”, “Song 2”, and “Song 3”. How to arrange the songs (horizontally, vertically, etc) is up to you.
(3 marks) The name of the currently playing song is drawn on the screen with a different font than that used for the other two songs. For example, in the images provided on this page, the playing song is written in font Menlo-Bold-32 while the other songs are written in font Menlo-Regular-32.
How you keep track of the currently playing song internally is up to you.
(1 mark) To implement the drawSongList(), you will need to create three fonts using the font creator and load them into three global font variables that you created.
Implement the function drawSongSlider() to achieve the following:
- (4 marks) A rectangle is drawn with top-left corner (100, 400), height 5, and rounded corners. The width of the rectangle is determined by using the currentSongPos which has been declared for you and initialized to hold the current song position in milliseconds. That is, the number of milliseconds of the song already played. The width must be at most 300
Since most songs will have more milliseconds than you have pixels on the screen (do you know any 500 millisecond hit songs?), you will have to massage currentSongPos to get a proportional value. The function song.length(), giving the length of the song in milliseconds might come in handy, when coupled with another function that was heavily used in class.
(2 mark) A grey circle is drawn at the end of the rectangle drawn above (as seen in the examples). The circle should be of diameter roughly 10, though its actual size is up to you. The circle should progress with the rectangle.
Hint: Having determined the width of the rectangle, you do not need a dx variable to keep track of the circle’s position.
(3 marks) The number of seconds of the song that have already played is drawn on the left of the song slider. The total number of seconds in the song is displayed on the right of the song slider. Again, the function song.length() might come in handy. You should not display milliseconds, but only seconds.
You will need a smaller font than the font used for the songs.
Note
Due to an issue with AudioPlayer’s length() function, there may be a discrepancy when the song ends between the current time and the total time. This is expected and you do not need to worry about it.
- (Bonus 1: 2 marks) Draw a background rectangle for the song slider, as depicted in
the images on this page. The slider should slowly fill the background rectangle. You may wish to use transparency. As noted above, due to a problem with length(), if the slider fails to fill the background rectangle because of a discrepancy, that is OK.
(Bonus 2: 3 marks) Instead of simply showing the number of seconds elapsed and number total number of seconds, display the time in minutes. For this you will need the / and % operators.
(3 marks) Implement drawPlay() so that a play button is drawn in the centre of the screen. The choice of colours and dimensions is up to you, but you should make it nice. See the image below for a sample of a play button
(3 marks) Implement drawPause() so that pause button is drawn in the centre of the screen. The choice of colours and dimensions is up to you, but you should make it nice. See the image below for a sample of a pause button
Note
The buttons above are drawn using the Processing shapes we all know and love such as, ellipse, rect, and triangle. You may choose to do the same or, if you like, get images of play and pause buttons from the internet.
The music player will be controlled entirely by the keyboard. This means that the player will need to write a keyPressed() function to deal with the various buttons pressed by the user. A keyPressed() has in fact been written for you in the starter code. Note that it is divided into two cases: either key == CODED, or key != CODED. In the former, the function dealWithNonCodedKeys() is called, and in the latter the function dealWithCodedKeys() is called. You will have to implement both of these functions as follows:
dealWithNonCodedKeys(). This function must implement the following functionality, depending on the value of the global variable key:
(3 marks) if key is the space bar, then if music is playing, it should be paused, and if music is paused, it should resume playing from when it was last paused.
(2 mark) if key is r, the song should start playing from the beginning.
(3 marks) if key is n, then the next song on the list should play.
Current Song
Next Song
song 1
song 2
song 2
song 3
song 3
song 1
(Bonus 3 marks) If key is p, then the previous song should play:
Current Song
Next Song
song 1
song 3
song 2
song 1
song 3
song 2
dealWithCodedKeys(). The only coded keys we are interested in for this assignment are the left arrow and the right arrow. The case where the left arrow has been pressed corresponds to the case in which keyCode == 37 and the case where the right arrow has been pressed corresponds to the case in which keyCode == 39:
- (3 marks) If keyCode == 37, then the user has pressed the left arrow key. The song should rewind by 3 seconds.
- (3 marks) If keyCode == 39, then the user has pressed the right arrow key. The song should skip forward by 3 seconds.
In either of these cases, you will want to use the song.cue(int miliseconds) function, which changes the song’s position.
You may notice that the rewinding is not as fluid as skipping forward. That is natural and you do not have to fix this.
In addition to the points allocated to each part of the assignment above, 4 marks are allocated for style. Namely:
- Proper indentation of code.
- Sensible variable names.
1 mark is allocated to logging onto the course bulletin board, navigating to the Assignment 3 forum and replying to the “Hi everybody!” thread.
Please rename the given file (musicPlayer.pde) to firstname_lastname_studentNum_ass3.pde, where firstname_lastname is your full name separated by an underscore and studentNum is your student number.
What you should submit is a folder called firstname_lastname_studentNum_assn3 that contains the pde file as well as the vlw files for the font you created, and any images you may have used, inside a subdirectory named data. Compress this folder as an archive named firstname_lastname_studentNum_assn3.zip.
Note
Do NOT submit the music files. As much as we would love to listen your musical selections, our system is limited in capacity and will reject your submission if it is too big.
Please submit this assignment on-line no later than the due date listed on the course marking scheme.
If you submit the assignment after the deadline, you will be deducted %10 of the maximum points available for the assignment, for each day that you are late. For example if the assignment when submitted on time is marked out of 100, then after one day the maximum mark will be 90, after two days it will be 80, and so on.