Blog

Tag Archives: Cocoa

A drop-in universal solution for moving text fields out of the way of the keyboard

There are a hundred and one proposed solutions out there for how to move UITextField and UITextView out of the way of the keyboard during editing — usually, it comes down to observing UIKeyboardWillShowNotification and UIKeyboardWillHideNotification, or implementing UITextFieldDelegate delegate methods, and adjusting the frame of the superview, or using UITableView‘s scrollToRowAtIndexPath:atScrollPosition:animated:, but all the proposed solutions I’ve found tend to be quite DIY, and have to be implemented for each view controller that needs it.

I thought I’d put together a relatively universal, drop-in solution: UIScrollView and UITableView subclasses that handle everything.

When the keyboard is about to appear, the subclass will find the subview that’s about to be edited, and adjust its frame and content offset to make sure that view is visible, with an animation to match the keyboard pop-up. When the keyboard disappears, it restores its prior size.

It should work with basically any setup, either a UITableView-based interface, or one consisting of views placed manually.

Read More »

Also tagged , , | Comments closed

Easy AAC compressed audio conversion on iOS

From the iPhone 3Gs up, it’s possible to encode compressed AAC audio from PCM audio data. That means great things for apps that deal with audio sharing and transmission, as the audio can be sent in compressed form, rather than sending huge PCM audio files over the network.

Apple’s produced some sample code (iPhoneExtAudioFileConvertTest), which demonstrates how it’s done, but their implementation isn’t particularly easy to use in existing projects, as it requires some wrapping to make it play nice.

For my upcoming looper app Loopy, I’ve put together a simple Objective-C class that performs the conversion of any audio file to an AAC-encoded m4a, asynchronously with a delegate, or converts any audio provided by a data source class (which provides for recording straight to AAC) and I thought I’d share it. Read More »

Also tagged , , | Comments closed

A simple, fast circular buffer implementation for audio processing

Circular buffers are pretty much what they sound like – arrays that wrap around. They’re fantastically useful as scratch space for audio processing, and generally passing audio around efficiently.

They’re designed for FIFO (first-in-first-out) use, like storing audio coming in the microphone for later playback or processing.

Consider a naive alternative: You copy the incoming audio into an NSData you allocate, and then pass that NSData off. This means you’re allocating memory each time, and deallocating the memory later once you’re done processing. That allocation incurs a penalty, which can be a show-stopper when part of an audio pipeline – The Core Audio documentation advises against any allocations when within a render callback, for example.

Alternatively, you can allocate space in advance, and write to that, but that has problems too: Either you have a synchronisation nightmare, or you spend lots of time moving bytes around so that the unprocessed audio is always at the beginning of the array.

A better solution is to use a circular buffer, where data goes in at the head, and is read from the tail. When you produce data at the head, the head moves up the array, and wraps around at the end. When you consume at the tail, the tail moves up too, so the tail chases the head around the circle.

Here’s a simple C implementation I recently put together for my app Loopy: TPCircularBuffer Read More »

Also tagged , , , | Comments closed

Objective-C + Cocoa on the Command Line

Sometimes there’s just one tiny snippet of Cocoa code that you want to test — maybe to find out the output of NSDateFormatter for various cases, testing out some text replacement routine, or testing out some image drawing code.

It’s often too much trouble to create a new XCode project and set up the framework to do one simple test, which is why I put together this little shell script that lets you run Cocoa code from the command line:

$ runcocoa 'NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease]; [formatter setDateFormat:@"d MMM, h:mm a"]; NSLog(@"%@", [formatter stringFromDate:[NSDate date]]);'

2011-02-23 20:02:10.313 runcocoa-output[28025:903] 23 Feb, 8:02 PM

You have full access to all Cocoa libraries, and in iOS mode, access to most iOS stuff too, straight from the command line.

Update: This is now available as a GitHub project Read More »

Also tagged , | Comments closed

Oh, Cocoa: Why I love my job

XCode as a beatnik (You heard me) There are some with a passion for paint and canvas; others, for playing musical instruments, or writing stories. For me, as I’ve discovered, it’s striving to create beautiful and functional user interfaces, or constructing in code the perfect representation of a workflow. It’s creating a piece of software that works like an extension of yourself, with the charm and elegance that makes you want to pick it up, and not put it down again.

