82
GUMBALL DRUM MACHINE SOFTWARE & CONSTRUCTION GUIDE Reproduce this fun and practical project for yourself in Visual Basic.NET Easy step-by-step guide designed for everybody from beginner up

Gumball Drum Machine Guide (Sample)

Embed Size (px)

DESCRIPTION

Gumball Drum Machine - Software and Construction Guide.Make beats with sweets! Reproduce this fun and practical project idea for yourself in Visual Basic.NET. This easy step-by-step guide is designed for everybody from beginner up. Chapter 1 guides you through the easy process of building your own device out of foam board. Chapters 2 and 3 explain in detail how to write the software that brings the device to life. Check out gumballdrummachine.com for more details, videos, downloads and an interactive drum machine app.

Citation preview

Page 1: Gumball Drum Machine Guide (Sample)

GUMBALL

DRUM

MACHINE

SOFTWARE & CONSTRUCTION GUIDE

Reproduce this fun and practical project for yourself in Visual Basic.NET

Easy step-by-step guide designed for everybody from beginner up

Page 2: Gumball Drum Machine Guide (Sample)

All contents Copyright © 2010 by Barry Shee. All Rights Reserved worldwide under the Berne Convention.

No part of this document or the related files may be reproduced or transmitted in any form, by any means (electronic, photocopying, recording, or otherwise) without the prior written permission of the publisher. Limit of Liability and Disclaimer of Warranty: The publisher has used its best efforts in preparing this book, and the information provided herein is provided "as is." The author makes no representation or warranties with respect to the accuracy or completeness of the contents of this book and specifically disclaims any implied warranties of merchantability or fitness for any particular purpose and shall in no event be liable for any loss of profit or any other commercial damage, including but not limited to special, incidental, consequential, or other damages. Trademarks: This book identifies product names and services known to be trademarks, registered trademarks, or service marks of their respective holders. They are used throughout this book in an editorial fashion only. In addition, terms suspected of being trademarks, registered trademarks, or service marks have been appropriately capitalized, although the author cannot attest to the accuracy of this information. Use of a term in this book should not be regarded as affecting the validity of any trademark, registered trademark, or service mark. The author is not associated with any product or vendor mentioned in this book.

Page 3: Gumball Drum Machine Guide (Sample)

Contents INTRODUCTION ................................................................................................................................ 1

About the Project ................................................................................................................................ 1

Objectives........................................................................................................................................ 2

About the Guide .................................................................................................................................. 2

Resource Pack ................................................................................................................................. 3

Conventions .................................................................................................................................... 3

Software and Hardware Requirements .............................................................................................. 2

Visual Studio .................................................................................................................................... 2

Webcam .......................................................................................................................................... 3

BUILD ............................................................................................................................................ 5

Objectives ........................................................................................................................................... 5

Design Considerations ........................................................................................................................ 6

My First Design.................................................................................................................................... 6

Gumball Table ................................................................................................................................. 7

Camera Mount ................................................................................................................................ 8

Light ................................................................................................................................................. 9

Gumballs ....................................................................................................................................... 10

Alternative Designs ........................................................................................................................... 11

Structural Foam ............................................................................................................................. 11

Cardboard ..................................................................................................................................... 19

COLOR ......................................................................................................................................... 20

Making a Start ................................................................................................................................... 21

Virtual Gumballs................................................................................................................................ 24

Camera .......................................................................................................................................... 27

Recognition Timer ......................................................................................................................... 32

Virtual Grid .................................................................................................................................... 34

Hole Locations ............................................................................................................................... 40

Camera Settings ............................................................................................................................ 56

Average Hole Color ....................................................................................................................... 58

Gumball Definition ............................................................................................................................ 67

Calibration ..................................................................................................................................... 68

Recognition ................................................................................................................................... 78

Display Results .............................................................................................................................. 80

Page 4: Gumball Drum Machine Guide (Sample)

SOUND ........................................................................................................................................ 83

Introduction ...................................................................................................................................... 83

File System ........................................................................................................................................ 83

Sound ................................................................................................................................................ 89

Direct X .......................................................................................................................................... 89

Playing Sound ................................................................................................................................ 93

Frequency...................................................................................................................................... 97

Beat ................................................................................................................................................. 101

Play/Stop ..................................................................................................................................... 106

Visualizing the Beat ..................................................................................................................... 109

Tempo ......................................................................................................................................... 111

Clean Up .......................................................................................................................................... 112

The End ........................................................................................................................................... 114

REFERENCES ................................................................................................................................ 115

APPENDIX A ............................................................................................................................... 117

Future Developments ..................................................................................................................... 117

APPENDIX B ................................................................................................................................ 120

Hello World ..................................................................................................................................... 120

Hello Graphics ................................................................................................................................. 124

APPENDIX C ................................................................................................................................ 127

Text Files ......................................................................................................................................... 127

Writing ........................................................................................................................................ 127

Reading ....................................................................................................................................... 128

Page 5: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

1

Introduction

About the Project I started this project as a hobby after seeing a video on YouTube. The video showed a device and software designed and created by Hannes Hesse and Andrew McDiarmid of UC Berkeley. The video, entitled “Bubblegum Sequencer”, can be found at http://www.youtube.com/watch?v=ziIdjrR_MRs or by searching for the title on YouTube [1].

The video shows a table-like device with a grid of holes cut into the top surface. Underneath the table and pointing up at the grid is a webcam. The user places different color gumballs on the holes in whatever arrangement they desire.

The video goes on to show a computer program processing the webcam output and detecting the various color gumballs on the grid. It is explained that a sound is mapped to each color gumball and that these sounds are played in time based on the gumball’s position on the grid from left to right. After watching the video, I really wanted one of these for myself.

Only an hour after seeing the video, I had started the project for myself. A few days later, I had finished building the device and was writing the software, thoroughly enjoying it the whole time. It helped that I was reasonably comfortable with using the VB.NET programming language. Reading some of the comments for the video, I saw a lot of interest from others wanting to build the drum machine for themselves and saw an opportunity to help.

Page 6: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

2

The goal of this project is to construct a physical device and accompanying software, which together will constitute a drum machine. The user will place various color gumballs at various positions across a grid. The color of the gumball determines the sound that is played, while its position on the grid corresponds to the time at which it is played. Additionally, the user should be easily able to do the following in the software:

Objectives

• Start and stop the drum machine

• See live feedback on the computer screen of where they have placed gumballs

• Adjust the volume

• Adjust the tempo

• Set the sound to be played for each color gumball during use

• Be able to change the pitch of the sounds on each row

About the Guide The first time I watched the Bubblegum Sequencer video on YouTube, it looked very impressive and somewhat difficult to reproduce. Thinking about it and breaking it down into smaller chunks, I realized that if I put my mind to it, I could probably manage each of the smaller tasks. Similarly, this guide is laid out so that each step in itself seems small until eventually the whole lot comes together at the end and you have a fully functional Gumball Drum Machine.

This guide is a tutorial about making the device and writing the required software. It is written in easy to follow steps so that a person who isn’t experienced with programming can follow it. By following the instructions in this guide, those with previously little or no programming experience will at least learn the basics. This project is an ideal candidate for an introductory Visual Basic tutorial because it spans so many different topics from sound production to image recognition and everything in between.

I do not have the qualifications to speak with any authority on the theory side of Visual Basic and you will not find any definitions in this guide. Rather, the guide is intended as a practical aid with the aim of building a working drum machine. I apologize now for any instances in the guide where I have

Page 7: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

3

not explained something correctly. To get a full understanding of the language, I suggest that the reader references textbooks such as “Programming Microsoft Visual Basic 2005: The Language” by Francesco Balena [2] and websites such as MSDN[3], as well as many other helpful forum sites that can all be found in the References section at the end of this guide.

Wherever I was in doubt as to the level of practical detail required for a particular topic in this guide, I have aimed to err on the side of too much explanation. Where something isn’t fully understood relating to Visual Basic, I would urge you to search the internet for a better explanation or reference a suitable textbook. As you progress through writing the source code, don’t be afraid to take time out and experiment with the code as this can be a powerful method of learning. There is usually several ways of achieving the same results in programming so settle on a way that makes sense to you.

A compressed folder containing useful material accompanies this guide. The folder contains: Resource Pack

• Full commented source code, saved at 13 different milestones throughout the development

• A ready to use version of the Gumball Drum Machine software

• Construction plans for various Gumball Drum Machine devices

• Reference libraries that are required to run the software

• Useful images for your program’s visual design

• A selection of sound files to get your Drum Machine up and running

Download the file and decompress it using windows or a third party application such as WinZip.

There are a number of different typographic and layout styles used in this book to indicate different types of information.

Conventions

Code Excerpts Direct excerpts from the source code are contained in boxes with a gray edge and background. Line numbers appear down the left edge of code excerpts so that the individual lines can be referred to easily from the text.

Some lines of source code have had to be wrapped to fit the width format of this guide. The line continuation character was used to split the code over two or more lines so that the allowed width was not exceeded e.g. Lines 1 and 2 in the sample excerpt above would naturally be joined on a single line. In the code editor, the line continuation character is just a space followed by an underscore at the end of the line (at the end of Line 1 above). Personally, I find these wrapped lines difficult to read and I recommend that you remove them when writing your own code.

1 2 3 4 5 6 7

Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click 'Set the Image of picWebcam to the current webcam frame picWebcam.Image = WebCam.GetFrame End Sub

Page 8: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

2

Background Information and Notes Here and there throughout the code, I have included some further explanation of a method that has been used. These are indicated by a light bulb symbol.

Milestones There are 13 milestones spread throughout the software sections (Chapters 2 and 3) of this guide. Whenever you see this symbol in the guide, a folder with the same name can be found in the Resource Pack, in the Source Code directory. The folder contains a snapshot of the Visual Basic project, as it should be at that milestone in the guide. By comparing this code with your own, it will help you locate and fix any mistakes you may have made along the way.

Software and Hardware Requirements Before you start writing your program, you will need some tools to help you. The following outlines the software that you need and some useful installation instructions.

I wrote the software for this project using Microsoft Visual Studio 2010 Express. This is a relatively sophisticated product and at the time of writing was available free on the Microsoft website at

Visual Studio

http://www.microsoft.com/express/Downloads/#2010-Visual-Basic. The Express Edition contains practically all the features of its professional retail cousin, at least for our purposes.

The installation is quite straightforward. Visit the link above and click the download button on the page to get Visual Studio 2010 Express Edition. This will download the setup program which itself is about 3MB in size. Once this is downloaded, go to it and double click to run the setup program. Follow the installation instructions on screen. You will not need SQL Server for this project so you may uncheck this box if you wish (installing it can cause complications in my experience). The setup program will need to download more files during installation. The download is 157MB.

Sometimes Microsoft Visual Studio 2010 Express will be referred to as simply Visual Studio or even VS in this guide.

Getting Around If you are familiar with the Microsoft Visual Studio series then you will find that the layout of Visual Studio 2010 Express Edition is almost the same. If you are new to Visual Studio, some of the most important button controls and features that are referred to in this guide are illustrated in the images that follow. For readers who are new to Visual Studio or Visual Basic, I recommend starting with the Hello World tutorial in Appendix B.

Milestone 1 The name of the milestone

Information here is usually intended to provide a better understanding of an aspect of Visual Basic.NET than is strictly required by the project. They are usually important concepts in Visual Basic and further research should be carried out to get a full understanding.

Page 9: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

3

Figure 1 Design View features

Figure 2 Code Editor features

