Monday, August 24, 2009

CoreAudio and viewing default output

I have a great idea (or had one a long time ago) for Breakaway to use information about what is playing through the speakers to decide whether or not to unpause iTunes. My first leap was when I found the CoreAudio constant kAudioDevicePropertyDeviceIsRunningSomewhere. I've included code for how I did it, just because I had such a hard time working with CoreAudio.


AudioDeviceID defaultDevice;
UInt32 audioDeviceSize = sizeof defaultDevice;
AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice,&audioDeviceSize,&defaultDevice);

UInt32 runningSomewhere;
UInt32 uint32Size = sizeof runningSomewhere;
AudioDeviceGetProperty(defaultDevice,0,0,kAudioDevicePropertyDeviceIsRunningSomewhere,&uint32Size,&runningSomewhere);

Get the default output device, and check if it is running somewhere; simple enough. It's disheartening though, to find out that "is running somewhere" is not what you may think it to mean. The documentation says:

... [T]he device can be running even if there are no active IOProcs such as by calling AudioDeviceStart() and passing a NULL IOProc.
Unfortunately, lots of applications tend to do this. VLC and any Flash video through Safari come to mind, and I'm sure there are plenty of other examples. So the application grabs the audio and says it's playing, but it really isn't. It's like calling someone on the telephone, and never actually saying anything (or more appropriately, there is no microphone connected).

But good news; if get 0, you are guaranteed no audio to be playing. But if you get 1, well, you are pretty much in the dark.

So since there are no simple properties to look at, the next logical step would be to look ourselves at the device and see what data is flowing. There is a function called AudioDeviceRead(), and Apple has provided some documentation on how to use it, but I couldn't get it working. It referenced some old code that I wasn't able to find, as well as used some (presumably) dated constructs that I couldn't find much about. In the documentation, Apple states that the functionality of AudioDeviceRead() can be found in aggregate devices, so that function could be marked for depreciation in the future. To make a long story short, I tried virtually everything CoreAudio could offer me at face value; I just couldn't get it working. At first, I thought I was just missing the elephant in the room, but then I looked at other applications I know grab system audio.

The application called iShowU uses a virtual audio device called Soundflower. Apparently, the iShowU developers came to the same conclusion I did about CoreAudio, so they turned to this loopback type of device. So, I download that, and give it a shot. I had to set the Soundflower device as my default output, but I was still able to analyze the system sound! Unfortunately, Soundflower likes to blow up when you do something crazy, like pull out/put in the headphones (which, unfortunately, is what Breakaway basically does). In addition, you have to set the default output, which requires a wait for it to get configured, then switch it back afterwards (also associated with a wait). And you must remember that humans can easily pick up breaks in audio, and these .1 second breaks waiting for the audio devices to reconfigure are easily picked up. Soundflower works for it's intended audience, but it does not work in the critical environment I demand.

The next application is of many awards and praises: ScreenFlow. I have used ScreenFlow before and remembered how eloquently it handled audio. When I try to capture system output with that application, it says you must install a kernel extension for it to run correctly. A dive into the resources reveals this extension as VaraAudio.kext. The beauty of how ScreenFlow captures their audio is that it is (apparently) completely devoid of any CoreAudio hooks. Why? Because you can watch the default output, and it never changes. That and the fact that it's a kernel extension raises a flag that some serious low level work is going on. The perfect solution.

Gaining complete system audio output and bypass CoreAudio? It's so pure, like a fountain of data ready to be captured, without having to go through all the pipes and values of CoreAudio. I tried to interface with this kext, look at its properties, but I couldn't figure out what the magic code was to communicate with it. In hope, I emailed the actual developers of ScreenFlow asking for help. A few days later, they said that the code was proprietary, and could not help me; I was stunned that they actually replied to me. Not one, but two emails: one to say that my email was being forwarded to the developer team, and another with their response. Most of the time, requests like this are thrown away at first glance and the sender is shown the door by a canned response. Though, it was only a fool's hope, my pursuit for this code. I expected them to not reveal it, because if they gave me the code, anyone could use it (most notably competing screencast developers). But a sliver of chance is worth taking. I also figured since the audio in the demo is unstamped (unlike the video, which is watermarked), they are giving out their audio recording capability "for free", as it is easy to rip the audio from a video into your encoding of choice. But unfortunately, their code is, understandably, too critical to be handed out.

