Converting MIDI Pulses Per Quarter (PPQ) to Samples

I recently wrapped up an audio project for OS X based on JUCE (a cross platform C++ library for applications with an emphasis on audio) and using Propellerhead's ReWire protocol to allow the application to feed audio with very low latency to another audio app (e.g., Logic Pro).

The ReWire protocol defines a host, a device and a GUI (or "panel") that controls the device. The ReWire ecosystem is divided up that way so a ReWire device can be run inside a host (in the host's address space) in a similar way to how Audio Units or VSTs run as "plugins" in a host application. In order to control the device, a GUI or panel communicates with it via inter-process communication. (For standard plugins, this GUI would be directly managed by the host application.)

ReWire speaks both MIDI and audio data. It also communicates transport position and control commands (play, stop, etc) in both directions, allowing the transports of two applications to run in sync. For transport position, it uses MIDI PPQ (also called ticks or just PPQ) to give an offset. If you're building an audio data only application, as I was in this case, your ReWire device will probably ignore the MIDI side of ReWire and therefore will have no reference to utilize PPQ with. That means you'll need to convert a PPQ offset to a sample offset.

Even if you're ignoring the MIDI side of ReWire, the host will still announce all of the information you need to determine the current sample offset of the transport.

A few definitions first:

  • PPQ (pulses per quarter note) is expressed as its smallest subdivision, so PPQ 96 means a maximum resolution of 1/96th of a quarter note. ReWire uses PPQ 15360.
  • BPM (beats per minute) as our tempo. In this case we can assume each beat is a quarter note. The actual value ReWire supplies is BPM * 1000.
  • Sample rate is the number of samples per second (per channel) of our audio. In this case we need to use the sample rate as announced by the host, not by any of the audio files we're playing back (though we need to convert the sample rate of each audio file to that of the host for playback, so they'll end up being equivalent).

To convert PPQ to samples, we'll first convert our PPQ offset to milliseconds. The formula for that is milliseconds = milliseconds per minute / (BPM * PPQ) or in this case 60000 / ((120000 / 1000) * 15360) or 0.03255208333 ms per tick for a tempo of 120 BPM. Our offset in milliseconds is then PPQ offset * milliseconds per tick. To convert that value to a sample offset, we multiply by our sample rate (divided by 1000) or sample offset = (PPQ offset * milliseconds per tick) * (sample rate / 1000).

Putting it all together, if we have a tempo of 120 BPM, a sample rate of 44100, a PPQ value of 15360 and a PPQ offset of 1 million, we'll end up with ((60000 / ((120000 / 1000) * 15360)) * 1000000) * (44100 / 1000) or approximately 1435546 samples.

Since our PPQ value won't change (it's always 15360 for ReWire) we can simplify this quite a bit. Here is a simplified version in function form (as well as the complementary conversion from samples to PPQ):

First Five (and a Half) Minutes on a Server with Ansible

This is a response/addendum to two really good "first five minutes" style posts discussing the setting up and basic hardening of a remote server. Brian Kennedy discusses his first five minutes here1 on Ubuntu. It's a great tutorial covering the basics of security. Of course, if you've gone through it once you'll want to automate it. There is also a post on automating the process2 (actually using the steps described in Brian's post) with Ansible. The latter was either not tested or only worked on earlier version of Ubuntu/Ansible. I'll cover an updated version here that works with the most recent version of Ansible and Ubuntu 13.04 x64 and includes some helpful additions. 

So, starting from a virgin install of Ubuntu server we're going to want to perform the following steps:

  1. Update & upgrade the system via apt-get
  2. Install vim & mosh (personal preferences)
  3. Install fail2ban to block ssh brute-force attempts
  4. Reset our root password to something strong
  5. Create a new user so we don't have to use root
  6. Copy over our pub key
  7. Lock down sudo
  8. Lock down ssh to prevent root & password login
  9. Setup the ufw firewall
  10. Configure unattended security upgrades
  11. Configure logwatch to email daily server logs

Even if you can do all of that in five minutes, this is obviously complicated enough that we want an automation tool to handle it. After reviewing popular automation tools like Chef and Puppet, I decided to go with the slightly lesser known and arguably simpler Ansible. Ansible is simpler because it doesn't require any server side installs to work. All Ansible commands are run via ssh from your computer and only need a password or private key to run. Ansible commands are organized in "playbooks" and Ansible has a extensive set of modules that simplify common tasks.

Read more »

Building a Fast Web App in 2013

I recently decided to put some other projects aside and build a web app/service that's sort of a "scratch my own itch project". My aspirations for it go beyond a personal project, however, so I wanted to build it in a way it could handle a lot of users without too much maintenance and resources. 

