ATTENTION ALL FANS!!! THIS BLOG HAS MOVED!!!
go to: http://www.taotekaching.com

Showing posts with label programming. Show all posts
Showing posts with label programming. Show all posts

Tuesday, February 24, 2009

Binary Data Transforms, Hex Editing, Design Patterns, and Me…

Lately for work I have been responsible for developing a .NET layer to read from and write to an existing application's binary data files.  The task has proven tedious, but not necessarily boring, as I've discovered some invaluable tools and development principles from this.

First off, the HxD hex editor, and, more importantly, comparison tool is simply perfect for the job.

hxd

Many minute differences in my binary output were discovered with this tool.  By using the comparison feature:

hxd-compare

I could determine the first instance of a difference in output and, if unexpected, use the location from HxD to quickly narrow down the area of code responsible.

hxd-compare2

In my code, a Stream is passed to a method that will populate a struct representing the file.  This Stream is put into a BinaryReader for sequential type-based reading of the file.   By simply adding conditional breakpoints at various places in the code, locating the problem was easy.  The condition of the breakpoint would be something like:

myBinReader.BaseStream.Position > 10000

where 10000 would be just below the difference location given by HxD.

hxd-compare3

So this greatly, greatly, very much helped speed up the process of making sure I was reading and writing the native binary file format out correctly.  Next, I was to transform some of this data to XML for use by another application.  I already had the struct of native data, and wanted to make the transformation to and from XML as stupidly simple as possible.  To do this, I threw down a bunch of different classes, each representing the XML element I was to turn out, and had the elements inherit a base interface with a ToXML() contract method.  Some of the “element” classes contained List<>s of the other “element” classes, so when churning out the XML, it was as simple as doing a foreach and callling ToXML() from each of those to produce my child nodes correctly.

I very much realize this solution is neither new nor ingenious.  I am using it, in fact, as a tangent off into a discussion on this patterns-war stemming from the Spolsky comment on the SOLID method.  Quite frankly, I’m not sure what pattern or patterns I implemented above.  The Proxy or Facade?  I would like to know, as I’ve used this technique of a sort of “translation class” a bazillion times, except my bosses really don’t provide me much time to learn about it, much less, say, spend time with my family (I know you gobblers are reading this).  However, I have an opinion on this patterns-war that I would love some feedback on.  It centers around hiring:  if your team is hiring a new developer / engineer, and you or your team are big into design patterns, don't make knowledge of design patterns a requisite for hiring.

I have been programming most of my life, but only somewhat recently have been able to make it my career.  Already I've met a good range of coders: the hardcore enthusiast, the day-job-only coder, the serious professional.  They seem to come in all types, but all have the same common denominator:  they enjoy writing code.  Some more than others, but ultimately, there is a certain gene-pool that simply enjoys writing code.  It actually has little to do with being a computer enthusiast.  A good majority of systems administrators I've worked with or under don't like programming, period.  But there are those of us who are addicted to "realizing" our thoughts right there on the screen.

Until maybe two or three years ago, I knew little to nothing about design patterns.  As I became familiar with and researched them, I've discovered that I've been using many of them for a long, long time.  And that's exactly what they are:  patterns that have been "recognized" in the programming trade.  As such, they are most valuable as a means of communicating an approach to a task or problem at hand.  They are not, however, a requirement to attack a programming task, nor are they any indication of the competency of the prospective engineer / developer.

If your programming shop or R&D department or whatever group you work in is a pattern-heavy group, then make the applicant aware of this, but don't dismiss them if they simply don't know design patterns.  Most likely the applicant would be more than eager to learn them, and will discover they’ve already used many of them anyways.  Ergo, it's a subset of a lexicon we, as coders, may or may not need to know, depending only on how to be most efficient in our team.

