Friday, November 20, 2009

How Not To Make A Corporate Web Site

Ok, Time to blow off some steam.

I think I have found the worst large corporation web sit there is.
www.motorola.com

What I was trying to do is simply find the manual for a Motorola XTS 5000 portable radio so I can hook it up to a PPP serial port on my Vista laptop.

Sounds easy, huh?

Well I tried the obvious, I googled Motorola XTS 5000 manual.
All the results are for very unsafe web sites for manuals, none of which actually have the manuals.

(Annoyed)

A few links were to www.motorola.com, but all actual documents were just marketing brochures with no details.

Their search function is so broken as to be nearly useless.

(Anger level rising, 1 hour wasted)

I finally called support and was told that all those manuals are on Solutions - Motorola USA
though "solutions" was obviously used as a euphemism for "marketing".
But I would need to register to get an online acocunt and it would take two days.

So I went to the site to sign up. Wow, I think the signup form was designed by committee where any field that was suggested was put in.

Ok, this is silly. All I wanted was to find an online manual for a radio. Instead I got a process that would make passage of Obama's Medical Fiasco look easy.

So while I waste two work days waiting for a simple piece of information, I noticed that there is a feed back email address. Ohhhh, nifty. So I careful write a short email about the shortcomings of the site. Yup, you guessed it, the email bounced.

So If it wasn't for the fact that my job requires that I get this software written...

Ok, I'm done. All better now.

Oh, and let me theorize how the web site got this way...
All the CXX managers of Motorola fought over getting their pet project in, and the web designer inside Motorola was ignored. Nobody any where the top of the organization has ever actually used the site to try to do anything remotely like what a customer would do. The web site is obviously organized by someone who is thinking about what they want the customer to see, and has no idea at all about what the customer actually wants.

TF

Three days later, after the weekend, yet another hurdle to cross.
This is regarding your account with us. Will you be reselling our products? Or will it be for your own company use?
If for company use than please state you are taxable. If for resell then fill out the attached tax cert and fax back
to NNN-NNN-NNNN

Aaaaaargh!

TF

Tuesday, October 20, 2009

COM Port Listing in C#

Ok, here is the problem.
How does one get a listing of COM ports in C# ?

The short answer is...

String[] portNames = System.IO.Ports.SerialPort.GetPortNames();

Like most short answers it is correct but not useful.
The resulting list is a series of entries like "COM14". In my application I want the
list to have the long port description like "Prolific USB-to-Serial Bridge (COM16)"

This is tricky. There can be regular serial ports and there can be USB dongles with serial ports.

So what you do instead is first list the ports and make a list of them with both the simple name
and a friendly name that are the same.
Then you look through the plug n play devices for COM ports and get the Name from that.
Like this...


using System.Management;
using System.IO;

Then ...


private void SetupCOMPortInformation()
{
String[] portNames = System.IO.Ports.SerialPort.GetPortNames();
foreach (String s in portNames)
{
// s is like "COM14"
COMPortInfo ci = new COMPortInfo();
ci.portName = s;
ci.friendlyName = s;
ComPortInformation.Add(ci);
}

String[] usbDevs = GetUSBCOMDevices();
foreach (String s in usbDevs)
{
// Name will be like "USB Bridge (COM14)"
int start = s.IndexOf("(COM") + 1;
if (start >= 0)
{
int end = s.IndexOf(")", start + 3);
if (end >= 0)
{
// cname is like "COM14"
String cname = s.Substring(start, end - start);
for (int i = 0; i < ComPortInformation.Count; i++)
{
if (ComPortInformation[i].portName == cname)
{
ComPortInformation[i].friendlyName = s;
}
}
}
}
}
}

static string[] GetUSBCOMDevices()
{
List list = new List();

ManagementObjectSearcher searcher2 = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity");
foreach (ManagementObject mo2 in searcher2.Get())
{
string name = mo2["Name"].ToString();
// Name will have a substring like "(COM12)" in it.
if (name.Contains("(COM"))
{
list.Add(name);
}
}
// remove duplicates, sort alphabetically and convert to array
string[] usbDevices = list.Distinct().OrderBy(s => s).ToArray();
return usbDevices;
}



And we need the list element class...


public class COMPortInfo
{
public String portName;
public String friendlyName;
}



There you are.

Oh, and as extra credit. This code lets you list every possible Management class.



private static void ListAllManagementClasses()
{
string cimRoot = "root\\";
ManagementClass nsClass = new ManagementClass(
new ManagementScope(@"root"),
new ManagementPath("__namespace"),
null);
foreach (ManagementObject ns in nsClass.GetInstances())
{
try
{
Console.WriteLine(cimRoot + ns["Name"].ToString());
ManagementClass newClass = new ManagementClass(cimRoot + ns["Name"].ToString());
EnumerationOptions options = new EnumerationOptions();
options.EnumerateDeep = true; // set to false if only the root classes are needed
ManagementObjectCollection moc = newClass.GetSubclasses(options);
foreach (ManagementObject o in moc)
{
if (o["__SuperClass"] == null)
Console.WriteLine(o["__Class"]);
else
Console.WriteLine("\t" + o["__Class"]);
}
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.Message);
}
}
}


