the subtle art of being a dick, part 1

the subtle art of being a dick, part 1

History

I’ve mellowed a lot in my old age. I still like a good joke or a raze but I’m not as bad as I used to be. I guess that’s another thing that comes with getting older. I’ve always been a smart ass and I probably always will be. I think it’s in my DNA. I like to joke and kid with the people I spend a lot of my life with.  That’s my family, my friends and my co-workers. I’m never intentionally mean to people, I just like a good laugh and that includes laughing at myself. Sometimes though, you run across people that just rub you the wrong way. That’s where the subtle art of being a dick really shines.

For almost 20 years I was a partner in a software company that I helped co-found. A year before we sold that company, my partner and I had a falling out and he decided he was going to bring in a consultant. His decision was based mostly on picking up the slack if I decided… screw it, I’m out. I don’t want to use his real name so let’s just call him…. Bill. Bill was the kind of person who thought a lot of himself and not so much about the people around him. The people around him worked hard for me to insure myself and my family had a decent life. That’s the kind of person that definitely rubs me the wrong way. That’s someone who really deserves to experience my particular set of skills.

Our company created productivity products for real estate professionals the utilized data from multiple listings systems around the country and automated many of the common tasks they would do a daily basis. This isn’t too terribly important but does give some background to the events of the story.

My partner and his new consultant Bill decided that they were going to redesign the core component of all of our products, our script and parse engines. These were the components that allowed us to take property listing information from totally different systems and collect and standardize that data. In essence making a super set of common data from desperate system. It was the component that made all of our other products work. It was also the system that was my original design.  I’m not really one who suffers from “Pride of Authorship”. If you have an idea for a better mouse trap, then I’m all in. The problem was, neither one of then actually dealt with any of the data that they now decided they were going to re-create in there own image. They only used the current script and parse language features that we had in the my original code. These languages where written in a time before the internet. Yes, i know it’s hard to believe, but there was a time before the internet.  They were originally written to download data from online systems that used text based command. The data from these systems came if the form of full screen text layouts.

What I knew and what they didn’t seem to know is that the data landscape had changed since we first wrote our engine. It changed A LOT. Almost 100% of the data we now collected came in the form of a delimited file of some sort. We had to retro-fit all of ours system to basically import a comma delimited file. We no longer used all the “screen-scraping” code we had relied on for so many years.

The Art

We finally had our meeting to discuss what the dynamic duo had been designing for months with asking a single question to myself or my team, all of which were data experts. The entire company was present. I had never seen a system so complex that had as it’s only purpose was to import a delimited ASCII file. Don’t get me wrong, there was plenty of room for improvement on what we where currently using. None of those things where in the design I was staring at. I tried to explain the level of complexity they had designed wasn’t necessary anymore. The days of getting data in those formats were long gone, we were bypassing all of those and not using any of that functionality. I was sort of dismissed, I guess as being jealous of their obvious superior design. As Bill continued to roll out his master plan he was asked a question by one of my programming team regarding what seemed like a bunch of code and database tables that didn’t seem to be needed, the details of the actual question are a little fuzzy. Bill explained they existed because his system was muti-threaded and that a running task doesn’t have access to it’s own process id. That caught my attention, the day was looking up! Not because of my interest in multi-threaded programming, but because I knew his statement was false. And there was my opening to weave my craft.

I interrupted Bill every five minutes during his lecture, even though he had moved off the topic, to ask the same question albeit in slightly different ways. It was always a form of “Bill, are you sure a process can’t access it’s own id?” I was good, always asking it nonchalantly, like an after thought but loud enough for everyone in the meeting to hear. Bill never disappointed, he always responded the same “I am POSITIVE” sounding more and more irritated each time he answered. Sometimes I would throw in an immediate “Really?” after his response, the verbal equivalent of twisting the knife. After about the tenth time I asked the rest of the team was already smiling because they knew too well and knew what was coming. I have a well deserved reputation.

The meeting adjourned at which time I returned to my office, opened up my Outlook, and within two minutes sent an email to Bill and CC’d all in the meeting with the code for a running task to retrieve it’s own id.

I would like the thank these guys for existing  DEMOTIVATORS, Despair, Inc. I bought the Consultant poster the next day and hung it in my office. They get me.

~Rob

 

 

 

forcing asp.net webapi return format

forcing asp.net webapi return format

Problem

I do a work everyday in my professional life in Microsoft’s ASP.NET application framework. In more recent year I started utilizing more and more WEBAPI call through jQuery calls instead of trying to load data during a page’s Page_Load event. WEBAPI handles a lot of the conversions of datatypes to JSON (JavaScipt Object Notation) format for you. Sometimes I have simple calls that can be called directly from typing the URL into the browser and passing values through the use of the QueryString parameters. The idea being I could quickly test a WEBAPI call by typing a URL directly into the browser and making sure it’s working correct. Usually doing this returns the value in XML format and not the JSON format that I would expect when I call it from a jQuery Ajax call. I know I could use a utility like POSTMAN, which I love, but it just seems like I should be able to type the URL while I’m running the application in Visual Studio and get the results the way I want it.