You will need a USB webcam from the outset with this project. If you have not already done so, you will need to install drivers for your particular webcam. It is often the case that Microsoft Windows will install the drivers automatically when you plug in your webcam.

Webcam

The choice of webcam is up to you. I chose to buy what I considered a standard webcam with standard features and 1.3 megapixels. The webcam also had a built in clamp so that it could attach to laptop screens etc. The lens of the webcam that I bought can be focused by rotating the focus ring on the lens. The adjustable focus length made constructing the device easier.

Class Name drop-down list

Solution Explorer Panel

Properties Panel

Design View Tab

Method Name drop-down list

Form

Code Editor

Page 10: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

4

Figure 3 The webcam I used

Webcams usually come with a CD containing additional software. This software is well worth installing, as it will usually allow you to adjust the color, contrast and brightness settings of your webcam. When it comes to gumball color recognition, later in the project, it will be very useful to be able to adjust the settings to get a better contrast between the different colored gumballs.

Page 11: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

5

Build

Objectives The objective of this chapter is to build a physical device that we can use as our Gumball Drum Machine. For me, the project is more about doing interesting things in Visual Basic.NET than about fabrication or woodwork. Depending on your motivation, you can put in as much or as little time and effort as you wish into making the device. The aim of this chapter is to outline the basic requirements of a Gumball Drum Machine and show you how I built each of my devices.

Page 12: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

6

Design Considerations The most characteristic feature of the device is the perforated top surface on which the gumballs sit. The holes are only slightly smaller than the gumballs so that the gumballs sit securely and so that the camera can see the undersides of the gumballs from below.

The webcam needs a sturdy mount below the gumball table if it is to maintain even a rough alignment after the inevitable impacts during use. When designing the camera mount, consider the distance between the gumball table and the webcam and ensure that the camera can focus properly within that distance.

In my experience, a light source is needed to illuminate the underside of the gumballs so that their colors can be seen accurately. The light should be placed out of the field of view of the camera so that it doesn’t cause over-exposure. Notwithstanding this, the light should be placed as close as possible to the webcam, so that any shadows that are cast by the edges of the holes aren’t visible on the gumballs, by the webcam. If adding a light, ensure that the whole of the gumball table receives a similar amount of light. If more light is incident towards the center of the table than around the edges, it will cause problems later when we come to calibrating the gumballs in the software. A method for diffusing the light over the whole table is suggested in the next section.

My First Design

I built my original Gumball Drum Machine from wood. Wood has the advantage of being sturdy, workable, cheap and readily available. Detailed construction plans can be found in the Resource Pack that accompanies this guide.

Page 13: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

7

Gumball Table

Figure 4 Gumball table

The gumball table, by which I mean the basic frame and top surface, is shown in Figure 4. The top surface is made from sheet MDF (Medium Density Fiberboard). A rectangular grid of holes is cut into the sheet using a 16mm spade drill bit (Figure 5). I found the best results are achieved by drilling to half the depth of the sheet from one side and then finishing the hole from the reverse side.

Figure 5 16mm spade wood bit

The size of the grid, in terms of the number of holes, is up to you. I chose to make my grid 16 holes, or columns, wide. This corresponds in musical terms to the number of quarter beats in a measure in the standard 4/4 time. The number of rows on the grid is also arbitrary. When deciding on the number of rows, you should consider that the number of rows is the maximum number of sounds that can play at once. In addition, since the user will have the option of setting a different sound pitch for each row, the number of rows will be the maximum number of different pitches that they can have. My devices have eight rows but six would be plenty.

The legs of the table are made from square dowel softwood. In deciding on the leg length, consider user comfort and webcam focal length, as already mentioned. As long as you ensure that the legs are at least longer than the minimum focal length of the webcam, then you shouldn’t have problems later.

Page 14: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

8

Figure 6 Assembly of the gumball table

Use the dowel to make a rectangular frame around the table perimeter. Attach the legs in the corners with glue and wood screws as shown in Figure 6. The tabletop is then simply tacked with panel pins and glued onto the frame.

Once the gumball table is made, the next step is to make the camera mount. The mount should be sturdy so that no camera movement can occur during use. Screw and glue dowel pieces between the legs at either end of the table as in

Camera Mount

Figure 7. The two cross members should be fixed at roughly the height that the camera will be mounted. Attach another piece of dowel between the centers of the first two members (see Figure 7). You should now have a solid base on which to make a mount, specific for your webcam. The leg bracing also gives extra stability to the whole structure.

Page 15: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

9

Figure 7 Making the camera mount

Most webcams have some method of attaching onto a computer monitor. The particular webcam that I used happened to have a clamp and I decided to use this feature to save some time. I built a wooden bracket onto which the camera could clamp by itself (Figure 8). Remember to ensure that when mounted, the lens of the webcam is centered on the tabletop above. This may mean that the camera mount itself has to be off-centre.

Figure 8 The mount for my webcam

Early versions of my Gumball Drum Machine did not have their own light source. With only the ambient light of the room, the gumballs appeared very dark when viewed through the webcam. As a result, there was no clear definition between colors. Calibration of the gumball recognition software was virtually impossible in this configuration.

Light

Figure 9 DC Strip light used

To improve the situation, a strip light was added, similar to that shown in Figure 9. I chose this light because it spanned the length of the grid, giving a more even light distribution over the area of the gumball grid, compared with a single bulb. The light is powered by batteries or an adapter. Another

Page 16: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

10

possible solution, but one which I have not yet tried, would be to install a grid of six bright LEDs on the base of the device, pointing upwards. Whatever light source you use, you should ensure that it isn’t in the field of view of the webcam or else you run the risk of over-exposing the webcam output with flared highlights.

Even with a diffused light source, it was found that the Gumball Drum Machine yielded very inconsistent results. It seemed to depend on the ambient light at the time of day. At night in a darkened room, the device gave a much more reliable performance. To simulate the darkened room, I added cardboard panels to the floor and walls of the device so that it could be used at any time of the day. The only foreign light that remained to influence the gumballs after these measures were taken was the light coming through the vacant holes on the gumball grid, and this was unavoidable.

Figure 10 Walls to block external light

To maximize the diffusion of light inside the device, I tried a number of coverings on the inside surface of the wall and floor panels. I was surprised that aluminum foil yielded poor results and eventually a white gloss finish was found to reflect the most light evenly over the grid. The required finish was achieved by applying white contact paper onto the cardboard panels. This is available at craft and DIY shops.

When it comes to gumballs, be aware that their size dictates that of the holes in the grid. Large holes are important so that there is a sufficient area of the gumball visible to the webcam underneath the grid. After searching a number of shops, I found suitably large, brightly colored gumballs measuring approximately 21mm in diameter.

Gumballs

I chose eight plain, distinct and brightly colored gumballs so that the software would have minimal problems differentiating between them. I bought more than 16 of each color to ensure that I would have enough of each color to place in each hole for the length of the grid, if that was ever desired.

Page 17: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

11

The gumballs started as bright colors in the shop but the sugar coating quickly faded through use. This was remedied by painting the gumballs with bright paint, which I found available in small tins in my local craft shop. Painting the gumballs is a slow and messy job and its best to paint half of the gumball at a time and allow it to dry before finishing the other half. Finally, once the paint is set, dipping the gumballs in clear varnish hardens the surface and protects the paint. If you do paint the gumballs, they are obviously no longer edible and you must guard against the temptation of eating them, children especially.

Alternative Designs If you don’t have a suitable workspace and the tools with which to build a wooden device, there are much easier construction methods.

Structural Foam

Figure 11 Foam board

This was my favorite construction medium. Foam board is used mainly by modelers and architects to build scale models of objects such as buildings. It is available in most craft shops. The product that I chose came in a pack of three A3 sheets, as in Figure 11. The sheets are 3mm thick. I needed two of these packs for my device.

Page 18: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

12

Figure 12 Computer model of the foam board Gumball Drum Machine

The image in Figure 12 shows the device I built. I created a computer model using a solid modeling application so that I could generate drawings to accompany this guide. The plans are available in the Resource Pack. An example of a drawing of the top panel is shown in Figure 13.

Figure 13 Example of the plans contained in the Resource Pack

Page 19: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

13

Figure 14 Using the needle of the compass to transfer the hole centers from a template onto the board

The holes can be cut out using a device called a compass cutter, shown in Figure 14. They can be readily bought online or in craft shops. The device is just like a regular compass that you would use to draw circles but instead of a graphite tip, there is a scalpel blade. There are many holes to cut into the top panel and the first step is to mark them out.

Figure 15 Hole centre template

Included among the drawings in the Resource Pack is a 1:1 scale template with the hole centers for a portion of the grid (Figure 15). This PDF template should be printed on A4 paper. To use the template, first measure and mark the position of the top left hole on the foam board. Lay the

Page 20: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

14

template page on top, aligning the top left hole of the template with the one marked underneath it on the board. Ensure that the template is flush horizontally and vertically with the foam board sheet. Now, stick the point of a needle, such as that of the compass cutter, through each of the template’s hole centre marks and down through the foam board. You will have to readjust the template several times to mark all the holes on the 16 x 8 grid (or whatever size your grid is). Now the template can be discarded.

Figure 16 Holding the pivot handle of the compass cutter in the chuck of an electric drill

The next step is to cut out the holes. Cutting up to 128 holes can take a lot of time and patience. To speed up the job, I tightened the chuck of an electric screwdriver around the handle of the compass cutter. This was a big improvement and I would recommend doing this if you can.

Before making any holes, make sure that the radius of the compass cutter is set correctly, and tightly, to 8mm. It is a good idea to make some test holes on a scrap piece of foam board and measure the diameter to ensure it is 16mm. To make the holes, hold the drill as steady and vertical as possible. Lower the needle of the compass cutter into the starter hole that we made earlier. Hold the drill up enough so that the blade is not yet touching the foam board surface. Set the drill turning and slowly lower it down so that the blade can begin cutting the hole. It may be useful to have another scrap piece of foam board underneath the piece you are working on in order to get a clean cut on the opposite surface. When you get into the rhythm of cutting the holes with this method, it is really quite quick.

Page 21: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

15

Figure 17 The top panel with all the holes cut out

Cutting the holes in the top panel is by far the most difficult and time-consuming part of making this device. The end panels are just plain sheets of board. The short edge of the front and back panels needs to be trimmed by 6mm so that it fits between the end panels.

Figure 18 Glue gun used to fix the panels together

Use a glue gun to stick the panels together. This type of glue tends not to react with the foam board and cause it to melt and disintegrate. I bought the glue gun shown in Figure 18 very cheaply and achieved very sturdy and clean results. To assemble the device, start by laying the top panel down flat on a table.

Page 22: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

16

Figure 19 Applying a bead of glue along an edge of foam board

Next, apply a thin bead of glue to the short edge of one of the end panels, as in Figure 19. Stick this edge to the top surface of the holed panel, making sure the edges are aligned. Repeat this for the second end panel and you should get the structure shown in Figure 20.

Figure 20 Assembly with the second end panel

Attaching the front and back panels to the model is a little trickier and must be done quickly so the glue does not set before the panels are in place. Apply a bead of glue to the two short edges of the front panel and position this in the assembly. You will need to hold it carefully in place until the glue has set enough to fix it. To finish the front panel, apply a bead of glue along the inside edge, where it

Page 23: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

17

meets the top panel. Repeat this for the back panel and you should have the structure shown in Figure 21.

Figure 21 View from underneath, of the almost complete structure

Finally, we will need something on which to mount the webcam. I cut a strip of foam board and stuck it lengthways along the device as shown in Figure 22 and Figure 23. To attach the strip, temporarily attach the webcam and determine by eye the best position of the lens of the webcam, relative to the grid. Stick it to the end panels using a bead of glue. A second strip may be necessary to provide strength.