Thursday, August 20, 2009

SATA RAID

Ok, for a compter game we are working on we need to record full HDMI video to make a marketing trailer. My current computer could not handle it at all.

First the math: HDTV is 1290 x 1080 at 24 frames per second.
That works out to 1.4 MPixels at 3 bytes per pixel is 100 MB per second.
But there is also sound and some other overhead.

So we went to NewEgg and bought parts:
  • RAIDMAX SAGITTA 2 ATX-928WB Black case. (Cool blue lights!)
  • ECS Black Series A790GXM-AD3 AM3 AMD 790GX HDMI ATX AMD Motherboard
  • AMD Phenom II x4 955 Black Edition Deneb 3.2 Ghz AM3 socket Quad-Core CPU
  • 6 GB Ram
  • 4 SATA Western Digital Caviar 160 GB Drives
  • Vista Home Premium 64 Bit
  • DVD SATA Drive
  • A Screen 22" wide screen
  • RAIDMAX 630W Power supply (More nifty blue lights)
  • Silver Thermal Past (not needed)
  • Cables etc.
The total was 1005.34 USD

We also have a BlackMagic Intensity Pro for 200 USD. This is a HDMI video grabber card and claims to be able to suck up full HDMI video.

So it all showed up in about 3 days. Lots of boxes.

We put it all together.

Then configured it in the BIOS for RAID 5. That was a mistake. RAID 5 means that 3 of the 4 disks are used in parallel for reads and writes, and one is used for parity error correction. This makes it more reliable. After all the install and config, we put in the disk speed test program that came with the Intensity Pro, and we were getting about 350 MB per second read, but only about 50 MB/Sec write. It would never do for what we needed.

(I think the parity generation was slowing it down.)

So...

We reconfigured for RAID 0 with all four disks. This uses all 4 disks in parallel for reads and writes. After a complete reinstall of Vista etc. we ran the disk test again.

450 MB/Sec read and write.

Smokin'

This box is amazing. The click and open on programs is almost instantaneous.

TF

Tuesday, August 11, 2009

XNA Screen Projection

In XNA there is a method,

Vector3 GraphicsDevice.Viewport.Project(Vector3 source, Matrix projection, Matrix view, Matrix world)

that converts a world point to screen coordinates.

The return value is a Vector3. The X and Y is the screen location of the point. It may not be
within the GraphicsDevice.Viewport if the object is "off screen".

One point of possible confusion is the Z part of the return value. It is the depth into the Z buffer.
Your projection matrix has a near and far plane. A Z value of 0 is right on the far plane and is very far away into the screen. A Z value of 1 is a point near the observer, right on the screen plane.

A value of 0.5 would be half way between the far and near planes.

If the Z value is greater than one then the point is behind the observer.

After calling Project, you should check the Z value and if it is greater than 1 then don't draw anything.

Note: if the Z value is > 1 then that means that X and Y must be negated to figure out where the object is relative to the screen. This is important if you are doing a "Mario Smash Bros." style arrow that points off screen at an object that has flown off the edge. But Smash Bros has it easy because no objects ever can get behind the observer.

The reason that X and Y have to be negated is simple. Imagine that the object is behind your head while you are looking at the screen. Draw a line from the object, through your head, to the screen. That is the screen location of the object.