So what language/framework to choose? PHP is still the most popular web language (according to a recent analysis1 of jobs posted on Twitter) but, well, it's PHP. Rails (and to a lesser extent Django) is very popular, though it's a "kitchen sink" framework and doesn't have the best reputation for performance. Node.js is interesting, not because I care that much about using one language for the server and the client (especially if that language is JavaScript), but because it's supposed to be fast. 

Since i started playing around with Haskell recently I also took a look at the most popular web frameworks: Yesod, Happstack and Snap. Not only are there three somewhat mature web frameworks (with documentation that ranges from ok to pretty good) there's some evidence that Haskell web apps can be fast, maybe even really fast2. Despite the promising start, I ended up dropping Haskell.

Read more »

LJSelectionView Now Available on GitHub

I recently pushed LJSelectionView to GitHub. The project makes it easy to manage an NSView with a collection of subviews and their selection -- either by mouse clicks or "drag to select" actions. Selection rectangles, highlighting and selection management is something I've had to write more than once for Cocoa apps so I decided to write a standalone version to share.

I've set this up as a controller with several NSView subclasses. The controller is responsible for managing selection (and undo/redo) and the views are fairly dumb affairs that mostly just draw themselves (just how it should be). The exception is the main LJSelectionView that also understands the difference between selection, highlighting and your "content" views and has methods for managing them.

The two other views, LJSelectionItemView and LJSelectionRectView are configurable (up to a point) for line color, line width, fill, etc to change what the selection and highlighting rectangles (the stuff drawn around selected views)  look like. If you want to go crazy with their appearance they're easy enough to modify or subclass.

