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

标签 c# algorithm audio naudio modulation

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

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

传送器:
该程序将调制数据写入 WAV 文件。
当位为1时,只需写“noise”(创建波),否则写“silence”(0振幅)。
静音和噪音的样本数量是预先定义的,并且在两种情况下都相等。

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

协议(protocol):

  1. 第一个字节是 255,不是数据的一部分(通知接收方一个新文件)。
  2. 然后写入数据(文件内容)。
  3. 写入 4 个指示 session 结束的预定义字节。
  4. 每个位传输 3 次,因此在出现错误的情况下,它可以通过其他两个 (ECC) 猜测正确的位。

我正在使用 NAudio处理 WAV 文件(录制、播放、写入、读取)的 C# 库。

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

发射器:

//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 ,但我不认为那样会更快(可能更不容易出错)。

最佳答案

你的方法有问题

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

如果您不必使用 ASK,那么还有许多其他编码可能性更好:

  1. 调频

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

    • 例如4个44100Hz的脉冲是1
    • 44100hz的2个脉冲为0
    • 和所有位之间的 2 个静默期
    • 这不需要任何额外的同步信号

你也可以添加开始信号

  • 在数据之前有一些明显的频率和精确的停顿
  • 你也可以在数据前添加一些标题
  • 所以接收方知道需要多少数据
  • 或者如果您想进行试验,可以使用哪种编码

[注释]

  • 您可以试验脉冲计数或频率
  • 我给你的设置是快速的,但仍然应该有效
  • 但是您应该测试错误率并配置它以匹配您的硬件设置...
  • 要安全地确定您至少需要 2 个周期的频率。
  • 在嘈杂的环境中更...

关于c# - 如何提高通过声卡传输文件的比特率?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24586584/

相关文章:

c++ - 零延迟麦克风环回、侧音

android - 如何保存多个音频文件?

c# - Response.Write(RSS) 导致 Javascript 异常 : "Unspecified error" (IIS 7. 5)

c++ - 如何快速找到 vector 和的最大元素?

algorithm - 为什么我们需要在 Kosaraju 算法中的图的补集上运行 DFS?

algorithm - 线性递归算法中的矩阵求幂

javascript 在音频中添加 onend 事件

c# - 如何为自定义 JsonConverter 设置 FloatParseHandling.Decimal?

c# - 如何为表单按钮编写鼠标事件?

c# - Blazor - 私有(private)组件