2010-11-26 5 views
1

私の質問はこの質問に関連していますが、逆です。 OPはリンクは、2つのsint16sサンプルを1つのuint32サンプルとして表します。

Split UInt32 (audio frame) into two SInt16s (left and right)?

2つの16ビットサンプル(左および右)に32ビットのフレームを分割したかったです。

私は2 16ビットのサンプルを持っています。私はそれらを単一の32ビットインターリーブフレームとして表現したいと思います。

私がこれまで試みたことは、このように見えます。

UInt32* ar = malloc(totalFramesInFile * sizeof (ar)); 

for (int b=0; b < totalFramesInFile; b++) 
{ 
    UInt32 l = soundStructArray[audioFile].audioDataLeft[b]; 
    UInt32 r = soundStructArray[audioFile].audioDataRight[b]; 

    UInt32 t = (UInt32) l + r; 

    ar[b] = t; 
} 
soundStructArray[audioFile].audioData = ar; 

正当で正しいですか?私は経験不足のために確信が持てません。私のオーディオ出力は少し独特の音がしています。私は間違ったことが何であるかを決定する排除のプロセスによって努力しています。

誰かが私がやっていることが2 16ビットサンプルを32ビットフレームとして表現したり、正しい方法を示唆したりする正しい方法であるかどうかを確認すると役に立ちます。

私がしたことが間違っていると感じています。 32ビットフレームの最初の16ビットは左にし、2番目の16ビットは右にする必要があるため、これを考えると思います。全体は2つの合計ではありません......私は思う。

+0

あなたのlとrのサンプルには、const UInt16タイプが必要ですか? – unwind

答えて

4

、変更する必要があります::

UInt32 t = (UInt32) l + r; 

へ:

UInt32 t = (l << 16) | (r & 0xffff); 

これは最下位の16ビットでtrの上位16ビットでlを置きます。

詳細説明

あなたはバイナリに次のようになり、2つの16ビットサンプル、lr、持っている場合:

l: LLLLLLLLLLLLLLLL 
r: RRRRRRRRRRRRRRRR 

レットの最初の32ビットにそれらを拡張します

l: 0000000000000000LLLLLLLLLLLLLLLL 
r: 0000000000000000RRRRRRRRRRRRRRRR 

次に、lを16ビット左にシフトしましょう(l << 16

l: LLLLLLLLLLLLLLLL0000000000000000 
r: 0000000000000000RRRRRRRRRRRRRRRR 

今、彼らは一緒に)(|をしてみましょうOR:

t: LLLLLLLLLLLLLLLLRRRRRRRRRRRRRRRR 

出来上がり!lrが32ビットの値にまとめられており、後から簡単に抽出できます。

+1

優れた説明! – dubbeat

+0

これは、*符号なし* 16ビットのサンプルが2つある場合にのみ機能します。負の符号付き16ビットサンプルは、すべての上位16ビットが「1」である符号なし32ビット数に変換される。 – caf

+0

@caf:true - 例をシンプルにするためにマスキングを省略しましたが、追加する必要があります。 –

2

私はこれをポールRの答えの補足として取り上げますが、コメントを入れるには少し時間がかかりました。

「明白な」別の解決方法は、明示的に32ビット値の上または下の16ビット値を設定することです。これは、ユニオンで行うことができます。

typedef union { 
    struct { 
     SInt16 high; 
     SInt16 low; 
    } parts; 
    UInt32 word; 
} IntConverter; 

使用法:それはデータが実際にメモリに格納される方法に依存しているので、

IntConverter * ar = malloc(totalFramesInFile * sizeof (IntConverter)); 

for (int b=0; b < totalFramesInFile; b++) 
{ 
    ar[b].parts.high = soundStructArray[audioFile].audioDataLeft[b]; 
    ar[b].parts.low = soundStructArray[audioFile].audioDataRight[b]; 
} 
soundStructArray[audioFile].audioData = (UInt32 *) ar; 

しかし、このアプローチは、基盤となるプラットフォームについてもう少し知っている必要があります。しかし、ターゲットプラットフォームとコンパイラによっては、より効率的である可能性があります。

+0

かなり役に立ちます。 "組合"は私には新しいものです。私は前にstructを見たことがあります – dubbeat

関連する問題