I've noticed that a majority of the programmers I've worked with thus far who are heavy into patterns arrogantly criticize and judge their colleagues when they find out they don't know what a singleton is or the proxy pattern or whatever.  So far, from what I've seen, neither camp has shown to be better programmers than the other.  The real thing that quickly separates an experienced programmer from a truly great programmer, though, is ego.  I personally love everything from learning new tricks and techniques from my colleagues to having them point out where I was really dumb in my code.  It only makes me ultimately a better programmer (hopefully).  What I don’t want to do, and I think this is a pretty unanimous feeling, is converse with an asshole.

When you really think about it, the literal sense of “conversing with an asshole” is identical to it’s figurative sense: an asshole really never listens, and only barks out useless foulness you’ll want to stay away from.  Plus, your friends, family, and colleagues all may very well think less of you if they see you regularly conversing with assholes, even if it’s the same asshole.

So really, whether you’re big into design patterns or not, don’t be an asshole, because it just means you don’t listen and no one wants to be near you anyways.  And if you’re hiring, replace “do they know what a flyweight pattern is?” with “are they an asshole?” on your checklist.  You’ll always build a better team that way.

~zagnut

Submit this story to DotNetKicks

Thursday, January 08, 2009

Device Independent Bitmaps, C#, and Me…REDUX!


Well, after using the previously posted code in some projects at work, some limitations arose quickly. The two biggest were support for 8-bit bitmaps, and support for both 5-5-5 and 5-6-5 16-bit bitmaps.

The new code looks like the following:

using System;

using System.Collections.Generic;

using System.Drawing;

using System.Drawing.Imaging;

using System.Runtime.InteropServices;

using System.IO;

namespace DIBitmaps

