NAudio-更改缓冲的麦克风音频的音调并发送到虚拟音频电缆 [英] NAudio - Change pitch of buffered microphone audio and send to Virtual Audio Cable
问题描述
我决定尝试使用NAudio和虚拟音频电缆创建与Discord(或类似软件)一起使用的音板.我能够将来自麦克风的音频注入"到音频电缆,因此可以通过在Discord中选择虚拟音频电缆作为输入设备来将声音文件和麦克风音频播放到Discord.
I decided to have a go at creating a sound board for use with Discord (or similar software) using NAudio and a Virtual Audio Cable. I was able to 'inject' the audio from the microphone to the audio cable so I could play sound files and mic audio to Discord by selecting the virtual audio cable as the input device in Discord.
为了好玩,我想我可以看看是否可以将麦克风音频修改为吱吱"或深沉".因此,我开始研究修改音频的音高.我发现NAudio具有SmbPitchShiftingSampleProvider
,然后找到
For fun I thought I would see if I could modify the mic audio to make it 'squeaky' or 'deep'. So I started looking into modifying the pitch of the audio. I discovered that NAudio has an SmbPitchShiftingSampleProvider
and then found this question which helps to work with buffered audio, but I can't figure out how to do it. Here's what I've got so far:
//Inject Mic Audio
WaveIn injectMicIn = null;
WaveOut injectMicOut = null;
private BufferedWaveProvider bufferedWaveProvider; //Buffer for mic audio
public int micDeviceID; //Device ID of selected microphone
public int virtualAudioCableID; //Device ID of selected virtual audio cable
ISampleProvider sampleP; //#### TO DO: Remove this if I don't use it.
NAudio.Wave.SampleProviders.SmbPitchShiftingSampleProvider pitchProvider; //#### TO DO: Remove this if I don't use it
private void InjectMicrophone()
{
//Mic Input
if (injectMicIn == null)
{
injectMicIn = new WaveIn();
injectMicIn.RecordingStopped += new EventHandler<StoppedEventArgs>(OnRecordingStopped);
injectMicIn.DataAvailable += InjectMicOnDataAvailable;
injectMicIn.WaveFormat = new WaveFormat(44100, 1);
}
injectMicIn.DeviceNumber = SharedVars.micInjectInputDeviceID; //Set the users selected input device
//Mic Output
if (injectMicOut == null)
{
injectMicOut = new WaveOut();
injectMicOut.PlaybackStopped += new EventHandler<StoppedEventArgs>(OnPlaybackStopped);
}
bufferedWaveProvider = new BufferedWaveProvider(injectMicIn.WaveFormat); //Prepare the buffer for the microphone audio
sampleP = bufferedWaveProvider.ToSampleProvider(); //#### TO DO: Remove this if I don't use it for pitch shifting
injectMicOut.DeviceNumber = SharedVars.micInjectOutputDeviceID; //Set the users selected output device
//injectMicOut.Init(bufferedWaveProvider);
SharedVars.currentlyInjectingMic = true;
injectMicIn.StartRecording(); //Record the mic and
//injectMicOut.Play(); //out play it on the selected output device
}
bool init = false;
private void InjectMicOnDataAvailable(object sender, WaveInEventArgs e)
{
bufferedWaveProvider.AddSamples(e.Buffer, 0, e.BytesRecorded); //Add the mic audio to the buffer
//#### TO DO: REMOVE THIS TEST CODE
var bytesPerFrame = (injectMicIn.WaveFormat.BitsPerSample / 8) * injectMicIn.WaveFormat.Channels;
var bufferedFrames = e.BytesRecorded / bytesPerFrame;
var frames = new float[bufferedFrames];
sampleP.Read(frames, 0, bufferedFrames);
pitchProvider = new NAudio.Wave.SampleProviders.SmbPitchShiftingSampleProvider(sampleP);
pitchProvider.PitchFactor = 2.0f;
if (!init)
{
injectMicOut.Init(pitchProvider);
init = true;
}
injectMicOut.Play();
//#### TO DO: REMOVE THIS TEST CODE
}
任何帮助将不胜感激.
最终代码
//Inject Mic Audio
WaveIn injectMicIn = null;
WaveOut injectMicOut = null;
private BufferedWaveProvider bufferedWaveProvider; //Buffer for mic audio
public int micDeviceID; //Device ID of selected microphone
public int virtualAudioCableID; //Device ID of selected virtual audio cable
SmbPitchShiftingSampleProvider pitchProvider; //Used to adjust the pitch of the mic audio if required
private void InjectMicrophone()
{
//Mic Input
if (injectMicIn == null)
{
injectMicIn = new WaveIn();
injectMicIn.RecordingStopped += new EventHandler<StoppedEventArgs>(OnRecordingStopped);
injectMicIn.DataAvailable += InjectMicOnDataAvailable;
injectMicIn.WaveFormat = new WaveFormat(44100, 1);
}
injectMicIn.DeviceNumber = SharedVars.micInjectInputDeviceID; //Set the users selected input device
//Mic Output
if (injectMicOut == null)
{
injectMicOut = new WaveOut();
injectMicOut.PlaybackStopped += new EventHandler<StoppedEventArgs>(OnMicPlaybackStopped);
}
injectMicOut.DeviceNumber = SharedVars.micInjectOutputDeviceID; //Set the users selected output device
bufferedWaveProvider = new BufferedWaveProvider(injectMicIn.WaveFormat); //Prepare the buffer for the microphone audio
pitchProvider = new SmbPitchShiftingSampleProvider(bufferedWaveProvider.ToSampleProvider()); //Create a pitch shifting sample provider to adjust the pitch of the mic audio if required
pitchProvider.PitchFactor = 1.0f; //#### TO DO: Retrieve value from a UI control
injectMicOut.Init(pitchProvider);
SharedVars.currentlyInjectingMic = true;
injectMicIn.StartRecording(); //Record the mic and
injectMicOut.Play(); //out play it on the selected output device
}
private void InjectMicOnDataAvailable(object sender, WaveInEventArgs e)
{
bufferedWaveProvider.AddSamples(e.Buffer, 0, e.BytesRecorded); //Add the mic audio to the buffer
}
推荐答案
您非常接近
在录制设备上,只需将录制的音频直接放入BufferedWaveProvider
.
On the recording device, just put the recorded audio directly into a BufferedWaveProvider
.
在播放设备上,传入从BufferedWaveProvider
读取的SmbPitchShiftingProvider
(使用ToSampleProvider
将其转换为ISampleProvider
)
On the playback device, pass in an SmbPitchShiftingProvider
that reads from the BufferedWaveProvider
(use ToSampleProvider
to turn it into an ISampleProvider
)
这篇关于NAudio-更改缓冲的麦克风音频的音调并发送到虚拟音频电缆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!