Mu-Law and A-Law Compression Tutorial

Disclaimer:
This post comes from my old blog back in 2004. I’m reposting it here so that I don’t lose the content. The source was hand-written HTML so the formatting probably appears a bit off.

Overview:
What are A-Law and Mu-Law compression? In the simplest terms, they are
standard forms of audio compression for 16 bit sounds. Like most audio
compression techniques, they are lossy, which means that when you expand them
back from their compressed state, they will not be exactly the same as
when you compressed them. The compression is always 2:1, meaning that
audio compressed with either of these algorithms will always be exactly half
of their original size.

Mu-Law and A-Law compression are both logarithmic forms of data compression,
and are extremely similar, as you will see in a minute. One definition of Mu-Law is



          “…a form of logarithmic data compression

          for audio data. Due to the fact that we hear logarithmically,

          sound recorded at higher levels does not require the same

          resolution as low-level sound. This allows us to disregard

          the least significant bits in high-level data. This turns

          out to resemble a logarithmic transformation. The resulting

          compression forces a 16-bit number to be represented as an 8-bit

          number.”


(www-s.ti.com/sc/psheets/spra267/spra267.pdf)

And from the comp.dsp newsgroup FAQ we also get this definition:



          Mu-law (also “u-law”) encoding is a form of logarithmic

          quantization or companding. It’s based on the observation that

          many signals are statistically more likely to be near a low

          signal level than a high signal level. Therefore, it makes

          more sense to have more quantization points near a low level

          than a high level. In a typical mu-law system, linear samples

          of 14 to 16 bits are companded to 8 bits. Most telephone

          quality codecs (including the Sparcstation’s audio codec) use

          mu-law encoded samples.



In simpler terms, this means that sound is represented as a wave, and humans
can only hear audio in the middle of the wave. We can remove data from the upper
and lower frequencies of a sound, and humans will not be able to hear a significant
difference. Both Mu-Law and A-Law take advantage of this, and are able to
compress 16-bit audio in an manner acceptable to human ears.
A-Law and Mu-Law compression appear to have been developed at around the
same time, and basically only differ by the particular logarithmic function
used to determine the translation. When we get to the work of
implementing the algorithms, you will see that the differences are nominal.
The main difference is that Mu-Law attempts to keep the top five bits of precision,
and uses a logarithmic function to determine the bottom three bits, while A-Law
compression keeps the top four bits and uses the logarithmic function to figure out
the bottom four. Both of these algorithms are used as telecommunication standards,
A-Law being used mainly in Europe, and Mu-Law being used in the United States.

DISCLAIMER:

Please understand that I am glossing over several of the details, but recognize that
the entire purpose of this document is to make two extremely useful algorithms much
more accessable to “average” programmers, like myself.

Mu-Law Compression:

As you read this explanation, remember that the purpose of the algorithm is to
compress a 16-bit source sample down to an 8-bit sample. The crux of Mu-Law
functionality is deciding which of the samples need to keep the most of their
precision. Even the “most-important” sample will still lose precision. It
simply becomes a matter of determining how much each sample loses, and minimizing
the loss on samples deemed “more important”.

To generate a compressed Mu-Law sample from an uncompressed sample, the following
algorithm is applied to the 16-bit source sample.

(Please refer to the code listing for Mu-Law compression.)

First, the algorithm first stores off the sign. It then adds in a bias value
which (due to wrapping) will cause high valued samples to lose precision.
The top five most significant bits are pulled out of the sample (which has
been previously biased). Then, the bottom three bits of the compressed byte are
generated using a small look-up table, based on the biased value of the source sample.
The 8-bit compressed sample is then finally created by logically OR’ing together
the 5 most important bits, the 3 lower bits, and the sign when applicable. The bits
are the logically NOT’ed, which I assume is for transmission reasons (although you
might not transmit your sample.)

MuLaw Compresion Code:



const int cBias = 0x84;

const int cClip = 32635;

static char MuLawCompressTable[256] =

{

     0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,

     4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,

     5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,

     5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,

     6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,

     6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,

     6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,

     6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,

     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,

     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,

     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,

     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,

     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,

     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,

     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,

     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7

};

unsigned char LinearToMuLawSample(short sample)