{

static public class DIB

{

// our BITMAPINFOHEADER struct, as per gdi

// use LayoutKind to make sure data is marshalled as we've laid it out

[StructLayout(LayoutKind.Sequential)]

public struct BITMAPINFOHEADER

{

public uint biSize;

public int biWidth;

public int biHeight;

public ushort biPlanes;

public ushort biBitCount;

public uint biCompression;

public uint biSizeImage;

public int biXPelsPerMeter;

public int biYPelsPerMeter;

public uint biClrUsed;

public uint biClrImportant;

//public void Init()

//{

// biSize = (uint)Marshal.SizeOf(this);

//}

}

public static Bitmap BitmapFromDIB(MemoryStream dib)

{

// get byte array of device independent bitmap

byte[] dibBytes = dib.ToArray();

// get the handle for the byte array and "pin" that memory (i.e. prevent

// garbage collector from gobbling it up right away)...

GCHandle hdl = GCHandle.Alloc(dibBytes, GCHandleType.Pinned);

// marshal our data into a BITMAPINFOHEADER struct per Win32

// definition of BITMAPINFOHEADER

BITMAPINFOHEADER dibHdr = (BITMAPINFOHEADER)Marshal.PtrToStructure

(hdl.AddrOfPinnedObject(), typeof(BITMAPINFOHEADER));

bool is555 = true;

Bitmap bmp = null;

if (dibHdr.biBitCount == 8)

{

// set our pointer to end of BITMAPINFOHEADER

Int64 jumpTo = hdl.AddrOfPinnedObject().ToInt64() + dibHdr.biSize;

bmp = new Bitmap(dibHdr.biWidth, dibHdr.biHeight, PixelFormat.Format8bppIndexed);

bmp.SetResolution((100f * (float)dibHdr.biXPelsPerMeter) / 2.54f,

(100f * (float)dibHdr.biYPelsPerMeter) / 2.54f);

// set the colors in our palette

ColorPalette palette = bmp.Palette;

IntPtr ptr = IntPtr.Zero;

int colors = (int)(dibBytes.Length - (bmp.Width * bmp.Height) - dibHdr.biSize);

for (int i = 0; i < 256; i++)

{

ptr = new IntPtr(jumpTo);

uint bmiColor = (uint)Marshal.ReadInt32(ptr);

int r = (int)((bmiColor & 0xFF0000) >> 16),

g = (int)((bmiColor & 0xFF00) >> 8),

b = (int)((bmiColor & 0xFF));

palette.Entries[i] = Color.FromArgb(r, g, b);

jumpTo += 4;

}

bmp.Palette = palette;

// now write the remaining bmp data to our bitmap

BitmapData _8bd = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),

ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);

jumpTo -= hdl.AddrOfPinnedObject().ToInt64();

Marshal.Copy(dibBytes, (int)jumpTo, _8bd.Scan0, _8bd.Stride * _8bd.Height);

bmp.UnlockBits(_8bd);

}

else if ((dibHdr.biBitCount == 16) && (dibHdr.biCompression == 3))

{

Int64 jumpTo = (Int64)(dibHdr.biClrUsed * (uint)4 + dibHdr.biSize);

IntPtr ptr = new IntPtr(hdl.AddrOfPinnedObject().ToInt64() + jumpTo);

ushort redMask = (ushort)Marshal.ReadInt16(ptr);

ptr = new IntPtr(ptr.ToInt64() + (2 * Marshal.SizeOf(typeof(UInt16))));

ushort greenMask = (ushort)Marshal.ReadInt16(ptr);

ptr = new IntPtr(ptr.ToInt64() + (2 * Marshal.SizeOf(typeof(UInt16))));

ushort blueMask = (ushort)Marshal.ReadInt16(ptr);

is555 = ((redMask == 0x7C00) && (greenMask == 0x03E0) && (blueMask == 0x001F));

}

// go ahead and release the "pin" from our handle on that memory

hdl.Free();

// If the target device does not have one plane, or we're working with a bitmap other

// than a non-compressed (BI_RGB) bitmap, we're not gonna work woith it

if (dibHdr.biPlanes != 1 || (dibHdr.biCompression != 0 && dibHdr.biCompression != 3))

return null;

if (bmp == null)

{

// we need to know beforehand the pixel-depth of our bitmap

PixelFormat fmt = PixelFormat.Format24bppRgb;

switch (dibHdr.biBitCount)

{

case 32:

fmt = PixelFormat.Format32bppRgb;

break;

case 24:

fmt = PixelFormat.Format24bppRgb;

break;

case 16:

fmt = (is555) ? PixelFormat.Format16bppRgb555 :

PixelFormat.Format16bppRgb565;

break;

default:

return null;

}

// prepare for our output bitmap

bmp = new Bitmap(dibHdr.biWidth, dibHdr.biHeight, fmt);

// load our "empty" bitmap into memory and lock it for

// writing in the format we specified

BitmapData bd = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),

ImageLockMode.WriteOnly, fmt);

// marshal our device independent bitmap data over to our output bitmap

Marshal.Copy(dibBytes, Marshal.SizeOf(dibHdr), bd.Scan0, bd.Stride * bd.Height);

// we're done marshalling, so release our bitmapdata lock

bmp.UnlockBits(bd);

}

if (dibHdr.biHeight > 0)

{

// DIB data is upside-down for some reason, so flip it

bmp.RotateFlip(RotateFlipType.RotateNoneFlipY);

}

// return our bitmap

return bmp;

}

}

}

The adjusted code can be downloaded here.

If you find any other issues, please let me know and I’ll get it updated ASAP.

~ZagNUT

Submit this story to DotNetKicks

Conway’s Game of Life, Pong, Screensavers, and Me…

Greetings, all:

Due to the massive increase in my blog traffic (I think I het around 20 / week or so) after I initially offered up my Game of Life screensaver, I now offer, in celebration of the new year, GoLPong!

GoLPong

That’s right, for 2009 you now can have a fancy new Game of Life screensaver.  BUT THIS ONE’S PACKED WITH NEW FEATURES!  Well, what are they?

  • Game of Life does both trails and no trails
  • Flickers between trails and non-trails
  • Pong played live by your computer against itself
  • Alternates randomly between these two!

Oh my god, you say, but how much does it cost?

Free.  Because I love you.