Note: UnProject is a method that does the inverse of Project. It converts a screen location (don't forget the Z part) to world space.

TF

Friday, July 10, 2009

The Easy Programming Allusion

The Utopian Requirement
On many project, I have seen the following logic...

  • Lets have a easy scripting language or visual programming lanuge so non-programmers can customize the system.
  • We currently have to have programmers put in custom code for each customer's need and it is expensive.
  • We'll let the analyst at the customer's company do the change instead so it is easy and inexpensive.
The Reality of Programming
What is wrong with this picture?

There are two types of changes to systems, configuration parameters, and code.
A configuration parameter is usually a single number or setting that has a very limited set of valid values. For example the department names in a company. Some programmer has thought out in advance what all the possible valid values will be and designed the program to handle them.
The second type of change is the one that causes the most trouble. It is a change in the logic and processing of the program. For example, maybe a 'if' statement that then calls any method available in the program to do processing. Such changes can bring down the whole house of cards that is the program.
Programmers deal with this by knowing the system well, making changes and debugging and testing.

The Flaw
The desire of management is to make such changes easy for a non-programmer. But there is a basic contradiction here. They want a person that does not know the code well, to make the change and not thoroughly test the whole system for interactions.

The Reality
What happens in the real world of product roll out, customer complaints, and emergency fixes to save the sales reps. account, is that the customer quickly gets the application into a state where is will not run, and then a programmer from the company ends up making the change, only now it is some 'scripting language' that is less flexible and powerful than the native language of the application.

The Exception
There is one exception in the real world to this logic, Excel.
Excel is the most widely used programming language in the world and is used mostly by non-programmers.

Why does this exception exits?
Because Excel spreadsheet language is a highly domain specific language in it's simple form. It lets you do simple math on cells. There is no sequential programming being done, no 'if' statements, and a highly limited and sanitized method set. If you make a mistake it tends to be located in exactly the cell you are editing.
Then Excel has deeper programming constructs which most users never use. Thus in some ways it is not being used as a programming language so much as simply customizing settings on cells, which are simple math.

The Secret Solution
There is a sweet spot of customization where the user is not programming, but simply customizing settings. If you can reduce your customers job to 'configuration' then you win.

So here is Keene's Rule of Customization:

"Only let your customer configure."

TF

Tuesday, June 30, 2009

Wrong Science, Write Answer, Wrong Execution

Congress is soon to pass a climate bill.

Wrong Science ?
The climate debate and the science behind it is inconclusive. On one side is the view the we create global warming by emitting CO2 and should stop it before the climate goes haywire and we have a disaster.

The evidence to support Global Warming is fairly good, and in some areas is the current best science we have. That does not make it correct and also the debate is not over. When the debate is over then science has stopped and there is nothing more to discover.

On the other side is the belief that Global Warming is not happening, or if it is, it is not our fault. The science for that point of view is also fairly good.

The data about global climate is buried under so many layers of politics, dogma, academic reputations and such, that even reading the raw scientific papers does not arrive at any clear conclusion.

So lets make a big assumption, that the whole Global Warming thing is one big mistake and hoax.


Write Answer
Ok, so then why cut carbon emissions, and do the economically painful, switch to non fossil fuels?

  • Firstly, the USA is currently shoveling cash at unbelievable rates at other nations to buy their oil. This is unsustainable from any point of view. (Yeah Pickens Plan!) We will go bankrupt as a nation trying to buy foreign energy.
  • Second, The oil is running out. We are just about out of 'Easy Oil' and as oil becomes more scarce, the price will be come increasingly volatile. As oil becomes harder to get, the funds to research and build a non-oil base infrastructure will not be available.
  • Third, The environment (not the climate) is damaged by fossil fuel burning, starting with the lungs of Humans.
  • Fourth, Oil is used to make plastics and fertilizer, not just for energy. The world food supply and much our modern junk we buy at WalMart is dependent on oil. It does not need to be. Fertilizer can be made from air and electricity. Plastics are the difficult one, and rubber for tires. That might be a far better use of oil.

Wrong Execution
So hooray for Obama and the climate bill. It forces a reduction in fossil fuel use and dependence on foreign oil.

And now for the main point (drum roll please)

The massive tax that the new climate bill represents $175 per household, with 105,480,101 households in the USA so that would be 18 billion dollars. There has been absolutely no talk about how the fees collected as 'carbon taxes' would be spent. There has also been no talk about how much money the carbon credits would rais for the government. The 18 billion dollar estimate is the best I can do for now. Maybe it is more like a trillion dollars? Who knows? It does not get talked about.

Not only that, there are zillions of loopholes in the bill so that the major emmiters of carbon won't suffer too much. So who is going to suffer if we are to actualy reduce carbon emissions? I bet it will be the middle class, as usual.

My crystal ball tells me that the money will go to social spending.

The correct answer should be to earmark ALL the money gathered from carbon sin taxes to alternate energy.

Could you imagine what 18 billion dollars of research into algae oil would do?

TF


Footnote: The down side...
Obama's climate bill will bankrupt the nation, while spending the money on 'lets be happy' programs. This will result in an economy with no money to change over to alternate energy, an no time to research alternatives before the oil runs out, leaving us in poverty and despair. Nations in poverty have no desire to help the environment. Conclusion: Obama's climate bill will be the worst thing ever for the climate.

Go Google 'The law of unintended consequences.'

Friday, June 12, 2009

What is 1 + 1?

  • A five year old: two
  • A mathematician: That is arbitrary symbol system and unless I know which system you are using the answers are infinite.
  • A Physicist: 1.95 +- 0.01
  • A Poet: The many splendors of love...
  • A Computer Programmer: printf("%d\n", 1+1);
  • A Computer Scientist: 10
  • Bush: that is classified for national security reasons.
  • Obama: How about we fund that research out of the stimulus money?
  • A Drunk: Shoe.
  • A Policeman: I'll ask the questions here unless you want to get tasered.
  • A Ninja: (Could not find one to ask)
  • Chuck Norris: That would be my Punch (tm) followed by my hallmark Roundhouse Kick (tm).
  • A Manager: Lets hold a meting to plan the response to that question.
  • A Consultant: I see we are funded for three weeks work, so come back in three weeks for the answer.
  • A Tester: Your program crashed while calculating the answer.
  • Buddha: Your attachment to the number one causes suffering for all beings.
  • The Pope: The correct question is what is 1 + 1 + 1.
  • Global Warming Alarmists: Our simulation shows that the answer will be increasing over time.
  • Global Warming Deniers: Our leading scientist says the answer is 2 but has recently been fired for saying so.
  • Mormons: Actually 1 + 2 or 1 + 3 works well too.
  • McDonald's Employee: Do you want fries with that.
  • Picasso: N

Tuesday, May 5, 2009

Worlds Apart

I recently read the article Heavy Boots and was struck by the difference of world view that some people can have.

The article is about "If you were standing on the moon and drop a rock, will it float away, or fall down". The answer is obvious to me. But then I got thinking...

I grew up with a father that designed the lunar orbiters in the 1960's, build telescopes for fun, we launched rockets, read SciFi, I have a degree in engineering. I can remember standing on a street on a hill in Spain in 1980, with a perfect starry sky, and several planets and moon in the sky, and the sun had just set. I could perfectly visualize the actual and relative motions of all the bodies in my mind.

So many people live in a different world than I do. They have no real concept of science or how the world around them works. It reminds me of the dark ages when the world was haunted by spirits and people were killed for witchcraft. (See Monty Python and the Holy Grail, "She's a witch!") Such persecutions were not done so much out of cruelty , but on response to a world view of "how things work".

There seems to be a common thread through conflict and conflicting world views.

1.) If you have conflicting world views, and you try to change the world view of someone else, they can get very angry. This seems to be because people see attacks on their world view as a personal attack on them self. Everyone's world view has a huge chunk in it called "I" and who "I" is. A change of world view is nearly impossible for anyone over 20, and difficult for anyone over 2.

