Created
July 9, 2011 11:25
-
-
Save jimmcgowan/1073528 to your computer and use it in GitHub Desktop.
A simple example of using the EchoPrint Codegen to fingerprint an mp3 file and look for a match on EchoNest. For OS X or iOS using Cocoa and Core Audio.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// EchoPrint Cocoa Example | |
// Created by Jim McGowan on 08/07/2011. | |
// jim at bleepsandpops dot com | |
// | |
// A simple example of using the EchoPrint Codegen to fingerprint an mp3 file and | |
// look for a match on EchoNest. For OS X or iOS. Error checking removed for brevity. | |
// | |
// Requires the 'Other C Flags' XCode build setting "-x objective-c++" to compile as Objective-C++ | |
// | |
#import <Foundation/Foundation.h> | |
#import <AudioToolbox/AudioToolbox.h> | |
#import <CoreAudio/CoreAudio.h> | |
#import "CAStreamBasicDescription.h" | |
#import "CAXException.h" | |
#include <string> | |
#include <zlib.h> // used by EchoPrint Codegen, may not need to include depending on how the Codegen library was built/linked | |
// declaration of the Codegen Class, from Codegen.h | |
#define VERSION 4.11 | |
using namespace std; | |
class Codegen { | |
public: | |
Codegen(const float* pcm, unsigned int numSamples, int start_offset); | |
string getCodeString(){return _CodeString;} | |
int getNumCodes(){return _NumCodes;} | |
float getVersion() { return VERSION; } | |
private: | |
string _CodeString; | |
int _NumCodes; | |
}; | |
void fingerprint() | |
{ | |
// the input mp3 file, open as an ExtAudioFile for reading and converting | |
CFURLRef inputFileURL = (CFURLRef)[NSURL fileURLWithPath:@"/path/to/song/mp3"]]; | |
ExtAudioFileRef inputFileRef; | |
ExtAudioFileOpenURL(inputFileURL, &inputFileRef); | |
// setup an mono LPCM format description for conversion & set as the input file's client format | |
Float64 sampleRate = 11025; | |
CAStreamBasicDescription outputFormat; | |
outputFormat.mSampleRate = sampleRate; | |
outputFormat.mFormatID = kAudioFormatLinearPCM; | |
outputFormat.mChannelsPerFrame = 1; | |
outputFormat.mBitsPerChannel = 32; | |
outputFormat.mBytesPerPacket = outputFormat.mBytesPerFrame = 4 * outputFormat.mChannelsPerFrame; | |
outputFormat.mFramesPerPacket = 1; | |
outputFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked; | |
ExtAudioFileSetProperty(inputFileRef, kExtAudioFileProperty_ClientDataFormat, sizeof(outputFormat), &outputFormat); | |
// read the first 30 seconds of the file into a buffer | |
NSInteger secondsToDecode = 30; | |
UInt32 lpcm30SecondsBufferSize = sizeof(Float32) * sampleRate * secondsToDecode; // for mono, multi channel would require * ChannelsPerFrame | |
Float32 *lpcm30SecondsBuffer = (Float32 *)malloc(lpcm30SecondsBufferSize); | |
AudioBufferList audioBufferList; | |
audioBufferList.mNumberBuffers = 1; | |
audioBufferList.mBuffers[0].mNumberChannels = 1; | |
audioBufferList.mBuffers[0].mDataByteSize = lpcm30SecondsBufferSize; | |
audioBufferList.mBuffers[0].mData = lpcm30SecondsBuffer; | |
UInt32 numberOfFrames = sampleRate * secondsToDecode; | |
NSLog(@"Expect to read %d frames", numberOfFrames); | |
NSLogOSStatus(ExtAudioFileRead(inputFileRef, &numberOfFrames, &audioBufferList)); | |
NSLog(@"Actually read %d frames", numberOfFrames); | |
// get the fingerprint code | |
Codegen *codegen = new Codegen(lpcm30SecondsBuffer, numberOfFrames, 0); | |
NSString *fingerprintString = [NSString stringWithUTF8String:codegen->getCodeString().c_str()]; | |
NSLog(@"%@", fingerprintString); | |
// look up echonest | |
NSURL *fpLookupURL = [NSURL URLWithString:[NSString stringWithFormat:@"http://developer.echonest.com/api/v4/song/identify?api_key=YOUR_API_KEY_HERE&version=4.11&code=%@", fingerprintString]]; | |
NSString *response = [NSString stringWithContentsOfURL:fpLookupURL encoding:NSUTF8StringEncoding error:nil]; | |
NSLog(@"%@", response); | |
free(lpcm30SecondsBuffer); | |
ExtAudioFileDispose(inputFileRef); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment