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

时间:2014-07-05 12:46:53

标签: c# algorithm audio naudio modulation

我只需要使用声卡传输文件。

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

发射器:
程序将调制数据写入WAV文件。
只需写下"噪音"当比特为1时,(创建波形),写入"静默" (0幅度)否则。
静音和噪声的样本数量是预先定义的,在两种情况下都相同。

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

协议:

  1. 第一个字节是255,不是数据的一部分(在新文件上通知接收方)。
  2. 然后写入数据(文件内容)。
  3. 写入4个预定义的字节,表示会话结束。
  4. 每个位传输3次,因此如果出现错误,可以通过其他两个(ECC)猜测正确的位。
  5. 我正在使用NAudio 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);
        }
     }
    

    我有这个文件后,会播放一次:

    System.Media.SoundPlayer player = new System.Media.SoundPlayer(tempFile);
    player.Play();
    

    接收器:

    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(幅度保持不变,频率变化)和FastFourierTransform class in Naudio这样做,但我不认为它会更快(可能不那么容易出错)。< / p>

1 个答案:

答案 0 :(得分:0)

您的方法存在的问题

  • 太长的静音或太长的噪音会导致流不同步
  • 例如传输100MB的零,并且最终解码的比特数可以不同
  • 这可以通过偶尔的同步信号修复
  • 使用不易检测的噪音(因此传输速度慢)
  • 在音频硬件上你沿途有电容器,因此直流信号被破坏
  • 所以使用直流信号的代码是没有问题的,但还有很多其他的......

如果您不受ASK约束,那么还有许多其他编码可能性更好:

  1. FM

    • 例如0将是22050Hz并且1将是44100Hz
    • 每个位可以编码为几个周期(至少2个)
    • 还需要不时地获得一些同步信号(例如,每分钟11025Hz 10个周期
  2. PCM

    • 例如4个44100Hz的脉冲是1 /
    • 4个44100hz的脉冲为0
    • 和所有位之间的2个静默期
    • 这不需要任何额外的同步信号
  3. 您还可以添加开始信号

    • 数据之前的一些不同频率和精确暂停
    • 您也可以在数据
    • 之前添加某种标题
    • 让接收者知道预期会有多少数据
    • 或者如果要进行实验,可以使用哪种编码

    [注释]

    • 您可以尝试脉冲计数或频率
    • 我为您提供快速且仍应正常工作的设置
    • 但您应该测试错误率并将其配置为与您的硬件设置相匹配......
    • 安全地识别您需要至少2个周期的频率。
    • 在嘈杂的环境中更是......