2010-09-30 52 views
10

Tôi đang gặp khó khăn khi trích xuất dữ liệu biên độ từ PCM tuyến tính trên iPhone được lưu trữ trong audio.caf.Trích xuất dữ liệu biên độ từ PCM tuyến tính trên iPhone

Câu hỏi của tôi là:

  1. cửa hàng Linear PCM biên độ mẫu như các giá trị 16-bit. Điều này có đúng không?
  2. Biên độ được lưu trữ trong các gói được trả về bởi AudioFileReadPacketData() như thế nào? Khi ghi lại PCM tuyến tính mono, không phải mỗi mẫu, (trong một khung, trong một gói) chỉ là một mảng cho SInt16? Thứ tự byte (big endian vs. little endian) là gì?
  3. Mỗi bước trong biên độ PCM tuyến tính có ý nghĩa gì về mặt vật lý?
  4. Khi PCM tuyến tính được ghi trên iPhone, là điểm trung tâm 0 (SInt16) hoặc 32768 (UInt16)? Giá trị tối đa có nghĩa là gì ở dạng sóng vật lý/áp suất không khí?

và câu hỏi tiền thưởng: Có sóng âm áp/sóng áp suất nào mà micrô iPhone không đo được không?

Mã của tôi sau:

// get the audio file proxy object for the audio 
AudioFileID fileID; 
AudioFileOpenURL((CFURLRef)audioURL, kAudioFileReadPermission, kAudioFileCAFType, &fileID); 

// get the number of packets of audio data contained in the file 
UInt64 totalPacketCount = [self packetCountForAudioFile:fileID]; 

// get the size of each packet for this audio file 
UInt32 maxPacketSizeInBytes = [self packetSizeForAudioFile:fileID]; 

// setup to extract the audio data 
Boolean inUseCache = false; 
UInt32 numberOfPacketsToRead = 4410; // 0.1 seconds of data 
UInt32 ioNumPackets = numberOfPacketsToRead; 
UInt32 ioNumBytes = maxPacketSizeInBytes * ioNumPackets; 
char *outBuffer = malloc(ioNumBytes); 
memset(outBuffer, 0, ioNumBytes); 

SInt16 signedMinAmplitude = -32768; 
SInt16 signedCenterpoint = 0; 
SInt16 signedMaxAmplitude = 32767; 

SInt16 minAmplitude = signedMaxAmplitude; 
SInt16 maxAmplitude = signedMinAmplitude; 

// process each and every packet 
for (UInt64 packetIndex = 0; packetIndex < totalPacketCount; packetIndex = packetIndex + ioNumPackets) 
{ 
    // reset the number of packets to get 
    ioNumPackets = numberOfPacketsToRead; 

    AudioFileReadPacketData(fileID, inUseCache, &ioNumBytes, NULL, packetIndex, &ioNumPackets, outBuffer); 

    for (UInt32 batchPacketIndex = 0; batchPacketIndex < ioNumPackets; batchPacketIndex++) 
    { 
     SInt16 packetData = outBuffer[batchPacketIndex * maxPacketSizeInBytes]; 
     SInt16 absoluteValue = abs(packetData); 

     if (absoluteValue < minAmplitude) { minAmplitude = absoluteValue; } 
     if (absoluteValue > maxAmplitude) { maxAmplitude = absoluteValue; } 
    } 
} 

NSLog(@"minAmplitude: %hi", minAmplitude); 
NSLog(@"maxAmplitude: %hi", maxAmplitude); 

Với mã này, tôi hầu như luôn luôn có được một phút từ 0 và tối đa là 128! Điều đó làm cho không có ý nghĩa với tôi.

Tôi ghi lại âm thanh bằng cách sử dụng AVAudioRecorder như sau:

// specify mono, 44.1 kHz, Linear PCM with Max Quality as recording format 
NSDictionary *recordSettings = [[NSDictionary alloc] initWithObjectsAndKeys: 
    [NSNumber numberWithFloat: 44100.0], AVSampleRateKey, 
    [NSNumber numberWithInt: kAudioFormatLinearPCM], AVFormatIDKey, 
    [NSNumber numberWithInt: 1], AVNumberOfChannelsKey, 
    [NSNumber numberWithInt: AVAudioQualityMax], AVEncoderAudioQualityKey, 
    nil]; 

// store the sound file in the app doc folder as calibration.caf 
NSString *documentsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; 
NSURL *audioFileURL = [NSURL fileURLWithPath:[documentsDir stringByAppendingPathComponent: @"audio.caf"]]; 

// create the audio recorder 
NSError *createAudioRecorderError = nil; 
AVAudioRecorder *newAudioRecorder = [[AVAudioRecorder alloc] initWithURL:audioFileURL settings:recordSettings error:&createAudioRecorderError]; 
[recordSettings release]; 

