Nikon D7000, Playback

There are a couple of options for reviewing your video once you have finished recording. The first, and probably the easiest, is to press the Image Review button to bring up the recorded image on the rear LCD, and then use the OK button to start playing the video. The Multi-selector acts as the video controller and allows you to rewind and fast-forward as well as stop the video altogether

If you would like to get a larger look at things, you will need to either watch the video on your TV or move the video files to your computer. To watch low-res video on your TV, you can use the video cable that came with your camera and plug it into the small port on the side of the camera body (Figure 10.3). To get the full effect from your HD video, you will need to buy an HDMI cable (your TV needs to support at least 720HD and have an HDMI port to use this option). Once you have the cable hooked up, simply use the same camera controls that you use for watching the video on the rear LCD.

If you want to watch a video on your computer, you will need to download it using Nikon software or an SD card reader attached to the computer. The video file will have the extension .avi at the end of the filename. These files should play on either a Mac or a PC using software that came with your operating system (QuickTime for Mac and Windows Media Player for PC).

Plug your cable into
Figure 10.3 Plug your cable into this port to watch videos on your television.

 

Canon PowerShot G12, Watching Your Videos

There are a couple of different options for you to review your video once you have finished recording. The first is probably the easiest: Press the Playback button to bring up the recorded image on the LCD screen, and then use the Set button to start playing the video. The Left/Right buttons act as the video controller and allow you to rewind and fast-forward as well as stop the video altogether.

If you would like to get a larger look at things, you will need to either watch the video on your TV or move the video files to your computer. To watch on your TV, connect an HDMI cable to the HDMI Out port, or connect the video cable that came with the camera to the A/V Out/Digital port (Figure 11.4).

The video ports on the G12.
Figure 11.4 The video ports on the G12.

Once you’ve connected to your TV, simply use the same camera controls that you used for watching the video on the LCD screen.

If you want to watch or use the videos on your computer, you need to download the images using the Canon software or by using an SD card reader attached to your computer. The video files will have the extension “.mov” at the end of the file name. These files should play on either a Mac or a PC using software that came with your operating system or that can be downloaded for free (Apple’s QuickTime for Mac and Windows is available at www.apple.com/quicktime/download/).

Windows Phone Using Location Services (GPS)

GPS 101

Let’s spend a few minutes to just learn the basics of GPS, in order to better use it in our code. What GPS boils down to—the nitty-gritty—are two floating-point numbers representing the X and Y position on the Earth. The X value has traditionally been called longitude, and the Y value has been known as the latitude. From a game programming perspective, this is an easier way to grasp the terms, but a naval veteran would scoff at the overly simplistic way this is being presented. We’ll gloss over issues of precision in order to grasp the concepts first.

Longitude represents the “X” or horizontal coordinate on the surface of the Earth, running east or west from the zero point.

Latitude represents the “Y” or vertical coordinate on the surface of the Earth, running north or south from the zero point.

The origin (0,0) is located about 400 miles off the western coast of Africa, southwest of Nigeria and south of Ghana. From that origin point, longitude increases to the right (east), and decreases to the left (west); latitude increases up (north), and decreases down (south). In other words, it is oriented exactly like the Cartesian coordinate system we’ve been using all along for our trig-heavy examples. This makes translating GPS coordinates for the purpose of making a reality game a cinch!

To help make sense of the coordinate system, Table 17.1 shows the approximate latitude and longitude values of several major cities in the world, formatted in a way that makes sense to game programmers (such that longitude comes before latitude— remember, we aren’t navigating here). Note that these are far from precise, just rough estimates to present the general location of each city. More precise GPS coordinates will include up to six decimal places of increasing precision, down to just 10 feet or less in granularity.

GPS Data for Major Cities

If you want to learn more about latitude and longitude coordinates, there is an interactive world map available online at http://itouchmap.com/latlong.html.

Windows Phone Location Services

XNA provides us with a geographic location service in a library located in a namespace called System.Device.Location. This library is not included in the project’s references by default, so we must add it to use this library in our program.

Adding the Location Services Library

  1. Right-click References in the Solution Explorer, and then choose Add Reference.
  2. In the dialog box that comes up, there is a list with the .NET tab already in view, as shown in Figure 17.1. Select System.Device from the list and click the OK button.
  3. The geographic location services library is in a namespace called System.Device.Location, which must be added with a using statement to any program that needs these services:
    [code]
    using System.Device.Location;
    [/code]

Using the Location Services

To read the current device’s GPS location, we create an object using the GeoCoordinateWatcher class:

[code]
GeoCoordinateWatcherSim watcher;
[/code]

It is okay to create the watcher object in Initialize() or LoadContent(), or in response to a user event:

[code]
watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.Default);
[/code]

At this point, the object is created but is not yet receiving any GPS data. We have to create an event handler to handle position status change events. The trigger that causes such an event is movement of the device, which can be fine-tuned with the MovementThreshold property:

[code]
watcher.MovementThreshold = 20;
[/code]

Adding a reference to the System.Device library.
FIGURE 17.1 Adding a reference to the System.Device library.

The first event we’ll tap into is StatusChanged. A new event method will need to be created to correspond with the name of the method passed to this new event object. In this case, the example is using a string called statusText, which can be printed out from the main Draw() call. Optionally, a programmer-defined status could be set here and used elsewhere in the game:

[code]
watcher.StatusChanged += new EventHandler
<GeoPositionStatusChangedEventArgs>(watcher_StatusChanged);
void watcher_StatusChanged(object sender,
GeoPositionStatusChangedEventArgs e)
{
switch (e.Status)
{
case GeoPositionStatus.Disabled:
statusText += “Location service has been disabledn”;
break;
case GeoPositionStatus.Initializing:
statusText += “Location service is initializingn”;
break;
case GeoPositionStatus.NoData:
statusText += “Location service is not returning any datan”;
break;
case GeoPositionStatus.Ready:
statusText += “Location service is receiving datan”;
break;
}
}
[/code]

The actual movement of the GPS device triggers position change events that we can tap into with the PositionChanged event. A similar event method will have to be created for this event as well. In this example, a GeoCoordinate variable called coord is set using the passed parameter that contains the GPS location data:

[code]
watcher.PositionChanged += new EventHandler
<GeoPositionChangedEventArgs<GeoCoordinate>>(watcher_PositionChanged);
void watcher_PositionChanged(object sender,
GeoPositionChangedEventArgs<GeoCoordinate> e)
{
coord = e.Position.Location;
}
[/code]

Simulating Position Changes

The WP7 emulator does not have a GPS receiver, and even if your PC has one, the emulator doesn’t know how to use it—the emulator is a self-contained system that only uses the networking of your PC to simulate connectivity. I say “simulate” because in a real WP7 device, that Internet connection would come through the airwaves, presumably G3 or G4, depending on what the service provider supports.

There is a workaround for the limitation. If you want to create a game that uses location services, it’s a given you must be able to test it extensively, and even with a real WP7 device, testing GPS code can be a challenge. So, even with hardware, it may be preferred to develop this code with a GPS simulation rather than the real thing. With a simulation, you can define the location data yourself and write the gameplay code to respond to location data in a predictable way. Only the final testing stages of the game would need to be done “in the field.”

So, a question arises: How do we simulate GPS data?

The solution is to write a class that inherits from GeoLocationWatcher and then fill in data events with a timer that generates real-time updates via GeoLocation events. Voilà!

GeoLocationSim

There are three classes involved in the geographic location simulator. The first is GeoLocationSim, which inherits directly from GeoCoordinateWatcher, the main GPS class in XNA. There are quite a few properties, events, and methods defined in this abstract class that are required to pass this off as a legitimate GeoLocation class so that it works with normal GeoLocation code, but we don’t need all of that for testing purposes. Nevertheless, they are all required. In the sample project for this hour, I have added all three classes in a source file called GeoLocationSim.cs. First, take a look at Listing 17.1, the code for the sim class.

LISTING 17.1 Base GeoLocation Simulation Class