It is a beautifully dumb screensaver.  You can get it here.  The source code (uncommented, of course) is here.

Tell me how you like it.  Also, send me comments for the 2010 version you’d like to see.

~ZagNut

Submit this story to DotNetKicks

Thursday, December 04, 2008

Native MDI Containers, Managed Child Forms, and Me...

So, at work we have this (ugly) native C++ MFC application that the Powers-That-Be insist needs a complex web-services riddled interface to our social-networking-meets-file-sharing new website.  Initially, said interface was to be in MFC native code action.  I said, "sheeeeeeeeeiiiiiiiiiiiiiiiittt".  But then the light came: why not do the interface in a .NET form and pass the form handle somehow to the native application to pull it into its window as a child window.  Any interaction between the two can be handled easily through messaging calls.  I immediately began to Google on it.  I found nothing that directly addressed this problem.  I concluded it was one of two things: either it was so easy, no one bothered documenting it, or so rarely done, no one bothered documenting it.  Either way, no one bothered documenting it...UNTIL NOW!!!

Basically my solution was to grab the parent window's class using a call to GetClassName, then send this as a command line parameter to the .NET exe via a ShellExecute call.  Once in the .NET client, I use two DllImport-ed calls: FindWindow and SetParent -- FindWindow to get the window handle from the class name I passed in as a parameter, and SetParent to, well, set the parent of my form.

The sample code is here.  Note, you'll need to change the hardcoded path in the NativeMaster C++ solution to the output of the ManagedChild project.  Hope it's helpful...

~ZagNut

Submit this story to DotNetKicks

Monday, November 24, 2008

DIB, C#, and Me...

Ok, after pulling out my hair trying to generate thumbnails from device-independent bitmaps stored by a CArchive in an "old" MFC program, I finally got help here at the workplace on this.

I must say I could not find this easily with much Googling, ergo I'm gonna post this up here with comments for anyone else out there looking for the same thing.

Please suggest any updations to comments and / or code, if you see the need...

NOTE: This code has been updated. Look here for it.

// our BITMAPINFOHEADER struct, as per gdi
// use LayoutKind to make sure data is marshalled as we've laid it out
[StructLayout(LayoutKind.Sequential)]
public struct BITMAPINFOHEADER
{
public uint biSize;
public int biWidth;
public int biHeight;
public ushort biPlanes;
public ushort biBitCount;
public uint biCompression;
public uint biSizeImage;
public int biXPelsPerMeter;
public int biYPelsPerMeter;
public uint biClrUsed;
public uint biClrImportant;
public void Init()
{
biSize = (uint)Marshal.SizeOf(this);
}
}

public static Bitmap BitmapFromDIB(MemoryStream dib)
{
// get byte array of device independent bitmap
byte[] dibBytes = dib.ToArray();

// get the handle for the byte array and "pin" that memory (i.e. prevent garbage collector from
// gobbling it up right away)...
GCHandle hdl = GCHandle.Alloc(dibBytes, GCHandleType.Pinned);

// marshal our data into a BITMAPINFOHEADER struct per Win32 definition of BITMAPINFOHEADER
BITMAPINFOHEADER dibHdr = (BITMAPINFOHEADER)Marshal.PtrToStructure(hdl.AddrOfPinnedObject(), typeof(BITMAPINFOHEADER));

// go ahead and release the "pin" from our handle on that memory
hdl.Free();

// If the target device does not have one plane, or we're working with a bitmap other than a
// non-compressed (BI_RGB) bitmap, we're not gonna work woith it
if (dibHdr.biPlanes != 1 || dibHdr.biCompression != 0)
return null;

// we need to know beforehand the pixel-depth of our bitmap
PixelFormat fmt = PixelFormat.Format24bppRgb;
switch (dibHdr.biBitCount)
{
case 32:
fmt = PixelFormat.Format32bppRgb;
break;
case 24:
fmt = PixelFormat.Format24bppRgb;
break;
case 16:
fmt = PixelFormat.Format16bppRgb555;
break;
default:
return null;
}

// prepare for our output bitmap
Bitmap bmp = new Bitmap(dibHdr.biWidth, dibHdr.biHeight, fmt);

// load our "empty" bitmap into memory and lock it for writing in the format we specified
BitmapData bd = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, fmt);

