Я новичок в iOS и ее основах C, но не в программировании в целом. Моя дилемма такова. Я реализую эффект эха в сложном приложении на основе AudioUnits. Приложение, среди прочего, нуждается в реверберации, эхе и сжатии. Однако эхо работает правильно, только когда я использую определенный формат AudioStreamBasicDescriptionдля аудиосэмплов, созданных в моем приложении. Однако этот формат не работает с другими AudioUnits. Хотя есть и другие способы решения этой проблемы, исправление перестановки битов в эхо-алгоритме может быть самым прямым подходом.
* AudioStreamBasicDescription*, который работает с эхом, имеет mFormatFlagиз: kAudioFormatFlagsAudioUnitCanonical; Его особенности:
AudioUnit Stream Format (ECHO works, NO AUDIO UNITS)
Sample Rate: 44100
Format ID: lpcm
Format Flags: 3116 = kAudioFormatFlagsAudioUnitCanonical
Bytes per Packet: 4
Frames per Packet: 1
Bytes per Frame: 4
Channels per Frame: 2
Bits per Channel: 32
Set ASBD on input
Set ASBD on output
au SampleRate rate: 0.000000, 2 channels, 12 formatflags, 1819304813 mFormatID, 16 bits per channel
Формат потока, который работает с AudioUnits, тот же, за исключением mFormatFlag: kAudioFormatFlagIsFloat | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsNonInterleaved-- Его особенности таковы:
AudioUnit Stream Format (NO ECHO, AUDIO UNITS WORK)
Sample Rate: 44100
Format ID: lpcm
Format Flags: 41
Bytes per Packet: 4
Frames per Packet: 1
Bytes per Frame: 4
Channels per Frame: 2
Bits per Channel: 32
Set ASBD on input
Set ASBD on output
au SampleRate rate: 44100.000000, 2 channels, 41 formatflags, 1819304813 mFormatID, 32 bits per channel
Чтобы создать эффект эха, я использую две функции, которые сдвигают данные выборки в пространство SInt16и обратно.Как я уже сказал, это работает для формата kAudioFormatFlagsAudioUnitCanonical, но не для другого. Когда это не удается, звуки обрезаются и искажаются, но они есть. Я думаю, это указывает на то, что разница между этими двумя форматами заключается в том, как данные расположены в Float32.
// convert sample vector from fixed point 8.24 to SInt16
void fixedPointToSInt16( SInt32 * source, SInt16 * target, int length ) {
int i;
for(i = 0;i < length; i++ ) {
target[i] = (SInt16) (source[i] >> 9);
//target[i] *= 0.003;
}
}
*Как видите, я попытался изменить амплитуду сэмплов, чтобы избавиться от клиппирования --ясно, что это не сработало.
// convert sample vector from SInt16 to fixed point 8.24
void SInt16ToFixedPoint( SInt16 * source, SInt32 * target, int length ) {
int i;
for(i = 0;i < length; i++ ) {
target[i] = (SInt32) (source[i] << 9);
if(source[i] < 0) {
target[i] |= 0xFF000000;
}
else {
target[i] &= 0x00FFFFFF;
}
}
}
Если я могу определить разницу между kAudioFormatFlagIsFloat | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsNonInterleaved, то я могу соответствующим образом изменить вышеуказанные методы. Но я не уверен, как это понять. Документация в CoreAudio загадочна, но из того, что я там прочитал и почерпнул из файла CoreAudioTypes.h, оба mFormatFlag(s) относятся к одному и тому же формату Fixed Point 8.24. Явно что-то не так, но не могу понять что.
Спасибо, что прочитали этот длинный вопрос, и заранее спасибо за любую информацию, которую вы можете дать.