Introduction

This tutorial shows you how to build a simple audio fingerprinting iOS app from scratch. Audio fingerprinting involves taking a small audio sample and sending it to Gracenote for identification. The Mobile Client provides numerous methods to access Gracenote's metadata from an iOS device - most of these are demonstrated in the SDK's sample app. If you haven't downloaded the sample app, now's a good time to grab it.

Setting up Your Development Environment

The first thing you need to do is to make sure you have your development environment set up. Because I'm building an iOS app, we'll be using Xcode 4.5. You can download Xcode through Apple's developer center. If you plan on testing this out on a device, you'll need to make sure it's provisioned for development. Apple has a handy provisioning tool to build a provisioning profile.

Creating Your Project

To start, let's create a new project. For simplicity, let's make it a Single View Application. We will need to add the following libraries and frameworks for everything to work. If you've never done this before, check this out.

  • GracenoteMusicID.framework (included in the SDK)
  • libsqlite3
  • libstdc++
  • libxml2
  • CoreMedia.framework
  • QuartzCore.framework
  • MediaPlayer.framework
  • AVFoundation.framework
  • AudioToolbox.framework
  • Security.framework

Creating the UI

Now for the actual app building. In the Project Navigator, select the storyboard for the device that you are programming on. I'm using an iPad, so I'll edit MainStoryboard_iPad.storyboard. For this demo, we only need to add a label and a button. The label will display the artist's name, so let's make it big. Let's also add a button and create a function to be called when the button is pressed. For now, we'll leave the function empty. (This demo shows how to add UI elements and trigger functions with a button press.) That's about it for the storyboard. Pretty simple. You can see what mine looks like in the image below.

 

 

Coding the App