So what does that mean for the future of Breakaway? Well, I don't see my glorious idea ever coming into play. Patching Soundflower or developing my own .kext would prove to be very difficult and time consuming. It sounds like a very fun challenge, but I think that my time could be spend better elsewhere, implementing different features and making better applications.

Unless, that is, you, the Reader, have any suggestions?

Wednesday, August 5, 2009

NerdTool, check. Breakaway, ?

Now that NerdTool is picking up momentum, I figured I better go have a look at Breakaway, as there were a few more features I wanted to add in. And wow, was I shocked at what it looks like. My C callback function is roughly 200 lines of code, and I'm starting to remember what a pain Core Audio was to work with. I guess thats why my code is not clean and orderly, cause its hacked and taped together to get the thing to work. My plugin design isn't the best in the world either, but hey, it was my first go at plugins. I will probably pull programming mantra #1, which is, "if it ain't broke, don't fix it". I will try to get my head around AudioHardware, AudioStreams, AudioDevices, or whatever it is that tells me if sound is going to prevent mishaps. Say you are listining to some music, then you mute (pausing it). You come back later, start to watch a video, realize the mute is off, and your music and movie are going at the same time. A minor inconvience, yes, but it is worth putting the logic in to prevent. Plus, you could use it as a crude way to stop your music by double tapping mute, if you were starting a game or something and your hotkey applications would not function.

Wednesday, July 22, 2009

NerdTool foreshadowing

Just would like to let you know that NerdTool, a GeekTool like program (but not GeekTool 3) is about to be released very soon!

Right now, I would say it is very capable with features focusing on the setup portion of using GeekTool. Many of the UI bugs have been eradicated and new, powerful features have been added for your pleasure, such as multi-log editing and window snapping. That isn't to say NerdTool is just GeekTool with a new name. Exciting features like a Quartz view and colored text (ANSI escaped) are just a few of the new features available at this beta release.

NT does not have all the features I plan on putting in it, but I feel that it would be good for the public to get a taste. Plus with the automatic updating, releases can be more frequent to keep the app as sharp and fresh as possible.

Finally, I also suggest checking out Yann's (the original developer) version of GeekTool. A while after I started writing my "GeekTool 3", Yann picks up the project after many years of dormancy, and starts coding himself a version of "GeekTool 3". So my "GeekTool 3" was renamed to "NerdTool" for name clashing prevention and developer respect. At time of writing, GT3 is very nice and easy to use. NT sticks with the more tradional GT layout with some power editing tweaks thrown in. Try both and see which you like better! They can both be running simultaneously, so there is no need for choosing sides...yet :)

Friday, March 6, 2009

Crossover, Bootcamp, and Steam

My latest endeavor has been trying to get CodeWeaver's Crossover to work well with Apple's Bootcamp. Unfortunately, it has been elusively difficult.

The Situation

The situation is like this: I have my (Windows) games stored on an external hard drive (namely Steam) to be accessed on my Bootcamp partition (for space reasons). This works fine; I boot into Windows, play my games from my external hard drive, and life is good. But booting into Windows every time I want to play a game is a little annoying. It would be nice if I could scarface a little quality to be able to play my games directly from OS X.

A little while ago I got Crossover through some promotional deal. Crossover is supposed to be a good solution to playing games from OS X, so I decided to put it to the test.

I want to try and access my external hard drive games in OS X via Crossover. Simple enough, eh? Well, not so much. I have tried for quite some time, and it's just not working. Maybe it's Steam, maybe it's Crossover, or maybe it's just a little of both; I don't really know.

Inductive Reasoning

Easy Does It

The first thing I tried to do was the most obvious one: simply run Steam from the external hard drive. Unsurprisingly, Steam complained about something and wouldn't work. I was expecting something like this, as Windows has some registry files it likes to play around with. These being on the OS itself, my Wine "bottle" did not have these.