{

     int sign = (sample >> 8) & 0x80;

     if (sign)

          sample = (short)-sample;

     if (sample > cClip)

          sample = cClip;

     sample = (short)(sample + cBias);

     int exponent = (int)MuLawCompressTable[(sample>>7) & 0xFF];

     int mantissa = (sample >> (exponent+3)) & 0x0F;

     int compressedByte = ~ (sign | (exponent << 4) | mantissa);

     return (unsigned char)compressedByte;

}

A-Law Compression:

As mentioned earlier, A-Law compression is extremely similar to Mu-Law compression. As you
will see, they differ primarily in the way that they keep precision. The
following is a short synopsis of the encoding algorithm, and the code example follows the
written explanation.
First, the sign is stored off. Then the code branches. If the absolute value of the source
sample is less than 256, the 16-bit sample is simply shifted down 4 bits and converted
to an 8-bit value, thus losing the top 4 bits in the process.
However, if it is more than 256, a logarithmic algorithm is applied to the sample to
determine the precision to keep. In that case, the sample is shifted down to access the
seven most significant bits of the sample. Those seven bits are then used to determine the
precision of the bottom 4 bits. Finally, the top seven bits are shifted back up four bits
to make room for the bottom 4 bits. The two are then logically OR’d together to create the
eight bit compressed sample. The sign is then applied, and the entire compressed sample
is logically XOR’d, again, I assume for transmission reasons.

A-Law Compression Code:



static char ALawCompressTable[128] =

{

     1,1,2,2,3,3,3,3,

     4,4,4,4,4,4,4,4,

     5,5,5,5,5,5,5,5,

     5,5,5,5,5,5,5,5,

     6,6,6,6,6,6,6,6,

     6,6,6,6,6,6,6,6,

     6,6,6,6,6,6,6,6,

     6,6,6,6,6,6,6,6,

     7,7,7,7,7,7,7,7,

     7,7,7,7,7,7,7,7,

     7,7,7,7,7,7,7,7,

     7,7,7,7,7,7,7,7,

     7,7,7,7,7,7,7,7,

     7,7,7,7,7,7,7,7,

     7,7,7,7,7,7,7,7,

     7,7,7,7,7,7,7,7

};

unsigned char LinearToALawSample(short sample)

{

     int sign;

     int exponent;

     int mantissa;

     unsigned char compressedByte;

     sign = ((~sample) >> 8) & 0x80;

     if (!sign)

          sample = (short)-sample;

     if (sample > cClip)

          sample = cClip;

     if (sample >= 256)

     {

          exponent = (int)ALawCompressTable[(sample >> 8) & 0x7F];

          mantissa = (sample >> (exponent + 3) ) & 0x0F;

          compressedByte = ((exponent << 4) | mantissa);

     }

     else

     {

          compressedByte = (unsigned char)(sample >> 4);

     }

     compressedByte ^= (sign ^ 0x55);

     return compressedByte;

}

Decompression:

Now, the most obvious way to decompress a compressed Mu-Law or A-Law sample would
be to reverse the algorithm. But a more efficient method exists. Consider for a moment the
fact that A-Law and Mu-Law both take a 16-bit value and crunch it down to an 8-bit value.
The reverse of that is to take an 8-bit value and turn it into a sixteen bit value. In the
graphics world, it is extremely common to represent 32 and 24 bit values with an eight bit
index into a palette table. So, why not take a page from the world of graphics and use
palettes for the Mu-Law and A-Law compression look up? Sounds good to me. In fact,
these palettes will be smaller than their 24 and 32 bit cousins because we only need to
represent 16 bit values, not 24 and 32. In a nutshell, we will create static lookup
tables to do the reverse conversion from A-Law and Mu-Law. The two differing tables
are presented below. To convert from your compressed sample back to the raw 16-bit
sample, just use your compressed sample as the index into the table, and the corresponding
value in the table is your decompressed 16-bit sample. Obviously, the downside is that
this method requires the memory overhead for the tables, but each table is only 512 bytes.
In this day and age, that’s downright cheap for the absolute fastest decompression!

Decompression Code:



static short MuLawDecompressTable[256] =

