NAudio AsioOut + 插座

Posted

技术标签:

【中文标题】NAudio AsioOut + 插座【英文标题】:NAudio AsioOut + Sockets 【发布时间】:2015-07-05 11:22:36 【问题描述】:

我是音频编程和套接字编程的新手。我正在尝试使用 NAudio AsioOut 类和套接字通过网络发送吉他信号。 这里是接收方和发送方的源代码。 似乎接收方确实从发送方获取了字节数组,但我听到的只是白噪声。 接收器源代码

    using System;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Threading;
using NAudio.Utils;
using NAudio.Wave;
using NAudio.Wave.SampleProviders;

namespace Reciever

    internal class Program
    
        private static Socket Listener;
        private static Socket Accepter;
        private static AsioOut Output;
        private static BufferedWaveProvider OutputBuffer;
        [STAThread]
        private static void Main(string[] args)
        
            IPHostEntry ipHostEntry = Dns.GetHostEntry("192.168.1.4");
            IPAddress ipAddr = ipHostEntry.AddressList[2];
            IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, 7777);
            Listener = new Socket(ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

            Console.WriteLine("Слушатель готов по адресу:0 ", ipEndPoint);
            Listener.Bind(ipEndPoint);
            Listener.Listen(10);
            Accepter = Listener.Accept();
            Console.WriteLine("Клиент с адресом 0 подключен", Accepter.RemoteEndPoint);

            Output = new AsioOut();
            Output.ShowControlPanel();
            Console.Read();
            OutputBuffer = new BufferedWaveProvider(WaveFormat.CreateIeeeFloatWaveFormat(44100, 2));

            Output.Init(OutputBuffer);

            Thread playing = new Thread(new ThreadStart(Output.Play));
            Thread listening = new Thread(new ThreadStart(Listening));

            playing.Start();
            listening.Start();
        

        public static void Listening()
        
            while (true)
            
                byte[] buffer = new byte[65538];
                int ReceivedData = Accepter.Receive(buffer);
                OutputBuffer.AddSamples(buffer, 0, ReceivedData);
            
        
    

发送方源代码

    using System;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using NAudio.Wave;


namespace Sender

    class Program
    
        private static Socket sck;

        [STAThread]
        static void Main(string[] args)
        
            AsioOut asioout = new AsioOut();

            IPHostEntry ipHostEntry = Dns.GetHostEntry("192.168.1.2");
            IPAddress ipAddr = ipHostEntry.AddressList[1];
            IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, 7777);
            sck = new Socket(ipEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
            BufferedWaveProvider buffer = new BufferedWaveProvider(WaveFormat.CreateIeeeFloatWaveFormat(44100,2));
            sck.Bind(ipEndPoint);
            try
            
                sck.Connect("192.168.1.4", 7777);
            
            catch (Exception ex)
            
                Console.WriteLine("Соединие не установлено");
                Console.Read();
                return;
            
            Console.WriteLine("Соединение установлено");
            asioout.InitRecordAndPlayback(buffer, 2, 44100);
            asioout.AudioAvailable += new EventHandler<AsioAudioAvailableEventArgs>(asioout_AudioAvailable);
            asioout.Play();
            Console.Read();
        

        private static void asioout_AudioAvailable(object sender, AsioAudioAvailableEventArgs e)
        
            var samples = e.GetAsInterleavedSamples();
            byte[] OutputBuffer = new byte[e.SamplesPerBuffer*4];
            byte[] SendingBuffer = new byte[e.SamplesPerBuffer*4];
            Console.WriteLine(e.SamplesPerBuffer*4);
            for (int i = 0; i < e.InputBuffers.Length; i++)
            
                Marshal.Copy(e.InputBuffers[i], OutputBuffer, 0, e.SamplesPerBuffer*4);
                Buffer.BlockCopy(samples, 0, SendingBuffer, 0, e.SamplesPerBuffer*4);
                Marshal.Copy(OutputBuffer, 0, e.OutputBuffers[i], e.SamplesPerBuffer * 4);

            

            sck.Send(SendingBuffer);
            e.WrittenToOutputBuffers = true;
        
    

UPD.1 (07.10.2015):发送方代码和接收方代码已更新。现在我可以听到接收器发出的吉他信号,但听起来很失真。我做错了什么?

附:我在台式电脑上使用 M-Audio Fast Track USB 声卡。信号通过网络从那个通过 ASIO4ALL 驱动程序传输到我的笔记本电脑。

【问题讨论】:

【参考方案1】:

您的接收器假定传入的音频是 16 位的,但使用 ASIO,它很容易是 24 位或 32 位的。事实上,您的发送代码似乎假定为 32 位。因此,首先尝试在接收端使用 IEEE 浮点 WaveFormat

【讨论】:

感谢您的回答!在接收器中我做到了:bufferStream = new BufferedWaveProvider(WaveFormat.CreateIeeeFloatWaveFormat(44100,2));但我仍然能听到噪音,现在听起来像是失真的贝司吉他。 好的,你真的需要确切地知道样本记录的格式。什么位深度,它们是整数还是浮点数?有多少个频道? 44100 Hz,24 位,2 通道。 Sender 中的 e.AsiosampleType 返回 Int32LSB

以上是关于NAudio AsioOut + 插座的主要内容,如果未能解决你的问题,请参考以下文章

使用 NAudio 使用 asioout 录制时如何使声音更大?

Naudio:如何在不停止所有其他声音的情况下正确删除 AsioOut 播放的几种声音中的一种?

NAudio Asio 和 ieeefloat 格式

文件所有者插座与视图插座

路由器插座内的路由器插座不工作

角度 6 的主布局插座中的嵌套插座