[code]
abstract public class GeoLocationSim : GeoCoordinateWatcher
{
private GeoPosition<GeoCoordinate> current;
private Timer timer;
public GeoLocationSim()
{
current = new GeoPosition<GeoCoordinate>();
Status = GeoPositionStatus.Initializing;
RaiseStatusChanged();
}
private void RaiseStatusChanged()
{
GeoPositionStatusChangedEventArgs args =
new GeoPositionStatusChangedEventArgs(Status);
if (StatusChanged != null)
{
StatusChanged(this, args);
}
}
private void RaisePositionChanged()
{
GeoPositionChangedEventArgs<GeoCoordinate> args =
new GeoPositionChangedEventArgs<GeoCoordinate>(current);
if (PositionChanged != null)
PositionChanged(this, args);
}
public void OnTimerCallback(object state)
{
try
{
if (Status == GeoPositionStatus.Initializing)
{
Status = GeoPositionStatus.NoData;
RaiseStatusChanged();
}
StartGetCurrentPosition();
TimeSpan next = GetNextInterval();
timer.Change(next, next);
}
catch (Exception)
{
throw;
}
}
protected void UpdateLocation(double longitude, double latitude)
{
GeoCoordinate location = new GeoCoordinate(latitude, longitude);
if (!location.Equals(current.Location))
{
current = new GeoPosition<GeoCoordinate>(
DateTimeOffset.Now, location);
if (Status != GeoPositionStatus.Ready)
{
Status = GeoPositionStatus.Ready;
RaiseStatusChanged();
}
RaisePositionChanged();
}
}
abstract protected TimeSpan GetNextInterval();
abstract protected void StartGetCurrentPosition();
//override base property
public GeoPositionPermission Permission
{
get { return GeoPositionPermission.Granted; }
}
//override base property
public GeoPosition<GeoCoordinate> Position
{
get { return current; }
}
//override base event
public event EventHandler<GeoPositionChangedEventArgs
<GeoCoordinate>> PositionChanged;
//override base method
public void Start(bool suppressPermissionPrompt)
{
Start();
}
//override base method
public void Start()
{
TimeSpan span = GetNextInterval();
timer = new Timer(OnTimerCallback, null, span, span);
}
//override base property
public GeoPositionStatus Status
{
get;
protected set;
}
//override base event
public event EventHandler
<GeoPositionStatusChangedEventArgs> StatusChanged;
//override base method
public void Stop()
{
timer.Change(Timeout.Infinite, Timeout.Infinite);
Status = GeoPositionStatus.Disabled;
RaiseStatusChanged();
}
//override base method
public bool TryStart(bool suppressPermissionPrompt, TimeSpan timeout)
{
Start();
return true;
}
}
[/code]

Filling in GPS Data with Timing

SampleGeoCoord is a helper class that is used to fill in GPS position data with timing. Each position coordinate corresponds to a one-second interval at which the position update event is triggered. So, this class supplies longitude, latitude, and time.

[code]
public class SampleGeoCoord
{
public double Longitude { get; set; }
public double Latitude { get; set; }
public TimeSpan Time { get; set; }
public SampleGeoCoord(double Longitude, double Latitude, int seconds)
{
this.Longitude = Longitude;
this.Latitude = Latitude;
this.Time = new TimeSpan(0, 0, seconds);
}
}
[/code]

GeoCoordinateWatcherSim

The GeoCoordinateWatcherSim is our main workhorse simulation class, inheriting directly from GeoLocationSim. This class puts the GeoLocationSim properties, methods, and events to work using data populated within an array of SampleGeoCoord objects. In the example coming up that uses this class, I’ve centered the coordinates around Los Angeles, with 60 seconds of random locations within a radius of about 100 miles around the city coordinates (-118, 34). Listing 17.2 contains the code for the GeoCoordinateWatcherSim class.

LISTING 17.2 Usable GeoCoordinateWatcherSim Worker Class

[code]
public class GeoCoordinateWatcherSim : GeoLocationSim
{
List<SampleGeoCoord> events;
int currentEventId;
Random rand = new Random();
public GeoCoordinateWatcherSim(GeoPositionAccuracy accuracy)
{
currentEventId = 0;
events = new List<SampleGeoCoord>();
//create random coordinates in Los Angeles
for (int n = 1; n < 60; n++)
{
double Long = -118 – rand.Next(2) – rand.NextDouble();
double Lat = 33 + rand.Next(2) + rand.NextDouble();
events.Add(new SampleGeoCoord(Long, Lat, n));
}
}
private SampleGeoCoord Current
{
get
{
return events[currentEventId % events.Count];
}
}
protected override void StartGetCurrentPosition()
{
this.UpdateLocation(Current.Longitude, Current.Latitude);
currentEventId++;
}
protected override TimeSpan GetNextInterval()
{
return Current.Time;
}
}
[/code]

Creating the Geo Position Demo

Let’s write a program to demonstrate the GeoCoordinateWatcherSim class in action. The example requires only a font, because it just prints out the longitude and latitude of the geographical coordinate data and the status of the watcher. The code for the Geo Position Demo program is found in Listing 17.3, and Figure 17.2 shows the program running. Note that this example will work on a WP7 device without the simulated data with a single line change, from

[code]
watcher = new GeoCoordinateWatcherSim(…);
[/code]

to

[code]
watcher = new GeoCoordinateWatcher(…);
[/code]

The Geo Position Demo simulates GPS movement.
FIGURE 17.2 The Geo Position Demo simulates GPS movement.

LISTING 17.3 The Geo Position Demo Program

[code]
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
TouchLocation oldTouch;
Random rand;
SpriteFont font;
string statusText = ““;
GeoCoordinateWatcherSim watcher = null;
GeoCoordinate coord = null;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = “Content”;
TargetElapsedTime = TimeSpan.FromTicks(333333);
oldTouch = new TouchLocation();
}
protected override void Initialize()
{
base.Initialize();
StartGeoLocation();
}
protected override void LoadContent()
{
rand = new Random();
spriteBatch = new SpriteBatch(GraphicsDevice);
font = Content.Load<SpriteFont>(“WascoSans”);
}
protected override void UnloadContent()
{
base.UnloadContent();
watcher.Stop();
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back ==
ButtonState.Pressed)
this.Exit();
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Black);
spriteBatch.Begin(SpriteSortMode.FrontToBack,
BlendState.AlphaBlend);
spriteBatch.DrawString(font, “Latitude: “ +
coord.Latitude.ToString(“0.000”),
new Vector2(100, 10), Color.White);
spriteBatch.DrawString(font, “Longitude: “ +
coord.Longitude.ToString(“0.000”),
new Vector2(100, 30), Color.White);
spriteBatch.DrawString(font, statusText,
new Vector2(100, 100), Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
void StartGeoLocation()
{
coord = new GeoCoordinate();
//try to create geo coordinate watcher
if (watcher == null)
{
statusText += “Starting location service…n”;
watcher = new GeoCoordinateWatcherSim(
GeoPositionAccuracy.Default);
watcher.MovementThreshold = 20;
watcher.StatusChanged += new EventHandler
<GeoPositionStatusChangedEventArgs>(
watcher_StatusChanged);
watcher.PositionChanged += new EventHandler
<GeoPositionChangedEventArgs<GeoCoordinate>>
(watcher_PositionChanged);
watcher.Start();
}
}
void watcher_StatusChanged(object sender,
GeoPositionStatusChangedEventArgs e)
{
switch (e.Status)
{
case GeoPositionStatus.Disabled:
statusText += “Location service has been disabledn”;
break;
case GeoPositionStatus.Initializing:
statusText += “Location service is initializingn”;
break;
case GeoPositionStatus.NoData:
statusText += “Location service is not returning any datan”;
break;
case GeoPositionStatus.Ready:
statusText += “Location service is receiving datan”;
break;
}
}
void watcher_PositionChanged(object sender,
GeoPositionChangedEventArgs<GeoCoordinate> e)
{
coord = e.Position.Location;
}
}
[/code]

There are many uses for GPS tracking, not to mention potential multiplayer games, but one thing to keep in mind is that GPS only provides location data, but there’s no transmitting of that data. After the location is received, that’s it—it’s data, and it’s not transmitted anywhere. GPS is read-only. So, if you have in mind a game, there must still be a network infrastructure connecting all the players, wherein each player will transmit his or her GPS location to the other players over the network. The WP7 platform supports Xbox Live for networking, so that is likely the next subject to study if you’re interested in making a networked game.

Getting User Input

Exploring Windows Phone Touchscreen Input

Programming a game’s input system really does require a lot of design consideration ahead of time because all we really can use is the touchscreen! Oh, there is an accelerometer that can be used for input, but it is a rare and often niche game that uses the accelerometer to read the phone’s orientation (the angle and position at which it is being held). The touchscreen, for all practical purposes, is treated like mouse input without a visible mouse cursor. Windows programmers will have a slightly harder time adjusting than someone who has been working with the Xbox 360 or another console, which already requires an adjustment in one’s assumptions about user input. Windows games are a cakewalk, with 100-plus keyboard keys, the mouse, and an optional controller! That’s a lot of input! On the Windows Phone, though, all we have is the touchscreen. So we need to make the most of it, being mindful that a user’s finger is rather large compared to the precise input of a mouse cursor.