{

     -32124,-31100,-30076,-29052,-28028,-27004,-25980,-24956,

     -23932,-22908,-21884,-20860,-19836,-18812,-17788,-16764,

     -15996,-15484,-14972,-14460,-13948,-13436,-12924,-12412,

     -11900,-11388,-10876,-10364, -9852, -9340, -8828, -8316,

      -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,

      -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,

      -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,

      -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,

      -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,

      -1372, -1308, -1244, -1180, -1116, -1052,  -988,  -924,

       -876,  -844,  -812,  -780,  -748,  -716,  -684,  -652,

       -620,  -588,  -556,  -524,  -492,  -460,  -428,  -396,

       -372,  -356,  -340,  -324,  -308,  -292,  -276,  -260,

       -244,  -228,  -212,  -196,  -180,  -164,  -148,  -132,

       -120,  -112,  -104,   -96,   -88,   -80,   -72,   -64,

        -56,   -48,   -40,   -32,   -24,   -16,    -8,     0,

      32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,

      23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,

      15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,

      11900, 11388, 10876, 10364,  9852,  9340,  8828,  8316,

       7932,  7676,  7420,  7164,  6908,  6652,  6396,  6140,

       5884,  5628,  5372,  5116,  4860,  4604,  4348,  4092,

       3900,  3772,  3644,  3516,  3388,  3260,  3132,  3004,

       2876,  2748,  2620,  2492,  2364,  2236,  2108,  1980,

       1884,  1820,  1756,  1692,  1628,  1564,  1500,  1436,

       1372,  1308,  1244,  1180,  1116,  1052,   988,   924,

        876,   844,   812,   780,   748,   716,   684,   652,

        620,   588,   556,   524,   492,   460,   428,   396,

        372,   356,   340,   324,   308,   292,   276,   260,

        244,   228,   212,   196,   180,   164,   148,   132,

        120,   112,   104,    96,    88,    80,    72,    64,

         56,    48,    40,    32,    24,    16,     8,     0

};



static short ALawDecompressTable[256] =

{

     -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736,

     -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784,

     -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368,

     -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392,

     -22016,-20992,-24064,-23040,-17920,-16896,-19968,-18944,

     -30208,-29184,-32256,-31232,-26112,-25088,-28160,-27136,

     -11008,-10496,-12032,-11520,-8960, -8448, -9984, -9472,

     -15104,-14592,-16128,-15616,-13056,-12544,-14080,-13568,

     -344,  -328,  -376,  -360,  -280,  -264,  -312,  -296,

     -472,  -456,  -504,  -488,  -408,  -392,  -440,  -424,

     -88,   -72,   -120,  -104,  -24,   -8,    -56,   -40,

     -216,  -200,  -248,  -232,  -152,  -136,  -184,  -168,

     -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184,

     -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696,

     -688,  -656,  -752,  -720,  -560,  -528,  -624,  -592,

     -944,  -912,  -1008, -976,  -816,  -784,  -880,  -848,

      5504,  5248,  6016,  5760,  4480,  4224,  4992,  4736,

      7552,  7296,  8064,  7808,  6528,  6272,  7040,  6784,

      2752,  2624,  3008,  2880,  2240,  2112,  2496,  2368,

      3776,  3648,  4032,  3904,  3264,  3136,  3520,  3392,

      22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944,

      30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136,

      11008, 10496, 12032, 11520, 8960,  8448,  9984,  9472,

      15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568,

      344,   328,   376,   360,   280,   264,   312,   296,

      472,   456,   504,   488,   408,   392,   440,   424,

      88,    72,   120,   104,    24,     8,    56,    40,

      216,   200,   248,   232,   152,   136,   184,   168,

      1376,  1312,  1504,  1440,  1120,  1056,  1248,  1184,

      1888,  1824,  2016,  1952,  1632,  1568,  1760,  1696,

      688,   656,   752,   720,   560,   528,   624,   592,

      944,   912,  1008,   976,   816,   784,   880,   848

};

Some Not-So-Random Oregon Statistics

Recently, I heard a fascinating interview with Larry Krasner, the DA for Philadelphia. It really challenged some of my thoughts on incarceration and inspired me to do a little research, locally. Here are some interesting statistics that I found for Oregon:

  • 2017-2019 Dept of Corrections Budget: $1.76B ($880m annually) Source
  • Average Daily Prison Population: 14,835 Source
  • Average cost per inmate: $59,319 ($880m / 14,835)

So who is in our prison system? Here are some other things I found: Source

  • White 74.5% (vs 76.4% of normal state population)
  • Hispanic 12.1% (vs 12.8% of normal state population)
  • Black 9% (vs 2.1% of normal state population)
  • 62.7% are over the age of 30
  • Male 81%
  • Female 19%

