Introduction
In
part 1 we examined the prototype version of Tasty Beat, a music
sequencer designed to help you create interesting beats & rhythms.
Part 1 concentrated on the exploration of MIDI and Tasty Beat's object model
assembly TastyBeatLib.
Here in part 2 we'll be examining the complete (and far more polished)
version 1.0 of Tasty Beat. We'll be taking a close look at the user
interface elements of Tasty Beat and how they were assembled into an
attractive and functional software application.
New & Improved
As you can see in Figure 1, the Tasty Beat user interface has come a long
way since the prototype. A ToolStrip control has been docked to the
top of the form, significantly cleaning up the appearance while also adding
noteworthy new capabilities. New features include the ability to
create and manage multiple patterns, as well as multiple tracks for each pattern.
When in this pattern view and the Play button is clicked (or its keyboard
shortcut F5 is pressed) the pattern will begin to play. This pattern
will loop continuously until stopped by the user (via F5 or the Stop
button).
Figure 1: Version 1.0 of Tasty Beat, a musical beat making program
Additionally, the new Song tab
shown in Figure 2 empowers users to assemble patterns in any desired order
to construct a complete song. Patterns may be repeated in any
imaginable arrangement by utilizing the arrow buttons to add, remove, and
shift patterns around. When this song tab is active and the Play
button is clicked (or its keyboard shortcut F5 is pressed) the complete song
will play, starting with the pattern listed at the top of the Song Pattern
Arrangement list and working its way progressively down to the bottom.
The song will stop playing once it reaches the end, or alternately it can be
stopped prematurely via the F5 key or Stop button.
Figure 2: The new Song tab of Tasty Beat 1.0 allows complete songs to be
formed from custom beat patterns.
Tasty Source Code
When the user loads a song (a *.tbeat file) the DisplaySong function is
called to load the song data into the TastyBeatLib object model and display
that song data in the user interface. The DisplaySong subroutine is
shown below. The first line tells the object model to load the data,
then the next few lines set a couple internal variables as set the form's
caption. The final few lines delegate the user interface rendering to helper subroutines.
The Pattern tab shown in Figure 1 contains a FlowLayoutPanel control.
This FlowLayoutPanel is then filled with elements that represent the track
data for each track in the currently selected pattern. The DisplayPattern
subroutine (shown below) makes this happen.
The DisplayPattern subroutine starts by clearing out any old pattern data
before looping through each track in the current pattern to display its
data. The display of each track's data is delegated to a user control
named ucPatternTrack. Rounding things out, some final user interface elements are
set to coordinate the tempo (playback speed) of the pattern and the number
of beats per bar. Finally, the form's size is adjusted to fit nicely
with the displayed tracks.
The ucPatternTrack user control is used to display the data for one track
in a pattern. The pattern shown in Figure 1 has four tracks, each set
to play a different drum sound. So in this case there
are four instances of the ucPatternTrack control inside the FlowLayoutPanel.
I chose to use a ToolStrip control as a convenient way of displaying the
track data. Each X shown in the Pattern tab of Figure 1 is actually
a ToolStripButton contained inside a ToolStrip. Each ToolStrip is
contained in an instance of the ucPatternTrack control, and (as
mentioned previously) all
of the ucPatternTrack controls are contained in the
FlowLayoutPanel.
My Resources
The images contained in the ToolStripButtons (and many of the other images
also used in this application) are stored as embedded resources. These
resources were configured via the Visual
Studio Project Resource tab shown in Figure 3.
Figure 3: Visual Studio's Resources tab is a convenient way to configure
embedded resources such as images.

This easily allows resources to
be assigned to controls dynamically with a single line of code, thanks to
VB.NET's convenient My namespace shortcut:
Similarly, VB.NETs' built in My namespace is also used to store the
last song with which a user worked. Tasty Beat's FormClosed event
contains the following code to store the filename of the song:
As you can see, it takes surprisingly little code to store user preference data
such as this. The only thing I had to do in advance was use Visual
Studio's Project Settings tab to tell it I planned to store a user configurable
string named LastSong. Tasty Beat's FormLoad event uses a similar line of
code to retrieve the filename of the song the user last worked with:
The setting will contain an empty string if the value has never been assigned.
Song Playback
Tasty Beat has two different play modes; one to play just the current pattern,
and one to play the whole song. The playback mode is determined by which
tab (Pattern or Song) the user is looking at when the click the play button.
When the user clicks the play button at runtime, the form's timer control is
enabled. Its interval property has been synchronized with the tempo chosen
by the user. The timer's Tick event invokes either the PatternTick or
SongTick subroutine depending on the playback mode.
The PatternTick subroutine loops through each track of the selected pattern and plays
the drum sound associated with that track if the data specifies it should do so.
The SongTick subroutine is a little more complicated:
Since each pattern may have a different tempo, the tempo is set at the
beginning of each pattern. Next, each track is iterated in a manner
similar to the PatternTick subroutine. Finally, the next action must be
determined and prepared. The next action might simply be to play the next
beat in the current pattern. However, if the end of the pattern has been
reached then the next pattern must be queued up. If there is no next
pattern then the end of the song has been reached and playback should be
stopped.
Summary
Part 1 of this article introduced you to the MIDI standard, Windows
API calls, Xml Serialization, and the TastyBeatLib object model. Part
2 has taken you through the Tasty Beat user interface and explored useful
programming concepts such as user controls, embedded resources, and VB.NET's
convenient
My namespace.
I hope you'll install Tasty Beat and have
fun with your musical creativity. I also encourage you to
download the source code of Tasty Beat
to get a more detailed look at the 1000+ lines of source code that I've only been able to
shown in a cursory manner in the limited space available here.
Might there
be a Tasty Beat 2.0 in the future?
Let me know if you're
interested and tell me about the features you'd like to see. Until
then, feel free to enhance the code yourself;
I'd love to hear what
you do with it.
Downloads
About Steve Orr
 |
Steve C. Orr is an ASP Insider, MCSD, Certified ScrumMaster, Microsoft MVP in ASP.NET, and author of the book “Beginning ASP.NET 2.0 AJAX” by Wrox press. He’s been developing software solutions for leading companies in the Seattle area for more than a decade. When he’s not busy designing software ...
This author has published 9 articles on DotNetSlackers. View other articles or the complete profile here.
|
You might also be interested in the following related blog posts
Introducing SharePoint 2010 Training at U2U
read more
The Underground at PDC
read more
My History of Visual Studio (Part 6)
read more
BeginDialOut with Office Communicator Clients
read more
DotNetNuke Fusion Results for Q3
read more
GiveCamps Get a new Sponsor
read more
Announcing the WebsiteSpark Program
read more
Scenarios for WS-Passive and OpenID
read more
More On The CodePlex Foundation
read more
Foxit PDF Previewer update
read more
|
|
Please login to rate or to leave a comment.