Fixing the assembly hopping between WP7 and WP8

If you want to develop an Windows Phone app that can run on both WP7 and WP8 you can simply submit one built for Windows Phone 7. But if you want to take advantage of some of the new feature of Windows Phone 8 you will need to submit two versions of it (one for 7 and one for 8). This means that you will have to maintain two copies of the project file — but you obviously don’t want two copies of each source code file.

This can be solved by putting the code in a Portable Class Library and then reference it by the two projects. There are however some limitations using a Portable Class Library, and you might find yourself stuck between a rock and a hard [coded] place trying to use it.

Each time I was facing the dual project problem, I ended up with using linked source code files instead, i.e. making one of the projects the “main” project, and then simply linking all the source code files into the other project (i.e. “Add As Link” rather than “Add” when adding “Existing Item…”). An annoying problem with this solution is however that each time you rename a source file you will need to remove and add the linked file again. Aaarrgghh! :[ But for me this actually was less painful than using the Portable Class Library.

Anyway, this way you will only have to maintain one copy of the code files that are identical on both platforms. For the ones that differs a bit, you either use compiler switches (e.g. “#if WP7 [...] #endif“) — or totally different classes (i.e. non-linked code, if there are “too much” differences to make use of #if‘s).

But when it comes to XAML you are in more trouble. For instance, if you are sharing the same implementation of a page in both WP7 and WP8, you will notice that the home of the Pivot (and Panorama) has changed between the two platforms. Ouch.

In WP7 your page declaration looks like this:

but your WP8 projects want this line:

As you can see above, the assembly name has changed.

This makes you yearn for the following (illegal) construction:

But unfortunately compiler switches are not allowed in XAML… So the above will NOT compile. 🙁

There is however a pretty simple solution to this. Create the following two classes:

This file can be linked across the two platforms intact without any need of #if‘s (since it wasn’t the namespace that was changed, “just” the assembly).

Now you simply use the MyPivot wrapper classes (instead of the Pivot directly) in your XAML, and you’re good to go:

 

Announcing the Diversify app for Øredev 2012

A collegue of mine, Fredrik Mörk, noticed the announcement of the Øredev 2012 mobile app contest, and soon a team was formed that happily started hacking away (hosting the code in a Mercurial repository on BitBucket, and also using Trello to have some sort of control of who was what, and what needed to be done). The team consisted of Micael Carlstedt, Niclas Carlstedt, Fredrik Mörk, Markus Wallén, Sebastian Johansson and myself.

The app is supposed to function as a companion before and during the conference. The main functionality is that it offers you to easily navigate and explore in the conference program, and build your own personalized conference program by “favoriting” sessions. It also features a twitter feed, listening to stuff related to the conference and the app. One focus of the design has been to allow you to explore. From almost every view, there is a way to move on and get information about related stuff. One example is when you are looking at a session, from this view you can in one touch navigate to

  • a page highlighting the room in which the session is on a map
  • a page showing all sessions in that room during the conference
  • a page showing details about the speaker (OK, this typically requires two interactions; scroll to the bottom of the page and then tap the speaker)
  • a page showing details about each other session running in other rooms at the same time
  • a page showing all sessions for a topic that this session also has

This may be the most extreme example, but it’s not unique in its concept.

One other thing that the app does is that it invites to sharing information about the conference. You can (again with very few interactions) share info about a session or speaker to social networks.

There is an update submitted to the market place which will add a couple of features (tell the app what days you will attend and it will filter the data throughout the app accordingly and, as a personal touch, the app authors’ suggestions for some sessions we find extra interesting). Go ahead and get the app from the Windows Phone Marketplace.

 

(Thank you Fredrik, for allowing me to steal your words from your blog postSmile)

 

Some screen shots (click for full size):
Splash screen My Øredev List of sessions Session details

Speaker details Twitter feed Tweet detail About us

Rendering the audio captured by a Windows Phone device

This small app displays the audio captured by the microphone of a Windows Phone device and displays it as a continous waveform on the screen using the XNA framework.

A slightly modified version of the app (changing color when touching the screen) can be found in the Windows Phone Marketplace.

Background

In order to capture the audio on a Windows Phone device, you need an instance to the default microphone (Microphone.Default), decide how often you want samples using the BufferDuration-property and hook up the BufferReady-event. Then you control the capturing with the Start() and Stop() methods.

The microphone is giving you samples at a fixed rate of 16 000 Hz, i.e. 16 000 samples per second. There is a property SampleRate that will tell this value. This means that you won’t be able to capture audio of higher frequency than 8000 Hz (without distortion) according to the sampling theorem.

You are also limited when it comes to choose the value for the BufferDuration-property; it must be between 0.1 and 1 seconds (100 – 1000 ms) in 10ms-steps. This means that you must choose a value of 100, 110, 120, …, 990, 1000 milliseconds.

When the microphone event BufferReady is fired, you should call the microphone.GetData(myBuffer)-method, in order to copy the samples from the microphone’s internal buffer to a buffer that belongs to you. The recorded audio comes in the form of a byte-array, but since the samples are actually signed 16-bits integers (i.e. an integer in the range of -32’768 … 32’767), you will probably need to do some convertion before you can process them.

How this application works

The way this application works is keeping a fixed number of narrow images, here called “(image) slices”, arranged in a linked list. The images are rendered on the screen and smoothly moved from the right to the left. When the left-most slice has gone off the screen, it is moved to the far right (still outside the screen) in order to create the illusion of an unlimited number of images.

Each slice holds the rendered samples from the content of one microphone buffer. When the buffer is filled by the microphone mechanism, the rightmost slice (outside of the screen) is rendered with these new samples and started to be moved inwards the screen.

The speed of how fast the slices are moving across the screen is correlated to the duration of the buffer in such a way that the slices are moved a total of “one slice width” during the time the microphone is capturing the next buffer.

Since the buffer of captured audio is rendered as graphic on a texture as soon it is received, there is no reason to keep any old buffer data. Therefore the application only keeps one buffer in memory which is reused over and over.

A flag is set each time the microphone buffer is ready. Since the BufferReady event is fired on the main thread, there is no need for any lock-mechanism.

In the Update()-method of the XNA app, the flag is checked whether new data has arrived, and if so, the slice in line is drawn. In the Draw()-method, the slices are drawn on the screen and slightly moved as time goes by.

The complete Visual Studio solution file can be downloaded from here.

Here’s a description of the structure of the main “Game”-class.

Some constants:

Fields regarding the microphone and the captured data:

Choose a color that is almost transparent (the last of the four parameters; it’s the red, green, blue and alpha-component of the color). The reason is that many samples are drawn on top of each other, and keeping each individual sample almost see-through makes an interesting visual effect.

The drawing classes. The white pixel texture is doing all the drawing.

The size of each image slice.

There’s no need to keep a reference to the linked list itself; just the first and last link. These links keeps references to their neighbors. The currentImageSlice is the one to draw on the next time.

The speed of the slices moving across the screen.

In order to know how far the current samples should be moved, the application must keep track of when they appeared.

 The signal that tells the Update()-method that there is new data to handle.

 The density of samples per pixel.

Here’s the constructor. In it the graphics mode is set and the microphone is wired up and asked to start listening.

In the XNA’s LoadContent nothing is actually loaded since the app is not dependent on any predrawn images. The SpriteBatch is created, the white pixel texture is generated and the image slices are initialized (as black images).

The CreateSliceImages is calculating how many slices that are needed to cover the entire screen (plus two so there’s room for movement). In the end of the method the regular RenderSamples-method is called in order to initial all the images. Since there is no data yet (all samples are zero) it will generate black images.

The XNA’s UnloadContent is just cleaning up what the LoadContent created.

The event handler to the microphone’s BufferReady-event. It copies the data from the microphone buffer and raises the flag that new data has arrived.

The XNA’s Update method checks the phone’s Back-button to see if it’s time to quit. After that it checks the flag to see if new data has been recorded. If so, the new samples are rendered by calling the RenderSamles-method.

The XNA’s Draw-method takes care of drawing the rendered slices. It handles the two screen orientation modes; landscape and portrait, by scaling the images accordingly. If it is landscape mode the height of the images are squeezed and if it is portrait mode the width of the images are squeezed.

When all is setup, the method iterates through the images and render them one-by-one on the screen, adjusted a bit along the X-axis to make up for the time that has passed.

The RenderSamples is taking a RenderTarget2D as an argument, which is the texture to be drawn on. The routine iterates through the samples and render them one by one.

Follow the rules when developing your Windows Phone app

Roughly one month after the first version of Badgers Rock had passed the certification cycle and happily thrived in the Windows Phone Marketplace, I received the following e-mail from one of the app testers: 

Dear Windows Phone Marketplace Developer,

It has been determined through certification testing that the application indicated in the subject line has the following problem(s):

5.2.4.4
Pass with Notes: Pressing the device back button has no effect on the application.

Steps to Reproduce:
1. Launch the application.
2. Select “PLAY!”.
3. Select a stage.
4. Press the device Back button.
5. A pause menu is displayed.
6. Press the device Back button again.
7. Observe the application the application does not respond.

The application passes certification, however the reported issues need to be resolved in the next update to the application.

ACTIONS REQUIRED: Please address the issues listed above, review the Windows Phone Application Certification requirements (http://go.microsoft.com/?linkid=9730556) and resubmit your updated application for certification testing.  Future application update submissions will fail certification testing if the same issue(s) are not corrected.
P
LEASE DO NOT REPLY TO THIS MESSAGE. For further assistance, please visit Developing for Windows Phone 7 forum.

Thanks,

Sam
Windows Phone Marketplace Certification

Sam was absolutely right about his finding, but it was in fact a design decision from my side. In the described scenario you are in an ongoing game and then you press the physical Back button on the phone. The game is now paused and you are presented with a couple of options; basically “do you want to end the game or resume?”. So, at this point, how should I handle the Back-button? It was of course out of the question to end the game; it’s way too simple to accidentally touch this button (depending on how you are holding the device). So making a double miss-tap ending the game would not make any hardcore Badgers Rock-gamer happy. So should the game resume then? This was the only obvious option left (making the game respond to the click), but I didn’t really like that anyway because it would not be 100% clear to the player what the Back button would actually do in this case. So I decided to ignore the Back button in this screen and force the player to take an active decision choosing from the spelled-out options on screen — again, to make it perfectly clear for the player what will happen.

Then this message came from which a couple of things can be noticed:

  • First of all, Microsoft is (for the first time?) really anxious that all the applications are behaving in a consistent way, not only giving guidelines. This is a good thing.
     
  • Secondly, it’s not only automatic testing being performed on your submitted app. This is also a good thing. Although it doesn’t seem as every release is tested manually since I had maybe four versions successfully passing the certification cycle when I got this message — and the behavior in question had been there from the start.
     
  • Also, at the point in time when I received this message there was no certification phase currently going on; my latest release had already been passed successfully some time ago. Does this mean that the testers are doing the manual testing as a parallel task on top of the (more or less) automatic certification cycle? My app was presumably put in a queue and rested there for a month until someone (Sam!) had time to perform the manual testing.
     
  • A side note is the not-so-professional link they’ve included in the e-mail (http://go.microsoft.com/?linkid=9730556). This points to a PDF-file you’ll have to download that’s only telling you that the link has been moved (and of course where to). Suprising? Not really. Elegant? Well, not really…

Of course I should follow the requirements of always having a responsive Back-button!
So now during game-play, the Back-button will basically toggle pause mode on and off.

Badgers Rock

Windows Phone TileBadgers Rock is a small, completely free (no ads) Windows Phone game I created using the XNA framework during the autumn of 2011.
You can find it on the Windows Phone Marketplace and on Facebook.The latest released version (V1.4) has both an online high score and cool retro sound.There was a contest arranged by the “Windows Phone Sweden” Facebook page, that ended on February 3, 2012, and the Winner Niklas Dahlman successfully completed all thirty levels with “three stars” on each levels. Not an easy task considering some levels are really hard and time-demanding to complete. He won a Nokia Bluetooth Stereo Headset BH-111. Congratulations!

The online highscore is provided and hosted by http://mogade.com/. It is free, open source and have a very easy API to integrate. You can choose to host your data yourself or let them do it for you. Really nice.

All the sounds in the game were taken from the http://www.freesound.org/. Here is a complete list of the sounds that I used in the game.