Есть ли способ, на С#, на .NET, обрабатывать аудио "на лету"? Например, если я хочу оценить среднюю интенсивность звука AT в момент записи (для этого мне понадобится последняя пара миллисекунд).
Обработка звука "на лету" (С#, WP7)
Ответ 1
Инициализация микрофона и обработка записанных звуков:
private void Initialize()
{
Microphone microphone = Microphone.Default;
// 100 ms is a minimum buffer duration
microphone.BufferDuration = TimeSpan.FromMilliseconds(100);
DispatcherTimer updateTimer = new DispatcherTimer()
{
Interval = TimeSpan.FromMilliseconds(0.1)
};
updateTimer.Tick += (s, e) =>
{
FrameworkDispatcher.Update();
};
updateTimer.Start();
byte[] microphoneSignal = new byte[microphone.GetSampleSizeInBytes(microphone.BufferDuration)];
microphone.BufferReady += (s, e) =>
{
int microphoneDataSize = microphone.GetData(microphoneSignal);
double amplitude = GetSignalAmplitude(microphoneSignal);
// do your stuff with amplitude here
};
microphone.Start();
}
Амплитуда общего сигнала. Вы можете найти средние значения не во всех байтовых массивах, а в меньших окнах, чтобы получить амплитудную кривую:
private double GetSignalAmplitude(byte[] signal)
{
int BytesInSample = 2;
int signalSize = signal.Length / BytesInSample;
double Sum = 0.0;
for (int i = 0; i < signalSize; i++)
{
int sample = Math.Abs(BitConverter.ToInt16(signal, i * BytesInSample));
Sum += sample;
}
double amplitude = Sum / signalSize;
return amplitude;
}
Другие вещи для генерации звуков "на лету", которые помогут вам в будущем:
DynamicSoundEffectInstance generatedSound = new DynamicSoundEffectInstance(SampleRate, AudioChannels.Mono);
generatedSound.SubmitBuffer(buffer);
private void Int16ToTwoBytes(byte[] output, Int16 value, int offset)
{
output[offset + 1] = (byte)(value >> 8);
output[offset] = (byte)(value & 0x00FF);
}