Figure 22 Adding a strip of foam board on which to mount the camera

Page 24: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

18

Figure 23 Camera attached to the device

Figure 24 The finished structure, complete with camera and gumballs

Page 25: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

19

There is no reason that a Gumball Drum Machine cannot be built from a simple cardboard box. Again, the only difficult part of this build is cutting the holes for the grid. The compass cutter tool described in the previous section is also suitable for cutting the holes in cardboard. The camera mount can be made from cardboard, in a similar fashion to the foam board model. You can use a glue gun to fix the camera mount in place but even adhesive tape would be sufficient for this device.

Cardboard

Figure 25 Typical dimensions for the grid

It may be a good idea to make the top surface a hinged or removable lid – like a shoebox lid. This would allow access to install, adjust and remove the webcam, as necessary. Like the two previous devices, this one will require a light source to illuminate the underside of the top panel evenly.

Page 26: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

20

Color

In this chapter, we will write the first half of the software required to run the Gumball Drum Machine. We will concentrate on processing the gumball’s position and color and create a virtual gumball grid in the computer’s memory that stores information about each hole on the physical grid. Processing this gumball information to create sound will be left until Chapter 3. The webcam in the device will be used to capture a constant image of the grid and update the color at each hole in real time. To account for light conditions that are constantly changing across the grid, each gumball color will be represented by a color range rather than one specific value. The presence of a gumball at a particular hole, and at a particular time, is determined by comparing the recorded color at the hole

Page 27: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

21

with the color range definitions for each gumball e.g. if the recorded color falls within the red gumball’s range, the gumball at that hole is flagged within the program as being red.

Making a Start Before we get down to the details of gumball recognition, we must first set up a new project. This is a relatively straightforward task in Visual Studio 2010. A typical “Hello World” tutorial is explained in Appendix B and may be of benefit in getting you started with a simple program. To begin developing the Gumball Drum Machine program, launch Visual Basic 2010 and start a new project (instructions for downloading Visual Basic 2010 Express Edition are to be found in the introductory section):

1. Click File → New Project from the main menu. 2. In the New Project dialogue which appears (Figure 26), select “Windows Forms Application”

from the list and name the project “slnGumballDrumMachine”.

Figure 26 Starting a new project

Page 28: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

22

The new project is created and you are immediately brought to the Design view. Open the Properties Panel on the right of the screen (Figure 27). Now click anywhere on the new form,

Form1, to see the Form’s properties appear there.

Figure 27 Changing the properties of the main form

Change the Name property of the form to frmMain . Change the Text property to “Gumball Drum Machine” (this text appears in the title bar of the form). Set the size of the form by either

dragging the bottom right corner of the form or by specifying it numerically with the Size property. I started my form at (600, 800) but depending on your monitor resolution, you may choose to make yours larger. It can easily be changed later by returning to the properties panel of the form.

Naming Convention It is good practice to use a naming convention when writing code. It has the advantage of making the code easy to read, understand and maintain. For this project I have chosen to stick with my usual convention.

According to this convention, when naming classes and visual controls, the name should

always have a three letter prefix, identifying the type of object being named e.g. frmMain indicates a Form. A list of common prefixes including all of those used in this project is given in Table 1 which follows.

The names of any objects or variables use Camel Case convention [22]. This is where the name is formed by several words with no spaces between them. Additionally, the first character of each word is capitalised. An exception to this rule is the prefixes mentioned above which are always lower case.

Toolbox

Properties

Solution Explorer

Form1

Page 29: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

23

Object Prefix

Array arr

Button btn

CheckBox chk

Class cls

ComboBox cbo

Form frm

GroupBox grp

Image img

Label lbl

Object Prefix

NumericUpDown num

Panel pnl

PictureBox pic

RadioButton rad

Structure str

TextBox txt

Timer tmr

TrackBar bar

Table 1 Object prefixes used in this project

Look at the Solution Explorer panel to the right of the screen in Figure 27. Even though we have

changed the Name of the form to frmMain, it still appears as Form1.vb in the Solution Explorer. Form1.vb here refers to the file name in the project’s folder and is separate to the Name property

of the form. To rename the folder, right-click on Form1.vb and click Rename from the context menu. Change the name to frmMain.vb and hit Enter.

Figure 28 The Toolbox with the drawing pin symbol circled

On the far left of the screen, near the top, you will see the Toolbox button (Figure 27). Click it to expand the Toolbox (Figure 28). To keep it open, click on the drawing pin symbol on the header bar (highlighted in Figure 28). The Toolbox is where we will choose the controls to add to the form, such as TextBoxes and Buttons.

Save the project by clicking File → Save All from the Main Menu. A dialogue will appear that will ask you to confirm the project name that we specified earlier. You will also be asked to choose a location for the project. You may select any location you wish but for the purposes of clarity in this guide, we will save the project in a directory named “GumballDrumMachine” on the root (C drive). In the

Location Field, enter C:\GumballDrumMachine. Uncheck the “Create Directory for Solution” option and click Save.

Run the program now by clicking Debug → Start Debugging from the Main Menu . You will see an empty window with the words Gumball Drum Machine in the title. The project is now set up and we can begin adding functionality - easy!

Page 30: Gumball Drum Machine Guide (Sample)

Pages 24-29 are not shown in the preview version. Go to www.gumballdrummachine.com to get the full version and the Resource Pack containing all the plans and source code.

Page 31: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

30

subroutine automatically appears in the code editor, which has a Handles keyword followed by

the Load Event (Excerpt 2). The handle in this case is Me.Load. When we are inside a class and accessing properties and events of that class, we must refer to it in the first person rather than the third person. Me is a special keyword that allows us to refer to the class we are currently in. For all

other object handles in the project, we can refer to them by their name e.g. picWebcam.Paint. Adding Me. before any of these names is perfectly valid but redundant.

Figure 35 Class Name and Method Name drop-down lists

Excerpt 2 Adding the Form Load event to class frmMain

The subroutine beginning on Line 5 of Excerpt 2 will execute immediately when the program starts

because of the presence of the Me.Load handle. Any code that is contained between the Sub and End Sub keywords will thus be executed. Copy the following code of Excerpt 3 into the subroutine in your program.

Excerpt 3 Beginning the Load event for frmMain

In Line 5 of Excerpt 3 we are creating a new instance of clsWebcam, named WebCam. The first thing we want to do is be able to see the output from the webcam in our dedicated PictureBox,

picWebcam. It is possible, and relatively trivial to show the video stream coming from the webcam

1 2 3 4 5 6 7 8 9 10

Private Sub frmMain_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Load 'Create an new instance of the clsWebcam class WebCam = New clsWebcam 'Set up the webcam WebCam.InitialiseWebcam() End Sub

1 2 3 4 5 6 7 8 9 10

Public Class frmMain Dim WebCam As New clsWebcam Private Sub frmMain_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Load End Sub End Class

Class Name drop-down list Method Name drop-down list

Page 32: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

31

in picWebcam. The webcam class that we are using however, clsWebcam, is specially designed for capturing individual frames (images) from the video stream. The class has a Function named

GetFrame, which returns a bitmap image of the current frame at the instant the function was called.

For demonstration purposes, we are going to create a temporary button on the form that, when clicked, will update picWebcam with the current frame coming from the webcam. Go back to the

Designer of frmMain. Click on the Button object in the Toolbox. Now click on an empty area of

frmMain to place the new button.

To quickly create a Click subroutine for this button, double click the button in the form. When any object is double-clicked in the Designer, Visual Studio automatically creates a subroutine for the default method of that object. For a Button, the default is unsurprisingly the Click method. Inside the new Click subroutine, add the code of Excerpt 4.

Excerpt 4 Code for the temporary "show webcam frame" button

Run the program at this stage, making sure your webcam is attached to the computer. Click the new

“Button 1” and you should see a frame from the webcam appear in picWebcam. Click the button rapidly while pointing the webcam at a moving scene and you will see an animation-like effect. This is similar to what we are hoping to do in the next section by using a timer trigger to grab discreet frames from the webcam in quick succession, for analysis.

Most webcams have a bezel that is twisted to alter the lens focus. You can find the optimum focus level now by repeatedly making slight adjustments to the bezel and clicking the button to check the

sharpness of the image in picWebcam.

Milestone 2 Using the webcam

1 2 3 4 5 6 7

Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click 'Set the Image of picWebcam to the current webcam frame picWebcam.Image = WebCam.GetFrame End Sub

Functions A function is similar to a subroutine but it returns a value. A function might be used instead of a subroutine to make calculations or evaluate data. A simple function might add two numbers and return the result to the calling procedure. Functions are often used to make conversions, such as in trigonometry for example, converting degrees to radians. This conversion may be used hundreds of times throughout the code of a program but using a function, the actual formula only has to be written once. This saves time writing code, eliminates potential mistakes and also facilitates easy maintenance. [17]

Page 33: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

32

Figure 36 Screenshot of the program with picWebcam working correctly

Now we know how to capture frames from the webcam and display them on picWebcam. We can delete the temporary button and associated click subroutine, and try to do this with a timer trigger in the next section.

For maximum user enjoyment, the program must be quick to react to changes in gumball placement on the grid. The frequency at which the recognition analysis is run, determines the apparent reaction time. A Timer control is the ideal way to trigger the repeated execution of the recognition code at discreet intervals.

Recognition Timer

The Timer will be used to call the GetFrame function at frequent intervals. The Timer’s Tick event will later be used to trigger all of our gumball recognition code. To add a Timer to frmMain:

1. With the Design View open, find the Timer control in the Toolbox and click on it. 2. Click once anywhere on frmMain to add the Timer to frmMain. 3. A timer symbol, “Timer1”, will appear below the form in the Design View to indicate that a

Timer has been added. It will not be visible when the program is running. 4. Click on the Timer1 symbol to see its properties appear in the Properties panel.

5. Change the Name property to “tmrRecognition”.

6. Change the Interval property to 250 to indicate 250 milliseconds (quarter of a second). Executing the intire recognition code takes a little time so a balance has to be reached

Timer One use for the Timer control is wherever we want to execute some code repeatedly, at certain time intervals. Every time the specified interval has elapsed, the Timer generates a Tick event. Any code contained in a subroutine with this Tick event is then executed. The

Timer is started and stopped by setting its Enabled property to True and False, respectively.

Page 34: Gumball Drum Machine Guide (Sample)

Pages 33-37 are not shown in the preview version. Go to www.gumballdrummachine.com to get the full version and the Resource Pack containing all the plans and source code.

Page 35: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

38

Excerpt 13 Microsoft IntelliSense giving possible values for the variable Gumball

A very convenient feature of structures is that they can contain other structures. It would be very handy here if we could combine the position, color and gumball status into a single structured

variable for each hole. We can create a new structure named strGrid to achieve this. Add the

code of Excerpt 14 below the previous structure definitions. The overall structure of strGrid is shown in Figure 39.

Excerpt 14 Creating a structure to combine all the information for each grid hole

1 2 3 4 5

Structure strGrid Dim Position As strPoint Dim AverageColor As strColor Dim Gumball As enuGumball End Structure

Enums Enums are a way of enumerating data. Say, if there are only a few anticipated values for a particular variable e.g. days of the week. The variable could be declared as an integer and each day given a number from 1 to 7, but this is awkward. The variable could be a string but then working with the variables value later becomes tedious. An Enum is a custom data type that can only have the value Monday or Tuesday or Wednesday etc. and Visual Studio makes it very easy and efficient, through IntelliSense, to specify values. It is delared with the