// marshal our device independent bitmap data over to our output bitmap
Marshal.Copy(dibBytes, Marshal.SizeOf(dibHdr), bd.Scan0, bd.Stride * bd.Height);

// we're done marshalling, so release our bitmapdata lock
bmp.UnlockBits(bd);

// DIB data is upside-down for some reason, so flip it
bmp.RotateFlip(RotateFlipType.RotateNoneFlipY);

// return our bitmap
return bmp;
}


~simon

Submit this story to DotNetKicks

Tuesday, November 11, 2008

C++, Web Services, TinyXML, and Me...

Greetings...

So my current employer wants our existing MFC application to interface with some web services exposed by our new website (sorry, need to stay hush-hush about it at the moment).  Now, while the MFC side of things is turning out to be a bitch, I threw together some classes to make life easier for me.  The source is here.

CppHttp.h is a simple class to do GET and POST requests through.  Currently, it does NOT do multi-part requests, but I promise to update this when I get to that.  To consume the responses, I'm using TinyXML.  I looked at some other libraries, including using the MsXml stuff, but they were WAY overboard what I needed.  I included a sample class that calls a stock market thing I found on xmethods.net.  The Find method in there is particularly useful when getting, say, a DataTable back and wanting to go straight to the nodes.

Anyway, hope this is useful.  Let me know your thoughts.

~ZagNut

Submit this story to DotNetKicks

Saturday, October 04, 2008

Java, Dice, Programming Languages and Me...

So, I decided to write another Applet, this time one that gives the "popularity" of a programming language based on the number of instances found from a generic Dice.com search.

The source code is here.

Submit this story to DotNetKicks

Thursday, September 04, 2008

Flash RGB, C#, and Me...

Greetings,

So a co-worker of mine had to translate Flash RGB data into a Bitmap. He noted that finding that out was difficult, ergo, for your coding pleasure, here's a tasty little static function you can use just for that:




static Bitmap BmpOut(string rgb, int width, int height)
{
Bitmap bmp = null;
try
{
int bytes = (rgb.Length / (width * height));
bool IsArgb = (bytes == 8);
double dWidth = (double)width;
bmp = new Bitmap(width, height);
int counter = -1;
for (int i = 0; i < rgb.Length; i += bytes)
bmp.SetPixel(++counter % width, (int)Math.Floor((double)counter / dWidth),
Color.FromArgb(int.Parse(((!IsArgb) ? "FF" + rgb.Substring(i, 6) : rgb.Substring(i, 8)), System.Globalization.NumberStyles.HexNumber)));
}
catch { bmp = null; }
return bmp;
}


enjoy...

Submit this story to DotNetKicks

Tuesday, July 22, 2008

A Programming Job Interview Challenge #13 - Brackets, and Me...

Ok, I've been doing the programming quizzes here and have a solution...

In Perl:


$FILE = "expressions.txt";
open(FILE) or die("Could not open expressions file.");
foreach $OLINE (<FILE>)
{
$LINE = $OLINE;
if ($LINE =~ m/(^[\]}\)>])|([\[{\(<]$)/)
{ print "bad : $OLINE" }
else
{
while ($LINE =~ m/(\[\])|({})|(\(\))|(<>)/)
{ $LINE =~ s/(\[\])|({})|(\(\))|(<>)//g }
$strLen = length($LINE);
if ($strLen > 1)
{ print "bad : $OLINE" }
else
{ print "good : $OLINE" }
}
}

And a C# console app to generate the "sample" strings (i.e. the "expressions.txt" file used above):




using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Creator();
//Console.ReadKey();
}
static void Creator()
{
Random r = new Random((DateTime.Now.DayOfYear + DateTime.Now.Millisecond) * (DateTime.Now.Second + DateTime.Now.Minute + 1));
string encs = "[{(<>)}]";

string sb = "";
for (int i = 0; i < 100; i++)
{
sb = "";
bool good = (r.Next(0, 100) > 50) ? true : false;
int strlen = r.Next(1, 21) * 2;
for (int j = 0; j < strlen; j++)
{
if (!good)
sb = String.Format("{0}{1}", sb, encs[r.Next(0, encs.Length)]);
else
{
int p = r.Next(0, encs.Length / 2);
int q = r.Next(0, 3);
if (q == 0)
sb = String.Format("{0}{1}{2}", encs[p], sb, encs[encs.Length - p - 1]);
else if (q == 1)
sb = String.Format("{0}{1}{2}", sb, encs[p], encs[encs.Length - p - 1]);
else
sb = String.Format("{0}{1}{2}", encs[p], encs[encs.Length - p - 1], sb);
}
}
//Console.WriteLine(String.Format("{0}: {1}", good, sb.ToString()));
Console.WriteLine(sb);
}
}
}
}

I couldn't spend that much time on this, as I am at work. Ergo, I'm a little disappointed with the Perl, although it was my first Perl program ever!


I'm particularly curious about how I could have done some sort of recursive check. Please give any suggestions to the Perl script that would make it as close to a one-liner regex check.


~simon

Submit this story to DotNetKicks

Wednesday, July 09, 2008

Conway's Game of Life, Java, Smoking, and Me...

Ok, I've done it again. Another Conway's Game of Life, this time in Java:

The source code can be had here. It's called Gola (Game Of Life Applet).

So, I've quit smoking. I started July 6 at 11:27pm (my last cigarette). It is going much better this time.  This is my third time.  The first two times I quit for 2+ years each time.  I know this time is my final one.  Why?  I had a "moment" where I just didn't want them anymore.

That feeling stayed, even after I failed, so I set a quit date, got the patch, got lots of pretzel sticks, and made sure I didn't sit around and drink coffee in the morning.  This is the third day, and I had to stay home today.  I felt like I had the flu and slept until 1:00pm.  I've been a vegetable and sleeping on and off since.  It's 5:33pm now, and I'm finally getting a little energy back.  I wrote a little C# program for watching the "progress" of quitting.  I was going to include the health benefits stages as stages that would appear below the timer, but I slacked.  Here's the code and benefits list.

Submit this story to DotNetKicks

Thursday, July 03, 2008

Conway's Game of Life in Javascript, and Me...

Ok, I went and done it...

With my inability to purge my rotting brain of Conway's Game of Life, I have produced none-other than a super double-buffered javascript only Conway's Game of Life!

Hopefully I can sleep now. Below is it in all it's glory. You can get the javascript to run it here.

NOTE: ARRRRRRGGGGHHH!!! Ok, trying to get javascript to run in blogger, but it'll take a little work. Here's so you can see it works

ADDENDUM: In Blogspot, IE doesn't like this script so well, nor does Firefox. I've removed it from the page but you can still see it at the link above.

ADDENDUM REDUX: Well, IE does not like this script at all. Performance is lousy and display is f-ed up. Firefox runs it like a champ.

Submit this story to DotNetKicks

Saturday, September 01, 2007

SAPI and Me

So I've been messing around with SAPI 5.1. Pretty damn cool API, if you ask me.

Very easy to work with it through C#. The documentation is, for some reason, almost all in C++ and like VB 6. It took a little Google-ing to get what I wanted done: suck in a WAV file and transcribe it. Here's the class I wrote for doing it:



using System;
using System.Collections.Generic;
using System.Text;

using SpeechLib;

