Rss

Archives for : c

Haste-All

iPhone book has gone to an internal review which, should it be accepted, gets us to a beta book soon. Really soon. There are many chapters from the three authors in various states of completion. As things split, three of my initial four were ready for inclusion, so of the 102 pages in this early build, I wrote 50 of them. Which is damned strange considering that early on, I was the silent and unproductive member of the team (during and immediately after one of our house-shopping trips up to Grand Rapids).

File I/O, Preferences, and SQLite are in the can, Network’s getting there (though I’ve bogged for two days on various crashes I created after having to switch an in-memory cache from Cocoa’s NSDictionary to Core Foundation’s CFDictionaryRef… figured out Tuesday’s, now I’m on to one a few functions later). Apple rejected a feature request I sent in regarding the techniques of determining your network interface, but did so with interesting comments, so that’ll make a good topic to wrap the network chapter with.

Media’s after that, and that’ll probably be a couple weeks of heads-down coding to finally make Audio Toolbox happy (for a change) and OpenAL. And after that, I’d have five of 17 chapters done and presumably be able to see the finish line. Not a bad crunch overall… and the project’s velocity has definitely been kicked into high gear with the addition of Bill Dudney, whose enthusiasm and productivity are inspiring.

Don’t know if they’ll put out a sample chapter, but I’d nominate the SQLite one, actually. Apple’s docs basically say “you have a database, here’s its home page, go nuts,” so the stuff I wrote couldn’t help but be new and novel and tell you stuff that isn’t in Apple’s docs.

No official announcement of the book yet, but there was a sly reference in the latest newsletter (though one could interpret that as a reference to the iPhone material in Bill’s Core Animation book. Of course, we know better…

Four chapters for the price of one

It’s crunch time for the book’s beta, which is where I’ve been spending a lot of my time. Curiously, one of my chapters has grown from an omnibus overview of I/O, to separate file and network chapters, and may now end up as four chapters, covering the file APIs, preferences, the SQLite3 database, and networking.

The latter is giving me a little pain today. My example for handling HTTP authentication wouldn’t be able to re-use the same authentication throughout multiple pages of a password-protected realm, and as I’ve fixed it (unwittingly evolving closer and closer to one of Apple’s sample apps, ImageClient 5, I’ve had to use more and more Core Foundation stuff instead of Cocoa. I’ve spent the afternoon baffled by a CF dictionary that seems to be losing the values I put into it. Surely that’s not really what’s going on, but right now I really don’t know what I’m looking at, and the debugger is surprisingly unhelpful on this one.

I solved a heck of a problem with IB and table view cells last week. I am so blogging that once the NDA lifts.

Someone care to explain pointer arithmetic to me again?

So, one of the weird things I’m getting used to in the C-based frameworks (Core Audio, CFNetwork) is a pattern for holding “state data” together across a number of calls to related functions. Coming from 10+ years of OO, it seems unwieldy, but it does afford a certain freedom.

What these functions often have as their first parameter is a pointer to a user-defined structure that can have more or less whatever you want to put in it. The idea is that it needs to contain everything you’re going to need to go into or come out of any of a series of related function calls. For example, if you’re going to read bytes from a file and play them in an audio stream, your structure will have pointers to the AudioQueueRef, the AudioFileID, some ints for the buffer size and number of packets you read on your last call, etc. Each call may use only one or two of these, but you bundle them in one big typedef, and that block of data is passed to and from all the related calls.

So, my current challenge is converting the example in the Audio Queue Services Programming Guide from one that plays bytes from a file to one that gets them from a network stream. What’s hanging me up — and will probably become an ADC support request in the next few days — is that the callback-oriented nature of these APIs requires me to buffer some packets extracted from the stream, and hang on to them until I get a callback from the queue telling me it’s ready for me to fill one of its audio buffers with packets. Typically, I get multiple “you have packets” callbacks for each “fill AQ buffers” callback, which is a complexity that the example doesn’t need to deal with, as it can read exactly the amount of data it needs from the file on demand.

Thus, my attempt to hold onto the packets from the callbacks is where the pointer math comes in. Start with my state structure:

typedef struct  { 
	AudioStreamBasicDescription mDataFormat; 
	AudioQueueRef mQueue;
// ...
	void* myAudioData;	// from last handle packets callback
	UInt32 myAudioDataByteSize; // from last handle packets callback
} AQPlayerState; 

Notice the last two here: I have a big-ass buffer of data that I malloc at some point, and a size counter. The counter is effectively an offset: if I get another callback with more data, I need to copy the new data into the buffer at an offset of myAudioDataByteSize, and then update the offset, of course.

Now, since Dr. Gosling has kept me away from pointers for a good 12 years now, I’m not sure how I cajole the C syntax to express the concept of “the address pointed to by taking the address of myAudioData and adding myAudioDataByteSize bytes”. Currently I’m trying to do something like:

memcpy (&pAqData->myAudioData + pAqData->myAudioDataByteSize,
          (void*) inInputData,
          inNumberBytes);

And given that I’m segfaulting somewhere… probably here… I assume that the first argument is pointing to nonsense.

So, C-friendly people, assuming for a second that this approach is even valid (it may well not be), what’s the syntax for saying “take address A, add B, and treat the result as an address”?