Top 5 incarceration rates by county: Source

  1. Sherman County, 2.83 / 1000
  2. Marion County, 2.14 / 1000
  3. Jefferson County, 1.96 / 1000
  4. Linn County, 1.89 / 1000
  5. Clatsop County, 1.86 / 1000

And what did they do to get there? Source

  1. Drugs 20%
  2. Assault 13.4%
  3. Other 12.6%
  4. Theft 9.3%
  5. Burglary 8.9%

This also made me curious relative to education in Oregon. Here are a few statistics I found:

  • Average Teacher Salary: $59,204 Source
  • Total Number of Teachers: 22,357 Source
  • Median Class Size: 25 Source

So here are some of my random thoughts after doing this research:

  • It’s fascinating that every incarcerated inmate almost exactly equals a full time teacher. (These costs don’t even include local and municipal jail costs.)
  • African American Oregonians are clearly incarcerated at a much higher rate than either caucasian or hispanic Oregonians.
  • It’s ALARMING that 12.6% of the prison population is incarcerated for offenses labeled as “other”. Take a look at the source for the incarceration cause breakdown and you can see how granular it gets which makes the “other” classification that much more troublesome. (Forgery weighs in at a whopping 0.4%)
  • The likelihood of incarceration has nothing to do with the population density that you live in. Only one of the top 5 counties in the per capita list would be considered urban.

Does any of this mean anything? I’m not sure. I’ll definitely be thinking about it for a while. In the alarmist era we currently find ourselves in, I find it helpful to have some actual data behind to fall back on. As such, I’ve included links to all of my sources in case anyone else feels so inspired to do some data spelunking. If you do, please share what you find!

 

 

A Coffee Retrospective

2016-04-01 10.51.28Back in March, I was inspired by Manton’s Austin coffee quest and decided to try my own “30 Days of Coffee.” Starting on April 1 and continuing for 30 straight days, I would experience a new cafe or coffee shop that I had never visited before. The rules I set for myself were fairly simple:

  1. I must visit a coffee shop each day for 30 days.
  2. I can not have had coffee there previously.
  3. The coffee shop must reside within the boundaries of N/NE Portland. (I did this so that I could somewhat mimic Manton’s challenge given the plethora of coffee shops in Portland vs. Austin.)
  4. In order to count as a “coffee shop” it must serve lattes (my drink of choice)

I have now completed my 30 days, and I have to tell you that despite sounding easy, it’s actually quite difficult to do ANYTHING for 30 days straight. There were more than a few times that Tiffany had to remind me that I hadn’t made my daily trip (especially difficult since most non-chain coffee shops close at 4 p.m.)

Along the way, I documented each visit on my microblog which you can find here. I also snapped a picture of each location that hopefully gave a small glimpse into the ambiance of each.

This entire endeavor was an experiment in a number of areas, and I can honestly say that I learned a little bit about myself along the way. As I mentioned, I was microblogging the adventure and somehow ended up having a number of people who followed along. A few have even asked for a summary/recommendation list, to which I am more than happy to oblige.

The following is my list of coffee shops that I would gladly return to again. The rankings are relative to me, which means that it’s based on a blend of coffee quality, ambiance, location and overall comfort (including my ability to work remotely). This is simply a ranked list out of the 30 that I visited, not my overall list for Portland. In fact, I think only one of these would crack my Portland top 10 list.