For this app, we want to record audio input through the device and display the artist name. The function that will accomplish this is called recognizeMIDStreamFromMic. You can explore the other search functions in the GNOperations.h file inside the GracenoteMusicID framework. (I've drawn an arrow on the image above that shows you where to find the header files for the SDK.)

All the SDK functions used to query the Gracenote database take a result function and a GNConfig object as arguments. The result function must implement the GNSearchResultReady protocol. More on that later. The config object is extremely straight forward. All this really does is store your Client ID and Client ID Tag. In the ViewController.h file I've included the GNConfig.h header and added a GNConfig* property named config. The entirety of my ViewController.h file is:

#import <UIKit/UIKit.h>
#import <GracenoteMusicID/GNConfig.h>

@interface ViewController : UIViewController
@property (strong, nonatomic) IBOutlet UILabel *artistLabel;
@property (retain, nonatomic) GNConfig *config; 

@end

I then initialize the GNConfig object in the viewDidLoad function inside ViewController.m:

- (void)viewDidLoad
{
    [superviewDidLoad];
    self.config = [GNConfig init:@"NNNNNNN-NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN"]; // <Client ID>-<Client ID Tag>
}

NOTE: You will need to replace all those Ns with your personal client ID, which can be found in the "My Apps" page in your account profile.

Now we need to create a class that implements the GNSearchResultReady protocol. This class needs to have a function, GNResultReady, that will be called when the fingerprint lookup returns. I implemented this protocol in a class called FPResponse. An FPResponse object has a single property, label, that points to a UILabel. It has two functions:

  • initWithLabel - Allows the ViewController to initialize the object with a pointer to one of its UILabel objects.
  • GNResultReady - Sets the text of this label. If the fingerprint search returns a match, the artist name will be written to the label. Otherwise the label's text is set to "No Match".
//
//  FPResponse.h
//

#import <Foundation/Foundation.h>
#import <GracenoteMusicID/GNSearchResultReady.h>

@interface FPResponse : NSObject <GNSearchResultReady>
{
    
}

@property (strong, nonatomic) UILabel *label;

- (id) initWithLabel: (UILabel *) alabel;
- (void) GNResultReady:(GNSearchResult*) result;

@end
//
//  FPResponse.m
//

#import "FPResponse.h"
#import <GracenoteMusicID/GNSearchResultReady.h>
#import <GracenoteMusicID/GNSearchResponse.h>
#import <GracenoteMusicID/GNSearchResult.h>

@implementation FPResponse

@synthesize label;

- (id) initWithLabel:(UILabel *) alabel
{
    self = [super init];
    if (self)
        self.label = alabel;
    return self;
}

- (void) GNResultReady:(GNSearchResult *) result
{
    GNSearchResponse *best = [result bestResponse];
    if (![result isFailure] && (best.artist!=nil))
        [self.label setText:best.artist];
    else
        [self.label setText:@"No Match"];
}
@end

Finally, we need to call the fingerprint lookup when the button is pressed. I created a function named didPress in the ViewController.m file:>

- (IBAction)didPress:(id)sender {
    id resp = [[FPResponse alloc] initWithLabel:self.artistLabel];
    [GNOperations recognizeMIDStreamFromMic:resp config:self.config];
}

We first create the FPResponse* object, resp, with a pointer to the view's UILabel, which is called artistLabel. Then we call the operation, recognizeMIDStreamFromMic, that actually records the mic input and searches the Gracenote database for the track. When the function returns, FPResponse handles the result object and (hopefully) prints the artist's name to the screen. If you are interested in more than just the artist name, view the GNSearchResponse.h file in the GracenoteMusicID framework that lists all the metadata that a response may return.

Conclusion

Alright, it is time to give this app a shot. You can run the demo on the iPad simulator (using the computer's mic) or on an iPad. It is not going to win any design awards, but it works!

Hopefully, this super simple fingerprinting app has given you a launch point to start exploring the many other features and functionality the SDK offers. Any feedback on this tutorial is welcome.

Happy hacking!

Comments

 I'm having problems implementing the protocol.  My build is not able to locate GNSearchResultReady.h.  Can you suggest a fix?  I have added the reference to the libraries and Frameworks 

  • the GracenoteMusicID framework that's included in the SDK
  • libstdc++
  • libxml2
  • CoreMedia.framework
  • QuartzCore.framework
  • MediaPlayer.framework
  • AVFoundation.framework
  • AudioToolbox.framework

 ********************************************** This is my attempt at the code.********************************************////  GraceNoteApp_FPResponse.h//  BareBonesMusicID////  Created by Ishmael on 2/18/13.//  Copyright (c) 2013 Ishmael. All rights reserved.// #import <Foundation/Foundation.h>#import <GNSearchResultReady.h> @protocol GraceNoteApp_FPResponse <GNSearchResultReady>- (id) initWithLabel:(UILabel *) label{    self = [super init];    if (self)        self.label=label;    return self;} - (void) GNResultReady:(GNSearchResult*)result{    GNSearchResponse *best = [result bestResponse];    if (![result isFailure] && (best.artist!=nil))        [self.label setText:best.artist];    else        [self.label setText:@"nope"];    return;} @end

Try #import <GracenoteMusicID/GNSearchResultReady.h> instead of #import <GNSearchResultReady.h>

Hi your documentation section its offline?

I also needed to add libz.dylib as a framework

Any ideas on this?
I've double checked all the headers are installed and that library search paths are identical

Undefined symbols for architecture i386:
"_safer_ebox", referenced from:
_saferp_ecb_decrypt in GracenoteMusicID(saferp.o)

Got an *_OBJC_CLASS_$_ASIdentifierManager* linker error until I added the AdSupport framework.

i have used this tutorial demo but output is return nil so what is the problem i dont know so any body help me to fetch records.

 

how to get cover image of song with this tutorial pls help me 

Regards:

Jatiender Kumar

You will have to set content.coverArt config property to “1” and make sure that content.musicId.queryPreference.singleBestMatch is also set to “1”.

whre is framework 

<GracenoteMusicID/GNConfig.h>??

I have downloaed sdk for ios "https://developer.gracenote.com/gnsdk" and In this folder I found "GnSDKObjC.framework".

Please let me know as you mention this tutorial import "GracenoteMusicID.framework"

Can i use "GnSDKObjC.framework" instead of "GracenoteMusicID.framework"? Its work? both are same

If not Would you provide link for "GracenoteMusicID.framework" .

Looking for your reply as soon as possible.

Xcode 6 iOS SDK doesnt seem to have the GracenotemusicID framework. Please help

Hi,
Sorry for the confusion. This tutorial is for the deprecated old Mobile Client.
In the iOS Gracenote for Mobile SDK package, you will find a doc folder, and you can follow the Getting Started guide from there.
(I suppose GracenotemusicID framework is replaced by the GnSDKObjC.framwork.)

Must be like this amazing blog here this is the very nice to all users so have to look the play spider solitaire and have to join the best fun to join this card i must be say you have to best score to play hard.

It truly relies upon your inclination, the two dialects and SDK's are not interchangeable. Make my essay I discover Xcode awesome to work with, however, Objective-C can be eccentric now and then. To me, Java and Android feel less cleaned than iOS. Notwithstanding, in the event that you've contemplated Java previously and like it, why not give it a go for Android and perceive how it goes?