Simple Installation

So, what seems like the next most obvious step? Well, install Steam in Crossover and see if it will work there! So, I did just that. I installed Steam through Crossover and then tried to run again from the external hard drive. Again, nothing but errors happened.

More Complex Installation

Now I'm starting to think that these registry files have something about file system paths in them. When you install something in Windows, they ask you a path of where you want to install it. If this location were to change without the application knowing, this could spell failure for the application. Of course, this depends on how the application functions. I guessed Steam would have this sort of pain in the ass "you can't move our executable" stuff, so I went ahead and tried to trick it.

I'm thinking, "Well, I installed Steam (in Bootcamp) to F:\games\. If I installed it there on Crossover, maybe the paths registries (if there are any) will line up and everything will be golden". I made myself a new bottle, told Crossover there was an F:\ drive, and then proceeded to install Steam on this "F:\ drive". It is important to note that Crossover treats all it's "drives" as merely mount points (or at least thats how I see it). So my C:\ drive is actually a directory called "drive_c", and my F:\ drive is a directory called "drive_f" somewhere on my hard drive. Continuing on, I then tried again to launch the executable from the external hard drive, and it still didn't work. Sadness.

False Hopes

While I was going through Crossover's preferences, I found one that lit up my heart. When you create drives, you can specify where it's "mount point" is (obviously). But what I found out is that you can assign this "mount point" to be anything you desire! This means that I can assign my real, external hard drive directly to my virtual F:\ drive; none of this external folder stuff. So after installing Steam on my fake (local) F:\ drive, I simply redirected the way Crossover sees the F:\ drive: instead of looking at the "drive_f" directory, it now looks at my real, external hard drive. This seemed like the ultimate solution. Crossover and Steam are now both unaware of my attacks; victory is assured...or not.

Turns out that didn't work either. Seeing my perfect plan fail like that showed me that I working on the wrong problem the entire time. The location and interpretation of the executable is not the problem, rather, the actual problem is accessing the external hard drive. It may seem weird, but it's probably the truth. Looking at the previous results makes everything make sense. Further, I have tried other approaches that supports this claim.

Epiphany

I discovered that Steam would only run locally, so I decided to link in the actual game files into the directory. This kind of worked, but Steam gave some sort of message about not being able to write to some file. I tried various methods of linking, but they all turned out in the same way; failure.

Afterward

So what is there to gain from all of this and what do I plan to do about it? Well, I believe since my external hard drive is formatted in NTFS is why I'm getting all of these problems. If it were in something more friendly, like FAT, it might actually work. I encourage one of you to try and see if that works, as I am curious to see if it will. I have read a few posts about Wine and Linux talking about how they just linked the SteamApps folder in and it worked flawlessly. Maybe that would work for me as well if my system had better support for NTFS file manipulation

Friday, February 6, 2009

Vimperator: Mapping Command Key

Vimperator is a neat little addon I found for Firefox. I normally don't use Firefox, but thought it would be nice to break from Safari to see what else can be offered. I really miss the Cocoa feel, but having full keyboard access is really nice as well.

Of course, being a vi user myself, one of the first things I did after scouring the help files was get some customization going on. Naturally, I couldn't get vimperator to cooperate with my wishes, so I had to do some trial and error.

All I really wanted was to have a keypress to use the location bar instead of the little status bar at the bottom. The status bar is sleek, but the location bar has all that autocomplete stuff that I wanted to take some advantage of. Everyone knows you access the location bar with Command + L, but unfortunately, vimperator never gave me details on how to map to the command key.

MacVim uses D, but that didn't work. Turns out, the magic key is M. Heres an example of what I wanted to do, along with a few of my other customizations I find useful

"Make hints a bit easier to turn on.
map c f
map C F

"Make control-c act like escape
map <C-c> <ESC>
imap <c-c> <esc>

" have vimperator take advantage of FF3's features more
map o <M-l>
map t <M-t>

" easy way to search with vimperator (which was impossible without combining the location bar and the search bar)
map e <M-l><tab>

" Address bar etc
" As much as I like the minimalist approach, there are some things that won't change...
set guioptions+=mTb

