Saturday, July 26, 2014

the perils of spare-time programming

So, it was only three days ago that I posted this, but already I'm having second thoughts and afterthoughts. These appear below as block quotes.

Frankly, I wasn't making much headway before, hardly managing to keep up with changes to Objective-C, and significant changes to the frameworks, like ARC, and to the developer tools.

Shortly after completing RatioKey 1.1, I became involved with the Robots Association, the organization behind Robots Podcast and Robohub.org. This involvement relates to another consuming interest of mine, which is detailed in my Cultibotics blog. As I began to feel I was making headway on that front, the amount of time I gave to it increased until it consumed nearly all of the spare time I could muster, at which point I burned out (not completely, but I had to dramatically reduce my level of involvement to keep it going). However, I couldn't just pick up where I'd left off with RatioKey, because the intervening time had left me unfamiliar with my own code, and only vaguely acquainted with the changes Apple has introduced, so I began the process of getting back up to speed.

Now there's a whole new language (Swift) to learn, and learn it I will, even if it means putting off everything else until I've done so.

(Hopefully not to the point of another burn out!) The introduction of Swift has helped to focus my attention. Since I don't have a large Objective-C code base, it doesn't make much sense for me to continue to work in that language, especially considering that the language has continued to change while I was looking the other way.

Even if, as I expect is the case, Swift can't yet be used with Core Audio, which is a C-based API, it will be otherwise applicable, and important for me to get an early start with it, rather than trying to put off the inevitable change.

Actually, I may be wrong about Swift not working with Core Audio. At the very least, I should be able to import a C header into Swift.

Besides, there's quite a bit to like about Swift. It's clear that a lot of thought has gone into its design, and it continues the trend, which began with the addition of declared properties to Objective-C, of reducing the amount of code needed to get something done.

Beyond that, from what I've seen so far, it strikes me as being closer to the metal, not of the machine, but of the essence of programming. I presume this is a result of it evolving out of compiler technology, rather than the compiler being created to fit the language. This impression gives me confidence that what I haven't yet seen will also make sense to me.

...out of compiler technology and modern programming concepts...

Understand that I wasn't one of those who was easy to convince regarding the need for a new language. I like both C and Objective-C. In particular I like being able to use numerical variables as logical values (zero being false and everything else being true), and, while I haven't used it much, pointer arithmetic strikes me as an elegant solution. Admittedly, it took me more time and fretting than it should have to wrap my mind around expressions like primativeValue** or &scratchpadMemory, but I did eventually catch on, and now I appreciate the precise control they allow. On the other hand, having to use malloc() to obtain scratchpadMemory is a pain.

It's actually worse than that, because you sometimes have to first ask for the size of the data to be received, then allocate a block of memory to hold that, then ask for the data itself, passing in a pointer to the memory block you've allocated, but that pattern typically applies to C APIs and likely isn't going away just yet.

But this is all moot. Apple wouldn't have introduced Swift with such fanfare if it weren't destined to be the future. There are already Swift versions of frameworks that worked with Objective-C, and lower-level frameworks, like Core Audio, are sure to be given the same treatment or replaced with updated versions that are Swift compatible, and that's a trend I don't care to buck.

Actually, "Swift versions of the frameworks" is probably imprecise. It's more like they've created a very fast translator, but I really don't understand how it works, only that it does and is fairly easy to use.

So, RatioKey 2.0, or whatever it ends up being called, if and when I get it done, and provided that it's accepted for distribution by Apple, will be a complete rewrite, using Swift, and probably targeted for iOS8, or, realistically, maybe even iOS9.

Emphasis on "if and when"...

Thank you for your patience!

Thursday, September 26, 2013

Ratio Key still runs on iOS 7

Having recently updated my third generation iPad to iOS 7, it was with some trepidation that I launched the legacy version (1.1) of RatioKey, which hasn't seen an update for three years, but remains on the app store (last I checked).

Eureka! It ran perfectly, perhaps even better than under iOS 6.1.

So I'll be retargeting the update I'm currently working on for iOS 7.

Friday, August 09, 2013

at work on an update

In the anticipation that RatioKey version 1.1 may no longer work on iOS 7, I've begun work on an update that doesn't make use of deprecated programming techniques. I can't promise to have this done before iOS 7 ships, but I am further along with it than with any past attempt since pushing 1.1 out the door.

This update, which I'm calling version 2.0, will also be free, assuming I get it done and Apple accepts it.

If it turns out that 1.1 does run on iOS 7, I'll probably retarget for that, which will add some time, but may also add functionality.

What's been the holdup? I've been distracted by another strong interest, robotics. For more about that, check out the links on my home page.

Sunday, July 15, 2012

intentions, constraints, & future possibilities

I do not intend to abandon this project, and do intend to produce further updates.

I'm happy to say that among the constraints that have held me back from doing so sooner is the abundance of options, more than I could possibly juggle for a single iteration. Another is embarrassment, over the initial version's lack of usability, and frustration over initially not knowing how to fix it.

The future offers even more options, as new and interesting ways of interacting with computers become available, such as The LEAP.