For the purpose of detecting input for a game, the most obvious method might be to just detect the touch location and convert that to an average coordinate—like mouse input. But the Windows Phone touchscreen is capable of multitouch, not just single-touch input. Although the screen is very small compared to a tablet or PC screen, it is still capable of detecting input from up to four fingers at once. To develop a multitouch game, you will need the actual Windows Phone hardware— either a real phone or an unlocked development model (with no phone service).

Multitouch is a significant feature for the new phone! For our purposes here, however, we will just be concerned with single “tap” input from one finger, simulated with mouse motion in the emulator. We can do a single tap with a mouse click, or a drag operation by touching the screen and moving the finger across the screen. Again, this will have to be done with your mouse for development on the emulator (unless your Windows system uses a touchscreen!).

You will not be able to test multitouch in the emulator without a multitouch screen on your Windows development system or an actual Windows Phone device.

Simulating Touch Input

The key to touch input with a WP7 device with XNA is a class called TouchPanel. The XNA services for mouse, keyboard, and Xbox 360 controller input are not available in a WP7 project. So, for most XNA programmers, TouchPanel will be a new experience. Not to worry; it’s similar to the mouse code if we don’t tap into the multitouch capabilities.

The TouchPanel class includes one very interesting property that we can parse— MaximumTouchCount represents the number of touch inputs that the device can handle at a time.

The second class that we need to use for touch input is called TouchCollection. As the name implies, this is a collection that will be filled when we parse the TouchPanel while the game is running. TouchCollection has a State property that is similar to MouseState, with the enumerated values Pressed, Moved, and Released.

The Touch Demo Project, Step by Step