word Enum followed by a name. The body of the Enum consists of the possible values on

separate lines. The Enum declaration is closed with the End Enum keywords. [18]

Page 36: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

39

Figure 39 Diagram of Structure of each cell in arrGrid

The final step is to create an array that can hold strGrid information for each hole on the grid[6]. The grid of holes is two-dimensional and so it makes sense to make the array two-dimensional to keep the code intuitive. The array must be declared at class level so that it is available to all the

future subroutines and functions of frmMain. We want the size of the array to be NumberHolesHorizontal in one dimension and NumberHolesVertical in the other. Using variables to store the grid dimensions makes any future development or alterations very easy – only these variable’s values need to be changed. Remember that VB.NET is base 0 and when creating the array we have to subtract 1 from each dimension. The top of clsMain should now look something like Excerpt 15.

Excerpt 15 The start of frmMain showing the four class level variables so far

1 2 3 4 5 6 7 8 9

Public Class frmMain Dim WebCam As New clsWebcam Dim NumberHolesHorizontal As Integer = 16 Dim NumberHolesVertical As Integer = 8 Dim arrGrid(NumberHolesHorizontal - 1, NumberHolesVertical - 1) _ As strGrid

Page 37: Gumball Drum Machine Guide (Sample)

Pages 40-44 are not shown in the preview version. Go to www.gumballdrummachine.com to get the full version and the Resource Pack containing all the plans and source code.

Page 38: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

45

Figure 44 Dividing a line segment into 5 equal parts by adding multiples of the spacing vector (6, 3)

The general formula to calculate the spacing vector between points on Figure 43, where n is the number of holes (n=6) is:

𝑆𝑆(𝑋𝑋,𝑌𝑌) = �(𝑃𝑃2𝑋𝑋 − 𝑃𝑃1𝑋𝑋)

(𝑛𝑛 − 1) ,(𝑃𝑃2𝑌𝑌 − 𝑃𝑃1𝑌𝑌)

(𝑛𝑛 − 1) � 1

�(47 − 17)

(6 − 1),

(136 − 121)(6 − 1)

� = (6, 3)

We can find the ith hole between the start and end by adding multiples of the spacing vector to the original start coordinates as in the following formula:

