我正在创建一个使用NAudio
通过TCP / IP连接发送音频的应用程序。
这是我的服务器代码:
// Get server port.
var iServerPort = GetServerPort();
// Initialize memory stream.
_bytes = new List<byte>();
// Initialize tcp listener.
var tcpListener = new TcpListener(IPAddress.Any, iServerPort);
tcpListener.Start();
// Accept a tcp client.
Console.WriteLine("Waiting for incoming connection");
_tcpClient = tcpListener.AcceptTcpClient();
Console.WriteLine("Client found !");
// Buffered wave provider.
_bufferedWaveProvider = new BufferedWaveProvider(new WaveFormat());
_bufferedWaveProvider.DiscardOnBufferOverflow = true;
_bufferedWaveProvider.BufferLength = iBufferBytes;
_waveOut = new WaveOut();
_waveOut.Init(_bufferedWaveProvider);
_waveOut.Play();
// Initialize a thread to listen to incoming data from another source.
_tcpConnectionListeningThread = new Thread(() =>
{
// Get data stream of tcp connection.
var networkStream = _tcpClient.GetStream();
// Initalize buffer.
var buffer = new byte[iBufferBytes];
// Number of bytes which have been read.
while (true)
{
try
{
int iReadBytes;
while ((iReadBytes = networkStream.Read(buffer, 0, buffer.Length)) > 0)
{
//var memoryStream = new MemoryStream();
//memoryStream.Write(buffer, 0, iReadBytes);
//_memoryStreams.Enqueue(memoryStream);
//_memoryStream.CopyTo();
//_memoryStream.Write(buffer, 0, iReadBytes);
var realBytes = buffer.Take(iReadBytes).ToList();
_bytes.AddRange(realBytes);
Console.WriteLine($"Read: {iReadBytes} bytes. Enqueue a stream. Count: {realBytes.Count}");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
break;
}
}
});
// Initialize a thread to check audio buffer. Reload as audio stream consumes whole data.
_waveBufferCheckThread = new Thread(() =>
{
while (true)
{
// Get remaining bytes in buffer.
var iRemainingBytes = _bufferedWaveProvider.BufferedBytes;
// No byte is available in buffer.
// Check memory stream to find available bytes array. If nothing found, terminate this thread.
if (iRemainingBytes >= iBufferBytes)
continue;
// No byte available.
if (_bytes.Count < 1)
{
//Console.WriteLine("No data in memory stream");
continue;
}
// Get bytes array from memory stream.
var iDifferent = iBufferBytes - iRemainingBytes;
if (iDifferent > _bytes.Count)
iDifferent = _bytes.Count;
var bytes = _bytes.GetRange(0, iDifferent).ToArray();
_bytes.RemoveRange(0, iDifferent);
//var bytes = new byte[iBufferBytes];
_bufferedWaveProvider.AddSamples(bytes, 0, bytes.Length);
//Console.WriteLine($"Wrote {iReadBytes} to buffer. Count: {_memoryStream.Length}");
//Thread.Sleep(TimeSpan.FromSeconds(1));
//_waveOut.Play();
}
});
_tcpConnectionListeningThread.IsBackground = true;
_waveBufferCheckThread.IsBackground = true;
_tcpConnectionListeningThread.Start();
_waveBufferCheckThread.Start();
Console.ReadLine();
_tcpConnectionListeningThread.Abort();
_waveBufferCheckThread.Abort();
_bufferedWaveProvider.ClearBuffer();
_waveOut.Stop();
tcpListener.Stop();
这是我的客户代码:
public Main()
{
InitializeComponent();
// Initialize tcp client.
_tcpClient = new TcpClient();
_recordingStream = new MemoryStream();
_soundRecorder = new WaveIn();
_waveOut = new WaveOut();
_playbackBufferedWaveProvider = new BufferedWaveProvider(_soundRecorder.WaveFormat);
_waveOut.Init(_playbackBufferedWaveProvider);
_soundRecorder.DataAvailable += SoundRecorderOnDataAvailable;
btnRecord.Enabled = true;
}
private void SoundRecorderOnDataAvailable(object sender, WaveInEventArgs waveInEventArgs)
{
if (_networkStream != null)
{
_networkStream.Write(waveInEventArgs.Buffer, 0, waveInEventArgs.BytesRecorded);
_networkStream.Flush();
}
}
我的应用程序运行正常。但是我面临的一个问题是: - 发送到服务器端点时无法听到录制的语音。如果我将它保存到内存流并播放,质量就可以了。
我应该在发送到服务器之前压缩录制的语音吗?有什么方法可以解决这个问题吗?
谢谢,
答案 0 :(得分:0)
您的_tcpConnectionListeningThread
应直接写入BufferedWaveProvider
,而不是经过复制到非线程安全列表的中间步骤。 _waveBufferCheckThread
完全没必要。更新监听线程以执行以下操作:
while ((iReadBytes = networkStream.Read(buffer, 0, buffer.Length)) > 0)
{
_bufferedWaveProvider.AddSamples(buffer, 0, iReadBytes);
}
此外,您必须确保服务器端的WaveFormat
与客户端使用的完全相同。