Waveファイルを読み込んで、Waveヘッダー情報構造体で返す
Category - C# のメモ - [3]
Waveファイルを読み込んで、ヘッダー情報を構造体で返します。
Waveファイルを読むついでに、Waveファイルの再生時間も計算します。
まずは、 Waveヘッダー情報の構造体 WaveHeaderObj を定義します。
(参照)
using System.Runtime.InteropServices; // for DllImport , StructLayout関係
// Waveファイルヘッダー情報 [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct WaveHeaderObj { public string riffHeader; public int fileSize; public string waveHeader; public string fmtChank; public int fmtChankSize; public short formatID; public short channel; public int sampleRate; public int bytePerSec; public short blockSize; public short bitPerSample; public string dataChank; public int dataChankSize; public int PlayTimeMs; }
★Waveファイルを読み込んで、Waveヘッダー情報構造体で返す
// ====================================================================== // Waveファイルのヘッダー情報を返す // ====================================================================== /// <summary> /// ファイル(パス)を指定してWaveファイルのヘッダー情報を読み込んで返す。 /// 成功:nResult に 1を格納。 失敗:nResult に -1を格納。 ファイル存在しない:nResult に 0を格納。 /// </summary> /// <param name="sFilePath">ファイル(パス)</param> /// <returns>WaveHeaderObj</returns> public static WaveHeaderObj ReadWaveHeader(string sFilePath, ref short nResult) { short nRlt = -1; WaveHeaderObj wh = new WaveHeaderObj(); try { if (!File.Exists(sFilePath)) { nResult = 0; return wh; } FileStream fs = new FileStream(sFilePath, FileMode.Open, FileAccess.Read, FileShare.Read); try { BinaryReader br = new BinaryReader(fs); wh.riffHeader = System.Text.Encoding.GetEncoding(20127).GetString(br.ReadBytes(4)); wh.fileSize = BitConverter.ToInt32(br.ReadBytes(4), 0); wh.waveHeader = System.Text.Encoding.GetEncoding(20127).GetString(br.ReadBytes(4)); wh.fmtChank = System.Text.Encoding.GetEncoding(20127).GetString(br.ReadBytes(4)); // WAVEファイルかチェック if (wh.riffHeader.ToUpper() == "RIFF" && wh.waveHeader.ToUpper() == "WAVE" && wh.fmtChank.ToLower().Trim() == "fmt") { // ----- formatID ----- //0x0000 unknown //0x0001 PCM //0x0002 MS ADPCM //0x0005 IBM CSVD //0x0006 A-Law Windows 標準サポート //0x0007 μ-Law // ..... // ..... wh.fmtChankSize = BitConverter.ToInt32(br.ReadBytes(4), 0); wh.formatID = BitConverter.ToInt16(br.ReadBytes(2), 0); wh.channel = BitConverter.ToInt16(br.ReadBytes(2), 0); wh.sampleRate = BitConverter.ToInt32(br.ReadBytes(4), 0); wh.bytePerSec = BitConverter.ToInt32(br.ReadBytes(4), 0); wh.blockSize = BitConverter.ToInt16(br.ReadBytes(2), 0); wh.bitPerSample = BitConverter.ToInt16(br.ReadBytes(2), 0); // サンプルあたりのビット数 (bit/sample) WAV フォーマットでは 8bit か 16bit // dataチャンクを探す bool bMatch = false; int n = 0; string s = ""; for (int i = 0; i < br.BaseStream.Length; i++) { // 1バイトづつ読んで data 文字を探す s = System.Text.Encoding.GetEncoding(20127).GetString(br.ReadBytes(1)); switch (n) { case 1: if (s.ToLower() == "a") n++; else if (s.ToUpper() == "d") n = 1; else n = 0; break; case 2: if (s.ToLower() == "t") n++; else if (s.ToUpper() == "d") n = 1; else n = 0; break; case 3: if (s.ToLower() == "a") { bMatch = true; break; } else if (s.ToUpper() == "d") n = 1; else n = 0; break; default: if (s.ToLower() == "d") n = 1; else n = 0; break; } if (bMatch) { wh.dataChank = "data"; wh.dataChankSize = BitConverter.ToInt32(br.ReadBytes(4), 0); int n1SecBytes = wh.sampleRate * wh.channel * wh.blockSize; // 1秒再生するのに使用するバイト数 //int n1SecBytes = wh.sampleRate * wh.channel * (wh.bitPerSample / 8); // 上のと同じこと wh.PlayTimeMs = (int)(((double)wh.dataChankSize / (double)n1SecBytes) * 1000); // 全再生時間(ミリ秒)を計算していれとく //System.Diagnostics.Debug.WriteLine("PLAYTIME:" + wh.PlayTimeMs.ToString()); nRlt = 1; break; } } } } catch { } fs.Close(); } catch { } nResult = nRlt; return wh; }