(𝑃𝑃𝑃𝑃𝑋𝑋 , 𝑃𝑃𝑃𝑃𝑌𝑌) = ���𝑃𝑃1𝑋𝑋 + SX ∗ (𝑃𝑃 − 1)��, ( 𝑃𝑃1𝑌𝑌 + SY ∗ (𝑃𝑃 − 1 �)� 2

So, to find the coordinates of the third point in Figure 43:

(𝑃𝑃𝑃𝑃𝑋𝑋 ,𝑃𝑃𝑃𝑃𝑌𝑌) = ��17 + 6 ∗ (3 − 1)�, �121 + 3 ∗ (3 − 1)�� = (29, 127)

We have points on each of the edges of the grid outline such as in Figure 42. If it was a piece of paper, all that would be required would be to join up the corresponding points on the opposite edges to create the grid. Wherever the lines we drew intersected, that would be a hole location. We will employ a similar technique in the code by finding the intersection point of the lines mathematically, using a formula.

Page 39: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

46

It was found that using strPoint was not accurate enough for storing the grid spacings because the values in X and Y are only stored as integers. Integers are perfectly alright for storing the final hole positions in pixels, but just don’t have the precision necessary for their calculation. When the spacing vector is rounded, whatever rounding that took place is compounded as you move along the length of the edge. For example, say the spacing vector between holes along some horizontal edge was calculated as being (6.34, 3.52) using Equation 1. If this vector is stored as two integers, such as in strPoint, the numbers are rounded to (6,4). When it comes to calculating the coordinates of hole 16, the integer vector gives us as fairly large error compared with the decimal vector:

𝐼𝐼𝑛𝑛𝐼𝐼𝐼𝐼𝐼𝐼𝐼𝐼𝐼𝐼… 16 ∗ (6, 4) = (96, 64)

𝐷𝐷𝐼𝐼𝐷𝐷𝑃𝑃𝐷𝐷𝐷𝐷𝐷𝐷… 16 ∗ (6.34, 3.52) = (101.44, 56.32)

𝐸𝐸𝐼𝐼𝐼𝐼𝐸𝐸𝐼𝐼 𝑃𝑃𝑛𝑛 𝑃𝑃𝑛𝑛𝐼𝐼𝐼𝐼𝐼𝐼𝐼𝐼𝐼𝐼 𝑣𝑣𝐼𝐼𝐷𝐷𝐼𝐼𝐸𝐸𝐼𝐼 = (5.44,−7.68) …error of nearly 8 pixels vertical and 5 pixels horizontal!

To improve accuracy, a new structure was created named strPointDouble which is the same as strPoint except that the X and Y components are of type Double .

Double A Double data type allows you to store “double precision”, signed, floating-point numbers. Basically, they store numbers very accuratly. [19]

Page 40: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

47

Excerpt 18 Calculating the edge spacing

Excerpt 18 shows the code to calculate the horizontal and vertical spacing on each edge. Equation 1

is used on each edge and the spacing vectors are stored in SpaceTop, SpaceBottom, SpaceLeft, SpaceRight. Excerpt 19 is concerned with calculating the intersection points of the grid. The code of both Excerpt 18 and Excerpt 19 should be placed together in a new subroutine

named MakeGrid.

IntersectionX =�(𝑋𝑋1𝑌𝑌2 − 𝑌𝑌1𝑋𝑋2)(𝑋𝑋3 − 𝑋𝑋4) − (𝑋𝑋1 − 𝑋𝑋2)(𝑋𝑋3𝑌𝑌4 − 𝑌𝑌3𝑋𝑋4)

(𝑋𝑋1 − 𝑋𝑋2)(𝑌𝑌3 − 𝑌𝑌4) − (𝑌𝑌1 − 𝑌𝑌2)(𝑋𝑋3 − 𝑋𝑋4) 3

IntersectionY =�(𝑋𝑋1𝑌𝑌2 − 𝑌𝑌1𝑋𝑋2)(𝑌𝑌3 − 𝑌𝑌4) − (𝑌𝑌1 − 𝑌𝑌2)(𝑋𝑋3𝑌𝑌4 − 𝑌𝑌3𝑋𝑋4)

(𝑋𝑋1 − 𝑋𝑋2)(𝑌𝑌3 − 𝑌𝑌4) − (𝑌𝑌1 − 𝑌𝑌2)(𝑋𝑋3 − 𝑋𝑋4) 4

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28

Private Sub MakeGrid() Dim SpaceTop As strPointDouble Dim SpaceBottom As strPointDouble Dim SpaceLeft As strPointDouble Dim SpaceRight As strPointDouble SpaceTop.X = (TopRight.X - TopLeft.X) / _ (NumberHolesHorizontal - 1) SpaceTop.Y = (TopRight.Y - TopLeft.Y) / _ (NumberHolesHorizontal - 1) SpaceBottom.X = (BottomRight.X - BottomLeft.X) / _ (NumberHolesHorizontal - 1) SpaceBottom.Y = (BottomRight.Y - BottomLeft.Y) / _ (NumberHolesHorizontal - 1) SpaceLeft.X = (BottomLeft.X - TopLeft.X) / _ (NumberHolesVertical - 1) SpaceLeft.Y = (BottomLeft.Y - TopLeft.Y) / _ (NumberHolesVertical - 1) SpaceRight.X = (BottomRight.X - TopRight.X) / _ (NumberHolesVertical - 1) SpaceRight.Y = (BottomRight.Y - TopRight.Y) / _ (NumberHolesVertical - 1) End Sub

Page 41: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

48

Excerpt 19 is controled by two loops[7]. The first loop on Line 1, iterates the variable “I” horizontally

through the grid, stepping from one column to the next. Lines 5 and 6 use “I” from this loop to calculate the start point for an imaginary vertical line. As in Equation 2, the point is calculated on the top edge by taking the original TopLeft point that the user clicked and adding on I times the spacing for the top edge. In a similar way, the end point of the imaginary line is calculated in Lines 8 and 9, on the bottom edge.

The inner “J” loop can be thought of as stepping down through the individual holes on column I. Lines 14-19 calculate the end points of another imaginary line, this time running horizontally along

Row J. We now have the start and end points of an imaginary, horizontal and vertical line and so we can use standard geometry formulae to calculate the line’s intersection point in X and Y (Equations 3 and 4)[8]. The formulae to calculate the X and Y components of the intersection point are implemented in the code on lines 22 and 25 of Excerpt 19, respectively

Excerpt 19 Calculating the hole positions for the entire grid

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33

For I As Integer = 0 To NumberHolesHorizontal - 1 Dim P1, P2 As strPointDouble 'Current point on the top edge P1.X = TopLeft.X + I * SpaceTop.X P1.Y = TopLeft.Y + I * SpaceTop.Y 'Current point on bottom edge P2.X = BottomLeft.X + I * SpaceBottom.X P2.Y = BottomLeft.Y + I * SpaceBottom.Y For J As Integer = 0 To NumberHolesVertical - 1 Dim P3, P4, Intersection As strPointDouble 'Current point on left edge P3.X = TopLeft.X + J * SpaceLeft.X P3.Y = TopLeft.Y + J * SpaceLeft.Y 'Current point on right edge P4.X = TopRight.X + J * SpaceRight.X P4.Y = TopRight.Y + J * SpaceRight.Y 'Get the intersection of lines P1P2 and P3P4 Intersection.X = ((P1.X * P2.Y - P1.Y * P2.X) * (P3.X - P4.X) _ - (P1.X - P2.X) * (P3.X * P4.Y - P3.Y * P4.X)) / ((P1.X - P2.X) _ * (P3.Y - P4.Y) - (P1.Y - P2.Y) * (P3.X - P4.X)) Intersection.Y = ((P1.X * P2.Y - P1.Y * P2.X) * (P3.Y - P4.Y) _ - (P1.Y - P2.Y) * (P3.X * P4.Y - P3.Y * P4.X)) / ((P1.X - P2.X) _ * (P3.Y - P4.Y) - (P1.Y - P2.Y) * (P3.X - P4.X)) 'Set X and Y for that cell in arrGrid. arrGrid(I, J).Position.X = CInt(Intersection.X) arrGrid(I, J).Position.Y = CInt(Intersection.Y) Next J Next I

Page 42: Gumball Drum Machine Guide (Sample)

Pages 49-53 are not shown in the preview version. Go to www.gumballdrummachine.com to get the full version and the Resource Pack containing all the plans and source code.

Page 43: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

54

Excerpt 23 The FormClosing event, used to call the SaveSettings routine

Run the program at this stage and click on picWebcam to specify the four corners of the grid. In Windows, open the application debug directory at “C:\GumballDrumMachine\slnGumballDrumMachine\bin\Debug”. If your program worked, you should see a file named “Settings.txt”. Open the file in Notepad and you should see text like that in Figure 46.

Figure 47 The settings file after writing the four grid corner coordinates

We still need to write code that can read the settings file when the program is opening and set the grid corner values accordingly. Create a new subroutine named LoadSettings and copy in the

code of Excerpt 24. The code uses the StreamReader class and this is explained in Appendix C.

1 2 3 4 5 6

Private Sub frmMain_FormClosing(ByVal sender As Object, ByVal e As _ System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing SaveSettings() End Sub

Page 44: Gumball Drum Machine Guide (Sample)

Pages 55-61 are not shown in the preview version. Go to www.gumballdrummachine.com to get the full version and the Resource Pack containing all the plans and source code.

Page 45: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

62

Figure 52 Flow diagram of the IdentifyGumballs subroutine

We will now create a second PictureBox on which we can display the average color of each hole. When the recognition is working, we will update this new PictureBox to show also the gumball that has been identified at each hole, if any, by adding a colored circle, such as in Figure 52. The name of

the new PictureBox is picGumballGrid.

Page 46: Gumball Drum Machine Guide (Sample)

Pages 63-65 are not shown in the preview version. Go to www.gumballdrummachine.com to get the full version and the Resource Pack containing all the plans and source code.

Page 47: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

66

was used because this is the highest precision variable allowed by the draw functions. It is designed to store decimal numbers with half the precision of the Double type, thus taking up less space. I set

GumballSize to 16 simply because the holes looked the correct proportion. Add the code of Excerpt 32 at the top of frmMain.

Excerpt 32 Declaration of the GumballSize variable

The DrawArc method on Line 12 is very similar to the FillPie routine except that it only draws an arc outline. It is important that it is executed after the FillPie method so that the outline that it draws appears on top of the filled circle.

Add a call to the DrawAverageColor subroutine in the new Paint event of picGumballGrid

(see Excerpt 76 for the final layout of the Paint routine). Add a call to refresh picGumballGrid at the end of the Tick event for tmrRecognition so that the PictureBox is updated frequently, as on Line 17 of Excerpt 30. Run the program and you should see a rectangular grid of filled circles as in Figure 53. The color of each of these disks is the average color calculated at that hole.

Figure 54 picGumballGrid with the average color drawn as colored disks

Milestone 7 Calculating the average color at each hole

1

Dim GumballSize As Single = 16

Page 48: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

67

Gumball Definition We want the program to be capable of identifying between what we see as distinctly colored gumballs. To achieve this, the program will require a strict definition of what makes the gumballs

distinct. When we look at the grid on picWebcam, we should be able to pick out the different gumballs clearly by eye. If this is not the case then it will be impossible for the program to do it. If you have this problem, then the first remedy may be to improve the lighting underneath the gumball grid.

Furthermore, the same color gumball must appear roughly the same shade on picWebcam, all across the grid. If a gumball looks significantly brighter at the centre of the grid than at the edges, then it is likely that the light source needs to be diffused more, to give a more even light distribution. All of this preparation will allow us to create a general and stable method for identifying gumballs.

We will never be able to associate a single color (RGB value) with a particular color of gumball because light conditions are constantly changing and it would be far too sensitive. We can however, associate a particular color of gumball with a range of R, G, and B values. If a hole’s calculated

average color (RGB value) displayed on picGumballGrid falls within the RGB range of say, the blue gumball, then that hole is considered by the program to have a blue gumball present. In this section, we will create an interface that will enable the user to define the color ranges for each colored gumball on their grid.

To define a RGB color range for each gumball, we simply need an upper and lower limit for each of R, G and B, for each color gumball. These range limit values will be declared at class level so that they are common to the many different subroutines that will use them. Having different variables for all of the range limits and for all of the gumballs, would get quite messy. To avoid having to create

many new variables, we could simply create two new strColor variables for each color gumball; one to store the upper and one for the lower limit. Since we are using structures anyway, it will make the code neater and development easier if we combine the upper and lower limit into one

structure tree, similar to what we did for strGrid.

Excerpt 33 The strColorRange structure

The structure, strColorRange of Excerpt 33, consists of two colors that define the upper and lower limits of the gumball color range.

1 2 3 4

Structure strColorRange Dim UpperLimit As strColor Dim LowerLimit As strColor End Structure

Page 49: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

68

Excerpt 34 The strGumballColorRange structure

The Structure strGumballColorRange of Excerpt 34 is designed to group all of the gumball color ranges into a single variable. Declare a new variable named GumballColorRange at class

level and make its type strGumballColorRange, as in Excerpt 35.

Excerpt 35 Declaring the GumballColorRange variable

The gumball color ranges must be calibrated before the program can be used. The calibration will provide the limit values for the color range variables created in the previous section. In this section, we will write code to enable the user to set the color range for each gumball.

Calibration

The user will be able to select a particular color gumball and then click the holes on picGumballGrid where they see that gumball on the grid. Each time the user clicks on a hole, the RGB range of the selected gumball is expanded automatically (if necessary), to include the average color at the clicked hole.

The user interface could have taken many forms but Figure 54 shows the group of controls that we will be creating on the Drum Machine Tab to handle user input.

Figure 55 Controls used to calibrate the gumballs

1

Dim GumballColorRange As strGumballColorRange

1 2 3 4 5 6 7 8 9

Structure strGumballColorRange Dim Blue As strColorRange Dim Red As strColorRange Dim Yellow As strColorRange Dim Green As strColorRange Dim Purple As strColorRange Dim Orange As strColorRange Dim Pink As strColorRange End Structure

radCalibrateBlue

txtCalibrateColorsCurrentB

txtCalibrateColorsMaxB txtCalibrateColorsMinB

btnResetRange grpColorRange

Page 50: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

69

Figure 56 Placing a new TabControl, tabSettings, on the form

The first thing to add to tpgDrumMachine is a new TabControl as shown in Figure 55. Name the

TabControl tabSettings. Open the TabPage Collection Editor via the TabPages property. In here, we want to add another page using the Add button, bringing the total to three. Name the

pages tpgColorCalibration, tpgSound and tpgFrequency by editing the Name property for each page. Change the Text properties to “Color”, “Sound” and “Frequency”, respectively. The TabPage dialogue can now be closed while we concentrate on adding the controls to the Color Tab.

At the top of Figure 54, buttons are arranged in a row representing all the different color gumballs. Once the user clicks a gumball button, that gumball becomes active and the current maximum value of R, G and B for that gumball will appear in the boxes on the “Max” row and the “R”, “G” and “B” columns, respectively. The minimum RGB values of the range appear in the “R”, “G” and “B” boxes of the “Min” row. Outputting the maximum and minimum range values is not strictly necessary but is done here to inform the user and aid debugging.

When the user clicks a hole on picgumballGrid, the color range of the currently selected gumball is expanded to incorporate the clicked hole’s average color. The “current”, “max” and “min” rows of textboxes are updated instantly. The user could make a mistake when they are clicking the gumballs and so a Reset Range button is provided in the form. Clicking this button will reset the range of the selected gumball.

Color Calibration Controls In this section, we will add the visual controls to the new tpgColorCalibration tab and leave creating the behind-the-scenes code until the next section. The colored gumball buttons along the top of Figure 54 are RadioButton controls. They are added from the toolbox in the Design View of frmMain. Add as many of these as you have different color gumballs. Change the Appearance

property of each RadioButton to Button so that they look like those in Figure 56.

Figure 57 The same RadioButton, checked and unchecked

Page 51: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

70

I could have used a text label on each button to indicate the color gumball that the button represented but using colors seemed a lot more intuitive to use. The first step to making the colored

buttons is to replace the text in the Text property with two space characters (press the spacebar twice). This results in a nice square button. To change the color, simply edit the BackColor property of the individual RadioButton controls to match the colors of your gumballs. Change the

Name property of the gumball buttons to radCalibrateBlue, radCalibrateRed etc.

→ → →

Figure 58 Steps when modifying a RadioButton to have a button appearance and background color

The other controls in Figure 54 are relatively easy to add. There are nine TextBox controls, which display values for the current gumball color range. These are placed by clicking TextBox in the Toolbox and then clicking on the page. Repeat this eight more times for the remaining boxes. The

TextBox controls can be moved and sized by dragging on the edges. Change the Name property of each TextBox, following the naming convention shown in Figure 54.

Add Labels to the form to indicate the purpose of each of the TextBox controls to the user. Change

the Text property to match the Labels in Figure 54. Change the Name property of each of the Label controls to something appropriate. Add a Button to the form – this will become the Reset button. Change the Name and Text properties of the Button to those shown in Figure 54.

For neatness, the color range TextBox controls and the Reset button are placed in a GroupBox

container named grpColorRange. Choose GroupBox from the Toolbox and click on the page to place it. Adjust the size and position with the mouse. Select all the TextBox controls and the Reset button by clicking and dragging a selection marquee around them. Now click and drag the selection into the GroupBox to move them all inside it. Finally, arrange all the controls so that they look some way neat, as in Figure 54.

The Code When using the program, the first thing the user will do when calibrating is to select the gumball they wish to calibrate using the colored gumball buttons. We will store the gumball that is selected

at any given time in a new class level variable of type enuGumball named

Panel and GroupBox Panel and a Groupbox controls are containers for other controls. A Panel usually has invisible edges and can have a scrollbar whereas a GroupBox has a caption and decorative rounded outline. Controls such as RadioButtons are usually placed in groups within these containers so that they are independent from other controls on the form. GroupBoxes are mostly used for neatness and asthetics.

RadioButton A RadioButton is a control that is used when the user must choose a single option from two or more. When a RadioButton is checked, all other RadioButtons in the same container are unchecked automatically. The name comes from the mechanism on old radio receivers whereby when a button was pressed for one particular radio station frequency, the other spring loaded buttons would release.

Page 52: Gumball Drum Machine Guide (Sample)

Pages 71-82 are not shown in the preview version. Go to www.gumballdrummachine.com to get the full version and the Resource Pack containing all the plans and source code.

Page 53: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

83

Sound

Introduction In the previous chapter, we used a camera to determine the position of gumballs on the grid. We identified the gumballs using a set of recognition criteria before finally storing the information in an array named arrGrid. In this chapter, we will step through the columns of this “virtual grid” and play sounds for each identified gumball at a particular rhythm or tempo. We will be using some basic features of DirectX, a tool used by developers to add sound and graphics to applications. By the end of the chapter, we should have a fully functional Gumball Drum Machine.

File System A basic requirement of this program is that the user can change the sound associated with a particular color gumball at will. When the user wishes to change a gumball’s sound, they will be prompted to choose one from any of the sound files located in a particular fixed folder. The user can manage the sound files in this folder using Windows Explorer.

The files will be located in a folder named “Sound Bank” which we are going to create in the Application Directory. The Application Directory is where the Visual Studio compiler puts the program executables and we have already saved the settings file there in Chapter 2. In our case, it is located at C:\GumballDrumMachine\slnGumballDrumMachine\bin\Debug. Using Windows Explorer, navigate to this folder and, in it, create a new folder named “Sound Bank”. Place your sound files in this new directory. A collection of sound files is included in the Resource Pack that accompanies this guide to get you started.

Page 54: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

84

We can access the path of the Application Directory from the code using

Application.StartupPath. This built-in function returns the full string path to the Application Folder, as stated above. For the complete path to the Sound Bank folder, simply add “&\Sound Bank” to the string. The ampersand character is used to join two strings together.

Declare a new String variable at class level called SoundBankPath, so we have access to this useful string in the future code. The full declaration, as described above is:

How it will work There is already a way to select a particular gumball thanks to the color calibration facilities implemented in the previous chapter. When finished and the user selects a new color gumball using these gumball radio buttons, the current sound associated with the selected gumball will immediately appear in a new drop down list, such as that in Figure 60.

Figure 61 The controls for enabling the user to change the sound for the selected gumball

To change the sound for the selected gumball, the user clicks to expand the drop-down list. This list contains the names of all the files located in the Sound Bank directory created earlier. After clicking one of the files, the gumballs sound is changed by code behind the scenes. The user can immediately listen to the selected sound file by clicking the Sample Button shown in Figure 60.

Setting up the controls Go to the Design View of frmMain and open the Sound tab in tabSettings. Add a GroupBox,

ComboBox, and Button as shown in Figure 60. Name the controls grpSound, cboSound and

btnSoundSample, respectively. Change the DropDownStyle property of the ComboBox to DropDownList. This setting prevents the user editing the text and rather, forces them to pick from the list of available files.

Create a new subroutine named ReadSoundBank, which will only be called when the program loads. Its job is to fill the drop-down list with files from the Sound Bank folder. First, we will create an array of String variables for storing all the sound filenames, as in Line 6 of Excerpt 48. A very handy

function, Directory.GetFiles, is built into VB and it returns all the file names from a directory that you specify as a string argument in brackets. In Line 5 alone, we have declared a new string array and filled it with all the file names in our Sound Bank folder. Before populating the ComboBox,

it is wise to ensure first that it is empty by clearing it using the code on Line 7. The If blocks in this routine are used to check for errors with the Sound Bank folder and its contents. These checks are

not strictly necessary but they are included here for robustness. Add a call to ReadSoundBank to

the Load routine of frmMain (for positioning, see the final layout of the Load routine in Excerpt 79.

1

Dim SoundBankPath As String = Application.StartupPath & "\Sound Bank"

Page 55: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

85

Excerpt 48 Filling the sound ComboBox with file names

Note that the Directory.GetFiles function on Line 5 returns the entire path of each file e.g. “C:\GumballDrumMachine\slnGumballDrumMachine\bin\Debug\Sound\DrumBeat1.wav”. For ease of use, we only want the actual filename to appear in the list, so we must have a method to strip off the rest of the path before it. The loop on Lines 10-13, steps through each of the entries in the

FileName array. On Line 9, each file name is split into substrings at every backslash character. The substrings are stored in a string array named Parts. With the example just mentioned, the

contents of the Parts array are:

Index Sub String

0 C:

1 GumballDrumMachine

2 slnGumballDrumMachine

3 bin

4 Debug

5 Sound Bank

6 DrumBeat1.wav

On Line 10, only the last sub string of Parts is added to the ComboBox, the rest are discarded. Run the program at this stage to check that the ComboBox is populated with the expected filenames.

The sound file associated with each gumball will be stored in a new string array named

arrSoundFile. Each gumball color will have a particular row in this array associated with it e.g. the first row will be the file name associated with the blue gumball; the second will be for green etc. Declare this new string array at class level and give it an appropriate size depending on your number of gumball colors e.g.

The subroutine of Excerpt 49 is used to update the new array. The subroutine is triggered with the SelectedValueChanged event. This event occurs just after the user selects a different value from the drop-down list.

1

Dim arrSoundFile(6) As String

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

Private Sub ReadSoundBank() Dim Parts() As String If Directory.Exists(SoundBankPath) Then Dim FileNames As String() = Directory.GetFiles(SoundBankPath) If FileNames.Length > 0 Then cboSound.Items.Clear() For I As Integer = 0 To FileNames.Length - 1 Parts = FileNames(I).Split("\") cboSound.Items.Add(Parts(Parts.Length - 1)) Next I End If End If End Sub

Page 56: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

86

This routine is created in the usual way, by selecting the ComboBox from the Class Name list and the

SelectedValueChanged method from the Method Name list. The Select Case on Line 5 controls

the execution depending on the currently selected gumball color. The row in arrSoundFile associated with the currently selected gumball is then set to the name of the newly selected sound

file i.e. if the red gumball was selected then the sixth row of arrSoundFile is set to

“filename.wav” or whatever the new text in cboSound is.

Excerpt 49 Updating arrSoundFile with the file paths for each gumball’s associated sound

Running the program now, you will see that if you change the selected gumball using the gumball

RadioButton controls, the sound in cboSound does not update. Why would it – we haven’t written any code to do that. We need to add a routine similar to

UpdateColorCalibrationTextBoxes that will update the sound file when the selected gumball changes.

The code in Excerpt 50 comprises the UpdateSoundComboBox routine. This routine simply checks on Line 3 which gumball is currently selected. Depending on which gumball is selected it sets

the Text property of the ComboBox equal to the corresponding row in arrSoundFile. A call to this routine should be added after the call to UpdateSoundComboBox at the end of the

radCalibrate_CheckedChanged routine.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

Private Sub cboSound_SelectedValueChanged(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles _ cboSound.SelectedValueChanged Select Case CurrentCalibrationColor Case enuGumball.Blue arrSoundFile(0) = cboSound.Text Case enuGumball.Green arrSoundFile(1) = cboSound.Text Case enuGumball.Orange arrSoundFile(2) = cboSound.Text Case enuGumball.Pink arrSoundFile(3) = cboSound.Text Case enuGumball.Purple arrSoundFile(4) = cboSound.Text Case enuGumball.Red arrSoundFile(5) = cboSound.Text Case enuGumball.Yellow arrSoundFile(6) = cboSound.Text End Select End Sub

Page 57: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

87

Excerpt 50 The UpdateSoundComboBox routine

Saving the gumball sounds. In Chapter 2 we saved grid and color calibration data in a text file so that it would be preserved from one run to the next, sparing the user from specifying it every time. We will now do the same for each gumball’s associated sound.

The code in Excerpt 51 should be added to the end of the SaveSettings routine created in

Chapter 2, just before the StreamWriter is closed. This code writes each item in arrSoundFile to the file on a single line, separated by commas. Run the program, set sounds for each of the gumballs and close it again. Now, open the settings file in Notepad and it should look something like Figure 61.

Excerpt 51 Saving the sound file data for each gumball

Figure 62 The settings file in Notepad after the file data is added

1 2 3

sw.WriteLine(arrSoundFile(0) & "," & arrSoundFile(1) & "," & _ arrSoundFile(2) & "," & arrSoundFile(3) & "," & arrSoundFile(4) & _ "," & arrSoundFile(5) & "," & arrSoundFile(6))

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

Private Sub UpdateSoundComboBox() Select Case CurrentCalibrationColor Case enuGumball.Blue cboSound.Text = arrSoundFile(0) Case enuGumball.Green cboSound.Text = arrSoundFile(1) Case enuGumball.Orange cboSound.Text = arrSoundFile(2) Case enuGumball.Pink cboSound.Text = arrSoundFile(3) Case enuGumball.Purple cboSound.Text = arrSoundFile(4) Case enuGumball.Red cboSound.Text = arrSoundFile(5) Case enuGumball.Yellow cboSound.Text = arrSoundFile(6) End Select End Sub

Page 58: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

88

The sound file data must be read back from the settings file again when the program is loading. The code to load the sound settings is contained in Excerpt 52. It should be placed at the end of the

LoadSettings routine. This code splits line 12 of the file, the line that contains the sound file list, into separate file names in the array Parts. The code then goes on to assign the various sound files

to the appropriate items in arrSoundFile. The Trim function is used to remove leading and trailing whitespace characters from the string that could otherwise cause problems.

Excerpt 52 Load sound file data

Finally add a call to UpdateSoundComboBox at the end of the Load routine to initialize cboSound with the file loaded from the settings file.

Milestone 10 Setting up the sound folder

1 2 3 4 5 6 7 8

Parts = Lines(11).Split(",") arrSoundFile(0) = Parts(0).Trim arrSoundFile(1) = Parts(1).Trim arrSoundFile(2) = Parts(2).Trim arrSoundFile(3) = Parts(3).Trim arrSoundFile(4) = Parts(4).Trim arrSoundFile(5) = Parts(5).Trim arrSoundFile(6) = Parts(6).Trim

Page 59: Gumball Drum Machine Guide (Sample)

Pages 89-97 are not shown in the preview version. Go to www.gumballdrummachine.com to get the full version and the Resource Pack containing all the plans and source code.

Page 60: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

98

Create a ValueChanged subroutine for numFrequencyRow and add the code of Excerpt 61. This routine is triggered immediately after the user changes the selected row on

numFrequencyRow. The If block on Line 4 is required to stop the program executing this code during initialization, as explained earlier for the Volume control.

Excerpt 61 Routine called when the selected row number is changed in the numeric up-down box

Frequency Adjustment Place a new TrackBar on tpgFrequency and name it barRowFrequency. This will enable the

user to change the frequency of the currently selected row. Change the Minimum property to

33000 and the Maximum to 150000. Set the Value property to 35000: this will be the default value and was chosen through trial and error to sound as close as possible to the original pitch of my drum

sounds. Finally, set both the SmallTick and LargeTick properties to intervals of 1000.

The TextBox in Figure 71, above the TrackBar, shows the current frequency selected on the slider in Hertz. We will set the text of the TextBox when the program loads and whenever the user adjusts the TrackBar. Place the TextBox on tpgFrequency and name it txtRowFrequency. Change the

ReadOnly property to True so that the user won’t be able to edit the value directly to an illegal value. In Line 5 of Excerpt 61, the text in the TextBox is changed to reflect the current frequency for

the newly selected row. The value is retrieved from the cell in the frequency array, arrRowFreq, associated with the currently selected row. The code in Line 6 is responsible for refreshing the frequency slider, barRowFrequency, to show the new row’s frequency.

Excerpt 62 Routine called when the value of the Frequency TrackBar is changed

Add a ValueChanged event for barRowFrequency, as in Excerpt 62. This routine is called each time the position of the slider is changed i.e. if the user smoothly moves the slider from 50000 to

60000, the routine will be called 10 times because the interval property is set to 1000. The If block to check that the program is fully loaded is used as before. The job of Line 5 is to update

txtRowFrequency with the newly chosen value on the slider. The frequency is then stored in the appropriate row in the frequency array at Line 6.

1 2 3 4 5 6 7 8 9

Private Sub barRowFrequency_ValueChanged(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles barRowFrequency.ValueChanged If ProgramLoadedSwitch Then txtRowFrequency.Text = barRowFrequency.Value arrRowFreq(numFrequencyRow.Value - 1) = barRowFrequency.Value End If End Sub

1 2 3 4 5 6 7 8 9

Private Sub numFrequencyRow_ValueChanged(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles numFrequencyRow.ValueChanged If ProgramLoadedSwitch Then txtRowFrequency.Text = arrRowFreq(numFrequencyRow.Value - 1) barRowFrequency.Value = arrRowFreq(numFrequencyRow.Value - 1) End If End Sub

Page 61: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

99

We now have a problem. We have set the Minimum property of barRowFrequency to 33000.

Currently, the value of frequency for each row in arrRowFreq is zero, the default. If we try to use

numFrequencyRow to change the selected row, Line 6 of Excerpt 61 will immediately try to set the value of barRowFrequency to zero, which is below the minimum range we have set for the TrackBar. Leave this problem for now; we will sort it out shortly, when it comes to saving the frequency data to the settings file.

Reset Frequency The last important control to add from Figure 71 is the Reset button. The default frequency for each of the rows will be set to give an even distribution over the range 33000Hz to 150000Hz. The top row of the grid will have the highest (Chipmunk-like) pitch. The frequency will then reduce in equal steps over the number of rows to the lowest pitch on the bottom row (Darth Vader). The Reset button will allow the user to reset the frequency of the selected row to the original default value rather than have to guess.

Excerpt 63 Click event for the Reset button

Place a Button control on frmMain and change the Name property to btnResetFrequency. Set the Text to “Reset”. Create a Click subroutine for the button as in Excerpt 63. The code to actually reset the frequency will be put in a separate subroutine in case it is required to be called in another part of the code. This ResetFrequency routine is given in Excerpt 64.

Excerpt 64 Code called by the Reset button to set frequency values back to default values

In Lines 3 and 4 of Excerpt 64 the lower and upper values of the frequency range are given variables to make the calculations easier. The frequency range is divided by the number of rows minus one in Line 5 to find the frequency gap between each row. On Line 8, a multiple of this frequency step is subtracted from the upper range value; the multiple depending on the selected row. Finally, Lines 10 and 11 update the TrackBar and the TextBox to show the new default frequency for that row.

1 2 3 4 5 6 7 8 9 10 11 12 13

Private Sub ResetFrequency(ByVal RowIndex As Integer) Dim LowFreq As Double = 33000 Dim HighFreq As Double = 145500 Dim FreqInterval As Double = FreqInterval = _ (HighFreq - LowFreq) / (NumberHolesVertical - 1) arrRowFreq(RowIndex) = HighFreq - (RowIndex * FreqInterval) txtRowFrequency.Text = arrRowFreq(numFrequencyRow.Value - 1) barRowFrequency.Value = arrRowFreq(numFrequencyRow.Value - 1) End Sub

1 2 3 4 5 6

Private Sub btnResetFrequency_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles btnResetFrequency.Click ResetFrequency(numFrequencyRow.Value - 1) End Sub

Page 62: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

100

After creating all the important controls, you should add some labels to help the user find their way around, such as in Figure 71. It is also a nice idea to enclose all the controls neatly in a GroupBox.

Saving and loading the sound settings At the end of the SaveSettings routine, before the StreamWriter is closed, add the code of Excerpt 65. This code writes the frequency and volume on two lines of the settings file. The frequency values for the seven rows are written on a single line, separated by commas.

Excerpt 65 Saving the playback settings to the settings file

Run the program at this stage to generate the updated settings file, shown in Figure 72. Notice on Line 15 of the file that the values for frequency for each row are 0. Open the settings file in Notepad

and change Line 13 of the file so that the numbers are all within the range of barRowFrequency, say 35000. This will overcome the problem we had earlier with the frequency values being out of range on barRowFrequency.

Figure 73 The settings file with the playback settings added

The playback settings are loaded again by placing the code of Excerpt 66 at the end of the LoadSettings routine. Run the program with the modified settings file. It should now be possible

to change the selected row using numFrequencyRow, without errors.

1 2 3 4 5

sw.WriteLine(arrRowFreq(0) & "," & arrRowFreq(1) & "," & _ arrRowFreq(2) & "," & arrRowFreq(3) & "," & arrRowFreq(4) _ & "," & arrRowFreq(5) & "," & arrRowFreq(6) & "," & arrRowFreq(7)) sw.WriteLine(Volume)

Page 63: Gumball Drum Machine Guide (Sample)

Pages 101-107 are not shown in the preview version. Go to www.gumballdrummachine.com to get the full version and the Resource Pack containing all the plans and source code.

Page 64: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

108

Excerpt 74 Code for the Play/Pause button

The only way the program would enter the CheckedChanged routine is if the user has just pressed

chkPlayPause. If on entering this routine we find the control’s state is checked, it means that the user has just pressed the CheckBox (the checked status of the CheckBox is updated before entering the routine). If Line 5 is executed, the user has just pressed the Play button to request the drum sequencer to start. The Image for the CheckBox is changed to the Stop symbol to indicate that the button can now be used to stop the sequencer again. The timer is started on Line 6, setting the

sequencer running. In the previous chapter, tmrRecognition was started and stopped by

toggling its enabled property. The multimedia timer, tmrBeat, uses its own Start and Stop methods instead.

If the status of chkPlayPause is found to be unchecked at Line 4, then it means the user has just

pressed the Stop button. In this case, Line 8 changes the Image back to the Play symbol. Line 9 stops the timer and thus the sequencer. Line 10 resets the Beat variable to 0 so that next time the user presses Play, the sequencer will start at the first column again (if this reset line was omitted, the Stop button would simply act as a Pause button: the sequencer would resume playing the column after which it was stopped).

Run the program now and you will find that the Gumball Drum Machine is almost fully functional. Press the Play button and whatever gumballs are on your grid should generate the appropriate sounds. You may find that you get a buzzing sound and this could be because the tempo for the timer has not been set to a sensible value yet. We will do this in the next chapter. The Sample button should work correctly at least.

If the volume is too loud or too quiet it is because the system volume on your computer is different to what mine was when the code was written. Adjust your system volume or change the value -5000 in the formula on Line 13 of Excerpt 58 to something more appropriate.

Milestone 12 Playing sounds

1 2 3 4 5 6 7 8 9 10 11 12 13

Private Sub chkPlayPause_CheckedChanged(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles chkPlayPause.CheckedChanged If chkPlayPause.Checked Then chkPlayPause.Image = My.Resources._Stop tmrBeat.Start() Else chkPlayPause.Image = My.Resources.Play tmrBeat.Stop() Beat = 0 End If End Sub

Page 65: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

109

We will now use the Graphics capabilities of picGumballGrid to add a position marker to the grid. The position marker will show the user which column of the grid is currently being played similar to a seek/progress bar in any media player. I chose to have a vertical, 20 pixels wide, semi-transparent line appear on the active column. The code to draw the line is contained in the

DrawBeatPosition routine of

Visualizing the Beat

Excerpt 75. The e.FillRectangle function is used here to draw a filled rectangle to the required dimensions.

Excerpt 75 Draw routine for the active column cursor

On Line 3 of Excerpt 75, the brush is defined. Using the built-in Color.FromArgb function, we can create a transparent fill color . Using this method allows us to specify a transparency, albeit in a roundabout manner.

The filled rectangle is drawn on Line 4. The first argument in the list is the Brush defined in Line 3. The second and third arguments are the X and Y coordinates of the top left corner of the rectangle. The X coordinate will come from the hole centre of the first row (0) on the active column (Beat) of

arrGrid. We are using the PositionRegular coordinates we calculated in the previous chapter so that the column marker line matches up with the holes drawn earlier on

picGumballGrid. Note that we could have chosen any of the rows to take the X coordinate from

because using PositionRegular, all the holes on a column have the same X coordinates. A horizontal offset of -10 pixels is applied to the top left corner. This is so that the rectangle, with a width of 20 pixels, will be centered on the column. The Y coordinate is simply zero to specify that we

want our rectangle to start at the very top of picGumballGrid.

The fourth and fifth arguments in the FillRectangle function are the width and height of the rectangle we wish to draw. The width is simply 20 and the height is the full height of the PictureBox;

simply accessed using picGumballGrid.Height.

The DrawBeatPosition subroutine is called from the Paint event of picGumballGrid (Excerpt 76). The routine takes only one parameter; that is the graphics capability (e.graphics) of

picGumballGrid. The code of Excerpt 76 shows the Paint event for picGumballGrid. On Line

4 of Excerpt 76, the quality of the graphics is set to high, as we did earlier for picWebcam. Notice that the call to DrawBeatPosition is placed before that of the routine for drawing the holes and

ARGB This stands for Alpha, Red, Green, and Blue. The Alpha value defines the level of opacity. An Alpha value of 0 indicates a fully transparent color whereas a value of 255 indicates a fully opaque one.

1 2 3 4 5 6 7

Private Sub DrawBeatPosition(ByVal e As Graphics) Dim Brush As New SolidBrush(Color.FromArgb(100, Color.LightGreen)) e.FillRectangle(Brush, arrGrid(Beat, 0).PositionRegular.X - 10, 0, _ 20, picGumballGrid.Height) End Sub

Page 66: Gumball Drum Machine Guide (Sample)

Page 110 is not shown in the preview version. Go to www.gumballdrummachine.com to get the full version and the Resource Pack containing all the plans and source code.

Page 67: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

111

We will enable the user to control the tempo of the beat by using a TrackBar object similar to those used earlier for controlling volume and frequency. Add another TrackBar to frmMain in the Design

View and format it similar to barVolume. Name the new TrackBar barTempo and set the Maximum and Minimum properties to 100 and 0, respectively.

Tempo

Create a new ValueChanged subroutine for barTempo, just as we did for barVolume. Similar to what we did for volume, add a

TempoUpdate routine that will contain the actual tempo code. Add the usual

ProgramLoadedSwitch check to prevent any errors during initialization. To achieve a change in tempo, we will adjust the settings of

tmrBeat so that its tick rate increases or decreases depending on the value of

barTempo. For tmrBeat, the tick rate is

determined by its Period property, which controls the time between successive ticks. To increase the tempo (quicken the beat), the

Period property of tmrBeat must be reduced and vice versa.

The following formula is used to calculate the period based on the value of barTempo. The equation is plotted in Figure 78.

𝑃𝑃𝐼𝐼𝐼𝐼𝑃𝑃𝐸𝐸𝑃𝑃 = 𝑀𝑀𝐷𝐷𝑥𝑥 − �𝑏𝑏𝐷𝐷𝐼𝐼𝑇𝑇𝐼𝐼𝐷𝐷𝑏𝑏𝐸𝐸

100� (𝑀𝑀𝐷𝐷𝑥𝑥 −𝑀𝑀𝑃𝑃𝑛𝑛)

Figure 79 Graph of Period varying with TrackBar value

Max and Min in the above formula are constants that we will set explicitly in the code. They define the allowable range of values for the timer period. A sensible minimum timer period was found through testing to be about 50ms while a maximum period of one second (1000ms) yields a

Page 68: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

112

sufficiently slow beat. These should be adjusted if necessary. The ValueChanged and

TempoUpdate subroutines should look similar to those in Excerpt 78 when complete. Create a new

class-level integer variable named Tempo, similar to that created for volume. It is this variable that we will save to and load from the settings file.

Excerpt 78 Code for the Tempo slider ValueChanged event

To save the tempo value to the settings file, add the following line of code to the SaveSettings routine, before the StreamWriter is closed.

Run the program and close it again so that the settings file is updated. To load the tempo from the settings file, add the following line to the LoadSettings routine.

Finally, update the TrackBar at the end of the Load routine for frmMain with the following lines of

code. They should be placed after the ProgramLoadedSwitch is set to True.

Clean Up During development, we made many changes and amendments to the subroutine that handles the

Load event of frmMain. The routine is given again here for reference and clarity. The rough position of many of the calls is not critical. If something in your code is not working as expected this may be the place to start looking.

1 2

barTempo.Value = Tempo TempoUpdate()

1

Tempo = Lines(14)

1

sw.WriteLine(Tempo)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

Private Sub barTempo_ValueChanged(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles barTempo.ValueChanged TempoUpdate() Tempo = barTempo.Value End Sub Private Sub TempoUpdate() Dim MaxPeriod As Integer = 500 Dim MinPeriod As Integer = 50 If ProgramLoadedSwitch Then tmrBeat.Period = MaxPeriod - (MaxPeriod - MinPeriod) * _ (barTempo.Value / 100) End If End Sub

Page 69: Gumball Drum Machine Guide (Sample)

Page 113 is not shown in the preview version. Go to www.gumballdrummachine.com to get the full version and the Resource Pack containing all the plans and source code.

Page 70: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

114

The End Congratulations, you completed the project. I hope you have enjoyed making the Gumball Drum Machine and are using it to compose some funky beats! I also hope you have gained a working knowledge of Visual Basic.NET. I recommend that you look at Appendix A for a list of some possible improvements you could make to extend the project.

I would love to get some feedback from this guide and your experience of using it to build the device and code the software. A quick email to [email protected], saying what you did and maybe didn’t like, would be much appreciated so that I can improve it for the future.

Page 71: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

115

References 1. Hesse, Hannes and McDiarmid, Andrew. Bubblegum Sequencer. YouTube. [Online] [Cited: April 7, 2010.] http://www.youtube.com/watch?v=ziIdjrR_MRs.

2. Balena, Francesco. Programming Microsoft Visual Basic 2005: The Language. 2nd Edition . Redmond : Microsoft Press; 2nd edition, 2006. ISBN-10: 0735621837.

3. MSDN. Visual Basic Development Centre. [Online] Microsoft . [Cited: April 7, 2010.] http://msdn.microsoft.com/en-us/vbasic/default.aspx.

4. Webcam preview . vbcity.com. [Online] [Cited: April 23, 2010.] http://vbcity.com/forums/t/59261.aspx.

5. WebCam Class (ICam). vbforums.com. [Online] [Cited: April 3, 2010.] http://www.vbforums.com/showthread.php?p=2048466.

6. Arrays. StartVBdotnet.com. [Online] [Cited: April 7, 2010.] http://www.startvbdotnet.com/language/arrays.aspx.

7. Loops. StartVBdotnet.com. [Online] [Cited: April 7, 2010.] http://www.startvbdotnet.com/language/loops.aspx.

8. Weisstein, Eric W. Line- Line Intersection. From MathWorld--A Wolfram Web Resource. [Online] [Cited: April 6, 2010.] http://mathworld.wolfram.com/Line-LineIntersection.html.

9. —. Point-Point Distance--2-Dimensional. From MathWorld--A Wolfram Web Resource. [Online] [Cited: April 7, 2010.] http://mathworld.wolfram.com/Point-PointDistance2-Dimensional.html.

10. Audio frequency. Wikipedia. [Online] [Cited: April 7, 2010.] http://en.wikipedia.org/wiki/Audio_frequency.

11. ZylTimer.NET 1.21. Zyl Soft. [Online] [Cited: April 7, 2010.] http://www.zylsoft.com/zyltimernet.htm.

12. Sanford, Leslie. The Multimedia Timer for the .NET Framework. The Code Project. [Online] [Cited: April 6, 2010.] http://www.codeproject.com/KB/miscctrl/lescsmultimediatimer.aspx.

13. DirectX:DirectSound:Tutorials:VBNET:DX9:Playing Sounds. The Game Programming Wiki. [Online] [Cited: April 7, 2010.] http://gpwiki.org/index.php/VBNET:DirectSound.

14. Free Computer Tutorials. Home and Learn. [Online] [Cited: April 7, 2010.] http://www.homeandlearn.co.uk/net/nets5p6.html.

15. Structures in VB .NET . StartVBdotnet.com. [Online] [Cited: April 7, 2010.] http://www.startvbdotnet.com/oop/structure.aspx.

16. Strings, Math Functions. StartVBdotnet.com. [Online] [Cited: April 7, 2010.] http://www.startvbdotnet.com/language/strings.aspx.

Page 72: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

116

17. Methods. StartVBdotnet.com. [Online] [Cited: April 7, 2010.] http://www.startvbdotnet.com/language/methods.aspx.

18. Enumeration, Exception Handling . StartVBdotnet. [Online] [Cited: April 7, 2010.] http://www.startvbdotnet.com/language/enumeration.aspx.

19. Data Types, Access Specifiers. StartVBdotnet. [Online] [Cited: April 7, 2010.] http://www.startvbdotnet.com/language/datatypes.aspx.

20. Conditional Statements. StartVBdotnet. [Online] [Cited: April 7, 2010.] http://www.startvbdotnet.com/language/ifthen.aspx.

21. Classes n Objects. StartVBdotnet.com. [Online] [Cited: April 7, 2010.] http://www.startvbdotnet.com/oop/class.aspx.

22. Zahn, Martin. Naming Conventions for .NET / C# Projects. www.akadia.com. [Online] [Cited: April 7, 2010.] http://www.akadia.com/services/naming_conventions.html.

23. Burger, Jarno. Webcam using DirectShow.NET. The Code Project. [Online] April 26, 2007. [Cited: April 7, 2010.] http://www.codeproject.com/KB/audio-video/WebcamUsingDirectShowNET.aspx.

24. Interfaces. MSDN. [Online] Microsoft, March 11, 2010. [Cited: April 7, 2010.] http://msdn.microsoft.com/en-us/library/ms693372(v=VS.85).aspx.

25. Introduction to GDI+ in .NET. CodeProject. [Online] [Cited: April 7, 2010.] http://www.codeproject.com/KB/GDI-plus/GDI_.aspx.

Page 73: Gumball Drum Machine Guide (Sample)

Pages 117-119 are not shown in the preview version. Go to www.gumballdrummachine.com to get the full version and the Resource Pack containing all the plans and source code.

Page 74: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

120

Appendix B

Hello World This section is included in the guide so that somebody who is completely new to Visual Basic.NET can write their first program and learn the basics. We are going to create a small program that, when executed, will display a message box with the customary text “Hello, World!”

Start Microsoft Visual Basic 2010. From the Main Menu, click File → New Project. On the dialogue

that appears, select Windows Forms Application. In the Name box, type prjHelloWorld and then click OK (Figure 26).

Visual Studio starts every new Windows Forms Application project on the Design View. In the Design View you can see an empty form (window) called Form1 which Visual Studio automatically creates for you (Figure 81).

Figure 82 Design View of Form1

We will now run the program and see what we have created already without all that much effort. Click Debug → Start Debugging from the Main Menu or press the F5 key. A window should appear on the screen like that in Figure 82.

Page 75: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

121

Figure 83 Form1 running

We are going to add a simple button to the form. When we click on the button we want a message box to appear and say “Hello World!”. First, we place the button: open the Toolbox by clicking on the Toolbox button to the left of the screen (Figure 83).

Figure 84 Choosing a Button control from the Toolbox

Find the control called Button in the Toolbox list and click once on it. Place the Button on Form1 by clicking on an empty space in the form where you would like it to appear (Figure 84).

Figure 85 Placing a Button on the form

When the user clicks on the button when the program is running, an internal event is raised. We can add code to the program that is executed whenever this event is raised. The simplest way to do this is to double-click on the button in the Design View. Visual Studio automatically brings you to the Code Editor where it has already created a Subroutine that is triggered by the button’s Click event

Page 76: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

122

(the default event for a Button). Any code that’s added between the Private Sub and the End

Sub keywords will be executed when the user clicks on the button.

Figure 86 Code Editor with Button1 Click event

Add the following code so that the Button1_Click subroutine looks like:

Run the program by hitting F5. Click on Button1 and a Windows Message Box should appear as in Figure 86.

Figure 87 Hello World!

Rather than putting the “Hello World!” message in a Message Box we can put it in a Label control on

Form1. Choose Label from the Toolbox. Click on the form where you wish to place the Label. Change the text of the Label by editing the Text property in the Property panel on the right of the screen (Figure 87).

1 2 3 4 5 6

Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click MsgBox("Hello World!") End Sub

Page 77: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

123

Figure 88 Adding a Label to the form and editing the Text property

Visual Studio automatically sets the Text of the label to “Label1”. Delete the text so that the label has no text. Return to the Code Editor and change Button1_Click to reflect the following:

Run the program again. When you click on the button this time, the label text will go from saying nothing to saying the phrase “Hello World!” (see Figure 88). You should add breakpoints to your code to see the progress of the code as it is executed. A very good tutorial on using breakpoints can be found on www.HomeAndLearn.co.uk [14].

Figure 89 Label says "Hello World!" after button is clicked

1 2 3 4 5 6

Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click Label1.Text = "Hello World!" End Sub

Page 78: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

124

Hello Graphics Here we will again create the Hello World message but this time going back to basics by drawing lines and arcs. Use the same form as for the Hello World program previously. Click on the PictureBox control from the Toolbox panel . Click anywhere on the form to place the PictureBox at that location. The PictureBox can be resized by dragging the edges until it looks similar to Figure 89.

Figure 90 Create the PictureBox and size it so that it nearly fills the form

Go to the code editor by pressing F7. There are two drop down lists just above the code editor (see Figure 35). On the first of these, the Class Name, select the new PictureBox. It is automatically

named PictureBox1. On the second drop-down list, Method Name, select Paint and a new event will be created in the code editor. The Paint event is triggered every time the PictureBox is refreshed so this is where graphics code should be placed.

Within the Paint event, there are a number of useful tools available to help with creating graphics. The tools are accessed by typing e.graphics. . Once the last full stop is typed after graphics, the IntelliSense in Visual Studio shows all the possible functions. Some of the more common tools

are DrawLine, DrawEllipse and DrawArc and these will be used to create the lettering for “Hello World” in this section. One of the best ways to learn to use these tools is to copy the code from Excerpt 80 into the Paint event and then tweak it and experiment yourself.

Note that when using the DrawArc tool that the start angle is measured from the horizontal and that 0 is to the right. The start angle is taken as counter-clockwise positive. The sweep angle is relative to the start angle and is also counter-clockwise positive (Figure 90).

PictureBox PictureBoxes are rectangular panels on which images can be displayed. The images displayed can be anything varying from Bitmap, JPEG, GIF, PNG or any other image format files. The useful feature of PictureBox controls is that custom graphics can also be created using the Graphics object. [25]

Page 79: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

125

Figure 91 Illustration of a positive start (≈45°) and sweep angle (≈90°) for use with the DrawArc routine

The result of running the program is shown in Figure 91. By altering the arguments to the graphic functions in Excerpt 80, you can see how the various coordinates and radii affect the result. A full description of each of the graphics functions can be found via the help in Visual Studio.

Figure 92 The Hello World text drawn using lines and arcs

Page 80: Gumball Drum Machine Guide (Sample)

Page 126 is not shown in the preview version. Go to www.gumballdrummachine.com to get the full version and the Resource Pack containing all the plans and source code.

Page 81: Gumball Drum Machine Guide (Sample)

Gumball Drum Machine

127

Appendix C

Text Files Writing and reading files is a very useful competency in any programming language. In the case of this project it allows us to store information from one program execution to the next. A class named a StreamWriter is used to write text to a file and a StreamReader is used to read text from a file. They basically convert bits (used to store characters in memory) into encoded file-text and vice-versa.

A StreamWriter is the tool used to write the text file and each StreamWriter must be given its own variable. The first thing to do is import the functionality to read and write files into our class. At the

very top of the code editor, add the line Imports System.IO. This adds a reference to the IO namespace and spares us from typing out the full namespace path in subsequent code.

Writing

Excerpt 81 Declaring the StreamWriter variable

When a new instance of a StreamWriter is created, you supply a string parameter in the brackets specifying the name and path of the file to be created e.g.”C:\My_Filename.txt” (see Excerpt 81). Once the StreamWriter has been created and set, as in Lines 2 and 8 of Excerpt 82, it can be used to write text to the file. If the file exists already it will be overwritten, otherwise a new one will be

created. The WriteLine and Write functions of the StreamWriter class both write text to the file. The WriteLine function goes to the next line at the end of writing its text i.e. subsequent text isn’t

on the same line. The Write function continues writing on the same line until you tell it otherwise.

Notice in Line 8 that we used Application.StartupPath. This is a property built into the project that tells us the path of the program executable e.g. C:\GumballDrumMachine\slnGumballDrumMachine\bin\Debug. Using the StartupPath function makes the program adaptable so that it will work even if the program isn’t placed where we expect on the disk. The ampersand character (&) on Line 8 is used to join the two strings for the path and the file name together.

1

sw = New StreamWriter("C:\My_Filename.txt")

Page 82: Gumball Drum Machine Guide (Sample)

Pages 128-129 are not shown in the preview version. Go to www.gumballdrummachine.com to get the full version and the Resource Pack containing all the plans and source code.