2.) When people see you as threatening their well-being according to their world view, they will violently defend them selves.

Therefore...
  • Religious conversions are almost never a change in world view, they are a coming home to what is viewed as the world view they always had but never quite had right.
  • Wars are always justified as "If we don't act they will kill us." This may seem obvious, but in any war both sides always are justified this way. E.g. The Iraq war. If the USA didn't do something, those #$%@# terrorists will come over here and kill us." and the terrorists justify their actions as, "Those foreigners are trying to foster democracy which will reduce our power and will result in our death". (Note: I won't dignify their actions as actually religiously motivated. The leaders are thugs that justify their actions by assuming all the rest of the world is thugs, and there are a few rank-and-file terrorists that are actually motivated by religious ideals. See Bully below.)
  • Teenagers are solidifying their world view, but run hard up against reality, and so it is a difficult time of life.
  • Religion and Science: Many religions see science as an attack on their safety and salvation and that of their children. Scientists see religion as undermining the science that has brought us such a high standard of living, and endangering lives.
  • Swine Flu: The recent Swine Flue Hysteria, in several countries they want to or have killed all the pigs. This exactly fits a world view that includes pigs being fundamentally unclean, the flu has to do with cleanliness, governments can not be trusted, and a past history that includes plagues, and western science that is simply one more way for the heathen invaders to lie.
  • In politics, government decisions can be a basic way of ensuring standard of living and opportunities for people. There seem to be two basic world views on the USA, one is 'government is the problem' typified by the Republican view, and 'government is the solution' typified by the Democratic view. Thus politics is a very serious game indeed. We could argue quite a bit about whether Republican and/or Democratic actions seem to match such stated world views.
  • A bully or crook. there is a world view that the world is difficult, everyone is a bully (some more successful than others) and the only way to survive as a person is to be the most skilled bully. "Survival of the Strongest". The opposing view is along the lines of Brotherhood, or "I am a child of God, and so is everyone else", etc.
  • Pacifists: there is a world view that violence is unjustified no matter what. This vew tends to follow along the lines that the world has a 'rightness' to it and if we would just calm down, the bullies will change their world view.
  • Elitists: The world view that I am smarter than most every one else and I know what is best for you, so toddle along there and let me run things. This is one of the most dangerous world views there is. It is the exact opposite of brotherhood. (Ok, I'll bite, this is Obama all the way.)
Such a list could go on and on.

Now look at the specific conflicts of out time in light of this. Think "what are the conflicting world views". Who holds which views? (Not necessarily the neat packaged world views the opposition supposedly has.)
  • Us vs. Terrorism
  • Science and Religion
  • Bailouts vs. Let-em-die
  • Right to Choose vs. Right to Life
  • Global Warming vs. Many alternate priorities and conclusions.
  • Socialized "fill in the blank" vs. Free Market.
  • What Paris Hilton wears vs. Who is Paris Hilton?
  • Save the Planet vs. Save the Humans.
  • USA vs. China
  • Illegal Immigrants vs. Jobs
  • Inner Peace vs. Outer Appearance
  • Paper vs. Plastic vs. Bring Your Own Bag (Yes I'm serious about this one. It is a shallow placeholder for much deeper beliefs.)
  • Gun Control vs. Right to Bear Arms.

So what is the whole point here. Ill preach a bit now using absolutes...

If people would just realize that rule number one is "If it involves violence, be very cautious".
If justifying your acts of violence includes any level of indirect reasoning, it is almost certainly wrong.
Violence is always a result of conflicting basic world view issues. In all cases violence will never change someone's view.
Seek to understand first.

What would ever justify violence?
A direct and obvious attack on person, your family, or your ability to be left alone to 'do your own thing'.

All other cases should be handled with talking, and talking, and talking.

And then there is something deeper. Our values, world view, and beliefs are really conclusions that we have drawn from our individual experience. Everyone is in this same trap of a single thread of experience. 'They' can't hold any other world view because it is a result of their experience. Once you truly understand this, you can be very tolerant of others. Maybe this is the ultimate 'Brotherhood'.

There but for the grace of God, go I.

Your Fellow Human Being
TF

Wednesday, April 22, 2009

Air Energy vs. Ocean Energy

With all this talk about climate change and such, I got curious about how much total energy is stored in the heat in the atmosphere vs. the oceans. It seems that we talk about climate change, but because we are humans, we are highly biased toward the air being the climate and somewhat ignore the oceans. If we were all dolphins, we would see the oceans and ignore the air.

SO lets get some numbers, all gleaned from Google searches, mostly with hits on Wikipedia...

Weight of the atmosphere: 5.1x10^18 kg.
Weight of the oceans: 1.5x10^21 kg.

So the water out weighs the atmosphere by 294 times.

But, water holds more heat per kg than air...

The specific heat of water: 2.015 kJ/kg-K.

This means that it takes 2015 Joules of energy to raise one killogram of water by one degree Kelvin or Centigrade.

the specific heat of air: 1.0 kJ/kg-K

So water holds about twice the heat per pound than air, so

The total heat needed to change the temperature of the ocean vs. the air is
588 times greater
.

My point?

the global temperature that we all measure and quote as 'global warming' is irrelevant.

The oceans are the real climate and fluctuations in the atmosphere are trivial.

TF

Saturday, April 11, 2009

XNA, XACT, and Sound

Our project had a lot of difficulty in getting sound to work in XNA and in communication between the programmers and the sound artists.
This tutorial is intended as instructions for the audio folks at Sandswept Studios, but feel free to use it too.

Key Concepts

XACT lets the audio engineers tweak all sorts of sound parameters without the programmers having to worry about it.
The programmer just plays the cue.
The audio engineer can tweak volume, sound fall off distance, etc.

First and most important, you must have the correct version of XACT to work with XNA!
This means that you must use the XACT that comes with XNA Studio.
On my machine XACT is at C:\Program Files\Microsoft XNA\XNA Game Studio\v3.0\Tools\Xact.exe

When you are editing sounds in XACT it is nice to be able to hear them, so you have to run AudConsole.exe
that is in the same directory that Xact.exe is in.
You would think that XACT could just play sounds, but no, you have to run AudConsole.exe

Create An XACT Project

So lets get started. Run XACT and create a new project.
File ==> New project
I put the new project at C:\Users\rkeene\Documents\AudioTest\ and called it AudioTest

XACT Uses wave banks which are the 'raw sound' usualy from a .wav or .aif file.
We will use the regular old windows chimes sound. So create a wave bank
Wave Banks ==> New Wave Bank
You should get an empty wave bank window.
Now go find the .wav file we want. On my Vista machine it is in
C:\WINDOWS\Media\chimes.wav
So drag-n-drop that file onto the WaveBank area.

Now we want a sound bank, which ties a raw wave bank entry to all sorts of settings like volume and pitch.
Sound Banks ==> New Sound Bank
Then drag and drop the chimes.wav wave bank entry to the upper part of the Sound Banks window.
Sounds let you add event like volume changes, pitch changes, etc. creating nifty effects.

We also need an actual cue.
This is the name the programmer will use to find the cue and play it in the C# code in XNA.
So, drag-n-drop the sound to the lower part of the cues area.

Now we have a wave bank, a sound bank, and a project. So click on the save icon to save the project.

Sound Fade With Distance

In most games it is nifty to have sounds fade as your view point gets furthur away from the sound source.
Like in DETOUR the factory makes machine noises and we want them to fade out as the player's viewpoitn gets furthur from the factory.
But there are 'big' sound like nukes going off, and 'small' sounds like a dog barking. Big sounds fade out less with distance, and small sounds fade quickly.
In XACT there are RPC Presets that let you setup this fade out.

You need to determine what units distance is in in your game. Is it meters? Inches? Pixels?
On the DETOUR board tiles are 254x254 game units. These are also called World Coordinates.
So while the view point may be on tile 12,5 the world coordinates will be 12*254, 200, 5*254
which is X,Y,Z coordinates. The board is in the XZ plane and Y is 'up'.
Thus for our factory sound we want to be at full volume if you are looking at the factory and fade out
to silent in about 2000 units of distance.

First lets look at Variables. On the left side there is Variables ==> Cue Instance ==> Distance
This is the variable that we will relate to volume. Since our largest board is about 40x40 and thus
10,000 world units max, we want to limit distance ranges to 0 to 10000.
So click on Distance and down below set the range to 0 and 10000.

Next drag and drop your cue on to the RPC Presets item on the left of the screen.
This attaches the cue to the Presets.
Click on RPC Presets and a window comes up with a black window and lines on it.
The lines are (or will be) the sound level related to distance.

So in the RPC Presets window you first select the Variable whic is Distance.
Then select the Object whic is Sound, and then the Parameter which is Volume.
Thus "The distance effects sounds by changing colume."

Now you can drage the line around and get whatever sound vs. distance function you like.
You can double click on the line to make a new drag point. And Ctrl-Z undoes mistakes.

Testing 1 2 3 Testing

Make sure AudConsole is running, and up at the center top of the Xact tools there is a play button.
Click on the Cue, and then click play. Do you hear it?
Also, in the RPC Presets tool you can set the distance, click on the line, and then click the play button
in the RPC window and hear the sounds volume at a given distance.

Exporting

Next we need to export from XACT for XNA.
At the top of the XACT windows is a View menu and the first two items are View XBox36 and View Windows.
This is how you switch between compiling and exporting for the XBox and the PC.

You want to be able to tell the XBox vs. Windows files appart so click on the Wave Bank in the left tree,
and on the lower left there should be fields for
XBox 360 Build Path and Windows Build Path.

We use the convention that the file names end with _w or _x. So change these to be differnet.
Do the same for the sound banks.
Do the same for the top most level project too.

In my test project the top level is AudioTest
so the build path is AudioTest_w.xgs and SudioTest_x.xgs
The sound banks are SB1_w.xsb and SB1_x.xsb
and wave banks are WB1_w.xwb and WB1_x.xwb

Now you build, so make sure View is on View Windows Properties, and click the Builds The Current Project
icon in the top center of the XACT windows.
It will ask about the report you might want. I check Concise and enter rpt_w.txt

The reason for the report is that as your game gets bigger and has zillions of cues, the report helps you keep thing straight.
You can also give the report to the programmer so they know what the cue names are.
This is where all those 'notes' fields come in handy.
It is wise to add a note entry to every cue describing what it is intended for in the game.

Phew! We have exported the windows version.

You can set the View to View XBox Properties and export again to get the XBox version of the files.
Windows version files will not work on the XBox. Period.

Note: sound effects (sfx) are usually loaded into memory in advance so there is no delay to play them.
Music is HUGE so it is streamed from disk to the audio hardware on-the-fly with buffers.
If you click on the Wave Bank, the properties below will include Streaming or InMemory.
Sound effect should be InMemory, and Music should be Streaming.


C# and XNA and Sounds

Ok, now you have all the sounds build for XNA.

Now we move to the XNA C# world.
In XNA you have to load the project (.xgs) the sound bank (.xsb) and the wave bank (.xwb)
Then you find the cue, give it 3D position (optional), and play it.
If your sound person did things correctly, then that is all.

First we need to get the files into the XNA project.
So copy the three files into the Content area. (Ok, get organized and use a subdirectory, etc.)
Now in the Content part of the Solution Explorer, Add ==> Existing Item
You will need to set the pop up file chooser to All Files (*.*). It initially filters for non-sound files.
Select the three files and hit Ok.

They are now in the project, but you need to tell XNA and Visual Studio how to use them.
Select all three under the Content area and in the properties area set...
Build Action: Content
Content Importer: XACT Project - XNA FrameWork
Content ProcessorXACT Project - XNA FrameWork
Copy To Output Directory: Copy if Newer


Ok, now build the project to see if everything is Ok.

Now we need to load the sounds into our game so
add three new class instance level variables to your Game.cs file

public AudioEngine TheAudioEngineTest;
public WaveBank TheWaveBankTest;
public SoundBank TheSoundBankTest;

And in the LoadContent method put something like...

TheAudioEngineTest = new AudioEngine("Content\\AudioTest_w.xgs");
TheWaveBankTest = new WaveBank(TheAudioEngineTest, "Content\\WB1_w.xwb");
TheSoundBankTest = new SoundBank(TheAudioEngineTest, "Content\\SB1_w.xsb");
TheAudioEngineTest.Update();

The Update there is to 'fail fast' if there is a problem, and is not required.

Note: If you play a cue and never call Update on the audio engine, you not hear anything.
Note: The above is for in-memory sounds like sound effects. Music is streamed and the code might
then look like...

TheAudioEngine = new AudioEngine("Content\\music_w.xgs");
TheWaveBank = new WaveBank(TheAudioEngine, "Content\\music_w_wb.xwb", 0, 4);
TheSoundBank = new SoundBank(TheAudioEngine, "Content\\music_w_sb.xsb");
TheAudioEngine.Update();
Note the 0,4 on the end of the WaveBank entry. This is critical.It is the offset and packet size
and effects how smoothly the music plays back.

Oops - We need to differentiate between XBOX and not XBOX code so we need a
#if XBOX
// Load the XBox versions of the files.
#else
// Load the Windows versions of the files.
#endif
around our loads where the _w becomes _x

Now lets play our sound.
The simplest way is...

TheSoundBank.PlayCue("mycue");

Also in the main Update in your game you need to Update TheSoundEngine

You can also do...

Cue c = TheSoundBank.GetCue("mycue");
c.Play();

But of course, we want possitional sound so we do...
Object o = Gm.TheAudioEngineTest.RendererDetails;
AudioListener aListen = new AudioListener();
aListen.Position = FocusTile.LocationWorld;
AudioEmitter aEmit = new AudioEmitter();
aEmit.Position = FactoryTile.LocationWorld;
Cue c = Gm.TheSoundBankTest.GetCue("TestCue1");
float d = (aEmit.Position - aListen.Position).Length();
c.SetVariable("Distance", d);
c.Apply3D(aListen, aEmit);
c.Play();

Ok, the FocusTile.LocationWorld gives me the X,Y,Z coordinates of the tile in world units.
The FactoryTile is where my factory is.
The d is the distance between the two.
We have to set the Distance variable on the cue, and the Apply3D does the stereo
left-right speaker shift.
(You left and right speakers are in the correct place on your desk top?
The one with the volume knob is always the right speaker.)

Wow, that is how sound is done.

XBox Note: When you make the XNA project for the XBox you must remove the wave bank, project, and sound bank files in Content
and re-add the XBox versions.

Tips and Tricks

Randomize Cue Sound Choice
You can make a single cue play several different sound randomly. The programmer does not need to even know which one will play.
Cues have a weight or probability. You can give each sound in the cue a different weight and that is how often they will get picked.
This is cool if you have a repetitive sound, like gun fire, and you want to randomly choose between several different gun sounds to make it not-so-boring.

C# Code Structure
You can have several Audio Engines at the same time. We break out one music engine, and 3 different Sfx engines. Then we have a PlaySfx call that takes an enum flag as to which Sfx set the cue is in. This makes our code control checkins much faster since we don't have one giant Sfx Sound Bank and Wave Bank.

It is also handy to have a currently playing music track, and a NextMusicCue that will get played when the current one finishes.

We also have an SfxItem class that hold info about a currently playing item and each of the Sfx engines. So our overall update method loos like this...

private void UpdateAudioEngines()
{
if (TheAudioEngineTest != null)
{
TheAudioEngineTest.Update();
}
if (TheAudioEngine != null)
{
TheAudioEngine.Update();
if (CurrentMusicCue != null && CurrentMusicCue.IsStopped && NextMusicCue != null)
{
CurrentMusicCue = NextMusicCue;
NextMusicCue = null;
CurrentMusicCue.Play();
}
}
if (SfxActions != null && SfxActions.TheAudioEngine != null)
{
SfxActions.TheAudioEngine.Update();
}
SfxItem.UpdateAll();
}

Enjoy

T.F.

Tuesday, March 3, 2009

How to Dig for Truth

I read a recent post here there is some talk about the lack of information on the internet.

There in fact is no lack of very deep scientific information. The major problem is finding it.
General news articles are mostly wrong and usually the articles do not even match the conclusions of the underlying scientific papers.

There are two issues. First, finding real scientific papers, and second, understanding them.

So I'll guide you through an example...

The Initial News Article
Tuesday March 3, 2009 there is an article stating...
This article in on Google's front page news, and the title is

Older people face greater HIV infection risks: study

and it is on the Reuters UK page.

* Doctors failing to screen for HIV in older patients

* HIV progresses faster to AIDS in those aged 50-plus

* Older people more likely to risk unprotected sex

By Laura MacInnis GENEVA (Reuters) - Doctors are failing to diagnose HIV in older patients, who are exposed to greater risk of infection as erectile dysfunction drugs extend their sex lives, a study published by the World Health Organization said on Tuesday.

One Level Down, The source news article.

Ok, lets go find the original study...
Lucky, this one gives us a clue, it is WHO, the World Health Organization. So we google the site.
It's the top hit on Google.
An it is the top blurb on the WHO web site.
3 March 2009 -- HIV prevalence and incidence in people 50 years of age and over seem surprisingly high and the risk factors are largely unexplored. Understanding the epidemiology of HIV infection in older individuals can lead to interventions to make these years safer and more enjoyable, according to articles in the March edition of the WHO Bulletin.
Ah, there is a link to the actual bulletin.

The 'Real' Story and What was the Source of Funding

This has many authors, so now our trust level can go up some. These look like actual scientists.
See those little reference letters next to their names? those tell where they are from .
a. Department of HIV/AIDS, World Health Organization, 20 avenue Appia, 1211 Geneva 27, Switzerland.
b. Independent Consultant, Geneva, Switzerland.
c. St Olaf College, Northfield, MN, United States of America.
Now a. is the HIV/AIDS department. You can guess that they will have an agenda. Given that it is WHO, they will have scientific training, and are funded by, hmmm. lets see who pays their bills...
A google of WHO funding gets about the third hit down as Wikipedia, and the very first line says ...
The World Health Organization (WHO) is a specialized agency of the United Nations (UN) that acts as a coordinating authority on international public health.
Ok, so they are part of the UN, which is a ultra political organization. Just keep that in mind.

b. above is an independent consultant.
That could mean just about anything. So, who is Brian G Williams, back to google.
Wow, lots of hits. Lets try Brian G. Williams Geneva. The sixth hit down is Science magazine with a list of some papers he has co-authored. This guy is definitely for real in the HIV research community. And he has worked a lot with the UN.

Then there are several references with c.
I could search the first one, Chris Miller but that name is so common, I'll search a more unique name, Emily Segar and add in Olaf to get the university hits....
Hmm, she shows up as a student graduating this year, and very big on the golf team.
so I add HIV as a search word, and now I see college news about the research.
In here is the 23rd National Conference on Undergraduate Research where the same authors are showing off their study.

This is the abstract...
Over 22 million individuals in sub-Saharan Africa are infected with Human Immunodeficiency Virus (HIV). Recent epidemiological research suggests that an unexpectedly high prevalence of HIV exists among the elderly in South Africa, particularly among females (Schmid et al., 2004). This trend deviates from the norm in most countries, where the prevalence of HIV infection steadily decreases after the age of 25. In the current study, we sought to (1) describe the age specific prevalence of HIV for men and women in Sub-Saharan Africa, (2) identify the risk factors associated with HIV prevalence in elderly populations and (3) compare and contrast risk factors between sub-Saharan African countries. We utilized individual-level data from 16 sub-Saharan African countries in the Demographic Health Surveys (DHS). The DHS surveys were conducted between 2002 and 2006 using a cross-sectional stratified clustered sampling methodology, which, in theory, allows findings to be generalized to each country’s population. The surveys collected data on household and respondent characteristics, socioeconomic status, education, knowledge and beliefs about sexually transmitted disease, health status, nutrition, and HIV status. Due to the nature of the sampling method, we incorporated weighted estimates for each individual (N=100,000+) into the prevalence estimates. Multiple logistic regression analyses were performed to identify potential socioeconomic, demographic, and cultural factors that were associated with HIV prevalence in elderly populations. We hope to identify whether an increased prevalence of HIV in the elderly exists in sub-Saharan African countries, and which factors may mitigate the risk for this population. Implications for future research of the epidemiology of HIV in sub-Saharan Africa are discussed.
Oh, it is a study they did in Africa.
I wonder who the professor at the university doing the study is. Maybe the first name in the list? David Tonyan Olaf gets a hit on the same article.
Ok, so I go to the top level web site for St. Olaf college, then faculty, then departments.
First I went back and read the names of the c. people.
Ok, I got sick of digging out the names. I suppose I could email one of the students and ask who the acedemic advisor is. But...

A Nugget of Facts Not in the News Articles
Did you notice the line in the abstract above...
This trend deviates from the norm in most countries, where the prevalence of HIV infection steadily decreases after the age of 25.
What the heck. When I read the news article I was thinking along the lines of good old USA retirement homes. Why they must be hives of lust! skyrocketing HIV rates for the elderly!
What about dear old Mom!

Nope. Not even the core idea. The core idea of the paper is that African HIV rates are high for the elderly, in contrast to the rest of the world.

What we Didn't Do
We got off lucky on this one and did not have to read the actual scientific paper. Aand no, I did not plan it ahead of time. I wrote this blog as a stream of thought, as I did the research.

The Point
The whole point of this article is that YOU can do the research on any topic. Follow the rabiit down the hole. You never know where it will lead.

TF

P.S. I am NOT going to go back and edit or correct this article like I usualy do. It is a stram of thought, as it is. Typos and everything. :-)

P.P.S. I have to give credit to the WHO thought. They point out that in the developed countries HIV in the elderly is slowly going up. So it is not entirely a wrong news story.
But this begs the question; Is the WHO just trying to get more AIDS funding, and is it the best use of the money for world health issues? Yes, again, the UN is highly political.

P.P.P.S. Not that the WHO article title has the word Unexplored in it. In other words they have not yet explored the issue of the aging and HIV. So the news article is still way off.

P.P.P.P.S. After digging for the truth, wait a day or two and then rethink and reread the information. And dig a little more. On a technical subject it helps to read at least 6 technical papers (not news articles) on the subject to get more balance. And if the subject is climate, try reading some older papers from BAIT (Before An Inconvenient Truth).

P.P.P.P.P.S. the next day, a very good article on the same topic.