Let’s create a sample project to try out some of this code. I’ll skip the usual new project instructions at this point since the steps should be familiar by now. Just create a new project and add a font so that we can print something on the screen. I’ve used Moire Bold 24 as the font in this example.

  1. Add some needed variables for working with text output. (The code for the touchscreen input system will be added shortly.)
    [code]
    public class Game1 : Microsoft.Xna.Framework.Game
    {
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;
    SpriteFont MoireBold24;
    Vector2 position;
    Vector2 size;
    string text = “Touch Screen Demo”;
    [/code]
  2. Initialize the font and variables used in the program.
    [code]
    protected override void LoadContent()
    {
    spriteBatch = new SpriteBatch(GraphicsDevice);
    MoireBold24 = Content.Load<SpriteFont>(“MoireBold24”);
    size = MoireBold24.MeasureString(text);
    Viewport screen = GraphicsDevice.Viewport;
    position = new Vector2((screen.Width – size.X) / 2,
    (screen.Height – size.Y) / 2);
    }
    [/code]
  3. Write the update code to get touch input.
    [code]
    protected override void Update(GameTime gameTime)
    {
    if (GamePad.GetState(PlayerIndex.One).Buttons.Back ==
    ButtonState.Pressed)
    this.Exit();
    //get state of touch inputs
    TouchCollection touchInput = TouchPanel.GetState();
    //look at all touch points (usually 1)
    foreach(TouchLocation touch in touchInput)
    {
    position = new Vector2(touch.Position.X – size.X / 2,
    touch.Position.Y – size.Y / 2);
    }
    base.Update(gameTime);
    }
    [/code]
  4. Print the message on the screen at the touch coordinates.
    [code]
    protected override void Draw(GameTime gameTime)
    {
    GraphicsDevice.Clear(Color.CornflowerBlue);
    spriteBatch.Begin();
    spriteBatch.DrawString(MoireBold24, text, position, Color.White);
    spriteBatch.End();
    base.Draw(gameTime);
    }
    [/code]

Figure 4.1 shows the output of the program running in the WP7 emulator. Although the static figure doesn’t show movement, the message “Touch Screen Demo” moves on the screen with touch input! On a real Windows Phone device, this would work with finger input on the screen.

The Windows Phone hardware specification calls for at least four simultaneous touchscreen inputs!

The text message moves based on touch input.
FIGURE 4.1 The text message moves based on touch input.

How to Simulate More Inputs

What if you really do have a great design for a multitouch game but have no way to test it (that is, you do not have a WP7 device or a touchscreen for your Windows PC)? One alternative is to develop and test your game with simulated inputs for each finger, and then test each input separately in the emulator. This actually works quite well! Suppose your game requires one input to move a ship left or right on the screen, and another input to fire a weapon. The easy approach is to just leave the ship’s movement alone (presumably at the center of the screen without movement) to test the firing input. When that is working satisfactorily, then you might test leftto- right movement input with random or regular shooting intervals. This is how most developers will approach the problem.

Using Gestures on the Touchscreen

A related capability of the TouchPanel class is a gesture interface. This is potentially a really great feature for WP7 games, so don’t pass it up! A gesture is essentially nonverbal communication with your hands. A gesture on a touchscreen might be to flick an object across the screen rather than dragging to the exact location where you want it to go. Instead of manually moving something one direction or another, one might just flick it in the general direction. So, it’s up to the game to interpret the gestures based on the game’s user interface design.

Since gesture input can be used in place of touch input, you might want to just use gesture input instead. If all you need for your game is single-touch input, a tap gesture would work in place of the mouselike touch code seen previously. The main difference between the two methods is that gesture input does not support multitouch.

XNA supports gestures with the same TouchPanel class used for touch input. Here are the contents of the GestureType enumeration:

  • None
  • FreeDrag
  • Tap
  • Pinch
  • DoubleTap
  • Flick
  • Hold
  • DragComplete
  • HorizontalDrag
  • PinchComplete
  • VerticalDrag

Gesture-based input does not support multitouch. Only a single gesture (with one finger) can be used at a time.

To use gesture input, we have to enable it, because gesture input is not automatic. There are obvious problems with input if all gestures are enabled by default, because the game will behave erratically with flick gestures in a game using a lot of “drag”-style input to move and interact with the game. Even the simplest of arcadestyle or puzzle games will involve some dragging of the finger across the screen for input, and this could be misinterpreted as a flick if the intended movement is too fast. To enable both tap and flick gestures, add this line to the constructor, Game1(), or LoadContent():

[code]
TouchPanel.EnabledGestures = GestureType.Tap | GestureType.Flick;
[/code]

A simple example can be added to the Update() method of the Touch Demo to see how it works. Note that the first if condition is required. Trying to read a gesture when none is available will cause an exception!

[code]
if (TouchPanel.IsGestureAvailable)
{
GestureSample gesture = TouchPanel.ReadGesture();
if (gesture.GestureType == GestureType.Tap)
{
position = new Vector2(gesture.Position.X – size.X / 2,
gesture.Position.Y – size.Y / 2);
}
}
[/code]

Running this code, you might be surprised to find that the tap gesture is more like a mouse click-and-release event. Click-dragging does not produce the gesture! You can see for yourself by commenting out the touch input code in the Touch Demo program, and running just the gesture code instead. If you’re really interested in gesture input, a real WP7 device is a must-have! The emulator just doesn’t satisfy. If you are doing WP7 development for profit, a dev device or an actual Windows Phone device (with carrier subscription) is a good investment.

Touch input can be quite satisfying to a game designer after working with the traditional keyboard and mouse, because it offers the potential for very creative forms of input in a game. Although regular multitouch input will be the norm for most Windows Phone games, the ability to use gestures also might prove to be fun.

Making Games for Windows Phone 7

Getting Started with Windows Phone 7

There are two ways we can develop games for Windows Phone 7: Silverlight and XNA Game Studio. Although Silverlight does have basic graphics capabilities, those capabilities are provided to support applications and are not ideally suited for games. XNA, on the other hand, was developed specifically for game development!

Before learning all about XNA Game Studio 4.0, Visual C# 2010, projects, configurations, Xbox Live, App Hub, and other great things that will interest a game developer, we need to first understand this new platform. Windows Phone 7, which we might call WP7 for short, is an operating system for smartphone devices.

In “the old days,” if you knew how to turn on a computer, you were called a “computer geek.” It didn’t really matter if you knew how to do anything with a computer; it was just assumed by many (especially in the older generations) that turning it on required knowledge of the black arts in electronics wizardry. That seems to be the case with most new technology, which people will tend to resist and perhaps even fear to a certain degree. When cars were first invented at the dawn of the automobile industry, people who drove around in a “horseless carriage” were considered snobbish, among the wealthy class—that is, until Henry Ford built a car that just about anyone could afford to buy. Not only did most people not have a computer in the early days, but most people at the time did not even begin to know how to go about buying one.

I’m speaking in terms of the time period around the mid- to late-1970s, at the dawn of the personal computer (PC) age. At that time, PCs were few and far between, and a kid who owned a Commodore PET, a Tandy TRS-80, or an Apple was a rare and lucky kid indeed! Most big businesses used big mainframe computers to do the most time-consuming tasks of any business—accounting, payroll, and taxes. But even at this time period, most white-collar employees who worked in an office did not have a PC. Imagine that! It’s unheard-of today! Today, the first thing a new employee must have is a cubicle or an office with a PC. And, not just that, but a networked PC with Internet access.

Windows Phone 7 as a Game Platform?

There was a time not too many years ago when just having a PC was enough to do your work—programming, software engineering, computer-aided design (CAD), word processing, accounting. Even in the 1980s, it was rare for every employee to have a PC at his or her desk, and even more rare for families to have a PC in their homes. A lot of kids might have had a Nintendo Entertainment System (NES) or Sega Master System (SMS) or the older Atari 2600, all of which used cartridge-based games. A step up from these video game systems were the true PCs of the time, such as the Apple II, Commodore 64, Amiga, Atari 400/800, and Atari ST. No computer enthusiasts at the time used an IBM PC at home! MS-DOS was a terrible operating system compared to the other, more user-friendly ones. If you wanted to do programming, you would naturally gravitate to the consumer PCs, not the business-oriented IBM PC. Now, at the time, the Apple Macintosh was pretty expensive and the ordinary kid would prefer an Apple II, but that was the start of the Mac, back in the 1980s (although it has been completely redesigned several times before reaching the modern OS X).

Well, today the world sure is a different place. If we just ignore how powerful computers are today, just look at all the hand-held systems—they’re everywhere! The Nintendo DS family and the Sony PlayStation Portable (PSP) family are the two leading competitors of hand-held video game systems, and they can do almost anything that their big brothers (Nintendo Wii and Sony PS3) can do, including online play. These things are everywhere! You can’t walk through a store or a mall without seeing kids carrying some sort of mobile video game system with them, not to mention phones. And it’s not just kids, but adults have their toys too, like Apple iPhone, iPod, and iPad, for which some really great games are available! One of my favorites is Plants vs Zombies by PopCap Games. You can also get the game for Xbox 360, Mac, Windows, and Nintendo DS. And you know what? Some popular games are starting to come out for Windows Phone 7 because it’s fairly easy to port an Xbox 360 game to Windows Phone 7.

So what is Windows Phone 7 all about? Obviously, since you’re reading this book, you are interested in programming games for the device. That goes without saying, but what is development for this platform really like? What’s it all about? We have to ask ourselves these questions because developing a game that you want to be taken seriously requires a pretty big investment of time, if not money. Most likely, anyone looking at Windows Phone 7 for game development is already experienced with XNA Game Studio. If you have never used this development tool, the next hour will be helpful because we’ll be creating projects and working with Visual C# quite a bit. I’ll assume that you might not have any experience with Visual Studio, but I do not want to annoy experienced developers, so bear with me a bit while we cover the basics such as these!

History of the Platform

Windows Phone 7 follows a long history of mobile devices from Microsoft, dating clear back to the Pocket PC in 2000. Pocket PC competed directly with the market leader of the time, Palm. The Palm Pilot was arguably the progenitor of all handsized mobile computers today, including cellphones.

Interestingly enough, I would not consider Apple’s iPhone as an evolutionary leap beyond Palm Pilot—ignoring the many devices that have entered the market in the intervening years of the past decade. The iPhone does not follow in the lineage of “mobile computer” dating back to the Palm Pilot and Pocket PC because it was derived from Apple’s wildly successful iPod. The iPod should have been invented by Sony, the company responsible for the “Walkman” generation of portable music players. Everyone in the 1980s and early 1990s owned a “Walkman,” regardless of the brand, in the same vein that everyone has played with a “Frisbee,” despite these being brand names with competing companies making similar products. We Americans, due to targeted advertising, come to associate whole industries with a single product name, merely out of habit.

At any rate, you might have heard the term “podcast.” The term is rather generalized today to mean audio streamed or recorded in digital form for playback on a digital media player. But the concept was invented by Apple for the iPod and iTunes (including iTunes University), which now work with video files as well as audio files. While everyone was caught up in the Napster lawsuits, Apple was busy developing iTunes and began selling music in a revolutionary new way: per track instead of per album. Have you ever heard a catchy new song on the radio and wanted to buy it for your iPod, Microsoft Zune, Creative Zen, or similar media player? Well, in the past decade, you would buy the whole CD and then rip the tracks into MP3 with software such as Windows Media Player or Winamp. This point is debatable, but I would argue that Apple iTunes proved that digital music sales can be a commercial success, highly profitable both for the recording artists and for the service provider (iTunes). Amazon is probably the second case example that proves this is now a commercially successful way to sell music.

The point is, iPod was so successful that it evolved into the iPhone and iPad, and competing companies have been trying to keep up with Apple in both of these markets now for years! The iPod and its relatives are insanely great, which is why everyone wants one. More than a fashion statement, Apple understood what the consumer wanted and made it for them. What did customers want? Not a do-everything badly device, but a do-the-most-important-thing great device. In contrast, many companies hire “experts” to conduct consumer studies, and then spend millions trying to convince customers that they really want and need that product. This might be one good way to break into a relatively unknown market or to adjust the feature set of a product according to consumer interest. But the situation Apple finds itself in today is enviable, and with that comes emulation.

The previous iteration of Windows Mobile was called Windows Phone 6.5, and over a dozen hardware manufacturers and networks supported it, from Acer to HP to Samsung. Prior to that, Windows Phone 5 revolutionized the platform with a GPU (graphics processing unit) for 3D rendering.

The current Windows Phone 7’s operating system traces its roots directly back to the original Pocket PC operating system released in 2000. Pocket PCs came with a stylus, much like the one used on a Nintendo DS. This allows for precise input coordinates, necessary for apps like a spreadsheet (a portable version of Excel called Pocket Excel was available). However, stylus input can be tedious in today’s hustle-and-bustle environment, where it is more convenient to use a thumb to do things on the device’s touchscreen. Who wants to fish out a stylus just to tap a silly pop-up button (which Microsoft developers are notoriously fond of) when a thumb or another finger will do the trick?

The online capabilities of the Sega Dreamcast video game console were made possible thanks to Windows CE. If you look at the front of the Dreamcast case, you will find a Windows CE logo.

To get technical, Windows Phone 7 is based on the Windows Mobile operating system, a new name for the classic Windows CE operating system. Windows CE goes back quite a few years. “Pocket PC” was a marketing name for Windows CE 3.1. Developers at the time used Microsoft eMbedded Visual Tools 3.0 (see Figure 1.1) to develop for Windows CE 3.1. This was a modified version of Visual Studio 6 for Windows CE that was actually a remarkable development environment! It was stable, fully featured, and free! This might be considered an early predecessor of the Express Editions now made available free by Microsoft. At the time, there were many Pocket PC models available, but the most notable ones were from Casio, HP, Dell, and Compaq.

FIGURE 1.1 Microsoft eMbedded Visual C++ 3.0.
FIGURE 1.1 Microsoft eMbedded Visual C++ 3.0.

Microsoft supported game development on the Pocket PC (Windows CE 3.1) by providing a low-level library called the Game API. It was nowhere near as powerful as DirectX for rendering; but neither was the Game API at the slower level of the Windows GDI (graphics device interface). No, the Game API did give access to the actual bits of the video memory, making it possible to write a low-level blitter (a term derived from the “bit-block transfer” form of memory copying). Many developers worked on sprite renderers and game libraries using the Game API, and a book was published on the subject—Pocket PC Game Programming: Using the Windows CE Game API, by Prima-Tech—in 2001. Some copies are still floating around if you’re curious about “the early days” and the predecessor of WP7. At the time, developers had their choice of eMbedded Visual Basic or eMbedded Visual C++, but today we’re developing games for WP7 using XNA and C#. In that 2001 book is a rudimentary game library surrounding WinMain() and the other Windows core code necessary when working in C++, as well as integrated Game API built into a series of classes.

I created one published game using the library from that early book, an indie game called Perfect Match, shown in Figure 1.2. It was sold on mobile sites such as www. Handango.com. Since I lost contact with the artist who did all the renderings, the game could not be updated or ported to any newer systems. By the way, the screen resolution was 240×320 in portrait orientation, and most games were designed to be played this way; but you’ll note that many WP7 games require the player to tilt the device sideways (landscape orientation). This is something that was not common back in the Pocket PC days, but it makes sense now.

FIGURE 1.2 Perfect Match, a Pocket PC 2000 game.

Another example from the time period is the final sample game in the book, a multiplayer game called Pocket Air Hockey, shown in Figure 1.3. This was a quick game, but even now, looking back on it, I think the chat keypad and networking code were quite good for a book example. I used the Windows Sockets (winsock) library with threading. To develop the game, I had two Pocket PCs (a Casio Cassiopeia and an HP Jornada) each equipped with a Hawking CF LAN card plugged into the top expansion port with blue CAT5 network cables going into each one. Can you imagine that? (There were also 802.11b Wi-Fi cards available for the Compact- Flash adapter port.) I just don’t think anyone was really into developing multiplayer games for this platform at the time.

FIGURE 1.3 Pocket Air Hockey, a networked multiplayer game.
FIGURE 1.3 Pocket Air Hockey, a networked multiplayer game.

There was no single processor standard for the original Pocket PC 2000 devices, but three came to be used: Hitachi SH-3, NEC VR MIPS, and StrongARM. The ARM processor would become the single standard for Pocket PC 2002. The reason there have been so many releases in recent years, compared to the past, without significant updates to the core operating system (Windows CE) is that there’s a need to keep up with the aggressive cellphone market’s demand for change, even when change is not entirely necessary. When a company releases some trivial new feature in one of its phones, all competitors must come up with a compelling reason for customers to choose their phone instead. The carrier networks (T-Mobile, AT&T, and Verizon, primarily) also push hard for new devices and plans to maintain their customers and attract new customers. So, Windows Mobile 6 might not even be recognizable between 2007 and 2009, but the changes are primarily cosmetic, but also have to do with user input and application support. This market has been chaotic, to say the least! Table 1.1 is a historical list of releases for the platform.

History of Windows Mobile
TABLE 1.1 History of Windows Mobile
History of Windows Mobile
TABLE 1.1 History of Windows Mobile

Windows Phone 7 was planned for release in 2009 with a core based on Windows CE 5.0—a core dating back to 2005. The core was just too old, so development failed. At that point, a stopgap product was released (Windows Phone 6.5) while Windows Phone 7 went back to the drawing board. The Windows Mobile team ended up rebuilding the new platform from scratch around the new Windows CE 6.0 core for release the following year (2010).

Hardware Specifications

What we have today in the WP7, a completely new operating system built from the ground up around the Windows CE 6.0 core, is a modern touch-enabled architecture with no resemblance to the Windows desktop computer operating system. It took many years, but Microsoft finally perfected the platform! No longer must mobile users tap with a stylus. A sample phone built by Samsung and connected to the AT&T network is shown in Figure 1.4. WP7 competes directly with two other smartphones in the industry today: Apple iPhone and Google Android. Apple is a closed architecture, meaning only Apple builds iPhone devices. WP7 and Android, on the other hand, are not so much mobile devices as they are operating systems. That is why there are many devices available in the Android and WP7 format—but there is only one iPhone. From a developer’s point of view, this openness makes life more difficult. Android, for instance, may be too open, with many different screen sizes and hardware specs. Developing a game for iPhone? That’s a piece of cake, as far as specifications go, because there is only one (although, admittedly, adjustments to the settings are required for iPad due to its larger screen resolution).

Table 1.2 shows the common hardware specifications among most of the models available at the time of this writing. The most notable thing about the specifications is that they now follow a basic standard across all manufacturers. Apple has proven that extreme openness and flexibility are not always desirable traits in mobile hardware. One of the difficulties facing Android developers today is the need to support many different hardware devices in a single code base. Windows Mobile developers had to deal with a similar problem in Windows Phone 6.4 and earlier versions, but as you can see, WP7 has a much simpler subset of hardware specifications. This is a good thing for developers, greatly simplifying the code, allowing developers to focus on game design and gameplay rather than hardware idiosyncrasies among the different makes and models.

A Windows Phone 7 device built by Samsung.
FIGURE 1.4 A Windows Phone 7 device built by Samsung.
Windows Phone 7 Hardware Specifications
TABLE 1.2 Windows Phone 7 Hardware Specifications

WP7 is an awesome integration of many technologies that have evolved over the years, beginning with the early Windows CE and Pocket PC devices, to the modern, powerful smartphone of today with advanced 3D rendering capabilities that truly bring cutting-edge gaming into the palm of your hand.

Trombone (Sound Manipulation)

Trombone is a much more sophisticated musical instrument app than the preceding chapter’s Cowbell app. You can move the slide up and down to different positions to play any note. (Other than starting at F, the slide positions bear little resemblance to real trombone slide positions!) This app supports two different sliding modes. If you use the left side of the screen, you can freely move the slide. If you use the right side of the screen, the slide snaps to the closest note line. Besides being an easier way to play this instrument, this means you could also use this app as a pitch pipe.

This trombone can play its notes in two octaves; to raise the sound by an octave, place a second finger anywhere on the screen. The most fun part about this app is that, like with a real trombone, you must actually blow on your phone to produce sound!

These last two app features require phone features discussed in later chapters (multi-touch and using the microphone) so that portion of the code is not explained in this chapter. Instead, the focus is on manipulating a single sound effect’s pitch and duration to create all the audio needed by this app.

The User Interface

The main page, pictured in Figure 31.1 in its initial state, contains the moveable trombone slide, note guide lines, and buttons that link to the other two pages. Listing 31.1 contains the XAML.

The main page simulates the appearance of a real trombone.
FIGURE 31.1 The main page simulates the appearance of a real trombone.

LISTING 31.1 MainPage.xaml—The User Interface for Trombone’s Main Page

[code]

<phone:PhoneApplicationPage x:Class=”WindowsPhoneApp.MainPage”
xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
xmlns:phone=”clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone”
SupportedOrientations=”Portrait”>
<Canvas x:Name=”LayoutRoot”>
<!– The stationary inner slide –>
<Image Canvas.Left=”72” Source=”Images/innerSlide.png”/>
<!– The moveable outer slide –>
<Image x:Name=”SlideImage” Canvas.Left=”72” Canvas.ZIndex=”1”
Source=”Images/outerSlide.png”/>
<!– An instructions button –>
<Rectangle Canvas.Left=”18” Canvas.Top=”30” Canvas.ZIndex=”1”
Width=”48” Height=”48” Fill=”{StaticResource PhoneForegroundBrush}”
MouseLeftButtonUp=”InstructionsButton_Click”>
<Rectangle.OpacityMask>
<ImageBrush ImageSource=”/Shared/Images/normal.instructions.png”/>
</Rectangle.OpacityMask>
</Rectangle>
<!– A settings button –>
<Rectangle Canvas.Left=”18” Canvas.Top=”94” Canvas.ZIndex=”1”
Width=”48” Height=”48” Fill=”{StaticResource PhoneForegroundBrush}”
MouseLeftButtonUp=”SettingsButton_Click”>
<Rectangle.OpacityMask>
<ImageBrush ImageSource=”/Shared/Images/normal.settings.png”/>
</Rectangle.OpacityMask>
</Rectangle>
</Canvas>
</phone:PhoneApplicationPage>

[/code]

  • The note guide lines pictured in Figure 31.1 are added in this page’s code-behind.
  • An application bar would get in the way of this user interface, so two rectangles acting as buttons are used instead. They use the familiar opacity mask trick to ensure they appear as expected for any theme.
  • The trombone slide consists of two images, one on top of the other. These two images are shown in Figure 31.2.
The slide consists of a moving image on top of a stationary image.
FIGURE 31.2 The slide consists of a moving image on top of a stationary image.

The Code-Behind

Listing 31.2 contains the code-behind for the main page.

LISTING 31.2 MainPage.xaml.cs—The Code-Behind for Trombone’s Main Page

[code]

using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Navigation;
using System.Windows.Resources;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Xna.Framework.Audio; // For SoundEffect
namespace WindowsPhoneApp
{
public partial class MainPage : PhoneApplicationPage
{
// The single sound effect instance
SoundEffectInstance soundEffectInstance;
string[] notes = { “G ”, “G”, “A ”, “A”, “B ”, “B”,
“C”, “D ”, “D”, “E ”, “E”, “F” };
// The relative distance of each note’s pitch,
// where 0 is the initial F and -1 is one octave lower
double[] pitches = { -.9 /*G */, -.82 /*G*/, -.75 /*A */, -.68 /*A*/,
-.6 /*B */, -.5 /*B*/, -.4 /*C*/, -.35 /*D */,
-.25 /*D*/, -.18 /*E */, -.08 /*E*/, 0 /*F*/ };
// For microphone processing
byte[] buffer;
int currentVolume;
// For several calculations
const int TOP_NOTE_POSITION = 20;
const int BOTTOM_NOTE_POSITION = 780;
const int OCTAVE_RANGE = 844;
public MainPage()
{
InitializeComponent();
// Load the single sound file used by this app: the sound of F
StreamResourceInfo info = App.GetResourceStream(
new Uri(“Audio/F.wav”, UriKind.Relative));
SoundEffect effect = SoundEffect.FromStream(info.Stream);
// Enables manipulation of the sound effect while it plays
this.soundEffectInstance = effect.CreateInstance();
// The source .wav file has a loop region, so exploit it
this.soundEffectInstance.IsLooped = true;
// Add each of the note guide lines
for (int i = 0; i < this.pitches.Length; i++)
{
double position = BOTTOM_NOTE_POSITION + this.pitches[i] * OCTAVE_RANGE;
// Add a line at the right position
Line line = new Line { X2 = 410,
Stroke = Application.Current.Resources[“PhoneAccentBrush”] as Brush,
StrokeThickness = 5, Opacity = .8 };
Canvas.SetTop(line, position);
this.LayoutRoot.Children.Add(line);
// Add the note label next to the line
TextBlock label = new TextBlock {
Text = this.notes[i][0].ToString(), // Ignore the , use 0th char only
Foreground = Application.Current.Resources[“PhoneAccentBrush”] as Brush,
FontSize = 40 };
Canvas.SetLeft(label, line.X2 + 12);
Canvas.SetTop(label, position – 20);
this.LayoutRoot.Children.Add(label);
// Add the  separately, simulating a superscript so it looks better
if (this.notes[i].EndsWith(“”))
{
TextBlock flat = new TextBlock { Text = “”, FontSize = 25,
FontWeight = FontWeights.Bold, Foreground =
Application.Current.Resources[“PhoneAccentBrush”] as Brush };
Canvas.SetLeft(flat, line.X2 + label.ActualWidth + 6);
Canvas.SetTop(flat, position – 21);
this.LayoutRoot.Children.Add(flat);
}
}
// Configure the microphone
Microphone.Default.BufferDuration = TimeSpan.FromSeconds(.1);
Microphone.Default.BufferReady += Microphone_BufferReady;
// Initialize the buffer for holding microphone data
int size = Microphone.Default.GetSampleSizeInBytes(
Microphone.Default.BufferDuration);
buffer = new byte[size];
// Start listening
Microphone.Default.Start();
CompositionTarget.Rendering += delegate(object sender, EventArgs e)
{
// Required for XNA Sound Effect API to work
Microsoft.Xna.Framework.FrameworkDispatcher.Update();
// Play the sound whenever the blowing into the microphone is loud enough
if (this.currentVolume > Settings.VolumeThreshold.Value)
{
if (soundEffectInstance.State != SoundState.Playing)
soundEffectInstance.Play();
}
else if (soundEffectInstance.State == SoundState.Playing)
{
// Rather than stopping immediately, the “false” makes the sound break
// out of the loop region and play the remainder
soundEffectInstance.Stop(false);
}
};
// Call also once at the beginning
Microsoft.Xna.Framework.FrameworkDispatcher.Update();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
// Subscribe to the touch/multi-touch event.
// This is application-wide, so only do this when on this page.
Touch.FrameReported += Touch_FrameReported;
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
// Unsubscribe from this application-wide event
Touch.FrameReported -= Touch_FrameReported;
}
void Touch_FrameReported(object sender, TouchFrameEventArgs e)
{
TouchPoint touchPoint = e.GetPrimaryTouchPoint(this);
if (touchPoint != null)
{
// Get the Y position of the primary finger
double position = touchPoint.Position.Y;
// If the finger is on the right side of the screen, snap to the
// closest note
if (touchPoint.Position.X > this.ActualWidth / 2)
{
// Search for the current offset, expressed as a negative value from
// 0-1, in the pitches array.
double percentage = (-BOTTOM_NOTE_POSITION + position) / OCTAVE_RANGE;
int index = Array.BinarySearch<double>(this.pitches, percentage);
if (index < 0)
{
// An exact match wasn’t found (which should almost always be the
// case), so BinarySearch has returned a negative number that is the
// bitwise complement of the index of the next value that is larger
// than percentage (or the array length if there’s no larger value).
index = ~index;
if (index < this.pitches.Length)
{
// Don’t always use the index of the larger value. Also check the
// closest smallest value (if there is one) and snap to it instead
// if it’s closer to the current value.
if (index > 0 &&
Math.Abs(percentage – this.pitches[index]) >
Math.Abs(percentage – this.pitches[index – 1]))
index–;
// Snap the position to the new location, expressed in pixels
position = BOTTOM_NOTE_POSITION +
this.pitches[index] * OCTAVE_RANGE;
}
}
}
// Place the outer slide to match the finger position or snapped position
Canvas.SetTop(this.SlideImage, position – this.ActualHeight – 40);
// See how many fingers are in contact with the screen
int numPoints =
(from p in e.GetTouchPoints(this)
where
p.Action != TouchAction.Up
select p).Count();
// 1 represents one octave higher (-1 represents one octave lower)
int startingPitch = (numPoints > 1) ? 1 : 0;
// Express the position as a delta from the bottom position, and
// clamp it to the valid range. This gives a little margin on both
// ends of the screen because it can be difficult for the user to move
// the slide all the way to either end.
double offset = BOTTOM_NOTE_POSITION –
Math.Max(TOP_NOTE_POSITION, Math.Min(BOTTOM_NOTE_POSITION,
touchPoint.Position.Y));
// Whether it’s currently playing or not, change the sound’s pitch based
// on the current slide position and whether the octave has been raised
this.soundEffectInstance.Pitch =
(float)(startingPitch – (offset / OCTAVE_RANGE));
}
}
void Microphone_BufferReady(object sender, EventArgs e)
{
int size = Microphone.Default.GetData(buffer);
if (size > 0)
this.currentVolume = GetAverageVolume(size);
}
// Returns the average value among all the values in the buffer
int GetAverageVolume(int numBytes)
{
long total = 0;
// Although buffer is an array of bytes, we want to examine each
// 2-byte value.
// [SampleDuration for 1 sec (32000) / SampleRate (16000) = 2 bytes]
// Therefore, we iterate through the array 2 bytes at a time.
for (int i = 0; i < numBytes; i += 2)
{
// Cast from short to int to prevent -32768 from overflowing Math.Abs:
int value = Math.Abs((int)BitConverter.ToInt16(buffer, i));
total += value;
}
return (int)(total / (numBytes / 2));
}
// Button handlers
void SettingsButton_Click(object sender, MouseButtonEventArgs e)
{
this.NavigationService.Navigate(
new Uri(“/SettingsPage.xaml”, UriKind.Relative));
}
void InstructionsButton_Click(object sender, MouseButtonEventArgs e)
{
this.NavigationService.Navigate(
new Uri(“/InstructionsPage.xaml”, UriKind.Relative));
}
}
}

[/code]

  • The single sound file used by this app is a recording of an F being played on a trombone. The different notes are created by dynamically altering the pitch of the F as it plays.
  • Rather than directly use the SoundEffect object, as in the preceding chapter, this app calls its CreateInstance method to get a SoundEffectInstance object. SoundEffectInstance provides a few more features compared to SoundEffect and, because it is tied to a single instance of the sound, it enables manipulation of the sound after it has already started to play. Trombone requires SoundEffectInstance for its looping behavior and its ability to modify the pitch of an already-playing sound.
  • SoundEffectInstance exposes an IsLooped property (false by default) that enables you to loop the audio indefinitely until Stop is called. This can behave in one of two ways, depending on the source audio file:
    • For a plain audio file, the looping applies to the entire duration, so the sound will seamlessly restart from the beginning each time it reaches the end.
    • For an audio file with a loop region, the sound will play from the beginning the first time through, but then only the loop region will loop indefinitely. Calling the default overload of Stop stops the sound immediately, but calling an overload and passing false for its immediate parameter finishes the current iteration of the loop, and then breaks out of the loop and plays the remainder of the sound.

Figure 31.3 demonstrates these two different behaviors. The latter behavior is perfect for this app, because it enables a realisticsounding trombone note of any length, complete with a beginning and end that makes a smooth transition to and from silence. Therefore, the F.wav sound file included with this app defines a loop region. Although the sound file is less than a third of a second long, the loop region enables it to last for as long as the user can sustain his or her blowing.

Be careful about the length of your loop region!

If you don’t want to stop a sound immediately, but want it to gracefully stop fairly quickly with Stop(false) as with this app’s sound effect, your loop region (and remainder of the sound) must be very short.Otherwise, the process of finishing the current loop iteration could be too time-consuming.

Wavosaur (www.wavosaur.com) is a free and very powerful sound editor that enables you to create a loop region inside a .wav file. Simply highlight a region of the sound; then select Tools, Loop, Create loop points.The exported .wav file will still play straight through under normal circumstances, but playing it with SoundEffectInstance and IsLooped set to true will leverage your custom loop region.

SoundEffect versus SoundEffectInstance

Whereas SoundEffect only enables you to play sounds, SoundEffectInstance enables you to pause/resume/stop the particular sound instance with its Pause, Resume, and Stop methods. Whereas each call to SoundEffect’s Play method starts playing a fresh instance of the sound that can’t be stopped (and may overlap sounds from earlier calls), a call to SoundEffectInstance’s Play method does nothing if that instance of the sound is currently playing. Because SoundEffectInstance is tied to a specific sound instance, it is also able to expose a State property that reveals whether the sound is playing, paused, or stopped. In addition to the IsLooped property, SoundEffectInstance exposes three properties for controlling the resulting sound.These can be set at any time, even in the middle of playback:

  • Volume (default=1)—A value from 0 (muted) to 1 (full volume).
  • Pitch (default=0)—A value from –1 (one octave lower) to 1 (one octave higher). A value of 0 plays the sound at its natural pitch.
  • Pan (default=0)—A value from –1 (all the way to the left speaker) to 1 (all the way to the right speaker). A value of 0 centers the sound.

SoundEffect also enables controlling these three values with a Play overload that accepts volume, pitch, and pan parameters.However, these values always apply for the duration of the sound. (SoundEffect’s parameterless Play method, used in the preceding chapter, uses a volume of 1 and a pitch and pan of 0.)

SoundEffectInstance also exposes two overloads of an Apply3D method that enables you to apply 3D positioning to the sound playback.This feature is most interesting for Xbox and PC games. For phones, 3D positioning (and even custom pan values) is likely to be overkill.

Regular Sound File

Regular Sound FileSound File with a Looping Region

Sound File with a Looping Region

FIGURE 31.3 Options for looping with SoundEffectInstance.IsLooped set to true.

  • In the CompositionTarget.Rendering event handler, the current volume from the microphone is continually compared against a threshold setting (adjustable on the settings page). If it’s loud enough and the sound isn’t already playing, Play is called. (The State check isn’t strictly necessary because, unlike SoundEffect.Play, SoundEffectInstance.Play does nothing if the sound is already playing.) If the sound is playing and the volume is no longer loud enough, then Stop(false) is called to break out of the loop and play the end of the sound.
  • Inside Touch_FrameReported, which detects where the primary finger is in contact with the screen and whether a second finger is touching the screen (as discussed in Part VII, “Touch and Multi- Touch”), the sound’s pitch is adjusted. The startingPitch variable tracks which octave the base F note is in (0 for the natural octave or 1 for an octave higher); then the distance that the finger is from the bottom of the screen determines how much lower the pitch is adjusted. As you can see from the values in the pitches array at the beginning of the listing, a D is produced by lowering the pitch of the F by 25% (producing a value of -.25 or .75 depending on the octave), and a B is produced by lowering the pitch of the F by half (producing a value of -.5 or .5 depending on the octave).

Can I make my audio heard when the phone’s master volume is muted, or can I play audio louder than the master volume level?

No, the user is empowered to choose the maximum volume level for any sound that could be made by their phone.The 0–1 volume level of a sound effect is relative to the master volume.Note that SoundEffect exposes a static MasterVolume property that enables you to simultaneously adjust the volume of all your sounds (whether played from SoundEffect or SoundEffectInstance), but this does not enable you to get any louder than the user’s chosen volume level.

The Finished Product

Trombone (Sound Manipulation)

 

3DTV Standardization and Related Activities

Standardization efforts have to be understood in the context of where stakeholders and proponents see the technology going. We already defined what we believe to be five generations of 3DTV commercialization in Chapter 1, which the reader will certainly recall. These generations fit in well with the following menu of research activity being sponsored by various European and global research initiatives, as described in Ref. [1]:

Short-term 3DV R&D (immediate commercialization, 2010–2013)

  • Digital stereoscopic projection
    • better/perfect alignment to minimize “eye-fatigue.”
  • End-to-end digital production-line for stereoscopic 3D cinema
    • digital stereo cameras;
    • digital baseline correction for realistic perspective;
    • digital postprocessing.

Medium-term 3DV R&D (commercialization during the next few years, 2013–2016)

  • End-to-end multi-view 3DV with autostereoscopic displays
    • cameras and automated camera calibration;
    • compression/coding for efficient delivery;
    • standardization;
    • view interpolation for free-view video;
    • better autostereoscopic displays, based on current and near future technology (lenticular, barrier-based);
    • natural immersive environments.

Long-term 3DV R&D (10+ years, 2016–2020+)

  • realistic/ultrarealistic displays;
  • “natural” interaction with 3D displays;
  • holographic 3D displays, including “integral imaging” variants;
  • natural immersive environments;
  • total decoupling of “capture” and “display”;
  • novel capture, representation, and display techniques.

One of the goals of the current standardization effort is to decouple the capture function from the display function. This is a very typical requirement for service providers, going back to voice and Internet services: there will be a large pool of end users each opting to choose a distinct Customer Premises Equipment (CPE) device (e.g., phone, PC, fax machine, cell phone, router, 3DTV display); therefore, the service provider needs to utilize an network-intrinsic protocol (encoding, framing, addressing, etc.) that can then be utilized by the end device to create its own internal representation, as needed. The same applies to 3DTV.

As noted in Chapter 1, there is a lot of interest shown in this topic by the industry and standards body. The MPEG of ISO/IEC is working on a coding format for 3DV. Standards are the key to cost-effective deployment of a technology. Examples of video-related standards include the Beta-VHS (Video Home System) and the HD DVD–Blu-ray controversies.  SMPTE is working on some of the key standards needed to deliver 3D to the home. As far back as 2003, a 3D Consortium with 70 partner organizations had been founded in Japan and, more recently, four new activities have been started: the [email protected] Consortium, the SMPTE 3D Home Entertainment Task Force, the Rapporteur Group on 3DTV of ITU-R Study Group 6, and the TM-3D-SM group of DVB. It will probably be somewhere around 2012 by the time there
will be an interoperable standard available in consumer systems to handle all the delivery mechanisms for 3DTV.

At a broad level and in the context of 3DTV, the following major initiatives had been undertaken at press time:

  • MPEG: standardizing multi-view and 3DV coding;
  • DVB: standardizing of digital video transmission to TVs and mobile devices;
  • SMPTE: standardizing 3D delivery to the home;
  • ITU-T: standardizing user experience of multimedia content;
  • VQEG (Video Quality Experts Group): standardizing of objective video quality assessment.

There is a pragmatic possibility that in the short term, equipment providers may have to support a number of formats for stereo 3D content. The ideal approach for stereoscopic 3DTV is to provide sequential left and right frames at twice the chosen viewing rate. However, because broadcasters and some devices may lack transport/interface bandwidth for that approach, a number of alternatives may also be used (at least in the short term). Broadcasters appear to be focusing on top/bottom interleaving; however, trials are still ongoing to examine other approaches that involve some form of compression including checkerboard, sideby-side, or interleaved rows or columns.

 

 

Formatting Your Email News Release

Keep your emailed news releases to one or two pages with short paragraphs. It is best to insert the news release in the body of the email. Do not send your news release as an attachment. You don’t know which platform or word-processing program the reporter is using. You might be using the latest Microsoft Word program on a PC, but the reporter could be using an incompatible program on a Mac and may not be able to open the file. There could also be problems downloading, which would prevent your release from being read.

Make sure the subject line of your email is compelling. Journalists can easily delete emailed releases unopened, and quite often they do, because they receive large volumes of these daily. Make sure your email is clear and concise. Get to the point with the first sentence. If you don’t grab the reader’s attention at the beginning of the release, the recipient might not keep reading to find out what your news is.

It’s important to be able to send news release information in digital format within the body of the email. With a quick copy-and-paste, the journalist would then have the “first draft” of the story. You have made it easy for him or her to then edit the draft and have a story quickly. Everybody loves to save time, and nearly all journalists are under tight deadlines.

 

Always Use Your Signature Files

As discussed previously, signature files are a great marketing tool. Always attach your signature file to your online communication. See later in this chapter for information on signature files. Remember to be sure that the signature files are right for the intended audience.

Discerning Use of Attachments

If you are sending a fairly large amount of data, you might want to send it as an attached file to your email message. However, only include an email attachment if the recipient is expecting it. You would never consider going to someone’s
home, letting yourself in, finding your way into their living room, and then leaving your brochure on the coffee table. However, people do the online equivalent of this when they send an unsolicited attachment. The attachment is sent across the Internet to the recipient’s computer and is downloaded and stored on the computer’s hard drive. This is considered quite rude and, in most cases, is unwanted.

Also, unless the recipient of your email is aware of the file size and is expecting it, don’t send an attachment that is larger than 50K. Although your Internet connection might be a cable modem or a T1 line, and a 3 MB file is sent in seconds, the person who is receiving your message and attachment might be using an old 56 Kbps modem and a slow machine. If you send a 3 MB file, it might take the person with the 56 Kbps modem awhile to download the file. Needless to say, he or she won’t be too pleased. Yes, there are still people on dial-up.

Another factor to consider when sending an unsolicited attachment is that the attachment you are sending might be incompatible with the operating system or the software on the recipient’s system. You might be using a different platform (Mac/PC) or different operating system, and the recipient might not be able to open and read your file. Even PC to PC or Mac to Mac, the recipient might not be able to open and view the attachment if that particular program is not installed on his or her machine. Someone using an old version of Corel WordPerfect might not be able to read a Microsoft Word 2007 document sent as an attachment. Thus, you have wasted your time sending the file and the recipient’s time downloading the file.

Finally, it is a well-known fact that email attachments can act as carriers for computer viruses. Many people will not open anything with an attachment, even if it is from someone they know, unless they have specifically requested a file. You
might unknowingly send someone an attachment with a virus, and even if the file you send is virusfree, you could still receive blame if recipients find a virus on their system, just because you sent them an attachment. Basically, avoid sending email attachments of any type unless you have the recipient’s permission. Be mindful of the size of the file you intend to send, compatibility with other platforms, and computer viruses. One alternative to sending a large attachment is to post the file on a Web server, and in your email message direct users to a URL from which they can download the file.

Viruses
A software program capable of reproducing itself and usually capable of causing great harm to files or other programs on the same computer.

 

Service level agreements

In this section I discuss service level agreements (SLAs) drawing on my own experience of managing a cloud computing business and reworking its SLA, but also borrowing a number of ideas from a ZDNet.com article by Frank Ohlhorst (Ohlhorst, 2009).

By its nature a cloud computing purchase is usually impersonal and automated. You typically buy a service online and pay as you go, and there is often no way to negotiate a service level agreement – you just get the standard one that every customer gets unless your business is enterprise class and you are considering a serious investment. Moreover, most suppliers create SLAs to protect themselves, not their customers, against litigation, and, typically, they only offer customers minimal assurances. Understandably this state of affairs deters many would-be cloud customers, but some SLAs are better than others and there are a number of things to look out for in the small print. There are three key areas to consider when you are reviewing SLAs and talking to suppliers: data protection; continuity of service; and Quality of Service (QoS).

Data protection

If you store business data in public clouds then system security failures and data loss are obvious risks, and there may be legal risks, too (see Chapter 3). In any case this data is your responsibility and you would not want it to be stolen or lost, so there follow five sets of questions on data protection for you or your legal team to bear in mind when you are reading the Service Level Agreement of a cloud provider. The five sets of questions cover the issues of ownership; security; access; storage; and retrieval. If you are in a highly regulated industry or you handle sensitive data then you will need satisfactory answers to many if not all of these questions because you, not your provider, are legally responsible for protecting your data.

First, on data ownership:

  • Is there agreement that you own your data and any software you develop on the provider’s systems?
  • Who owns the data about your data, such as access and modification log files?

Second, on data security:

  • How many data centres does the provider have and how are they secured physically?
  • How are data encrypted?
  • How are their customers’ data and backup files segregated?
  • Is security continually tested as they develop and improve their systems?
  • Can they produce evidence to show that their security systems have been externally audited and certified?

Third, on data access:

  • What personnel policies do they have, and are background checks carried out on new employees?
  • How is access controlled and logged?
  • What access, if any, do system administrators have to your data?
  • What access control reporting facilities do they provide for audit trails?
  • Do they permit any subcontractors or partners to access their systems?
  • Do they use two-factor authentication for remote access?

Fourth, on data storage:

  • How, and in what format, are data backed up, and where are the backups stored?
  • Are data ever stored on third-party systems?
  • Are data stored only in countries that subscribe to Safe Harbour agreements?
  • What happens to data copies when an agreement is terminated?
  • What happens to data copies if the provider’s business fails?
  • Do they offer the facility for periodic offline data backups, and, if so, what measures are in place to prevent unauthorized backups?
  • Can specific data retention policies be applied for regulatory purposes?
  • What is their disaster recovery plan?

And, fifth, on data retrieval for legal purposes:

  • What procedures do they follow in the event of international or domestic government inquiries into data stored on their systems?
  • Do they provide assurances that your data will not be compromised or seized if another of their customers is under legal investigation?
  • Do their systems satisfy your internal requirements for governance and compliance?
  • What facility for litigation searches or electronic discovery can they provide to investigators?
  • How quickly can data preservation or production requests be satisfied?
  • What costs will be charged by the provider to customers under investigation?

Continuity of service

Part of the appeal of cloud computing services is that you can access them at any time, but problems do occur  and sometimes systems have to be taken temporarily offline for upgrades and maintenance (scheduled downtime), but you can typically expect a guaranteed uptime of between 99.5 per cent and 99.9 per cent from a provider. Now, SLAs are full of legalese, but they should contain details on systems outages, and if you want to gain a better understanding of how the provider deals with outages, here are some good questions to ask:

  • What notice period do they have to give before any scheduled downtime?
  • How often do they have scheduled downtime and how much time is usually involved?
  • How are complete service outages and partial systems outages defined?
  • How do customers report service problems – is there a ticketing system in place?
  • How do they measure downtime and the severity of outages?
  • How are customers compensated for outages?
  • What redundancy is built into the systems to minimize outages?
  • Do they have alternative methods for accessing data if an outage is prolonged?
  • Do they provide reports on outages and other problems?

Quality of Service

Just as you would expect a Quality of Service (QoS) level for IP telephony or your broadband connection, you should also expect a desktop-like experience for Software as a Service and Platform as a Service, with no noticeable latency; and consistently fast provisioning of computing resources from Infrastructure as a Service. The supplier is not responsible for your internet connection or your local network, but they are responsible for the availability of their services and the performances of their cloud infrastructure. If your potential supplier’s Service Level Agreement (SLA) does not cover QoS to your satisfaction then here are some questions to ask them about availability and performance:

  • If additional resources are allocated dynamically to an overloaded application or server, how quickly does this happen?
  • If a server instance fails, how quickly is it rebooted or replaced?
  • Where in the world are the services hosted and how do the response times differ between geographical regions?
  • Does the failure or poor performance of an individual application or server instance count as an outage for SLA purposes?
  • Do they provide customers with monitoring tools for individual servers, applications and the cloud as a whole, and are these tools external?
  • What general QoS metrics do they measure, if any?

As it is difficult to determine where the fault lies when using a service based on the internet, here are a few things you can do to understand and maximize QoS:

  • Test and monitor your local internet connections (packet transmission speed, packet loss and response latency) during peak times, and measure data transfer speeds between your local networks and your chosen cloud – your Internet Service Provider may be able to help you improve connectivity.
  • If you are migrating software from your private network to the cloud you can benchmark the performance of affected applications and operations on a powerful local server and network first, and then see what effect variations in memory and storage have on the performance by virtualizing the local server. What performance level and response time are acceptable for end users?
  • Test your applications in the cloud, compare the performance with your local setup and document the differences. Can your cloud-based system deliver acceptable performance?

A very useful (and free!) tool for testing the performance of web-based applications and multi-page transactions is KITE, the Keynote Internet Testing Environment (http://kite.keynote.com/). You use the tool to navigate through a website
and record the process as a ‘script’, and then you can re-run this script locally (from your PC) and from five geographically separate locations in the KITE network to compare its performance. If, however, you want to continually
monitor your applications there is a charge for that Software as a Service product; and there are other products on the
market, including CapCal (http://www.capcal.com/), a web scalability and performance testing application that runs on
Amazon EC2 servers.

Quality of Service is a subjective term, but if you can define objective performance measurement tests and repeat them on a regular basis then you will be more likely to spot any gradual degradation of cloud services and bring them to the attention of your supplier. And if you can use your supplier’s own measurement tools to prove your point then you will be in a stronger position. Whether you can negotiate an SLA on the basis of QoS will probably depend on the size and influence of your organization, but it could be worth a try, and it is certainly worth monitoring your systems because you are sharing a public cloud with an increasing number of tenants and you are relying on your supplier to ensure their cloud’s capacity grows with demand.