So it turns out that if you need some code to read media information out of an m4a file the only viable option to be found on the interwebs is a project called Atomic Parsley. Written in C/C++, you can tell a lot of time was put into reverse engineering the structure of MPG-4 audio file meta data and specifically, the types of tags used by iTunes.
The downside to that set of code is that it is written as a command line utility (global state, lots of fprintf, and exit(1) for error handling) and not at all structured in a way to be easily used as a class or component; especially from managed code.
Since what I have been looking for is some code that can be used from C#, I took the pieces of Atomic Parsley that I needed and restructured them as C++ classes. From there it wasn't too hard to create a C++/CLI wrapper for easy consumption in C#.
On the nostalgia side: It has been a long time since I've seen calls to malloc and I even forgot for second that unmanaged memory needs to be manually initialized to NULL.
And on the new technology side: this was a good foray into the latest C++/Cli syntax, using VS.NET 2010 and .NET4. It's getting more and more like C# in flavor but is still feels cumbersome in comparison. That being said, when creating a shiny new managed interface around legacy code, it cannot be beat.
So if you are looking for a mechanism to read meta-data from iTunes/m4a files the result might be helpful. Check it out on google code.
Random babblings about creating, using and generally considering software.
Sunday, June 13, 2010
Monday, April 5, 2010
A new CodeProject article
A while back I came across a fun bit of code on CodeProject that used alpha blending to animate a fish swimming around on the screen. I've been toying around with that code on and off for awhile and it finally has turned into a whole bunch of fish swimming around on the screen.
If you've been dieing to have fish swimming around on your screen the wait is over. Check it out over at CodeProject.
(This is written against the .NET 4 RC. You may need to download this for it to work.)
If you've been dieing to have fish swimming around on your screen the wait is over. Check it out over at CodeProject.
(This is written against the .NET 4 RC. You may need to download this for it to work.)
Sunday, February 21, 2010
Dynamically evaluating a JOIN expression with Linq
For the last little while I've been toying around with System.Linq.Expressions and a mini SQL parser to see how far I can go with evaluating plain text SQL expressions against arbitrary collections of objects. It's mostly a side project for my own enjoyment but eventually I am hoping it actually turns into something broadly useful.
Results so far I've put on CodeProject:
So just now I've been able to get this unit test to pass:
This is cool because now I can start generating complex queries without having compile time knowledge of the underlying data structures. Once I get things fleshed out further I'll update things on CodeProject.
CodeProject
Results so far I've put on CodeProject:
- http://www.codeproject.com/KB/linq/SqlLinq.aspx
- http://www.codeproject.com/KB/linq/QueryAnything.aspx
So just now I've been able to get this unit test to pass:
[TestMethod]
public void SimpleJoin()
{
IEnumerable source<Person> = TestData.GetPeople();
IEnumerable families<Family> = TestData.GetFamilies();
var answer = source.Join(families, p => p.Address, f => f.Address,
(p, f) => new FamilyMember { Name = p.Name, LastName = f.Name, Location = f.Address });
var result = source.Query<Person, Family, FamilyMember>
("SELECT Name, that.Name AS LastName, Address AS Location
FROM this INNER JOIN that ON this.Address = that.Address", families);
Assert.IsTrue(result.SequenceEqual(answer));
}This is cool because now I can start generating complex queries without having compile time knowledge of the underlying data structures. Once I get things fleshed out further I'll update things on CodeProject.
CodeProject
Monday, February 15, 2010
A new CodeProject article
I always like to use System.Diagnostics.Trace to report detailed status to the user. For the longest time I used a handy little WinForms control that inherited from TextBox to do that. Well now that I am hiking up the WPF learning curve I need a new version.
Said version is posted on Codeproject. Check it out if you need such a thing.
Said version is posted on Codeproject. Check it out if you need such a thing.
Sunday, February 7, 2010
C# Property class Part 2
Commenter tonyt (from CodeProject) rightly points out that there are drawbacks to this approach: A C# Property Class.
He's right. But I still want to explore this approach. What if we take the Property class and have it implement INotifyPropertyChanged?
Now we can create an class like so:
And then we can bind to that in XAML like so:
That should go a little way to addressing tonyt's point (mostly because WPF data binding is so robust).
CodeProject
Why:
Because there is a mountain of core functionalty in .NET that relies heavily on things like property access via reflection (like data binding) and via System.ComponentModel (e.g., TypeDescriptor), none of which support your take on implementing properties.
You can implement INotifyPropertyChanged on any class that offers a more efficient way to get notified about property changes, as it requires only one delegate for each listener, regardless of how many supported properties you have.
He's right. But I still want to explore this approach. What if we take the Property class and have it implement INotifyPropertyChanged?
public class Property<T> : INotifyPropertyChanged
{
protected T _value = default(T);
public Property()
{
}
public Property(T value)
{
_value = value;
}
public event EventHandler Changed;
public event PropertyChangedEventHandler PropertyChanged;
public virtual T Value
{
get { return _value; }
set
{
if ((value != null && !value.Equals(_value)) ||
(_value != null && !_value.Equals(value)))
{
_value = value;
OnChanged();
}
}
}
public override string ToString()
{
return object.ReferenceEquals(_value, null) ? string.Empty : _value.ToString();
}
protected virtual void OnChanged()
{
if (Changed != null)
Changed(this, EventArgs.Empty);
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("Value"));
}
public static implicit operator T(Property property)
{
if (property == null)
return default(T);
return property.Value;
}
} Now we can create an class like so:
class ViewModel
{
public ViewModel()
{
Status = new Property<string>("");
}
public Property<string> Status { get; private set; }
}Note the switch from a readonly field to a read-only property. WPF binding requires properties and does not work with fields.And then we can bind to that in XAML like so:
<TextBox Text="{Binding Path=Status.Value}"/>(assuming that the DataContext of the TextBox is a ViewModel like the one above.)That should go a little way to addressing tonyt's point (mostly because WPF data binding is so robust).
CodeProject
Thursday, February 4, 2010
Why does Bluetooth insist on sucking so badly?
Every couple of years since I had the grand vision of owning wireless stereo headphones (which I still do not have), I purchase some bluetooth gadget marginally more complicated than a cell phone earbud in order to see if the technology has ceased to suck. So last week I bought a mini Bluetooth wireless mouse to go along with my new Netbook (yum on the netbook BTW: buy one; buy one right now).
So I get it home, unpack it and first thing first download the bluetooth drivers. 77 megs. Yes that's right 77 megabytes of driver. Oi oh well. Push forward.
Awhile and a reboot later up it comes. No findy the bluetooth radio. WTF? Oh wait gotta hotkey that to turn it on. Boink up comes Bluetooth but down goes WIFI. WTF? Hotkey, Hotkey. Bluetooth On; Wifi Off. Bluetooth Off; Wifi Off; Bluetooth off; Wifi On.
See something missing in that sequence? (this we can blame I suppose on the maker of the netbook but I think that the general suckiness of bluetooth forced it upon them)
Oh well I think. I'll come back to that later. Let's see if I can get this thing to recognize the mouse. A few pushes to the sync button on the mouse and "Installing new HID hardware..."
"Yay!" I think "Success!" Until... "Your new hardware installed successfully. Please reboot to complete the installation" Uh-oh. So dutifully I reboot; up comes the bluetooth "Let's find some hardware dialog"; push push push; hotkey hotkey hotkey. Nothing. No mouse. Under no combination of pushing and hotkeying does my netbook believe that there is a wireless mouse a mere centimeter away; crying to be recognized.
So I take the whole thing; dump it back in the bag and return it for one of the 2.4 GHz wireless jobs with the nano transceiver thingy. Pop that puppy in and and up it comes; no software install; recognizes the mouse with no intervention from me. Boop; 30 seconds; mouse.
So bluetooth has been around how long now? And it still sucks this bad? This is what happens when a technology tries to be all things to all people. I'm sure the designers of blueooth saw/see it as the last wireless technology stack ever needed. By anyone. Anywhere.
In truth it's a darn fine wireless earbud solution for your cell phone. That's about it. Perhaps I'll check back in a couple of years. In the meantime, nano-transceiver... yum.
So I get it home, unpack it and first thing first download the bluetooth drivers. 77 megs. Yes that's right 77 megabytes of driver. Oi oh well. Push forward.
Awhile and a reboot later up it comes. No findy the bluetooth radio. WTF? Oh wait gotta hotkey that to turn it on. Boink up comes Bluetooth but down goes WIFI. WTF? Hotkey, Hotkey. Bluetooth On; Wifi Off. Bluetooth Off; Wifi Off; Bluetooth off; Wifi On.
See something missing in that sequence? (this we can blame I suppose on the maker of the netbook but I think that the general suckiness of bluetooth forced it upon them)
Oh well I think. I'll come back to that later. Let's see if I can get this thing to recognize the mouse. A few pushes to the sync button on the mouse and "Installing new HID hardware..."
"Yay!" I think "Success!" Until... "Your new hardware installed successfully. Please reboot to complete the installation" Uh-oh. So dutifully I reboot; up comes the bluetooth "Let's find some hardware dialog"; push push push; hotkey hotkey hotkey. Nothing. No mouse. Under no combination of pushing and hotkeying does my netbook believe that there is a wireless mouse a mere centimeter away; crying to be recognized.
So I take the whole thing; dump it back in the bag and return it for one of the 2.4 GHz wireless jobs with the nano transceiver thingy. Pop that puppy in and and up it comes; no software install; recognizes the mouse with no intervention from me. Boop; 30 seconds; mouse.
So bluetooth has been around how long now? And it still sucks this bad? This is what happens when a technology tries to be all things to all people. I'm sure the designers of blueooth saw/see it as the last wireless technology stack ever needed. By anyone. Anywhere.
In truth it's a darn fine wireless earbud solution for your cell phone. That's about it. Perhaps I'll check back in a couple of years. In the meantime, nano-transceiver... yum.
Saturday, January 30, 2010
A C# Property class
Soon after starting work in C# there were a couple of code patterns that arose that made me miss the good ol' C/C++ pre-processor. One of these is the basic pattern of a class property with change notification.
You've got a class and you want the state of its properties to be observable via events. How many time have you written the following bit of code in some for or other?
The introduction of .NET generics opens up the opportunity to model a class property as a class itself, while retaining type safety and the same assignment semantics as intrinsic types. So this little class (and a derived class with a cancellable event) has become a handy part of my toolbox.
So anyway, I've found this to be a handy helper class and thought perhaps you might as well.
PS: the cancellable derived class looks like this:
CodeProject
You've got a class and you want the state of its properties to be observable via events. How many time have you written the following bit of code in some for or other?
int _age; public event EventHandler AgeChanged; protected virtual void OnAgeChanged() { if(Changed != null) Changed(this, EventArgs.Empty); } public int Age { get{ return _age; } set { if(value != age) { value = age; OnAgeChanged(); } } }Automatic properties help when you don't need notification, INotifyPropertyChange abstracts that event a little. Still, a lot of boilerplate. Having written a fair amount of MFC in the years prior I really wanted to be able to do something like:
DECLARE_PROPERTY(Age, int)and have a fancy macro that would handle the boiler plate. Alas there is no macro pre-processor in C#-land.The introduction of .NET generics opens up the opportunity to model a class property as a class itself, while retaining type safety and the same assignment semantics as intrinsic types. So this little class (and a derived class with a cancellable event) has become a handy part of my toolbox.
public class Property<T>
{
protected T _value = default(T);
public Property()
{
}
public Property(T value)
{
_value = value;
}
public event EventHandler Changed;
public virtual T Value
{
get { return _value; }
set
{
if ((value != null && !value.Equals(_value)) ||
(_value != null && !_value.Equals(value)))
{
_value = value;
OnChanged();
}
}
}
protected virtual void OnChanged()
{
if (Changed != null)
Changed(this, EventArgs.Empty);
}
public static implicit operator T(Property property)
{
if (property == null)
return default(T);
return property.Value;
}
} using it is just a matter of declaring a public field on a class declaration.class Person
{
public readonly Property<int> Age = new Property<int>();
public readonly Property<string> Name = new Property<string>();
}Interacting with the properties looks a lot like an intrinsic: Person don = new Person();
don.Name.Value = "Don";
don.Age.Value = 41;
if (don.Age > 40)
Console.WriteLine("Ooooooold"); with the difference that every property now comes with a built in Changed eventdon.Age.Changed += new EventHandler(Age_Changed);So anyway, I've found this to be a handy helper class and thought perhaps you might as well.
PS: the cancellable derived class looks like this:
class CancellableProperty<T> : Property<T>
{
public CancellableProperty(T value)
: base(value)
{
}
public event CancelEventHandler Changing;
public override T Value
{
set
{
if ((value != null && !value.Equals(_value)) ||
(_value != null && !_value.Equals(value)))
{
CancelEventArgs args = new CancelEventArgs(false);
OnChanging(args);
if (args.Cancel == false)
{
_value = value;
OnChanged();
}
}
}
}
protected virtual void OnChanging(CancelEventArgs args)
{
if (Changing != null)
Changing(this, args);
}
}CodeProject
Subscribe to:
Posts (Atom)