How to separate frequency from audio file (.wav)
I want to separate low, mid and high frequencies from .wav file. for that i have used FFT to convert data from time domain to frequency domain.
code for reading file and applying Fast Fourier Transform with help of NAudio is like
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();
Now I got the frequency domain data and I have plotted it on ZedGraph with Amplitude on Y-axis and Frequency on X-axis. FFT output on ZedGraph
Now I have complex data as FFT out with me, but how to separate below listed frequencies from given data and how to generate or play file of that particular frequency.
Any advise or guidance would be greatly appreciated..!!
If you just want to filter an audio stream, you are heading down a computationally expensive approach. FFTs are great for identifying spectral signatures. But if you want to go form time to frequency and back to time, that's a lot of number crunching (and you will most likely not like what you hear). If you keep the currently stated path, you will need to do some form of masking in the frequency domain, then convert back to time. When you convert back to time (a real product) it's going to sound "dirty" (you will need to implement some form of an imaginary to real merge). In your code, you form a magnitude squared to get back to a real time series (note - this will give you a rectified signal - which should sound hissy).
If you want to isolate a particular band, start with some form of a FIR band pass filter. If you want to hear the result as you are developing, check out examples of how to use the Android AudioTrack class.
链接地址: http://www.djcxy.com/p/33848.html上一篇: 在C中学习SDL
下一篇: 如何从音频文件(.wav)中分离频率