if (newAudioRecorder) 
{ 
    // record the audio 
    self.recorder = newAudioRecorder; 
    [newAudioRecorder release]; 

    self.recorder.delegate = self; 
    [self.recorder prepareToRecord]; 
    [self.recorder record]; 
} 
else 
{ 
    NSLog(@"%@", [createAudioRecorderError localizedDescription]); 
} 

Thanks cho bất kỳ cái nhìn sâu sắc, bạn có thể cung cấp. Đây là dự án đầu tiên của tôi sử dụng Core Audio, vì vậy hãy thoải mái xé toạc cách tiếp cận của tôi!

P.S. Tôi đã cố gắng tìm kiếm trong kho lưu trữ danh sách Core Audio, nhưng yêu cầu vẫn đưa ra một lỗi: (http://search.lists.apple.com/?q=linear+pcm+amplitude&cmd=Search%21&ul=coreaudio-api)

P.P.S. Tôi đã xem xét:

http://en.wikipedia.org/wiki/Sound_pressure

http://en.wikipedia.org/wiki/Linear_PCM

http://wiki.multimedia.cx/index.php?title=PCM

Get the amplitude at a given time within a sound file?

http://music.columbia.edu/pipermail/music-dsp/2002-April/048341.html

Tôi cũng đã đọc toàn bộ các Core Audio Tổng quan và hầu hết các âm thanh Lập trình phiên Hướng dẫn, nhưng câu hỏi của tôi vẫn còn.

Trả lời

7

1) os tập x/iphone đọc thói quen cho phép bạn xác định các định dạng mẫu, điển hình là một trong những SInt8, SInt16, SInt32, float32, Float64, hoặc tiếp giáp 24 bit ký int cho LPCM

2) cho các định dạng int, MIN_FOR_TYPE đại diện cho biên độ tối đa trong pha âm và MAX_FOR_TYPE đại diện cho biên độ tối đa trong tích cực. 0 bằng im lặng. các định dạng dấu chấm động điều chỉnh giữa [-1 ... 1], với 0 bằng float. khi đọc, viết, ghi âm hoặc làm việc với một định dạng cụ thể, tính cuối cùng sẽ quan trọng - một tệp có thể yêu cầu một định dạng cụ thể và bạn thường muốn thao tác dữ liệu theo độ tuổi gốc. một số thường trình trong tệp lib âm thanh của apple cho phép bạn chuyển một lá cờ biểu thị tính cuối cùng của nguồn, thay vì bạn chuyển đổi thủ công nó. CAF phức tạp hơn một chút - nó hoạt động như một trình bao bọc meta cho một hoặc nhiều tệp âm thanh và hỗ trợ nhiều loại.

3) biểu diễn biên độ cho lpcm chỉ là biểu diễn biên độ tuyến tính brute-force (không cần chuyển đổi/giải mã để phát lại và các bước biên độ bằng nhau).

4) xem # 2. các giá trị không liên quan đến áp suất không khí, chúng có liên quan đến 0 dBFS; ví dụ. nếu bạn outputting dòng thẳng đến một DAC, sau đó int max (hoặc -1/1 nếu floating point) đại diện cho mức mà tại đó một mẫu riêng lẻ sẽ clip.

Tiền thưởng), giống như mọi bộ ADC và chuỗi thành phần có giới hạn về những gì nó có thể xử lý trên đầu vào về điện áp. ngoài ra, tốc độ lấy mẫu xác định tần số cao nhất có thể được ghi lại (cao nhất là một nửa tỷ lệ lấy mẫu). adc có thể sử dụng độ sâu bit cố định hoặc có thể chọn, nhưng điện áp đầu vào tối đa thường không thay đổi khi chọn độ sâu bit khác.

một lỗi mà bạn đang thực hiện ở cấp mã: bạn đang thao tác `outBuffer 'làm ký tự - chứ không phải SInt16

2
  1. Nếu bạn yêu cầu mẫu 16 bit ở định dạng ghi, bạn sẽ nhận được mẫu 16 bit. Nhưng các định dạng khác tồn tại trong nhiều API bản ghi/phát âm thanh Core và trong các định dạng tệp tin có thể có của caf.

  2. Trong mono, bạn chỉ nhận được một mảng int có 16 bit đã ký. Bạn có thể yêu cầu cụ thể cho người lớn hoặc nhỏ trong một số API ghi âm Core.Trừ khi bạn muốn hiệu chỉnh micrô của mẫu thiết bị cụ thể hoặc micrô bên ngoài của bạn (và đảm bảo xử lý âm thanh/AGC bị tắt), bạn có thể muốn xem xét các mức âm thanh được chia tỷ lệ tùy ý. Ngoài ra, phản hồi cũng thay đổi theo hướng micrô và tần số âm thanh.

  3. Điểm trung tâm cho mẫu âm thanh 16 bit thường là 0 (khoảng từ -32k đến 32k). Không thiên vị.

Các vấn đề liên quan