2013-07-20 8 views
5

私はウェブ全体を検索しており、SoundTouch libraryをビート検出に使用する方法に関するチュートリアルを見つけることができません。iOS SoundTouch framework BPMの検出例

(注:。。。私は前にこれまでありませんC++の経験を持って、私はC、Objective-Cの、およびJavaだから私はこの一部を台無しにしている可能性があり、それはコンパイルを知っていますか)

私が追加

NSString *path = [[NSBundle mainBundle] pathForResource:@"song" ofType:@"wav"]; 

NSData *data = [NSData dataWithContentsOfFile:path]; 

player =[[AVAudioPlayer alloc] initWithData:data error:NULL]; 

player.volume = 1.0; 

player.delegate = self; 

[player prepareToPlay]; 
[player play]; 

NSUInteger len = [player.data length]; // Get the length of the data 

soundtouch::SAMPLETYPE sampleBuffer[len]; // Create buffer array 

[player.data getBytes:sampleBuffer length:len]; // Copy the bytes into the buffer 

soundtouch::BPMDetect *BPM = new soundtouch::BPMDetect(player.numberOfChannels, [[player.settings valueForKey:@"AVSampleRateKey"] longValue]); // This is working (tested) 

BPM->inputSamples(sampleBuffer, len); // Send the samples to the BPM class 

NSLog(@"Beats Per Minute = %f", BPM->getBpm()); // Print out the BPM - currently returns 0.00 for errors per documentation 

​​曲のバイト情報が私を混乱させる:私のプロジェクトへframeworkとは、コンパイルに次のことを得ることができました。

ソングファイルからこれらの情報を取得するにはどうすればよいですか?

私はmemcpy()を使ってみましたが、動作していないようです。

誰でも意見はありますか?

答えて

1

は時間とデバッグの時間やウェブ上の制限されたドキュメントを読んだ後、私はこの時につまずく前に、いくつかのことを変更:あなたはinputSamples()機能にnumberOfChannelsnumSamplesを分割する必要があります。

私の最終的なコードはそうのようなものです:

NSString *path = [[NSBundle mainBundle] pathForResource:@"song" ofType:@"wav"]; 

NSData *data = [NSData dataWithContentsOfFile:path]; 

player =[[AVAudioPlayer alloc] initWithData:data error:NULL]; 

player.volume = 1.0; // optional to play music 

player.delegate = self; 

[player prepareToPlay]; // optional to play music 
[player play];   // optional to play music 

NSUInteger len = [player.data length]; 

soundtouch::SAMPLETYPE sampleBuffer[len]; 

[player.data getBytes:sampleBuffer length:len]; 

soundtouch::BPMDetect BPM(player.numberOfChannels, [[player.settings valueForKey:@"AVSampleRateKey"] longValue]); 

BPM.inputSamples(sampleBuffer, len/player.numberOfChannels); 

NSLog(@"Beats Per Minute = %f", BPM.getBpm()); 
+0

SoundTouchライブラリをxcodeプロジェクトにどのように追加したのですか? – otakuProgrammer

+0

フレームワークをダウンロードしてプロジェクトにインポートするだけです。 – MrHappyAsthma

+0

ok私はxcodeプロジェクトにそれを組み込むことができました。上のコードはうまく動作しませんでした。アプリケーションがクラッシュしたとき、wavとmp3ファイルの両方を試したとき、soundtouchウェブサイトのorigオーディオサンプルを使用しても、クラッシュしましたissue、またはnan result(origサンプルオーディオを使用している場合) – otakuProgrammer

0

私はiOSのミュージックライブラリ内の(wavファイルに変換しTSLibraryImportクラスを使用して)mp3ファイルからBPMを読み取るために、このソリューションを試してみた:

       MPMediaItem *item = [collection representativeItem]; 

           NSURL *urlStr = [item valueForProperty:MPMediaItemPropertyAssetURL]; 

           TSLibraryImport* import = [[TSLibraryImport alloc] init]; 

           NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
           NSString *documentsDirectory = [paths objectAtIndex:0]; 

           NSURL* destinationURL = [NSURL fileURLWithPath:[documentsDirectory stringByAppendingPathComponent:@"temp_data"]]; 
           [[NSFileManager defaultManager] removeItemAtURL:destinationURL error:nil]; 

           [import importAsset:urlStr toURL:destinationURL completionBlock:^(TSLibraryImport* import) { 

            NSString *outPath = [documentsDirectory stringByAppendingPathComponent:@"temp_data"]; 


            NSData *data = [NSData dataWithContentsOfFile:outPath]; 
            AVAudioPlayer *player =[[AVAudioPlayer alloc] initWithData:data error:NULL]; 

            NSUInteger len = [player.data length]; 
            int numChannels = player.numberOfChannels; 

            soundtouch::SAMPLETYPE sampleBuffer[1024]; 

            soundtouch::BPMDetect *BPM = new soundtouch::BPMDetect(player.numberOfChannels, [[player.settings valueForKey:@"AVSampleRateKey"] longValue]); 


            for (NSUInteger i = 0; i <= len - 1024; i = i + 1024) { 

             NSRange r = NSMakeRange(i, 1024); 
             //NSData *temp = [player.data subdataWithRange:r]; 
             [player.data getBytes:sampleBuffer range:r]; 

             int samples = sizeof(sampleBuffer)/numChannels; 

             BPM->inputSamples(sampleBuffer, samples); // Send the samples to the BPM class 

            } 

            NSLog(@"Beats Per Minute = %f", BPM->getBpm()); 


           }]; 

ストレンジネスは、計算されたBMPは、常に同じ値であるということである。

2013-10-02 03:05:36.725 AppTestAudio[1464:1803] Beats Per Minute = 117.453835 

ありませんどのトラックがフレーム数かバッファサイズか(ここでは、ライブラリのソースコードのSoundTouchの例と同じ2Kのバッファサイズを使用していました)。スウィフト3については

0

https://github.com/Luccifer/BPM-Analyser

など、それを使用します。

guard let filePath = Bundle.main.path(forResource: "TestMusic", ofType: "m4a"), 
let url = URL(string: filePath) else {return "error occured, check fileURL"} 

BPMAnalyzer.core.getBpmFrom(url, completion: nil) 

はコメントをお気軽に!