Solution

I ran across and article on how to solve this problem. Adding this code into my application startup allows my to add a type parameter to the QueryString to force the format I want.

GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings.Add( new QueryStringMapping("type", "json", new MediaTypeHeaderValue("application/json"))); 

GlobalConfiguration.Configuration.Formatters.XmlFormatter.MediaTypeMappings.Add( new QueryStringMapping("type", "xml", new MediaTypeHeaderValue("application/xml"))); 

 

This little gem of code adds a QueryString parameter to a media type header value auto-magically. If I had a fictitious WEBAPI controller that returns detail for a customer record with an id of 100 that looks something like this:

http://myawesomeapplication.com/api/customers/get/100

I could just append a ?type=json to then to force the return value to json without ever leaving the browser debug session I’m working in.

http://myawesomeapplication.com/api/customers/get/100?type=json

Pretty Cool!

~Rob

soundfx.io and the speed of technology

soundfx.io and the speed of technology

History

Almost 20 years ago a wrote a small Visual Basic 3.0 program to generate sound “environments”. It was a fun project to create a utility for role playing games. I thought it would be cool to add a “sound” element to games to help the player be more immersed into the game by adding another sense to the mix. It used Microsoft’s Direct Sound library to mix sounds together and play. It allowed me to play multiple sounds and have them play at the same time even though they were starting and stopping at different times.  The code was for the program itself wasn’t too complex but the technologies behind playing the sounds where pretty sophisticated. DirectX was the domain of C++ and game developers.

I had played role playing games during high school but not too much after that, life and growing up in general got in the way. I had a group of friends who played religiously every week and they still do some 35 years later. My idea was to create a program that could create ambiance sounds for different scenarios that would be played during an adventure. Background sounds for a taverns, forests, storms, haunted houses and even battles. I called it DungeonFX – Hear what You’ve Been Missing. Like most of my ideas it was going to be really BIG! Like most of my ideas I lost interest before I finished and it never made it big. This seems to be recurring theme in my life.

The project was more than just playing a single static audio file. They were totally randomly generated environments that really never repeated. I was able to create a working version that consisted of text file to define the various component sounds and how they where played that made up the “environment”. It was some sort of homegrown format I created that was like a windows.ini (if you are old enough to know what I’m talking about) file but used html like tags to break up the sections. I have no idea why I did it this way, it was a long time ago, you’ll have to give me a break.

The components that comprised an environment were backgrounds sounds, sound events, and a single music track. Pretty simple but the results actually turned out quite impressive. The environments where packaged into zip archives that just had a custom .dfx extension. The archive contained the configuration file and the various sounds files that would be played to create the sound track. Being years ago, the sound files for the backgrounds and events where .wav files and the music sounds track was a a .midi file. When an environment was request to be played the program would unzip all the components and play the various sounds defined in the environment file based on specific parameters defined for each of those sounds.

How did all this work? An example environment file is a good way to start. Here is a sample file that created a stormy night complete with rain, wind gusts and random thunder and lightning:

<environment>
version=1.0
Name=Storm
description=Storm with light rain and thunder.
author=rob
date=04/12/2001
email=me@maximumrob.com
</environment>

<background>
rain.wav,70
</background>

<music>
track.midi
</music>

<event>
thunder.wav,0,100,-1,5,50
thunder6.wav,0,100,-1,5,20
thunder7.wav,0,100,-1,6,30
thunder5.wav,0,100,-1,10,20
howlwind.wav,40,0,0,60,60
</event>

Environment Section

This section just contained the various meta data for the environment. Name, author and other relative information that would be display in the player program

Backgrounds

This section had one line for each background sound that would be placed when the environment started playing. All the background sounds where designed to be played in a infinite loop while the environment was actively playing. For each background you could specify the volume (from 1 to 100) that the sound would play at. In this example it was only playing a rain loop. It could have easily added other sounds like a crackly camp fire or crickets.

Music

Music was similar to a background sound as it played in a loop. Difference was it was a midi music file. Gave the option of playing a soundtrack to go along with the sounds.

Events

These are the items that make the environment random. These are sound that only play when specific criteria are met. The example above has 4 different thunder events and 1 howling wind event. You can add as many sounds events that you like. The numbers after each sound defines when and how the sound is played. The number are as follows:

Min Volume, Max Volume, Random Volume, Frequency, Possibility

Min Volume - This is the minimum volume the event will play out if the volume is random. It is also the static volume the event will always play at is the volume is not random.
Max Volume - This is the maximum volume the event will pay at if the volume is random. It is not used if the volume isn't random.
Random Volume - Flag is this event generates a random volume each time it fires.
Frequency - Who often (in seconds) to check if the event happens.
Possibility - Percentage change (1-100) that the event fires and play.