So, with all of these caveats out of the way, here is my ordered list of places that I would gladly revisit:

  1. Blend Coffee – I cannot say enough good things about this place. From the cleanliness to the thoughtfulness of the seating to the ridiculous number of power outlets, everything about this place is well thought out. I only wish it was closer to my home. That being said, this is the only coffee shop on my list that I would go out of my way to visit. If you haven’t been here, I absolutely recommend a visit.
  2. Bassotto – This place was an absolute gem of a find because it’s actually a fantastic coffee shop disguised as a gelateria. It also doesn’t hurt that it’s located next door to the amazing Tamale Boy, but I think I’d come back even if it was located elsewhere. Finding Bassotto was one of the reasons that I did this challenge. It allowed me to find an awesome place that I normally wouldn’t have tried on my own.
  3. Prince Coffee – This place is SMALL. It’s also very new and in the beautiful Kenton neighborhood. I will revisit this place if for nothing else than their homemade stroopwafels.
  4. Miss Zumstein – This location is very comfortable, but their pastries are wonderful. The staff is friendly, and they have great coffee, but man are those pastries good.
  5. Locale Coffee – This is another of the new-wave Portland coffee shops located in the Mississippi neighborhood. I would definitely go back to it again, but there’s nothing particularly special about it. If you’re looking for a decent place to meet someone for coffee and you need to be near Mississippi, you can’t really go wrong here.
  6. Saint Simon – This is yet another stereotypical new-wave Portland coffee shop. It has good coffee, is nice inside, has a good location, but is a little too “trendy” for my taste. Think I’m exaggerating? Everything from the moose head on the wall to the forced industrial look to the “wood block” seating just screams Portlandia. I’d definitely take coffee from here again, but I probably wouldn’t stay for long.
  7. Seven Virtues – I didn’t want to like Seven Virtues because I find the entire Zipper building to be somewhat pretentious and annoying, but I have to admit that it was pretty nice inside and they had good coffee to boot. I’ve heard from at least one person that they went here right after it opened and were very unhappy with their experience. Perhaps they had some initial issues getting going?
  8. Posie’s Cafe – I’m not sure if I liked Posie’s based on its own merits or because it’s located in the Kenton neighborhood. Regardless, I found it to be very charming and a nice place to pop into if you’re looking for a quick caffeine pick me up. They had a lot of seating and had some pretty good looking pastries as well.

And that is it. Out of 30, I would revisit 8. Of the 8, only one of them would crack my top Portland Coffee Shops list. (I’ll try to put that together soon as well.)

As I mentioned, the challenge was more difficult than I expected given how often I go to coffee. In fact, I’ve started thinking differently about 30 day challenges in general and I have a few more I might try in the next few months. If you’d like to see the entire list of 30, I’ve included it below. You can also find my posts on Twitter or Facebook with the hashtag #pdxcoffeehunt.

  1. Cathedral Coffee – 7530 N Willamette Blvd
  2. TwentySix Cafe – NE 7th Ave
  3. Miss Zumstein – 5027 NE 42nd Ave.
  4. Saint Simon Coffee – 2005 NE Broadway
  5. Tiny’s Coffee2031 NE Martin Luther King Jr Blvd
  6. Fillmore Coffee – 7201 NE Glisan St
  7. Prince Coffee – 2030 N Willis Blvd
  8. Bison Coffee House – 3941 NE Cully Blvd
  9. Seven Virtues – 2705 NE Sandy Blvd
  10. Batter – 4425 NE Fremont St
  11. Kopi – 2327 E Burnside St
  12. Locale – 4330 N Mississippi Ave
  13. The Fresh Pot – 4001 N Mississippi Ave
  14. Goldrush – 2601 NE Martin Luther King Jr. Blvd
  15. Bassotto – 1760 NE Dekum
  16. Spielman Bagels – 2200 NE Broadway St
  17. Wholesome Blend – 4615 NE Sandy Blvd
  18. Cup & Bar – 118 NE Martin Luther King Jr. Blvd
  19. Heart Coffee Roasters – 2211 E Burnside St
  20. Blend Coffee Lounge – 2710 N Killingsworth St
  21. Cafe Eleven – 435 NE Rosa Parks Way
  22. The Arbor Lodge – 1507 N Rosa Parks Way
  23. Whole Foods Coffee Shop
  24. Extracto – 1465 NE Prescott St
  25. Coffee People – Portland Airport
  26. J Cafe – 533 NE Holladay St
  27. Coffee House Five – 740 N Killingsworth St
  28. Case Study – 1422 NE Alberta
  29. Posie’s Cafe – 8208 N Denver Ave
  30. Elevated Coffee – 5261 NE Martin Luther King Jr Blvd

 

 

The Trouble With Cross Posting

