Направление микрофонного ввода на динамики и написание пользовательской функции DSP с библиотекой CSCore
CSCore ( https://github.com/filoe/cscore), кажется, очень хорошая аудио библиотека для C#, но ей не хватает документации и хороших примеров.
Я давно играю с Bass.Net, и архитектура CSCore не похожа на библиотеку Bass, поэтому очень сложно найти правильный способ решения некоторых общих задач.
Я пытаюсь захватить вход микрофона с устройства WasapiCapture и вывести записанные данные на устройство WasapiOut, но мне это не удалось.
Ниже приведен код, который я смог найти после поиска в Google, но он не работает.
MMDeviceEnumerator deviceEnum = new MMDeviceEnumerator();
MMDeviceCollection devices = deviceEnum.EnumAudioEndpoints(DataFlow.Capture, DeviceState.Active);
using (var capture = new WasapiCapture())
{
capture.Device = deviceEnum.GetDefaultAudioEndpoint(DataFlow.Capture, Role.Multimedia);
capture.Initialize();
using (var source = new SoundInSource(capture))
{
using (var soundOut = new WasapiOut())
{
capture.Start();
soundOut.Device = deviceEnum.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia);
soundOut.Initialize(source);
soundOut.Play();
}
}
}
То, что я пытаюсь сделать, это написать приложение, подобное этому: http://www.pitchtech.ch/PitchBox/
У меня есть свои собственные функции DSP, которые я хочу применить к записанным данным.
У кого-нибудь есть примеры направления WasapiCapture в WasapiOut и написания собственного DSP?
РЕДАКТИРОВАТЬ:
Я нашел решение с помощью создателя библиотеки CSCore Флориана Росмана (filoe).
Вот пример класса DSP, который усиливает предоставленные аудиоданные.
class DSPGain: ISampleSource
{
ISampleSource _source;
public DSPGain(ISampleSource source)
{
if (source == null)
throw new ArgumentNullException("source");
_source = source;
}
public int Read(float[] buffer, int offset, int count)
{
float gainAmplification = (float)(Math.Pow(10.0, GainDB / 20.0));
int samples = _source.Read(buffer, offset, count);
for (int i = offset; i < offset + samples; i++)
{
buffer[i] = Math.Max(Math.Min(buffer[i] * gainAmplification, 1), -1);
}
return samples;
}
public float GainDB { get; set; }
public bool CanSeek
{
get { return _source.CanSeek; }
}
public WaveFormat WaveFormat
{
get { return _source.WaveFormat; }
}
public long Position
{
get
{
return _source.Position;
}
set
{
_source.Position = value;
}
}
public long Length
{
get { return _source.Length; }
}
public void Dispose()
{
}
}
И вы можете использовать этот класс как в примере ниже:
WasapiCapture waveIn;
WasapiOut soundOut;
DSPGain gain;
private void StartFullDuplex()
{
try
{
MMDeviceEnumerator deviceEnum = new MMDeviceEnumerator();
MMDeviceCollection devices = deviceEnum.EnumAudioEndpoints(DataFlow.Capture, DeviceState.Active);
waveIn = new WasapiCapture(false, AudioClientShareMode.Exclusive, 5);
waveIn.Device = deviceEnum.GetDefaultAudioEndpoint(DataFlow.Capture, Role.Multimedia);
waveIn.Initialize();
waveIn.Start();
var source = new SoundInSource(waveIn) { FillWithZeros = true };
soundOut = new WasapiOut(false, AudioClientShareMode.Exclusive, 5);
soundOut.Device = deviceEnum.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia);
gain = new DSPGain(source.ToSampleSource());
gain.GainDB = 5;
soundOut.Initialize(gain.ToWaveSource(16));
soundOut.Play();
}
catch (Exception ex)
{
Debug.WriteLine("Exception in StartFullDuplex: " + ex.Message);
}
}
private void StopFullDuplex()
{
if (soundOut != null) soundOut.Dispose();
if (waveIn != null) waveIn.Dispose();
}
1 ответ
Я нашел решение с помощью создателя библиотеки CSCore Флориана Росманна (filoe).
Вот пример класса DSP, который усиливает предоставленные аудиоданные.
class DSPGain: ISampleSource
{
ISampleSource _source;
public DSPGain(ISampleSource source)
{
if (source == null)
throw new ArgumentNullException("source");
_source = source;
}
public int Read(float[] buffer, int offset, int count)
{
float gainAmplification = (float)(Math.Pow(10.0, GainDB / 20.0));
int samples = _source.Read(buffer, offset, count);
for (int i = offset; i < offset + samples; i++)
{
buffer[i] = Math.Max(Math.Min(buffer[i] * gainAmplification, 1), -1);
}
return samples;
}
public float GainDB { get; set; }
public bool CanSeek
{
get { return _source.CanSeek; }
}
public WaveFormat WaveFormat
{
get { return _source.WaveFormat; }
}
public long Position
{
get
{
return _source.Position;
}
set
{
_source.Position = value;
}
}
public long Length
{
get { return _source.Length; }
}
public void Dispose()
{
}
}
И вы можете использовать этот класс, как в примере ниже:
WasapiCapture waveIn;
WasapiOut soundOut;
DSPGain gain;
private void StartFullDuplex()
{
try
{
MMDeviceEnumerator deviceEnum = new MMDeviceEnumerator();
MMDeviceCollection devices = deviceEnum.EnumAudioEndpoints(DataFlow.Capture, DeviceState.Active);
waveIn = new WasapiCapture(false, AudioClientShareMode.Exclusive, 5);
waveIn.Device = deviceEnum.GetDefaultAudioEndpoint(DataFlow.Capture, Role.Multimedia);
waveIn.Initialize();
waveIn.Start();
var source = new SoundInSource(waveIn) { FillWithZeros = true };
soundOut = new WasapiOut(false, AudioClientShareMode.Exclusive, 5);
soundOut.Device = deviceEnum.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia);
gain = new DSPGain(source.ToSampleSource());
gain.GainDB = 5;
soundOut.Initialize(gain.ToWaveSource(16));
soundOut.Play();
}
catch (Exception ex)
{
Debug.WriteLine("Exception in StartFullDuplex: " + ex.Message);
}
}
private void StopFullDuplex()
{
if (soundOut != null) soundOut.Dispose();
if (waveIn != null) waveIn.Dispose();
}
Этот ответ был опубликован как редактирование вопроса Направление входа микрофона на динамики и написание пользовательской функции DSP с библиотекой CSCore OP user5413816 под CC BY-SA 3.0.