低周波数、中周波数、高周波数を.wavファイルから分離したいと考えています。 私は時間領域から周波数領域にデータを変換するためにFFTを使用しています。ファイルを読み取り、高速フーリエNAudioの助けを借りて変換を適用するためのオーディオファイル(.wav)から周波数を分離する方法
コードは、今私は、周波数領域のデータを持って、私はXにY軸と周波数に振幅とZedGraph上にプロットされている
OpenFileDialog file = new OpenFileDialog();
file.ShowDialog();
WaveFileReader reader = new WaveFileReader(file.FileName);
int samepleRate = reader.WaveFormat.SampleRate;
double ts = 1.0/samepleRate;
int _fftLength = 4096;
double time = reader.TotalTime.TotalSeconds;
int channels = reader.WaveFormat.Channels;
int _m = (int)Math.Log(_fftLength, 2.0);
float fileSize = (float)reader.Length/1048576;
if (fileSize < 2)
window = 8;
else if (fileSize > 2 && fileSize < 4)
window = 16;
else if (fileSize > 4 && fileSize < 8)
window = 32;
else if (fileSize > 8 && fileSize < 12)
window = 128;
else if (fileSize > 12 && fileSize < 20)
window = 256;
else if (fileSize > 20 && fileSize < 30)
window = 512;
else
window = 2048;
byte[] readBuffer = new byte[reader.Length];
reader.Read(readBuffer,0,readBuffer.Length);
float[] data = ConvertByteToFloat(readBuffer,readBuffer.Length);
Complex[] fftBuffer= new Complex[_fftLength];
int fftPos = 0;
for (int i = 0; i < _fftLength; i++)
{
fftBuffer[fftPos].X = (float)(data[i] * NAudio.Dsp.FastFourierTransform.HammingWindow(i,_fftLength));
fftBuffer[fftPos].Y = 0;
fftPos++;
}
NAudio.Dsp.FastFourierTransform.FFT(true, _m, fftBuffer);
private float[] ConvertByteToFloat(byte[] array, int length)
{
int samplesNeeded = length/4;
float[] floatArr = new float[samplesNeeded];
for (int i = 0; i < samplesNeeded; i++)
{
floatArr[i] = (float)BitConverter.ToInt32(array, i * 4);
}
return floatArr;
}
//ZedGraph code
GraphPane myPane = zedGraphControl1.GraphPane;
myPane.Title.Text = "Frequency domain output";
PointPairList list1 = new PointPairList();
PointPairList list2 = new PointPairList();
for (int i = 0; i < fftBuffer.Length; i++)
{
list1.Add(i, fftBuffer[i].Y);
}
list2.Add(0, 0);
//list2.Add(time, 0);uncomment this and remove below to plot time domain graph
var maxIndex = -1;
var maxValue = 0f;
for (var j = 0; j < _fftLength/2; j++)
{
var value = fftBuffer[j].X * fftBuffer[j].X
+ fftBuffer[j].Y * fftBuffer[j].Y;
if (value > maxValue)
{
maxIndex = j;
maxValue = value;
}
var freq = maxIndex == -1 ? 0
: (ushort)Math.Round((_fftLength - maxIndex)/(_fftLength * ts));
list2.Add(freq, 0);
}
if (myCurve1 != null && myCurve2 != null)
{
myCurve1.Clear();
myCurve2.Clear();
}
myCurve1 = myPane.AddCurve(null, list1, Color.Blue, SymbolType.None);
myCurve1.IsX2Axis = true;
myCurve2 = myPane.AddCurve(null, list2, Color.Black, SymbolType.None);
myPane.XAxis.Scale.MaxAuto = true;
myPane.XAxis.Scale.MinAuto = true;
myPane.YAxis.Title.Text = "Amplitude";
myPane.XAxis.Title.Text = "Frequency";
zedGraphControl1.AxisChange();
zedGraphControl1.Invalidate();
のようなものです-軸。 FFT output on ZedGraph
今、私は私と一緒にFFTなどの複雑なデータを持っていますが、どのように与えられたデータから、リストされている周波数の下に分離し、どのように特定の周波数のファイルを生成したり、プレイします。
- 低 - 500Hzの 20Hzから
- ミッド - 500Hzの4kHzの
- ハイ4kHzのに20KHzの
に任意の助言や指導をいただければ幸いです..!
これらの周波数を分離してミキサーアプリケーションで使用する目的(DJミキシングを行うため)。私はいくつかのローパスとハイパスフィルタ関数を試してきましたが、このフィルタ関数が有効であるかどうかの後にデータが得られるかどうかは確かではありません。また、フィルタリングされたデータから.wavファイルを作成しようとしましたが、すべてのオーディオプレーヤーと。 .wavを保存して音声を再生することは私の目標ではありませんが、データが有効かどうかを確認する必要があります。私はちょうど低=>低、中=>中と高=高と2つの曲をミックスすることができるようにプレイ位置(基本的に時間領域)でデータ配列をフィルタリングする必要があります。 – Nitin