namespace Transcriber
{
public class TransSpeech
{
public class RecoEventArgs : EventArgs
{
public struct RecoBlock
{
public int index;
public ISpeechRecoResult result;
public RecoBlock(int idx, ISpeechRecoResult rez)
{
this.index = idx;
this.result = rez;
}
// TODO: order by index
}
private RecoBlock _block;
public RecoBlock Block
{
get
{
return _block;
}
}
public RecoEventArgs(int Index, ISpeechRecoResult Result)
{
this._block = new RecoBlock(Index, Result);
}
}
public delegate void RecoEventDelegate(RecoEventArgs args);
public event RecoEventDelegate RecoEvent;
public delegate void RecoFinishedDelegate(EventArgs args);
public event RecoFinishedDelegate RecoFinished;

static int objNumber = 0;

SpInprocRecognizerClass rec;
SpFileStreamClass fs;
SpInProcRecoContext cntxt;
ISpeechRecoGrammar g;

public TransSpeech()
{
rec = new SpInprocRecognizerClass();
fs = new SpFileStreamClass();
cntxt = (SpInProcRecoContext)rec.CreateRecoContext();
cntxt.RetainedAudio = SpeechRetainedAudioOptions.SRAORetainAudio;
cntxt.Recognition += new _ISpeechRecoContextEvents_RecognitionEventHandler(cntxt_Recognition);
cntxt.EndStream += new _ISpeechRecoContextEvents_EndStreamEventHandler(cntxt_EndStream);
g = cntxt.CreateGrammar(1);
g.DictationLoad("", SpeechLoadOption.SLOStatic);
}
~TransSpeech()
{
// TODO: final cleanup here
}
public void ReadInFile(string filename)
{
try
{
objNumber = 0;
// TODO: lock shit?

fs.Open(filename, SpeechStreamFileMode.SSFMOpenForRead, true);
rec.AudioInputStream = fs;
g.DictationSetState(SpeechRuleState.SGDSActive);
}
catch (Exception ex)
{
throw new Exception("TransSpeech error in ReadInFile:", ex);
}
}

void cntxt_EndStream(int StreamNumber, object StreamPosition, bool StreamReleased)
{
g.DictationSetState(SpeechRuleState.SGDSInactive);
g.DictationUnload();
fs.Close();

// TODO: additional cleanup

if (RecoFinished != null)
RecoFinished(new EventArgs());
}
void cntxt_Recognition(int StreamNumber, object StreamPosition, SpeechRecognitionType RecognitionType, ISpeechRecoResult Result)
{
lock (this)
{
objNumber++;

if (RecoEvent != null)
RecoEvent(new RecoEventArgs(objNumber, Result));
#region old code
//string msg = "";
//foreach (ISpeechPhraseElement el in Result.PhraseInfo.Elements)
//{
// msg += el.DisplayText + " ";
//}
//msg += "\r\n";
#endregion
}
}
}
}

Note that you'll need to download the SAPI 5.1 SDK and reference the Speech Library something or other in COM.


Trying it out on just random office conversation gave pretty poor results, but then I ran it on one of Cringley's weekly podcasts and it fared pretty damn well, for having not been trained or anything


Next test plan is to re-feed "good" recognitions back as training (if I can) and see if it improves recognition


NOTE: if anyone gives this code a try, please let me know if you know / have figured out how to take the retained audio from ISpeechRecoResult and send it directly to DirectSound or something, rather than save it in a WAV file. If I get to it before any responses (likely, given my massive following), I'll post the solution


I've been masterdebating lately about whether to pursue advanced studies in Computer Science. Part of me really wants to, in particular to be able to teach as well as just personal ambition / goal. All comments on this are very, very welcome.


Some of my colleagues at work despise this idea, including some with a BS in Computer Science. The common arguments seem to be as follows:



  • None of my BS has helped or come into play here in the "real" development world

  • It's a waste of money, when you can learn all you want from Google, books, and just doing it

  • The worst programmer's I've seen are fresh out of college with a BS in Computer Science

  • You've got a kid on the way...how the hell will you afford it? (this is particularly relevant to me, but thought I'd throw it in as a outlier argument


Your thoughts on this?

Submit this story to DotNetKicks