C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト


■88041 / )  Re[3]: C#でのwaveファイルの波形表示
□投稿者/ 魔界の仮面弁士 (1753回)-(2018/07/30(Mon) 17:24:41)
No88027 (akaveco さん) に返信
>> switch (waveHeader.BitPerSample) での判定が、
>>  case 8:
>>  case 16:
>> の 2 つしか無いからでしょうか。
> この部分にcase 24やcase 32などと追加するのは、なんとなくわかるのですが、
> 具体的にどうのように追加すればいいのでしょうか?

詳しく調べたわけではないので、間違ってるかも知れませんが:


たとえば元データが
 var data = new byte[]{ 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0xFE, 0xDC, 0xBA, 0x98, …};
だとして、ステレオチャンネルで分解する場合は、
 case 8:
  dataL = new byte[] { 0x12,       0x56,       0x9A,       0xDE,       0xFE,       0xBA,       …};
  dataR = new byte[] {       0x34,       0x78,       0xBC,       0xF0,       0xDC,       0x98, …};
  break;
 case 16:
  dataL = new byte[] { 0x12, 0x34,             0x9A, 0xBC,             0xFE, 0xDC,             …};
  dataR = new byte[] {             0x56, 0x78,             0xDE, 0xF0,             0xBA, 0x98, …};
  break;
 case 24:
  dataL = new byte[] { 0x12, 0x34, 0x56,                   0xDE, 0xF0, 0xFE,                   …};
  dataR = new byte[] {                   0x78, 0x9A, 0xBC,                   0xDC, 0xBA, 0x98, …};
  break;
 case 32:
  dataL = new byte[] { 0x12, 0x34, 0x56, 0x78,                         0xFE, 0xDC, 0xBA, 0x98, …};
  dataR = new byte[] {                         0x9A, 0xBC, 0xDE, 0xF0,                         …};
  break;
のように割り振られていくと思います。Left→Right の順に並んでいるそうなので。

先のサンプルでは chanelIndex == 1 の時に Left 系配列、
chanelIndex == 2 だと Right 系配列に代入していっていますね。

ただし上記は、PCM 系フォーマットの場合の話。
各チャンネルにどの要素音が割り当てられるのかは、音声フォーマットによっても
異なるようなので、先の URL からリンクされている下記の資料も読んでおいた方が良さそうです。
http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Docs/multichaudP.pdf


一方、各チャンネルにおけるバイナリから波形データへの復元については、ビット数に応じて
 case 8:
  SByte int8 = (sbyte)data[n];
  n++;
  break;
 case 16:
  Int16 int16 = BitConverter.ToInt16(data, n);
  n += 2;
  break;
 case 24:
  data4[0] = data[n + 0];
  data4[1] = data[n + 1];
  data4[2] = data[n + 2];
  data4[3] = (byte)0;
  Int32 int24 = BitConverter.ToInt32(data4, 0);
  n += 3;
  break;
 case 32:
  Int32 int32 = BitConverter.ToInt32(data4, n);
  n += 4;
  break;
のようなイメージになると思います。先のサンプルでは、変換結果を
 int work;  // この変数が、上記の int8, int16, int24, int32 に相当
 int[] valuesL;
 int[] valuesR;
へ代入しているようなので、適宜読み替えてみてください。


もしも PCM 系フォーマットではなく、float 系フォーマットだった場合には、
BitConverter.ToInt16 の代わりに BitConverter.ToSingle が使えるのかな…。

返信 編集キー/


管理者用

- Child Tree -