" we don't like beeps
se vb
" separation of URL and search
se ds=

"just so you know when this file is sucessfully run
echoe "rc file sourced"

All in all, vimperator is really nice, and I feel comfortable being able to navigate with the keyboard only, especially with the jk keys. There are some sites it can't handle, and you can't interface with Java, of course, but other than that, actually selecting links is very intuitive and fast.

Monday, January 5, 2009

Partitioning Problems

About 2 years ago, I tried to install linux on my computer (Macbook Pro). The way Mac works, it's a little complex to get this to work properly, especially the partitions (in my case). I didn't want to partition my boot HD again because of space and personal reasons (which I tried to do anyway despite my reasons, and as such, almost lost all my data, but that's another story), so I tried on an external HD, which happened to be my 1 TB backup HD. Needless to say, I screwed up bad somehow, leaving me linuxless and with broken partition tables. Disk Utility hated the partitioning, since it was in a format that it didn't recognize (among other things). But I have returned, armed with tools and knowledge to try and fix this beast.

Gparted is an excellent tool for pulling yourself out of any hole you may find yourself in. If you need something partitioned, gparted will do it for you correctly. Better yet, you can put it on a live CD and boot straight into it, making internal drive repairs relatively easy. Unfortunately, it could not make the partitions fine enough to Disk Utility's liking.

But a while ago, I found TestDisk. I was a little skeptical at first, but I went ahead and tried it anyway. So I launched it, analyzed the disk, and rewrote the table. It was that easy! At first, it found only 2 partitions, but after a quick search, it found my 2 partitions along with the EFI partition table at the front of the disk. After that, Disk Utility liked the way it was seeing things, displaying the partitions in a proper.

In gparted, I went ahead and partitioned some empty space at the end of my drive (something DU wouldn't do) with HFS+ (but non-journaled, as the option does not exist). After the TD repair, DU was able to see both partitions and able to delete the one gparted made.

But all stories can't end happily ever after. I tried to partition this drive twice, and both ended sadly. It was a simple procedure, shrink my original partition, and put in an 80 gig. Both took about an hour (drive half full). One, I woke up to find my machine unresponsive in a deep sleep. Had to force restart and Mac told me something bad happened when I rebooted. Everything was fine, my data was still there, but my drive was still unpartitioned.

I tried to partition a second time, this time with slightly different settings. I opted to sit and watch the thing run it's course, since I like to watch grass grow. And again, somewhere around the hour mark, something happened. This was a bit more interesting than waking up to a broken computer, because I got to see the fireworks first hand. Turns out the darn think breaks into a kernel panic, which is resolvable only through a forced restart. Fortunately though, everything was the way it was before the crash, even the partitioning.

So I'm just about done with this mess. There are a few other things I can try, but they would probably be in vain. Plus, partitioning all these times is going to leave me with a heart attack once my data is gone (since I'm partitioning my backup drive). The true way to fix something like this is to transfer your data temporarily to something and then nuke the drive from orbit. Eradicate everything on it and rebuild some firm partitions. Unfortunately, I don't have 500 gigs of contiguous space, and my need for the partition was not all that important anyway.

Some other things I forgot to mention I did was do multiple repairs with Disk Utility. Not that it helped with anything, but it was something I did.

Sunday, December 14, 2008

Compiling slash'em in OS X

Downloads:
binary
src

This has been about the upteenth time I've done this, and I have to reremember how to do it every time, so now I'm making a note of it:

How to compile Slash'em:

  • navigate to sys/unix
  • `sh setup.sh`
  • win/tty/termcap.c
    • add && !defined(OSX) on tparm ifdefs line
  • src/Makefile
    • use -ltermcap
  • includes/config.h
    • use gzip compression isntead of compress
    • make sure you change the path to whatever `which gzip` gives you
    • change the wizard name to your name

If you understand the above, you should find it helpful. If you are entirely lost and have no clue what I'm talking about, chances are you shouldn't be trying to compile slashem yourself. I'll post a binary for download if you guys want it. I currently just have the statuscolors on, but it's kind of buggy when you start getting lots of statuses (like HP disappears).