私は iOS とその C 基盤は初めてですが、プログラミング全般については初心者です。私のジレンマはこれです。複雑な AudioUnits ベースのアプリケーションにエコー効果を実装しています。アプリケーションには、特にリバーブ、エコー、および圧縮が必要です。ただし、エコーは、アプリで生成されたオーディオ サンプルに特定のAudioStreamBasicDescription形式を使用した場合にのみ正しく機能します。ただし、この形式は他の AudioUnits では機能しません。この問題を解決する方法は他にもありますが、エコー アルゴリズムのビット調整を修正するのが最も簡単な方法かもしれません。
echo で動作する* 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を除いて同じです。kAudioFormatFlagsNativeEndian | 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空間に戻したり戻したりする 2 つの関数を使用します。私が言ったように、これはkAudioFormatFlagsAudioUnitCanonical形式では機能しますが、他の形式では機能しません。失敗すると、音が途切れたり歪んだりしますが、そこにはあります。これは、これら 2 つの形式の違いが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 | kAudioFormatFlagIsFloat | kAudioFormatFlagsNativeEndian | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsNonInterleavedの場合、それに応じて上記のメソッドを変更できます。しかし、私はそれを理解する方法がわかりません。CoreAudio のドキュメントは謎めいていますが、私がそこで読んだ内容とCoreAudioTypes.hファイルから収集した内容から、両方のmFormatFlag (s) は同じ Fixed Point 8.24 形式を参照しています。明らかに何かが違うのですが、何が違うのかわかりません。
この長い質問をお読みいただきありがとうございます。また、ご提供いただける洞察に感謝します。