These options allow a lot of flexibility. You can choose how rare or regular events are. Setting a frequency to 30 seconds and a possibility to 2% would make a event hardly ever happen. Setting a frequency to 5 seconds and a possibility to 100% would cause a sounds event to fire every 5 seconds consistently. Volumes can be set to a specific volume or random. This has the effect of making an event sound closer or further away adding to the randomness.

I had also implement some experiments in 3D sound. This would allow an event to originate from a specific point in 3D space. If you were playing an environment in surround sound you could make a event sound like it was happening behind you. Another idea was to play an animated 3D sound where the sound would play moving along a path in 3D space. Imagine the sound an insect flying around your head or a car passing by. I never implemented the path feature but thought it would have brought even more COOL to an already pretty awesome little program.

So why this trip down memory lane?

I ran across the code for this utility a few months ago. I started to remember all the complicated libraries I had to use to make it happen. Then I start thinking about how far software development had progressed over this 20 years, specifically web development. I started to wonder if I could rewrite this sound generating machine using web technologies like html and JavaScript. It took me all of 10 minutes to decide I was going to give it a try, and 5 minutes after that I had been laying out the foundation for moving this to the web.

To my surprise I had a working port of this program running on a web page using JavaScript in about 3 hours. I used Howler.js , which is an excellent JavaScript audio library. It was able to replace everything that I was doing using the DirectX  library. I ported my environment file to a json format and dropped the whole idea of a zip file. I upgraded the sounds to mp3 files instead of the larger .wav files since it was downloading all the resources for web.  I was shocked at how fast I was able to put this all together. I think the original version took me a month to get working the way I wanted and here it was running in a web browser in one evening.

This new version doesn’t have all the features the original visual basic program has. I need to find a good midi library to implement the background music soundtrack and I didn’t implement the 3D sounds but Howler.js does have that ability. I will probably add that when I have some extra time. I never got to hear what that sounded like but I think it would be pretty amazing. I threw the result on a website called soundfx.io. It just plays a single storm environment is created for testing.

Here is an updated environment.json file using sounds I found on a great sound resource site freesound.org. Check them out and support them if you are into sounds. I added settings for the 3D sounds even though I haven’t implemented the feature yet. The overall readability of this format is so much better than the original I created.

{
"meta": {
"version": "1.0",
"description": "Two looped rain tracks with random thunder and lighting effects.",
"name": "Stormy Night",
"author": "Rob",
"email": "me@maximumrob.com"
},
"background": [
{
"file": "231686__fenrirfangs__rain-2.mp3",
"volume": 60
},
{
"file": "346642__inspectorj__rain-on-windows-interior-a.mp3",
"volume": 75
}
],
"event": [
{
"file": "253953__yoyodaman234__thunder-1.mp3",
"minVolume": 0,
"maxVolume": 100,
"randomVolume": true,
"frequency": 5,
"percentage": 40,
"is3D": false,
"posX3D": false,
"posY3D": false,
"posZ3d": false
},
{
"file": "324048__karas-homemade-sfx__wind-soundeffect.mp3",
"minVolume": 0,
"maxVolume": 100,
"randomVolume": true,
"frequency": 3,
"percentage": 45,
"is3D": false,
"posX3D": false,
"posY3D": false,
"posZ3d": false
},
{
"file": "394921__parasonya__022-single-strike.mp3",
"minVolume": 0,
"maxVolume": 100,
"randomVolume": true,
"frequency": 7,
"percentage": 60,
"is3D": false,
"posX3D": false,
"posY3D": false,
"posZ3d": false
},
{
"file": "399656__bajko__sfx-thunder-blast.mp3",
"minVolume": 30,
"maxVolume": 70,
"randomVolume": true,
"frequency": 5,
"percentage": 55,
"is3D": false,
"posX3D": false,
"posY3D": false,
"posZ3d": false
},
{
"file": "400987__techienanna__rumblings-of-thunder.mp3",
"minVolume": 10,
"maxVolume": 90,
"randomVolume": true,
"frequency": 5,
"percentage": 35,
"is3D": false,
"posX3D": false,
"posY3D": false,
"posZ3d": false
},
{
"file": "101948__juskiddink__dry-thunder3.mp3",
"minVolume": 10,
"maxVolume": 75,
"randomVolume": true,
"frequency": 3,
"percentage": 25,
"is3D": false,
"posX3D": false,
"posY3D": false,
"posZ3d": false
},
{
"file": "121945__hantorio__thunder-close.mp3",
"minVolume": 45,
"maxVolume": 80,
"randomVolume": true,
"frequency": 3,
"percentage": 65,
"is3D": false,
"posX3D": false,
"posY3D": false,
"posZ3d": false
}
]

SOUNDFX.IO

http://soundfx.io

*please note some browsers (I’m looking at you Chrome) require you to perform an event, like a clicking on the page, before it will start playing sounds.

Man…. I think this is going to be HUGE! 😜

~Rob