.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ファイルのすべてのプロパティが返されます。
それはそれが実行されなかったことを言及するのは非常に漠然と/動作しませんでした。バグに関連している場合は、例外を記述してください。 –
私はそれらのことを言及しました。私は最初の1つの後にバッファ内の "データ"を見ていないと私のsubchunk2sizeは小さすぎる方法です。 – Thundercleez
データをフォーマットする方法を説明できますか?コードからは次のようになります: ヘッダー(40):chunksize(4):(データチャンクサイズ):(新しいバイトサイズ):(データチャンクサイズ):等... は正しいですか? – meganaut