Recently, I setup a microblog (http://jonhays.me) to supplement my interactions on Twitter, Facebook and Instagram. After several conversations with my friend Manton, I decided that I would setup a new WordPress site and use that as the content “repository” and use cross-posting tools to distribute out to Twitter, Facebook and Instagram.

There are several reasons for doing this, but my primary motivations are:

  1. I want to spend less time on the individual social media platforms.
  2. I want to own my content and have better control over it.

After a little bit of consternation over appropriate domain names and blog names, I set about assembling the site and my work flow.

One of my high level requirements is that I wanted to be able to post to my microblog from my phone. Another of my requirements is that I wanted to be able to post entries both with and without images. Of course the third requirement that I mentioned above is that it needs to cross-post to Twitter, Facebook and Instagram.

Naively, I just assumed I could use the WordPress app and setup a few IFTTT triggers and be done with it. As you can guess, it’s not quite as simple as that.

Let’s tackle cross-posting of images first: what should be posted to Instagram for a blog entry with no image? With multiple images?

Realizing that simply posting from WordPress wasn’t going to work, my first instinct was to modify my workflow so that if I wanted to post an image, I would post from Instagram and use an IFTTT action to then cross-post the image to my microblog which would then cross-post to Facebook and Twitter.

Unfortunately, using this method is like playing a game of telephone with social media and the end result looks like this on Facebook:

Screen Shot 2016-04-12 at 10.30.16 AM

Several of my friends replied after seeing these asking if my computer got “hacked.”

Images aren’t the only troublesome area either. Take for instance cross-posting of text posts larger than 140 characters to Twitter. It turns out that IFTTT is actually quite terrible about handling these as well:

Screen Shot 2016-04-12 at 10.47.32 AM

Simply truncating the text without a link back to the original post is the worst kind of tease and also not acceptable. What a good cross-post tool should do is truncate at word boundaries and provide a link back to the original post. IFTTT is simply not up to the task for this.

In fact, as it turns out, IFTTT is actually quite terrible for cross-posting to just about every platform. I am investigating other alternatives at the moment but as of right now, I am still stuck with those terrible Facebook cross posts, and I have no way to post directly on the microblog and have the ones with images get cross-posted to Instagram.

Fortunately, there are smart people working on these problems! I’m using a beta tool to do the cross-posting to Twitter. The beta tool actually works quite well and I’ve been trying to convince the author to expand to include Facebook as well, but he’s reluctant to add more features at the moment because he’s trying to launch.

With so much out of control negativity and lack of author control on Twitter and Facebook, it feels like there is an opening for something like micro-blogs to augment existing platforms in a positive way. And while I don’t think Twitter or Facebook are going anywhere, I believe micro-blogs can help fill the gap for content creators that are conscientious about their craft.

I’m still exploring other avenues for cross-posting and I’ll try to post updates as I find them either here or on the microblog, but it feels like this is a viable, mostly untapped market.

 

State of the Pines – 6 Months

I cannot believe that it has been only 6 months since I took the leap of faith to try and turn SilverPine Software into something bigger than it had been! We have been so incredibly busy (in a good way) and sometimes I feel like my head is spinning with all the great things that are going on. Here are just a few of the highlights:

  • We have launched 8 iOS Apps, 3 Android Apps and 1 WindowsPhone App
  • We worked with a very talented designer to create a new and improved logo!
  • We continued to grow our open source Useful Utilities toolbox project as a gift back to the developer community
  • We have grown our team to include 9 amazingly gifted people!
  • One of our projects for a fortune 100 company has been featured in depth by the New York Times and referred to as a “game changer”
  • We purchased Photos+ from Justin Williams and re-launched it with native integration of Dropbox
  • We have had our projects featured by Apple not once, but twice!

Whew! That’s quite a bit for only half of a year. To say that some days my hair feels like it’s on fire is an understatement. That being said, I wouldn’t trade it for the world. The work we do is creative, challenging, cutting edge and very rewarding. Our clients are all amazing people with great ideas and I feel honored that we are able to help them create such amazing products.

So what’s ahead? I can’t quite tell you yet, but I can say that we have some awesome stuff in the pipeline. We can’t wait to share it with everyone.

It’s been a wonderful ride so far, and I’m really looking forward to finding out what the second half of the year looks like for us. Feel free to drop me a note if you want to chat about any of this or if you have an idea or product you’d like to discuss. Also, if you happen to be at Çingleton this year, make sure to say hi. (I’ll be the guy with the @cheesemaker shirt.)

-Jonathan Hays

A (Brief) Guide to Cease and Desists for Indie Developers

Before we go any further, the lawyers are making me post this part first: The following post is from my experience as a developer and I am in no way trained as a lawyer. Do not construe any of the following as legal advice. If you are in need of legal advice, consult a lawyer.

Ok, now to the post.

I have been developing apps for the iOS App Store since 2008 and as a result, I have many battle scars to show for my efforts. Unfortunately, the worst of these scars tend to come from lawyers. One particular blunt instrument that lawyers like to use is something called a Cease and Desist. These are very scary messages that are usually delivered via email but can often come in snail mail.

Over the years, I have received at least 10 different Cease and Desists (including one from the infamous Doodlegate debacle) and have learned quite a bit along the way. Some of what I have learned has been from actual lawyers, and some from the good old school of hard knocks. My intent here is to share a little of what I have learned because at the end of the day, this stuff sucks and we’d much rather be dealing with bugs than lawyers.

To start with, here is an example of one that I received last year:

I am legal counsel at [REDACTED] and represent the authorized of the rights infringed by the apps described.

[REDACTED] is the registered owner of both the [REDACTED] (and its French equivalent, [REDACTED]) and [REDACTED] Design trade-marks in Canada.  As such, it has the exclusive right to their use. 

When the trade-mark [REDACTED] is used as a search term in the Canadian iTunes store, not only does our App appear, but the Apps of a number of other individuals/companies. 

We would ask that individuals be prevented from using the [REDACTED] trade-mark as a “key word”, as this constitutes trade-mark infringement and could be the reason why other Apps are appearing when the trade-mark [REDACTED] is used a search term.  

[REDACTED] can not tolerate, these individuals/companies benefitting from the tremendous goodwill associated with these marks.

Most Cease and Desists follow a form similar to this. The entity that has protection for their intellectual property sends a sternly written message informing you that you need to fix/remove/change something. However frightening this might sound, a Cease and Desist is not the same as a lawsuit. You are not being sued. You are simply being informed that you need to make a change in accordance with someone else’s real or perceived protection of their intellectual property. So, what should you do? Here are a few things that I have learned along the way:

1. Don’t panic. Despite the fact that these messages intentionally sound scary, you don’t need to be afraid. In the example above, phrases like “infringement” and “can not tolerate” make it sound like these folks mean business and are prepared to bring down the hammer of justice. But if you look more closely, you will see that usually these messages are form letters. Notice that nothing mentions the name of my company or even my name. In fact, there is really nothing of substance in the email. (We’ll come back to that in a bit.)

2. Be polite and professional in your communication, but do not apologize or acknowledge fault. Just because you receive a C&D, it is still the responsibility of the claimant to show that you are at fault. Yes, you ultimately may be required to make a change but there are several things that need to be established first. Being polite and professional will go a long way in these types of issues. Additionally, do not immediately remove your app for sale or whatever it is they are requesting that you do. Doing so at this point would be acting with incomplete information, which leads to the third point.

3. Ask for additional information. There are a variety of reasons to do this. The first is to signal that you have received their request and are acting in good faith. This is also to flag the fact that their claim is incomplete. As I pointed out, the above C&D is almost completely devoid of meaningful information. Here was my response to the C&D above:

Hello Ms. [REDACTED],

Would you please send either a scanned copy of proof of your trademark or send via postal service a hardcopy that clearly shows when the trademark was issued and under what jurisdiction it applies and we will be happy to comply.

Sincerely,

Jonathan Hays

An excellent action is to ask for actual documentation of the patent, trademark or copyright. A few times, I have asked for documentation only to find that what they sent had absolutely no application to my app or that they were claiming to own something that they did not. If they cannot provide proof then they have no claim. Additionally, if you received the C&D through Apple Legal, make sure to cc them on all of your discourse with the lawyer. This helps to both keep the lawyers honest but also will help keep you in good standing with Apple. (It also provides a fairly neutral third party with a paper trail).

4. Once you receive the documentation, the next step is to actually read it. This can be fairly dry reading, but I assure you that it is worth it and that it is no less obtuse than technical documentation on the latest APIs. For example, many patents have multiple claims in them. A great thing to do is to ask for clarification regarding which claims they are actually citing against you. This is especially important if the C&D you received was a form letter because it means that your company was collected in some large data sweep without anyone actually taking the time to look at your App. As with any bulk data collection, there can be errors. At this point, you may or may not want to consult a lawyer on your side, however it is certainly fine to make the people that sent you a C&D actually do their jobs by asking for more information. Here is how I responded once I received the documentation:

Hello Ms. [REDACTED],

Thank you for your reply.  Apple has asked us to make sure to include them in all exchanges and you did not include them on this so I am re-adding them.  That being said, I have a few questions that you have not yet addressed:

  1. I am trying to make sure that I fully understand which of the services you are describing is in conflict to make sure that we are in full compliance.  To be clear, I am asking [REDACTED] to explain which of the wares and services that [REDACTED] falls within. The services that are listed include SMS, printed publications, business directories, and Internet websites.  [REDACTED] is none of those so I am seeking clarification of your claims. Also, as you acknowledged in your email below, at least one of the documents that was sent over do not apply so obviously there is some confusion for [REDACTED].  I am simply seeking verification that a mistake has not been made by [REDACTED].
  2. I need to understand your claim that [REDACTED] is infringing within the application description because that is not accurate as nowhere in the application description does the word [REDACTED] or [REDACTED] occur.
  3. I asked previously if you are claiming IP protection only for sale within Canada.  I have yet to receive a response.

Thank you,

-Jonathan Hays

5. Verify jurisdiction. Make sure that you understand where in the world they have permission to enforce their claim. The App Store is a global marketplace and unless they have protection for their claim in every country that you sell, you are only compelled to comply in the corresponding markets.

Good morning Jonathan, 

Yes, we are solely claiming IP protection for sale within Canada. In Canada, [REDACTED] has a registered trade-mark for [REDACTED], and the [REDACTED] & Design.  Under Canadian legislation this affords [REDACTED] with the sole and exclusive right to make use of the trade-marks in Canada and prevents any third party from making use of it in any context without [REDACTED]’s explicit permission even if the wares and services description is different.
 
In making use of [REDACTED]’s trade-marks in the description and logos of your app, you are creating an association between our respective entities that will confuse consumers and lead them to believe we are somehow related.  Unfortunately, this is contrary to Canadian Trade-mark legislation.  As such, we would ask that you cease making use of the trade-marks in the description and logos of your apps, or cease distribution of the apps in the Canadian iTunes store.
 
Best regards
So in this particular case, the IP owner only had protection for their claims in Canada and therefore only sales in the Canadian App Store were in question. Ultimately, I resolved the issue by simply removing it for sale in Canada and the app continues to garner downloads in all of the other App Stores. If I had not asked their lawyer to clarify the claimed jurisdiction, I might have lost out on continued revenue in the other countries for absolutely no reason.
As developers we generally avoid conflict. All things being equal, we prefer to make things. However, when we make things that we sell commercially, we often have to deal with lawyers and Cease and Desist requests. Always remember that these are requests, not legally binding demands. If/when you receive a C&D, do your due diligence. Be calm. Take measured steps. If all else fails, keep in mind that every time you send a request back to the lawyer on the other side of the C&D you are incurring billable hours to whomever is requesting the Cease and Desist. It’s only seems fair that if you’re going to lose time and money, that they be willing to do the work to back it up.

First Musings on WWDC 2014

I’m writing this sitting in the San Francisco airport waiting for my return flight after a great week at Apple’s annual developer conference. It’s been an amazing week and I’m still processing a lot of what I experienced. First off, let me say that I believe that WWDC 2014 will be considered a turning point when viewed in retrospect. As a developer, I am absolutely giddy with all of the possibilities that Apple has opened up with their announcements. There is a stark contrast between last year’s developer conference and this year’s conference. At the end of last year, I was thinking about all of the things that I HAD to do with iOS 7. With iOS 8, I am absolutely bubbling with ideas of things that I GET to do. iOS 8 is going to be a big deal. From HealthKit to HomeKit to Extensions to CloudKit, Apple has paved the way for some amazing things to be built.

And then there is Swift. Swift has taken my excitement about the new frameworks and cranked it to 11. Not only has Apple provided a sorely needed modern language to the platform, they have delivered it complete with a fantastic toolset. Clearly this has been in the works for a very long time. Swift development reminds me of the early days when I was first learning to program. Back in those ancient days, you simply turned on your computer and started typing. Swift very much has the same feel to it. In fact, I actually plan to have my 9 year old son sit down with me and learn it together.

This is big stuff. I am still processing a lot of what I have seen and learned and will post more as I unravel it. I think this is going to be a great year to be an iOS and Mac developer!