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;
}






JavaScriptを使用しています。