0

コード検出に関する論文に取り組んでいます。苦労した結果、私の問題の根本は、C# ベースのプログラムを使用して wav ファイルの振幅を取得することにあることがわかりました。

このコードを使用して振幅を取得しました。

public WavProcessing(String fileNameWithPath)
        {
            _fileNameWithPath = fileNameWithPath;

        }
public void Initialization()
        {
            AssignWaveHeaderData();
            streamBuffer = File.ReadAllBytes(_fileNameWithPath);
            fftBufferSize = 16384;
            fftBufferSize2 = fftBufferSize / 2;

        }
private void getAmplitude()
        {
            waveData = new short[numOfSamples];
            var xsample = new short[numOfSamples];
            var x = 0;
            var str = "";

            for (var i = 44 ; i <= waveData.Length; i = i + 2) //44 because the wave data          starts at 44th byte.
            {
               waveData[x] = BitConverter.ToInt16(streamBuffer,i);
               x++;

            }

    }

コードは最初は問題なく動作しました。コード検出プログラムでもある Delphi ベースのプログラムと比較しました。しかし、私が気付かなかったのは、私のコードは実際には振幅の半分の配列しか取得していないということです。

例: Chord C の wav ファイルを C# プログラムにロードすると、次のような振幅の配列が得られます。

[0] -279
[1] -262
[2] -231
[3] -216
[4] -199
[5] -185
[6] -178
[7] -186
[8] -217
[9] -237
[10] -267
[11] -298
[12] -319
[13] -348
[14] -374
[15] -373
[16] -376
[17] -366
[18] -357
[19] -340
[20] -319
[21] -312
[22] -300
[23] -301
[24] -308
[25] -321
[26] -339
...
[361042] 1950
[361043] 0
[361044] 0
...
[722128] 0

361043 番目の配列を開始すると、ゼロしか返されないことがわかります...これは、完全なストリーム サイズ (722128) の約半分です。

一方、誰かの Delphi プログラム (私はこれを参照として使用しました) では、そのコードは次のようになります。

procedure TForm1.openfilewave(NamaFile : string);
var
  Stream : TFileStream;
  i, start, endwave : Integer;
begin
  Application.ProcessMessages;
  Stream := TFileStream.Create(FileName, fmOpenRead);
  FillChar(wavehdr, SizeOf(wavehdr), 0);
  Stream.Read(wavehdr, SizeOf(wavehdr));

  SetLength(wavedata[0].Data, Round(wavehdr.chunkSize/wavehdr.BytesPerSample));

  for i := 0 to High(wavedata[0].Data) do
          begin
            Stream.Read(wavedata[0].Data[i], 2);
          end;
  end;

次のような振幅の完全な配列 (同じ wav ファイル) を返します。

0 -- -279
1 -- -262
2 -- -231
3 -- -216
4 -- -199
5 -- -185
6 -- -178
7 -- -186
8 -- -217
9 -- -237
10 -- -267
11 -- -298
12 -- -319
13 -- -348
14 -- -374
15 -- -373
16 -- -376
17 -- -366
18 -- -357
19 -- -340
20 -- -319
...
361042 -- 1950
361043 -- 1819       << not returning zero value
361044 -- 1655
361045 -- 1476
...
722100 -- 165
722101 -- 142
722102 -- 117
722103 -- 91
722104 -- 68
722105 -- 37
722106 -- 11
722107 -- -6
722108 -- -27
722109 -- -36
722110 -- 0
722111 -- 0
...
722128 -- 0

その Delphi プログラムでは、振幅の完全な配列が返され、次の計算で正しい値が得られます。

4

1 に答える 1

1

これが問題です:

for (var i = 44; i <= waveData.Length; i = i + 2)
{
   waveData[x] = BitConverter.ToInt16(streamBuffer,i);
   x++;
}

waveDataの半分のサイズですstreamBuffer-使用する必要があります:

for (var i = 44; i < streamBuffer.Length; i = i + 2)

または、変数を1つだけ使用して、次のように少し単純化します。

for (int x = 0; x < waveData.Length; x++)
{
   waveData[x] = BitConverter.ToInt16(streamBuffer, x * 2 + 44);
}
于 2012-04-24T07:25:33.757 に答える