How much of what has already been bubbling on the back burner I may ever actually get done, much less the new possibilities that are opening up, I can't say. Not only do I not know myself, but even if I did that would be promising something I haven't yet delivered. I just want to say, in case there's anyone out there waiting for version 1.2, or 2.0, or whatever it might be called, I'm looking forward to it also!

Friday, October 01, 2010

RatioKey Version 1.1

Version 1.1 adds the ability to independently control the volume and duration of each stage of the ADSR envelope. Even though the tone produced remains a simple sine wave, with no undertones, overtones, or other elaboration, this provides quite a bit of range to the sound.

As before, start with http://itunes.apple.com/us/app/ratiokey/id387640139?mt=8, and then follow the link labeled "View In iTunes" to go to the app's page on the App Store.

Saturday, September 25, 2010

Thanks for the very helpful reviews!

After three weeks of silence, there are now two, very helpful reviews of RatioKey on the App Store.

My thanks to the authors, especially with regard to the suggestion to use a Diamond Marimba interface (see also tonality diamond). I wish I'd known about that six months ago!

I can't talk about plans for future versions, if any, but such suggestions are sure to find their way onto my todo list, or, if they're already there, increase their priority. I have a lot of ideas for RatioKey or related applications, which are waiting on time, focus, and clarity (a clear notion of the larger context, which is largely about data formats). Given clarity, I can find focus and make time. Of course, anything I come up with must pass muster with Apple's reviewers, so I can't promise anything until it's actually available for download.

Let me say that I welcome competition. I'd hate to think that the potential of the iPad (and touchscreen devices in general) to help liberate us all from the equal tempered scale depended on the spare-time application of my own modest programming skills. RatioKey as it currently exists is, as much as anything, a vector for getting the idea of specifying ratios by adjusting their prime power components out into the noosphere. I hope to see and hear that come back in the form of new apps written by others.

Meanwhile, I'll be struggling with that clarity issue and whittling away at my todo list.

Please note that there's a lag between the completion of a new version and its availability on the App Store, even assuming that it's approved promptly, once reviewed, so if a new version were to appear within the next few days, it wouldn't reflect what's been discussed here. That will have to wait for later.

Monday, September 06, 2010

how RatioKey works

This is reposted (with edits) from the Tuning mailing list...

The code is divided into the user interface and an audio engine. They communicate via C structures that are passed back and forth between them, with the main item of interest in these structures being a pitch. That pitch could be expressed in cycles per second (Hz), but I have instead chosen to express it in terms of a proportional unit, which plugs directly into the sound generation code without conversion. That proportional unit needs some explanation.

To avoid having to calculate sine values while the audio hardware waits for input, I have set up a table of precalculated sines, which holds values for one complete cycle (2pi radians). The size of this table is one of the components of the proportional unit mentioned above. The other is the sample rate, which is 44100 samples per second, the same as a CD.

((table indices)/cycle) / (samples/second) ~ (table indices)/sample

and that's the proportional unit, (table indices)/sample. Given this quantity, the audio engine progresses from one sample to the next by adding this value to the previous value (resetting whenever it reaches the size of the table) and then uses the result it to look up the sine, which is what's passed to the hardware.

The user interface is composed of buttons, labeled with ratios, and associated with these values that are proportional to pitch. If the "1/1" frequency is changed, then all of the others are also changed.

The selection of ratios is a bit complicated. I begin with a permutation of every combination of powers of 2, 3, 5, 7, and 11, permitting the powers of 2 to vary from 1/32 to 32, the powers of 3 from 1/27 to 27, the powers of 5 from 1/25 to 25, the powers of 7 from 1/7 to 7, and the powers of 11 from 1/11 to 11. Fractional powers, like 1/32 and 1/25, appear as integers in the denominator of a ratio. The numerator and denominator are the products of their prime power components.

I then discard all combinations resulting in a ratio with a value greater than 2 or smaller than 1/2. Further I discard any combinations where either the numerator or the denominator is larger than 32.

There is a third test which may seem a bit arbitrary, but which I decided to use to make sure that I was winnowing out the more complicated ratios. For this test, each prime number is multiplied by the absolute value of its power (1/32 and 32 both yield 5, 5 times 2 is 10), and then these products are added together. If the sum of these is greater than 21, I also discard that ratio.

What's left after passing through these tests is what you find on the keyboard, arranged in ascending order from bottom to top, 105 distinct tones over two octaves.

Setting "1/1" is also a bit complicated. I use an arbitrary base frequency (which defaults to 11 Hz) and a picker to select powers of 2, 3, 5, 7, and 11, with the same limits as before, to produce a ratio which is resolved into a single quotient, which is then multiplied by the base frequency to produce the "1/1" frequency. This allows transposition by simply fiddling the prime powers to generate a different quotient.

The interface arrangement is far from ideal. It has no structure other than higher tones being placed closer to the top, and it's difficult to play. I've put a great deal of thought into how to fix this, and have some ideas that I hope to put into practice, but for the moment it is what it is, and, having published the app in this form, the current keyboard will have to remain as an option in any future version. My apologies to any who see gaping holes in my reasoning.