2013-07-20 52 views
5

Tôi đã tìm kiếm trên toàn bộ web và không thể tìm thấy hướng dẫn về cách sử dụng SoundTouch library để phát hiện nhịp.Khuôn khổ SoundTouch iOS Ví dụ về phát hiện BPM

(Lưu ý:... Tôi không có C++ kinh nghiệm trước đây tôi biết C, Objective-C và Java Vì vậy, tôi có thể đã sai lầm một số này lên, nhưng nó biên dịch)

tôi thêm framework để dự án của tôi và quản lý để có được những điều sau đây để biên dịch:

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 

thông tin byte inputSamples(*samples, numSamples) bài hát confuses me.

Làm cách nào để nhận những mẩu thông tin này từ tệp bài hát?

Tôi đã thử sử dụng memcpy() nhưng dường như không hoạt động.

Mọi người đều có bất kỳ suy nghĩ nào?

Trả lời

1

Sau giờ và giờ gỡ lỗi và đọc tài liệu giới hạn trên web, tôi đã sửa đổi một số điều trước khi gặp phải vấn đề này: Bạn cần chia numSamples theo numberOfChannels trong chức năng inputSamples().

mã cuối cùng của tôi là như vậy:

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

Bạn có thể cho biết cách bạn thêm Thư viện SoundTouch vào dự án xcode không? – otakuProgrammer

+0

Bạn chỉ cần tải xuống khung công tác và nhập nó vào dự án của bạn. – MrHappyAsthma

+0

ok tôi đã quản lý để đưa nó vào dự án xcode, mã ở trên sẽ không hoạt động, một số lần ứng dụng bị treo, tôi đã thử cả tệp wav và mp3, thậm chí tôi đã sử dụng mẫu âm thanh orig từ trang web soundtouch, nó mang lại cho tôi sự cố vấn đề hoặc kết quả nan (khi sử dụng âm thanh mẫu orig) – otakuProgrammer

0

Tôi đã thử giải pháp này để đọc các BPM từ các tập tin mp3 (sử dụng lớp TSLibraryImport để chuyển đổi sang wav) bên trong iOS Thư viện Âm nhạc:

       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()); 


           }]; 

các lạ là tính toán BMP luôn là giá trị như nhau:

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

Không vấn đề theo dõi đó là số lượng khung hình hoặc kích thước bộ đệm (ở đây tôi đã sử dụng kích thước bộ đệm 2K như đối với ví dụ SoundTouch trong mã nguồn của thư viện).

0

Đối Swift 3:

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

Và sử dụng nó như:

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) 

Hãy bình luận!