希望你能帮忙。我正在从麦克风录制音频并通过网络实时传输。样本的质量为 11025hz、8 位、单声道。虽然有一点延迟(1秒),但效果很好。我需要帮助的是我现在正在尝试实现降噪和压缩,以使音频更安静并使用更少的带宽。音频样本存储在 C# 的 bytes[] 数组中,我使用 Socket 发送/接收该数组。
谁能建议如何在 C# 中实现压缩和降噪?我不介意使用第三方库,只要它是免费的(LGPL 许可证等)并且可以从 C# 使用。但是,我更喜欢实际工作的源代码示例。预先感谢您的任何建议。
UPDATE:
我将位大小从 8 位音频更改为 16 位音频,噪音问题得到解决。显然,麦克风的 8 位音频信噪比太低。 11khz、16 位单声道的声音听起来很棒。
然而,自从我发布这篇文章以来,这个项目的要求已经发生了变化。我们现在也正在尝试添加视频。我有一个回调设置,每 100 毫秒从网络摄像头接收实时图像。我需要对音频和视频进行编码,混合它们,将它们在我的套接字上传输到服务器,服务器将流重新传输到另一个客户端,该客户端接收流,解复用流并解码音频和视频,显示图片框中的视频并将音频输出到扬声器。
我正在寻找 ffmpeg 来帮助进行(de|en)编码/[de]复用,并且我还在寻找 SharpFFmpeg 作为 ffmpeg 的 C# 互操作库。
我找不到任何这样做的好例子。我整个星期都在互联网上搜索,但没有真正的运气。非常感谢您提供的任何帮助!
这是一些代码,包括我的麦克风录音回调函数:
private const int AUDIO_FREQ = 11025;
private const int CHANNELS = 1;
private const int BITS = 16;
private const int BYTES_PER_SEC = AUDIO_FREQ * CHANNELS * (BITS / 8);
private const int BLOCKS_PER_SEC = 40;
private const int BUFFER_SECS = 1;
private const int BUF_SIZE = ((int)(BYTES_PER_SEC / BLOCKS_PER_SEC * BUFFER_SECS / 2)) * 2; // rounded to nearest EVEN number
private WaveLib.WaveOutPlayer m_Player;
private WaveLib.WaveInRecorder m_Recorder;
private WaveLib.FifoStream m_Fifo;
WebCam MyWebCam;
public void OnPickupHeadset()
{
stopRingTone();
m_Fifo = new WaveLib.FifoStream();
WaveLib.WaveFormat fmt = new WaveLib.WaveFormat(AUDIO_FREQ, BITS, CHANNELS);
m_Player = new WaveLib.WaveOutPlayer(-1, fmt, BUF_SIZE, BLOCKS_PER_SEC,
new WaveLib.BufferFillEventHandler(PlayerCB));
m_Recorder = new WaveLib.WaveInRecorder(-1, fmt, BUF_SIZE, BLOCKS_PER_SEC,
new WaveLib.BufferDoneEventHandler(RecorderCB));
MyWebCam = null;
try
{
MyWebCam = new WebCam();
MyWebCam.InitializeWebCam(ref pbMyPhoto, pbPhoto.Width, pbPhoto.Height);
MyWebCam.Start();
}
catch { }
}
private byte[] m_PlayBuffer;
private void PlayerCB(IntPtr data, int size)
{
try
{
if (m_PlayBuffer == null || m_PlayBuffer.Length != size)
m_PlayBuffer = new byte[size];
if (m_Fifo.Length >= size)
{
m_Fifo.Read(m_PlayBuffer, 0, size);
}
else
{
// Read what we can
int fifoLength = (int)m_Fifo.Length;
m_Fifo.Read(m_PlayBuffer, 0, fifoLength);
// Zero out rest of buffer
for (int i = fifoLength; i < m_PlayBuffer.Length; i++)
m_PlayBuffer[i] = 0;
}
// Return the play buffer
Marshal.Copy(m_PlayBuffer, 0, data, size);
}
catch { }
}
private byte[] m_RecBuffer;
private void RecorderCB(IntPtr data, int size)
{
try
{
if (m_RecBuffer == null || m_RecBuffer.Length != size)
m_RecBuffer = new byte[size];
Marshal.Copy(data, m_RecBuffer, 0, size);
// HERE'S WHERE I WOULD ENCODE THE AUDIO IF I KNEW HOW
// Send data to server
if (theForm.CallClient != null)
{
SocketAsyncEventArgs args = new SocketAsyncEventArgs();
args.SetBuffer(m_RecBuffer, 0, m_RecBuffer.Length);
theForm.CallClient.SendAsync(args);
}
}
catch { }
}
//Called from network stack when data received from server (other client)
public void PlayBuffer(byte[] buffer, int length)
{
try
{
//HERE'S WHERE I WOULD DECODE THE AUDIO IF I KNEW HOW
m_Fifo.Write(buffer, 0, length);
}
catch { }
}
那么我应该去哪里呢?