For the ARC-shy (not that there aren't good reasons to avoid ARC at this point) all files will support ARC or non-ARC project automatically. It cluttered up the code a bit but I thought it was better than supporting one vs the other.

The selection behavior is the same as Adobe Illustrator: If you hold the shift key while clicking or dragging, you toggle whatever is being selected against the current selection. If you're not holding the shift key, whatever is selected always replaces the current selection. As it is now, views aren't selected until after the selection operation is completed. It shouldn't be that hard to change it to support "live" selection but again I'm following Illustrator here.

To use, just copy the four main classes and their headers (what's in the root of the GitHub repo) to your project. You'll also want to setup the view hierarchy in IB and make sure the correct outlets are connected. It is possible to setup the view hierarchy without IB you just have to make sure the right connections are made. You can look at the demo project to see how it's setup. The tests aren't automated in any way but you can run them in Xcode with ⌘-U as normal.

The whole thing is MIT licensed so do with it what you will.

My First Algorithm in Haskell - Steps 2-5

This is a continuation of a series of posts starting here and following this. These three posts were front loaded since most of the work (and interesting explanations) were in the foundational work for the algorithm, with the actual steps (the steps as described in the original paper) being mostly data and application of the functions we wrote in part one.

Read more »

My First Algorithm in Haskell - Step 1

This is a continuation of a series of posts starting here. I've been implementing Porter's stemming algorithm in Haskell in order to learn Haskell. I normally wouldn't learn a language this way, but as I stated in the last post I haven't yet been able to find an excuse to build something else in the language.

This algorithm is broken down into 5 steps which process a word in order. I'll describe how I tackled step one in a moment. Before I do, I'll go over some of the foundational parts of the algorithm that we need in place before we go through the steps.

Read more »

My First Algorithm in Haskell

I recently started learning Haskell. Like many programmers who get interested in the language I've spent as much time studying the language as I have trying to find an excuse to actually use it. It's a somewhat difficult language to learn -- at least if you haven't worked with functional programming before -- and it's not really a go-to language for most situations. Finding a reason to use it can be challenging.

My answer to this has been to work on projects that don't have an immediate application. For reasons I won't bore you with, I decided to (re)implement Porter's stemming algorithm. The point of a stemming algorithm is to reduce words to common roots, which is often used as a pre-processing step when building a search engine or doing other NLP work. For example, the words "stemmer", "stemming", "stemmed" are all based on "stem" and share a common meaning. Reducing these words to their root, "stem", makes processing them further a lot easier.

Porter's English word stemming algorithm is described here and there's a Python implementation here and a Haskell implementation here. I'm so new to Haskell (and functional programming) that I wanted access to both the original paper, a version in a language I'm familiar with as well as something in Haskell. Having said that, after I worked on this algorithm for a while it became apparent that working from the Python version was actually a hindrance compared to just working from the paper. Since our functional approach will be so different from our imperative approach, one doesn't really inform the other.

Read more »

BUNGLETRUCK Development Update 2

I've been working on BUNGLETRUCK full time since I first started posting about it. While there's not much to look at, the core of the app has been built. (There's actually another window not in the above image that allows you to manage your search urls.)

The app in its current state ended up being a Core Data app in a standard MVC configuration. The main search interface above (basically just a mockup of itself at this point) is a custom window with some custom views drawn in it. It supports the animation of its interface elements though that part of it will get fleshed out in the near future. The App Delegate handles the initialization and maintenance of the core data stack (I don't see the need for the core data stack to be handled elsewhere) and there are some additional models that help to validate and prepare the query information (your search urls, placeholders, hotkeys, etc) for use. Right now most of the app's logic is handled by a single controller.

My original goal was to build a mockup/proof of concept. It would have been quicker in the short term to throw the app together with a "faked" model side and with less attention paid to separating functionality into an MVC setup. I didn't get very far with that before I decided to build out the app with a proper architecture. There are a couple of reasons for that decision:

1. Even built properly utilizing core data and a separation of concerns it's still a fairly simple application.

2. Even though this is still a test an idea, I'm certain that I'll end up using the app in some form, so there's no reason to keep it disposable.

I'm currently working on some additional (major) features and if they start to look usable I'll talk about them here.

BUNGLETRUCK Development Update

A couple of days ago I wrote a blog post about a new idea I have for a Mac App here and posted it to r/macapps. The response was stronger than I expected (it resulted in over 500 visits to that post, which is about 498 more than my blog had received up to that point) and the feedback was mixed, though friendly and mostly positive. Lots of people responded to the title (...don't know what to call it) and offered helpful suggestions for the name. One of the first, and funniest, suggestions was BUNGLETRUCK, which is what I'm going to call it while it's under development.

Several people compared it to existing apps, especially Alfred. I was aware of Alfred and think it's a well made app. I don't use it personally but I think it's a good execution of a good idea. What I want to do; however, is a bit different.

I want to remove as many steps as possible between the need to perform a custom or site-specific search and having that search loading in my browser. To be worthwhile to me, this app has be to fast -- have the minimal amount of indirection. Most apps that handle custom searches use a magic keyword approach, e.g., if you type in "gmaps" in front of the search to search Google Maps. 

The problem I have with that approach is I have to type an extra keyword. That's indirection +1. I suppose I can reduce that to "m", though it's still magic letter + query.

What I want to do is map a specific key combination (like ⌘⌥⇧1) to a specific custom search. I want to press those keys, type or ⌘-c my query in and hit enter. Just and only that. 

I also re-search those same keywords frequently, so I want my interface to have a keyboard-driven history that's easy to use. Again, it has to work with a minimal amount of indirection.

The rest of the app has to facilitate the management of custom search urls (by say watching the clipboard for urls that can be added automatically and have a custom url scheme that allows people to share custom urls, or grab them off the app's site, that can be loaded automatically).

This app is already being developed. I'm currently working on a mockup/mvp of the search bar. I'm going to post pics or videos here once it's a little bit further along.

I'm Building a New Mac App, Don't Know What to Call It

I've got the idea for a new Mac App that I'm going to start working on. It's a something to make search a lot better/easier on my Mac. I don't know what to call it however. I guess I'll figure that out as I go. 

I plan on sharing a lot of the in-progress development and artwork here on my shiny new Posthaven blog.

Some more detail:

I'm a computer power user. I have a pretty snappy rMBP that I frequently run half a dozen programs on at once. I'm also a search power user. I might search hundreds of times per day while developing software. One thing that I've figured out is that the process of going to my browser (Chrome), opening a new tab and then writing a search query is actually fairly time consuming when it's done constantly throughout the day. 

More importantly, the process of typing general searches into my browser is not the most efficient way to do so. Usually I want to search a specific set of sites. I can do this with a custom search query or in the case of Google, a "custom search engine". That's a much better way to limit search for a more narrowly defined area. 

The problem with custom search urls is that they're hard to remember and manage. 

Given that those are my two pain points, I've decided to develop a custom search manager for Mac. The concept is very simple. The app will run in the background with an icon in the menu bar for quick access to settings. It will have a hotkey manager that will allow you to assign the app to whatever global key combination that you like. When that combination is pressed, a large text input will appear in the middle of the screen where you can type in your query. Press enter and that custom search url, with your query, will load in a browser of your choosing.

Simple. But it should make life for power users a little bit better.

The planned features:

1. Hotkey management for both the main search bar and individual custom searches.

2. Run at startup management.

3. A search history. I frequently repeat the same searches more than once. Having them available in the main search input box will be nice.

4. Relevant customization options.

I plan on starting the artwork soon so I'll post here when stuff starts to get done. As I build out an MVP I'll also update here about the progress.