Developing software for me is an expression of my creativity, and an outlet for my compulsion to find order in the world — not to put things in boxes, but to shape the boxes around the things.

And if ever there’s an apt medium: If French is the language of love, Cocoa is the software development environment of it, too.

Also tagged , | Comments closed

Resuming ADC downloads (‘cos Safari sucks)

So, Safari’s resume facility is just awful — it’ll randomly restart downloads from the beginning, clobbering anything that’s already been downloaded, and the resume button will frequently disappear entirely and mysteriously from the downloads window. And if the session has expired, it’ll cause all kinds of havoc.

Anyone downloading the gazillion-gb iOS/Mac SDK + XCode on a slow and/or expensive connection will know the sheer fisticuffs-inspiring irritation this creates — speaking personally, living on a mobile broadband connection that’s usually changed at £3 per gig and often runs about as fast as I could send the data via carrier pigeon, this usually makes me want to storm Cupertino with a pitchfork.

Okay, so I could probably use Firefox or something else, but instead I figured I’d whip up* a shell script that lets me use my favoured long-haul download tool – curl. And in case there were any other sufferers of insanely-priced broadband and Safari’s antisocial behaviour, I thought I’d share it.

It’ll ask for your Apple ID and password, and store it in the keychain for you, and it’ll resume from the current working directory.

Chuck it somewhere like /usr/local/bin, make sure it’s executable (chmod +x /usr/local/bin/adc_download.sh) and call it from Terminal like:

adc_download.sh https://developer.apple.com/devcenter/download.action?path=/Developer_Tools/xcode_4_gm_seed/xcode_4_gm_seed_.dmg

If you’ve already started the download in Safari, just grab the partially-downloaded file from within the .download package Safari creates.

Here ’tis:

ADC Download Script (on Github)

P.S. I’d be interested to see how incremental updates fare when transferred from an intermediate server with rsync. It’s rather bizarre that Apple reissue the whole 3.x gb SDK with each update, rather than offering a ‘patch’ (I guess Apple lives blithely in the world of cheap bandwidth!), and it makes me wonder whether there’d be sufficient correlation between versions to save some bandwidth by avoiding transferring the similarities…

* read: spend hours on, as is my way.

Also tagged , | Comments closed

A quick-and-dirty audio sample mixing technique to avoid clipping

In the real world, when you hear two sounds at once, what you’re hearing is the combination (in the “+” sense) of the two noises. If you put five hundred drummers in the same room and, avoiding the obvious drummer jokes for now, told them all to play, you’d get drummer 1 + drummer 2 + … + drummer 500 (also bleeding ears).

With digital audio though, the volume doesn’t go up to oh-god-please-make-them-stop – it’s limited to a small dynamic range.

Naïve mixing, with overflow

So, digital mixing actually requires a little thought in order to avoid overflowing these bounds and clipping. I recently came across this when writing some mixing routines for my upcoming app Loopy 2, and found a very useful discussion on mixing digital audio by software developer and author Viktor Toth.

The basic concept is to mix in such a way that we stay within the dynamic range of the target audio format, while representing the dynamics of the mixed signals as faithfully as possible. Read More »

Also tagged , | Comments closed

Pushing MultiChannelMixer to the limit

A friend made an interesting suggestion to an issue I’m facing in the upcoming Loopy 2, and I thought I’d do some investigation: How many tracks can the MultiChannelMixer (kAudioUnitSubType_MultiChannelMixer) manage at once?

He was quite optimistic, and as it turns out, he was right: It’s rather capable.

I modified the iPhoneMultichannelMixerTest sample project to add a bunch of channels, and measured how my iPhone 4 performed. It looks pretty linear: there’s pretty much a 1:1 relationship between number of channels, and the CPU usage, actually.

Number of Inputs to MultiChannelMixer versus CPU usage

Of course, this is on the newest-most powerful iPhone, but there was no stuttering, and the interface (admittedly simple as it is) was fully responsive, including setting output volume, even with 100 channels. You’d probably want to stick with a maximum number of channels around the 75-100 mark, less for targeting lesser devices, but that’s a pretty generous limit.

Not bad.

Update: Not such great news for the iPhone 3G I just tested this on, though — it freaks at anything more than 20 channels, and isn’t too responsive with 20. The 3Gs seems to behave almost as well as the iPhone 4, but the CPU:channels relationship is more like 2:1.

Also tagged , | Comments closed