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à:
- 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?
- 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ì?
- Mỗi bước trong biên độ PCM tuyến tính có ý nghĩa gì về mặt vật lý?
- 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.