C# 如何通过声卡提高文件传输的比特率?

C# 如何通过声卡提高文件传输的比特率?,c#,algorithm,audio,naudio,modulation,C#,Algorithm,Audio,Naudio,Modulation,我只需要用声卡传输文件 到目前为止,我的算法是基于振幅移位键控(ASK) 发射机: 程序将调制数据写入WAV文件 只需在位为1时写入“噪声”(创建波形),否则写入“静音”(0振幅)。 静音和噪声的采样数是预定义的,并且在这两种情况下相等 接收者: 程序开始记录并等待高于预定义噪声阈值的样本 一旦检测到噪声,它将记录的样本解调为WAV文件,直到检测到“结束信号” 协议: 第一个字节是255,不是数据的一部分(通知接收者一个新文件) 然后写入数据(文件内容) 写入表示会话结束的4个预定义字节 每个位

我只需要用声卡传输文件

到目前为止,我的算法是基于振幅移位键控(ASK)

发射机:
程序将调制数据写入WAV文件
只需在位为1时写入“噪声”(创建波形),否则写入“静音”(0振幅)。
静音和噪声的采样数是预定义的,并且在这两种情况下相等

接收者:
程序开始记录并等待高于预定义噪声阈值的样本
一旦检测到噪声,它将记录的样本解调为WAV文件,直到检测到“结束信号”

协议:

  • 第一个字节是255,不是数据的一部分(通知接收者一个新文件)
  • 然后写入数据(文件内容)
  • 写入表示会话结束的4个预定义字节
  • 每个位传输3次,因此在发生错误的情况下,它可以通过其他两个(ECC)猜测正确的位
  • 我正在使用C#库处理WAV文件(录制、播放、写入、读取)

    为了更好地理解,我在下面添加了一些代码,但我认为您可以省去麻烦,我只想知道算法中的缺陷以及如何改进它

    发射机:

    //creates file with 44.1kHz sample-rate and 1 channel.
    mWaveFileWriter = new WaveFileWriter(tempFile, new WaveFormat(44100, 1));
    
    ....
    
    // save to WAV file modulated data the contains bytesData
    public void Modulate(byte[] bytesData)
    {
        foreach (var dataByte in bytesData)
        {
             // return 8 bit representation of the byte
             bool[] binaryByte = ToBinary(dataByte);
    
             foreach (bool bit in binaryByte)
             {
                 if (bit)
                    SaveNoise();
                 else
                    SaveSilence();
             }
             mWaveFileWriter.Dispose();
        }
    }
    
    private void SaveSilence()
    {
        for (int n = 0; n < mSamplesPerBit; n++)
        {
            mWaveFileWriter.WriteSample(0);
        }
    }
    
    private void SaveNoise()
    {
        // writes SamplesPerBit samples
        for (int n = 0; n < mSamplesPerBit; n++)
        {
            float sample = (float)(mNoiseAmplitude * Math.Sin((2 * Math.PI * n * mFrequency) / mWaveFileWriter.WaveFormat.SampleRate));
            mWaveFileWriter.WriteSample(sample);
        }
     }
    
    接收人:

    WaveInEvent mWaveIn = new WaveInEvent();
    mWaveIn.WaveFormat = new WaveFormat(44100, 1);
    mWaveIn.DataAvailable += mWaveIn_DataAvailable;
    
    ....
    
    void mWaveIn_DataAvailable(object sender, WaveInEventArgs e)
    {
        // since it's 16bit sampling, I normalize each 2 bytes to samples of range (-1.0f) - 1.0f.
        float[] samples = ToSamples(e.Buffer);
    
        ...   // saves data, process it etc...
    }
    
    我并没有全部写出来,但基本上接收器会寻找
    8*SamplesPerBit
    噪声样本。 (它通过将样本与“噪波阈值”进行比较来确定样本是否有噪波)。 然后保存所有其他数据,直到检测到结束信号。 最后,它将内容保存到一个文件中

    问题是为了让它正常工作,我需要SamplesPerBit至少为100。因为每秒有44100个样本,所以它大约每秒写入441位
    由于我的数据量增加了三倍,总的来说,它不到20字节/秒

    我需要能够以至少1KB/秒的速度传输数据

    任何关于如何提高比特率的建议都将非常有用


    我想用FSK(振幅保持不变,频率变化),用,但我不认为那样会更快(可能更不容易出错)。

    你的方法有问题

    • 过长的静音或过长的噪音可能导致流不同步
    • 例如,传输100MB的零,最终解码的位计数可能不同
    • 这可以通过偶尔的同步信号来修复
    • 您使用的噪声不容易正确检测(因此传输速度慢)
    • 在音频硬件上,沿途有电容器,因此直流信号被破坏
    • 所以使用直流信号的代码是毫无疑问的,但还有很多其他的,所以
    如果您不一定要问,那么还有许多其他编码的可能性,对此有更好的选择:

  • 调频

    • 例如,0为22050Hz,1为44100Hz
    • 每个位可以编码为几个周期(至少2个)
    • 此外,有时还需要一些同步信号(例如11025Hz,每分钟10个周期)
  • PCM

    • 例如,44100Hz的4个脉冲为1
    • 44100hz的2个脉冲为0
    • 所有位之间有2段静默时间
    • 这不需要任何额外的同步信号
  • 您还可以添加启动信号

    • 一些明显的频率和精确的数据前停顿
    • 您还可以在数据之前添加某种类型的标题
    • 所以接收器知道需要多少数据
    • 或者,如果您想进行实验,可以使用哪种编码
    [附注]

    • 您可以用脉冲计数或频率进行实验
    • 我给你的设置是快速的,仍然应该工作
    • 但是您应该测试错误率,并将其配置为与您的硬件设置相匹配
    • 要安全识别频率,您至少需要2个周期
    • 对嘈杂的环境更是如此
    WaveInEvent mWaveIn = new WaveInEvent();
    mWaveIn.WaveFormat = new WaveFormat(44100, 1);
    mWaveIn.DataAvailable += mWaveIn_DataAvailable;
    
    ....
    
    void mWaveIn_DataAvailable(object sender, WaveInEventArgs e)
    {
        // since it's 16bit sampling, I normalize each 2 bytes to samples of range (-1.0f) - 1.0f.
        float[] samples = ToSamples(e.Buffer);
    
        ...   // saves data, process it etc...
    }