2016-12-07 11 views
0

私はwavファイルを解析しようとしています。私はwavファイルに複数のデータチャンクが存在するかどうかはわかりませんが、当初はそこに書かれていたwavファイルフォーマットの記述から1つしかないと仮定しました。wavファイルの解析時に私は何が間違っていますか?

しかし、私は、subchunk2size (wavファイルが36MBのようなもので、サンプルレートが44100だったとき)(26のように)非常に小さくなっていました。

したがって、1つのチャンク見つけられる。

チャンクでチャンクを移動するには、私は...あなたは私が各データチャンクごとに繰り返されているチャンクサイズの一切の言及を参照してくださいいけない追加の参照では

を以下のコード

int chunkSize = System.BitConverter.ToInt32(strm, 40); 
int widx = 44; //wav data starts at the 44th byte 
//strm is a byte array of the wav file 
while(widx < strm.Length) 
{ 
    widx += chunkSize; 
    if(widx < 1000) 
    { 
     //log "data" or "100 97 116 97" for the subchunkid 
     //This is only getting printed the 1st time though. All prints after that are garbage 
     Debug.Log(strm[widx] + " " + strm[widx+1] + " " + strm[widx+2] + " " + strm[widx+3]); 
    } 
    if(widx + 8 < strm.Length) 
    { 
     widx += 4; 
     chunkSize = System.BitConverter.ToInt32(strm, widx); 
     widx += 4; 
    }else 
    { 
     widx += 8; 
    } 
} 
+0

それはそれが実行されなかったことを言及するのは非常に漠然と/動作しませんでした。バグに関連している場合は、例外を記述してください。 –

+0

私はそれらのことを言及しました。私は最初の1つの後にバッファ内の "データ"を見ていないと私のsubchunk2sizeは小さすぎる方法です。 – Thundercleez

+0

データをフォーマットする方法を説明できますか?コードからは次のようになります: ヘッダー(40):chunksize(4):(データチャンクサイズ):(新しいバイトサイズ):(データチャンクサイズ):等... は正しいですか? – meganaut

答えて

0

を使用していました

int chunkSize = System.BitConverter.ToInt32(strm, 40); 
int widx = 44; //wav data starts at the 44th byte 
//strm is a byte array of the wav file 
while(widx < strm.Length) 
{ 
    if(widx < 1000) 
    { 
     //log "data" or "100 97 116 97" for the subchunkid 
     //This is only getting printed the 1st time though. All prints after that are garbage 
     Debug.Log(strm[widx] + " " + strm[widx+1] + " " + strm[widx+2] + " " + strm[widx+3]); 
    }  
    widx += chunkSize; 
} 
+0

さて、私はそれが1しか言及していないことを知っていますが、他のチャンクがあるかどうかはわかりませんでした。私はちょうど別の "データ"チャンク識別子のためのデータの配列全体を検索しようとしたので、それは見えません。しかし、ファイルが36MBのときにsubchunk2sizeが26にすぎない理由は分かりません。それはそれよりはるかに大きいはずです。 1番目のチャンクサイズが偽であるため、wavファイルに何か問題があるかどうか疑問に思っています(私は0xffffffffを取得しています)。私はffmpegを使用してwavファイルを作成しているので、オプションがないかもしれませんか? – Thundercleez

+0

@Thundercleezファイルが壊れているようです。 ChunkSize(バイト4 - 8)を抜き出してみてください。 36 + SubChunk2Sizeに等しくなければなりません。 – meganaut

+0

このドキュメントの最後に、WAVファイルは一般的に古い形式を使用していると言われています。残念ながら、古い形式へのリンクが壊れています。私はあなたがデータのファイルを見て、すべてがあなたが期待している場所にいることを確認するべきだと思います。それがない場合は、 "データ"の単語(36-40で期待)を検索し、そこから作業するほうがよいかもしれません。 – meganaut

1

.WAV-ファイルは3つのチャンクを持っています: 各チャンクは4バイト

の大きさを持っている。このような何かを試してみてください

最初のチャンクは "RIFF"チャンクです。これには8バイトのファイルサイズ(4バイト)とフォーマットの名前(4バイト、通常は "WAVE")が含まれます。

次のチャンクは "fmt"チャンクです(チャンク名のスペースが重要です)。これは、オーディオフォーマット(2バイト)、チャネル数(2バイト)、サンプルレート(4バイト)、バイトレート(4バイト)、ブロックアライメント(2バイト)およびサンプルあたりのビット数(2バイト) 。

