はじめに
waveファイルの仕様についてはググってください。
非常にわかりやすいフォーマットになっているので、すぐ理解できると思います。
本記事ではwaveファイルを読み込んで各値を取得するプログラムを示します。
プロジェクト
プロジェクトはC#のフォームアプリを選択してください。
Form1.cs[デザイン]
デザインは以下のような感じです。
waveファイルを読み込むと以下のようになります。
Form1.cs
namespace SampleFormWave { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { OpenFileDialog openFileDialog = new(); openFileDialog.Filter = "wave files (*.wav)|"; openFileDialog.Multiselect = false; if (openFileDialog.ShowDialog() == DialogResult.OK) { string[] filenames = openFileDialog.FileNames; WaveReader wr = new(); wr.read(filenames[0]); // show labelFilePath.Text = wr.FilePath; labelRealFileSize.Text = wr.RealFileSize.ToString(); labelRiffHeader.Text = wr.RiffHeader; labelFileSize.Text = wr.FileSize.ToString(); labelWaveHeader.Text = wr.WaveHeader; labelFormatChunk.Text = wr.FormatChunk; labelFormatChunkSize.Text = wr.FormatChunkSize.ToString(); labelFormatID.Text = wr.FormatID.ToString(); labelChannel.Text = wr.Channel.ToString(); labelSampleRate.Text = wr.SampleRate.ToString(); labelBytePerSec.Text = wr.BytePerSec.ToString(); labelBlockSize.Text = wr.BlockSize.ToString(); labelBitPerSample.Text = wr.BitPerSample.ToString(); labelDataChunk.Text = wr.DataChunk; labelDataChunkSize.Text = wr.DataChunkSize.ToString(); labelPlayTimeMsec.Text = wr.PlayTimeMsec.ToString(); } } } }
WaveReader.cs
waveファイルを読み込むクラスです。
using System.Text; namespace SampleFormWave { internal class WaveReader { public string FilePath; public int RealFileSize; public string RiffHeader; public int FileSize; public string WaveHeader; public string FormatChunk; public int FormatChunkSize; public int FormatID; public int Channel; public int SampleRate; public int BytePerSec; public int BlockSize; public int BitPerSample; public string DataChunk; public int DataChunkSize; public int PlayTimeMsec; /// <summary> /// constructor /// </summary> public WaveReader() { } /// <summary> /// read wave file /// </summary> /// <param name="waveFilePath">path of wave file</param> public void read(string waveFilePath) { // confirm file exists if (!File.Exists(waveFilePath)) { return; } using (FileStream fs = new(waveFilePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { try { BinaryReader br = new(fs); this.FilePath = waveFilePath; this.RealFileSize = (int)fs.Length; this.RiffHeader = Encoding.GetEncoding(20127).GetString(br.ReadBytes(4)); this.FileSize = BitConverter.ToInt32(br.ReadBytes(4), 0); this.WaveHeader = Encoding.GetEncoding(20127).GetString(br.ReadBytes(4)); bool readFmtChunk = false; bool readDataChunk = false; while (!readFmtChunk || !readDataChunk) { // red chunk string chunk = Encoding.GetEncoding(20127).GetString(br.ReadBytes(4)); if (chunk.ToLower().CompareTo("fmt ") == 0) { // read fmt chunk this.FormatChunk = chunk; this.FormatChunkSize = BitConverter.ToInt32(br.ReadBytes(4), 0); this.FormatID = BitConverter.ToInt16(br.ReadBytes(2), 0); this.Channel = BitConverter.ToInt16(br.ReadBytes(2), 0); this.SampleRate = BitConverter.ToInt32(br.ReadBytes(4), 0); this.BytePerSec = BitConverter.ToInt32(br.ReadBytes(4), 0); this.BlockSize = BitConverter.ToInt16(br.ReadBytes(2), 0); this.BitPerSample = BitConverter.ToInt16(br.ReadBytes(2), 0); readFmtChunk = true; } else if (chunk.ToLower().CompareTo("data") == 0) { // read data chunk this.DataChunk = chunk; this.DataChunkSize = BitConverter.ToInt32(br.ReadBytes(4), 0); // compute play time int bytesPerSec = this.SampleRate * this.BlockSize; this.PlayTimeMsec = (int) (((double) this.DataChunkSize / (double) bytesPerSec) * 1000); readDataChunk = true; } else { // read chunk Int32 size = BitConverter.ToInt32(br.ReadBytes(4), 0); if (0 < size) { br.ReadBytes(size); } } } } catch { fs.Close(); } } } } }