2012-04-09 11 views
5

私はiOSとそのCの基礎から始めましたが、一般的なプログラミングではありません。私のジレンマはこれです。私は複雑なAudioUnitsベースのアプリケーションでエコーエフェクトを実装しています。アプリケーションでは、特に、リバーブ、エコー、および圧縮が必要です。しかし、私のアプリで生成されたオーディオサンプルに対して、特定のAudioStreamBasicDescriptionフォーマットを使用すると、エコーが正しく機能します。ただし、この形式は他のAudioUnitでは機能しません。 この問題を解決する他の方法はありますが、エコーアルゴリズムでビットツイイドリングを修正するのは最も単純なアプローチです。エコーで動作Float32のオーディオサンプルをSInt16にビットシフトすると、重大なクリッピングが発生します

* AudioStreamBasicDescription *はのmFormatFlagありますkAudioFormatFlagsAudioUnitCanonicalを。この仕様はあります:AudioUnitsと連携

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 

ストリーム形式は、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のフォーマットで、他のフォーマットでは動作しません。それが失敗すると、サウンドはクリップされて歪んでしまいますが、サウンドはそこにあります。私はこれが、これらの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間の差を決定することができた場合| kAudioFormatFlagsNativeEndian | | kAudioFormatFlagIsPacked | kAudioFormatFlagIsNonInterleaved、上記のメソッドを適宜変更することができます。しかし、私はそれを理解する方法がわかりません。 CoreAudioのドキュメントは不思議ですが、私がそこから読んだもので、CoreAudioTypes.hファイルから集められました。mFormatFlag(複数可)は同じ固定小数点8.24フォーマットを参照しています。明らかに何かが異なっていますが、私は何が分かりません。

この長い質問をお読みいただきありがとうございます。事前に感謝の意をお寄せいただきありがとうございます。

+0

私は何らかの理由で、クリッピングではなく歪みが発生している可能性が高いと考えています。何が起きているのかを見るために、アルゴリズムで生成されたWAVファイルをここに投稿できますか? –

+0

私のアプリは楽器として音を再生します。 Waveファイルを作成したり保存したりすることはありません。しかし、私はあなたが正しいと思います。基本的に、もし私がどのようなフォーマットを知っていたら* kAudioFormatFlagIsFloat | kAudioFormatFlagsNativeEndian | | kAudioFormatFlagIsPacked | kAudioFormatFlagIsNonInterleaved *は、SInt16の内部と外部でフォーマットされているビットトゥイードの仕方を理解することができます。現在、私が知っているのはFixedPointではないことです。8.24 –

答えて

11

kAudioFormatFlagIsFloatは、バッファに浮動小数点値が含まれていることを示します。 mBitsPerChannelが32の場合、floatデータ(Float32とも呼ばれます)を処理していて、64の場合はdoubleデータを処理しています。

kAudioFormatFlagsNativeEndianは、バッファ内のデータがプロセッサのエンディアンと一致するため、バイトスワッピングについて心配する必要はありません。

kAudioFormatFlagIsPackedは、データのすべてのビットが重要であることを意味します。たとえば、24ビットのオーディオデータを32ビットで格納する場合、このフラグは設定されません。

kAudioFormatFlagIsNonInterleavedは、個々のバッファが1チャンネルのデータで構成されていることを意味します。オーディオデータがインターリーブされるのは一般的であり、サンプルはLとRチャンネルの間で交互になります:LRLRLRLR。 DSPアプリケーションでは、データをデインタリーブして一度に1つのチャンネルで作業するほうが簡単です。

あなたのケースでは、浮動小数点データを固定小数点として扱っているというエラーがあると思います。浮動小数点データは一般に区間[-1、+1]にスケーリングされます。 floatSInt16に変換するには、各サンプルに最大16ビットの値(1u << 15、32768)を掛けて、[-32768,32767]の区間にクリップする必要があります。

+0

有益な答えをありがとう。実際、それは私が読んだことの多くを確認します。しかし、コールバックでAudioSampleバッファをFloat32 *にキャストしようとすると、警告が表示されます。 inSamplesLeft =(Float32 *)ioData-> mBuffers [0] .mData; 'AudioUnitSampleType *'(別名Float32)から 'AudioUnitSampleType *'(別名 'long *')に割り当てられた互換性のないポインタ型 –

+0

コードを見ることなく、何が起こっているのかを正確に知るのは難しいですが、 'を' float * 'に置き換え、正しい結果を得ることを期待します。 – sbooth

+0

私は別の刺し傷を負ってこの問題を解決し、あなたの答えを再読した後、私は良い進歩を遂げました。私はまだ多くの歪みがありますが、これは、私がFloat32をSInt16に変換するtrivalメソッドによって引き起こされる可能性があると思います。あなたは書いた16ビットのビットシフト構文について解説できますか?私はまだCプログラマーではなく、実装方法がわかりません:(1u << 15,32768) –

関連する問題