Playlist Generator  1.0
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Properties Defines
GetPCMFromFile.mm
Go to the documentation of this file.
00001 /*
00002  *  GetPCMFromFile.cpp
00003  *
00004  *  Created by Brian Whitman on 7/10/10.
00005  *  Copyright 2010 The Echo Nest. All rights reserved.
00006  *
00007  */
00008 #include <AudioToolbox/AudioToolbox.h>
00009 #include "CAStreamBasicDescription.h"
00010 #include "Codegen_wrapper.h"
00011 #include <stdio.h>
00012 #import <CoreFoundation/CoreFoundation.h>
00013    
00014     //extern void NSLog(CFStringRef format, ...); 
00015 
00016 
00017 const char * GetPCMFromFile(char * filename); 
00018 
00019     const char * GetPCMFromFile(char * filename) {
00020         
00021         CFURLRef audioFileURL =
00022         CFURLCreateFromFileSystemRepresentation (           // 1
00023                                                  NULL,                                           // 2
00024                                                  (const UInt8 *) filename,                       // 3
00025                                                  strlen (filename),                              // 4
00026                                                  false                                           // 5
00027                                                  );
00028         //CFURLRef audioFileURL = CFURLCreateWithFileSystemPath(NULL, filename, kCFURLHFSPathStyle, false);
00029         
00030         printf("%s", filename);
00031         ExtAudioFileRef outExtAudioFile;
00032         int err = ExtAudioFileOpenURL(audioFileURL, &outExtAudioFile);
00033         if (err) {
00034             printf("\nErr: %i \n", err); 
00035         }
00036         
00037         
00038         CAStreamBasicDescription clientFormat;
00039         clientFormat.mSampleRate = 11025;
00040         clientFormat.mFormatID = kAudioFormatLinearPCM;
00041         clientFormat.mChannelsPerFrame = 2;
00042         clientFormat.mBitsPerChannel = 32;
00043         clientFormat.mBytesPerPacket = clientFormat.mBytesPerFrame = 4 * clientFormat.mChannelsPerFrame;
00044         clientFormat.mFramesPerPacket = 1;
00045         clientFormat.mFormatFlags =  kAudioFormatFlagsNativeFloatPacked;// | kAudioFormatFlagIsNonInterleaved;
00046         
00047         int size = sizeof(clientFormat);
00048         err = ExtAudioFileSetProperty(outExtAudioFile, kExtAudioFileProperty_ClientDataFormat, size, &clientFormat);
00049         if (err) {
00050             //NSLog(CFSTR("err on set format %d"), err);
00051         }
00052         int seconds_to_decode = 30;
00053         int bytes_for_bigbuf = sizeof(float)*11025*seconds_to_decode;
00054         float *bigBuf = (float*) malloc(bytes_for_bigbuf);
00055         if(bigBuf == NULL) {
00056             //NSLog(CFSTR("Error mallocing bigbuf"));
00057         }
00058         int totalFrames = 0;
00059         while (1) {
00060             AudioBufferList fillBufList;
00061             fillBufList.mNumberBuffers = 1;
00062             UInt32 bufferByteSize = 11025 * 4 * 2; // 1s of audio
00063             char srcBuffer[bufferByteSize];
00064             UInt32 numFrames = clientFormat.BytesToFrames(bufferByteSize); // (bufferByteSize / clientFormat.mBytesPerFrame);
00065             
00066             fillBufList.mBuffers[0].mNumberChannels = clientFormat.NumberChannels();
00067             fillBufList.mBuffers[0].mDataByteSize = bufferByteSize;
00068             fillBufList.mBuffers[0].mData = srcBuffer;
00069             err = ExtAudioFileRead(outExtAudioFile, &numFrames, &fillBufList);  
00070             if (err) { 
00071                 //NSLog(CFSTR("err on read %d"), err);
00072                 totalFrames = 0;
00073                 break;
00074             }
00075             if (!numFrames)
00076                 break;
00077             
00078             float mono_version[numFrames];
00079             float* float_buf = (float*) fillBufList.mBuffers[0].mData;
00080             for(int i=0;i<numFrames;i++)
00081                 mono_version[i] = (float_buf[i*2] + float_buf[i*2 + 1]) / 2.0;
00082             
00083             int bytesLeftInBuffer = bytes_for_bigbuf - (totalFrames * sizeof(float));
00084             
00085             if (numFrames * sizeof(float) > bytesLeftInBuffer) {
00086                 memcpy(bigBuf + totalFrames, mono_version, bytesLeftInBuffer);
00087                 totalFrames = totalFrames + (bytesLeftInBuffer/4);
00088                 break;
00089             } else {
00090                 memcpy(bigBuf + totalFrames, mono_version, numFrames * sizeof(float));
00091                 totalFrames = totalFrames + numFrames;
00092             }
00093         }
00094         
00095         const char * what = "";
00096         if(totalFrames > 11025) {
00097             //NSLog(CFSTR("Doing codegen on %d samples..."), totalFrames);
00098             what = codegen_wrapper(bigBuf,      totalFrames);
00099             //NSLog(CFSTR("Done with codegen"));
00100             
00101         }
00102         free(bigBuf);
00103         //printf("\n %f \n", bigBuf[50]);
00104         return what;
00105     }