3番目と最後のチャンクはデータチャンクです。実際のデータとサンプルの振幅があります。これにはデータサイズの4バイトが含まれます。データサイズはデータのバイト数です。

.wavファイルのプロパティの詳細については、hereを参照してください。

using System; 
using System.IO; 
using System.Text; 

このクラスは、バイトあたりのすべてのチャンクのバイトを読み取り、プロパティを設定します。

public sealed class WaveFile 
{ 
    //privates 
    private int fileSize; 
    private string format; 
    private int fmtChunkSize; 
    private int audioFormat; 
    private int numChannels; 
    private int sampleRate; 
    private int byteRate; 
    private int blockAlign; 
    private int bitsPerSample; 
    private int dataSize; 
    private int[][] data;//One array per channel 

    //publics 
    public int FileSize => fileSize; 
    public string Format => format; 
    public int FmtChunkSize => fmtChunkSize; 
    public int AudioFormat => audioFormat; 
    public int NumChannels => numChannels; 
    public int SampleRate => sampleRate; 
    public int ByteRate => byteRate; 
    public int BitsPerSample => bitsPerSample; 
    public int DataSize => dataSize; 
    public int[][] Data => data; 

    public WaveFile(string path) 
    { 
     FileStream fs = File.OpenRead(path); 
     LoadChunk(fs); //read RIFF Chunk 
     LoadChunk(fs); //read fmt Chunk 
     LoadChunk(fs); //read data Chunk 
     fs.Close(); 
    } 

    private void LoadChunk(FileStream fs) 
    { 
     ASCIIEncoding Encoder = new ASCIIEncoding(); 
     byte[] bChunkID = new byte[4]; 

     fs.Read(bChunkID, 0, 4); 
     string sChunkID = Encoder.GetString(bChunkID); 

     byte[] ChunkSize = new byte[4]; 

     fs.Read(ChunkSize, 0, 4); 

     if (sChunkID.Equals("RIFF")) 
     { 
      fileSize = BitConverter.ToInt32(ChunkSize, 0); 

      byte[] Format = new byte[4]; 
      fs.Read(Format, 0, 4); 
      this.format = Encoder.GetString(Format); 
     } 

     if (sChunkID.Equals("fmt ")) 
     { 
      fmtChunkSize = BitConverter.ToInt32(ChunkSize, 0); 
      byte[] audioFormat = new byte[2]; 
      fs.Read(audioFormat, 0, 2); 
      this.audioFormat = BitConverter.ToInt16(audioFormat, 0); 
      byte[] numChannels = new byte[2]; 
      fs.Read(numChannels, 0, 2); 
      this.numChannels = BitConverter.ToInt16(numChannels, 0); 
      byte[] sampleRate = new byte[4]; 
      fs.Read(sampleRate, 0, 4); 
      this.sampleRate = BitConverter.ToInt32(sampleRate, 0); 
      byte[] byteRate = new byte[4]; 
      fs.Read(byteRate, 0, 4); 
      this.byteRate = BitConverter.ToInt32(byteRate, 0); 
      byte[] blockAlign = new byte[2]; 
      fs.Read(blockAlign, 0, 2); 
      this.blockAlign = BitConverter.ToInt16(blockAlign, 0); 
      byte[] bitsPerSample = new byte[2]; 
      fs.Read(bitsPerSample, 0, 2); 
      this.bitsPerSample = BitConverter.ToInt16(bitsPerSample, 0); 
     } 

     if (sChunkID.Equals("data")) 
     { 
      dataSize = BitConverter.ToInt32(ChunkSize, 0); 
      data = new int[this.numChannels][]; 

      byte[] temp = new byte[dataSize]; 

      for (int i = 0; i < this.numChannels; i++) 
      { 
       data[i] = new int[this.dataSize/(numChannels * bitsPerSample/8)]; 
      } 

      for (int i = 0; i < data[0].Length; i++) 
      { 
       for (int j = 0; j < numChannels; j++) 
       { 
        if (fs.Read(temp, 0, blockAlign/numChannels) > 0) 
        { 
         if (blockAlign/numChannels == 2) 
         { data[j][i] = BitConverter.ToInt32(temp, 0); } 
         else 
         { data[j][i] = BitConverter.ToInt16(temp, 0); } 

        } 
       } 
      } 
     } 
    } 
} 

必要な使用-ディレクティブ:この知識から

は、私はすでに、次のクラスを作成しています。このクラスを初期化するだけで、選択したwaveファイルのすべてのプロパティが返されます。

関連する問題