내가해야할 것은 마이크 입력의 주파수를 계산하는 것입니다. 나는 이것을 IWaveProvider
과 Read()
으로 구현했습니다. 버퍼는 항상 8820 요소의 크기를 가지며 뭔가 바이트 배열에서 float 배열로의 변환도 잘못 될 수 있습니다 (FloatBuffer
속성 부분). DataAvailable 이벤트 핸들러가 다음 실행이라고C# 주파수 검색
private void InitializeSoundRecording()
{
WaveIn waveIn = new WaveIn();
waveIn.DeviceNumber = 0;
waveIn.DataAvailable += (s, e) => this.waveIn_DataAvailable(s, e);
waveIn.RecordingStopped += (s, e) => this.waveIn_RecordingStopped(s, e);
waveIn.WaveFormat = new WaveFormat(44100, 1);
waveIn.StartRecording();
}
:
private void waveIn_DataAvailable(object sender, WaveInEventArgs e)
{
WaveBuffer wb = new WaveBuffer(e.Buffer.Length);
IWaveProvider iWaveProvider = new PitchDetector(new WaveInProvider(sender as WaveIn), new WaveBuffer(e.Buffer));
iWaveProvider.Read(wb, 0, e.Buffer.Length);
PitchDetector pd = iWaveProvider as PitchDetector;
this.ShowPitch(pd.Pitch);
}
여기
내가 내 녹음을 시작 어디에
이 ... 중요한 비트 중 일부입니다
마지막으로 이것은 "실제"중요한 비트입니다.
private const int FLOAT_BUFFER_SIZE = 8820;
private IWaveProvider source;
private WaveBuffer waveBuffer;
private int sampleRate;
private float[] fftBuffer;
private float[] prevBuffer;
public float Pitch { get; private set; }
public WaveFormat WaveFormat { get { return this.source.WaveFormat; } }
internal PitchDetector(IWaveProvider waveProvider, WaveBuffer waveBuffer = null)
{
this.source = waveProvider;
this.sampleRate = waveProvider.WaveFormat.SampleRate;
this.waveBuffer = waveBuffer;
}
/// <summary>
/// UNSAFE METHOD!
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
private unsafe float[] ByteArrayToFloatArray(byte[] input)
{
float[] fb = new float[FLOAT_BUFFER_SIZE];
unsafe
{
fixed (byte* ptrBuffer = input)
{
float* ptrFloatBuffer = (float*)ptrBuffer;
for (int i = 0; i < FLOAT_BUFFER_SIZE; i++)
{
fb[i] = *ptrFloatBuffer;
ptrFloatBuffer++;
}
}
}
return fb;
}
public int Read(byte[] buffer, int offset = 0, int count = 0)
{
if (this.waveBuffer == null || this.waveBuffer.MaxSize < count)
this.waveBuffer = new WaveBuffer(count);
int readBytes = this.source.Read(this.waveBuffer, 0, count);
if (readBytes > 0) readBytes = count;
int frames = readBytes/sizeof(float);
this.Pitch = this.DeterminePitch(this.waveBuffer.FloatBuffer, frames);
return frames * 4;
}
이상하게도, 생성자에 들어갈 때 waveBuffer에 데이터 (255, 1, 0 등)가 포함되어 있지만 "버퍼"매개 변수가 Read()
인 것을 확인하면 완전히 0입니다. 모든 요소.
호기심에서 벗어난 이유는 무엇입니까? Read()
에는 버퍼 매개 변수가 있지만 실제로 메서드에서 전혀 사용되지 않습니다 (기사에서 해당 코드를 얻었습니다)?
이 문제를 해결할 수있는 도움이 있으면 대단히 감사하겠습니다. 나는 이미 이것에 대해 꽤 오래 있었지만 아무런 의미가 없다.
감사합니다, 알랭
처럼 사용할 수 있을까? – Jodrell
마크 히스 (Mark Heath) - NAudio의 기사 중 하나입니다. – Alain