У меня возникают трудности с извлечением амплитудных данных из линейной PCM на iPhone, хранящихся в файле audio.caf.
Мои вопросы:
- Линейный PCM сохраняет выборки амплитуд как 16-битные значения.Это правильно?
- Как амплитуда сохраняется в пакетах, возвращаемых AudioFileReadPacketData ()?Разве при записи моно линейного PCM каждый сэмпл (в одном кадре, в одном пакете) не является просто массивом для SInt16?Каков порядок байтов (порядковый номер с прямым порядком байтов против младшего)?
- Что физически означает каждый шаг в линейной амплитуде PCM?
- Когда на iPhone записывается линейный PCM, является ли центральная точка0 (SInt16) или 32768 (UInt16)?Что означают максимальные минимальные значения в форме физической волны / давления воздуха?
и дополнительный вопрос: существуют ли формы волны звука / давления воздуха, которые микрофон iPhone не может измерить?
Мой код следующий:
// 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);
С этим кодом я почти всегда получаю минус 0 и максимум 128!Это не имеет смысла для меня.
Я записываю аудио с помощью AVAudioRecorder следующим образом:
// 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]);
}
Спасибо за любые идеи, которые вы можете предложить.Это мой первый проект, использующий Core Audio, поэтому не стесняйтесь разорвать мой подход!
PS Я пытался выполнить поиск в архивах списка Core Audio, но запрос продолжает выдавать ошибку: (* http://search.lists.apple.com/?q=linear+pcm+amplitude&cmd=Search%21&ul=coreaudio-api)
PPS Я смотрел:
http://en.wikipedia.org/wiki/Sound_pressure
http://en.wikipedia.org/wiki/Linear_PCM
http://wiki.multimedia.cx/index.php?title=PCM
Получить амплитуду в определенный момент времени в звуковом файле?
http://music.columbia.edu/pipermail/music-dsp/2002-April/048341.html
Я также прочитал полный обзор Core Audio и большую часть Руководства по программированию аудиосеанса,но мои вопросы остаются.