サウンド カードのみを使用してファイルを転送する必要があります。
これまでの私のアルゴリズムは、振幅シフト キーイング (ASK) に基づいています。
送信機:
プログラムは、変調されたデータを WAV ファイルに書き込みます。
ビットが 1 のときは単に「ノイズ」(波を作る) と書き、それ以外の場合は「無音」(振幅 0) と書きます。
無音とノイズのサンプル数は事前に定義されており、どちらの場合も同じです。
レシーバー:
プログラムは録音を開始し、あらかじめ定義されたノイズしきい値を超えるサンプルを待ちます。
ノイズを検出すると、「終了信号」が検出されるまで、録音されたサンプルを WAV ファイルに復調します。
プロトコル:
- 最初のバイトは 255 で、データの一部ではありません (新しいファイルで受信者に通知します)。
- 次に、データ (ファイルの内容) を書き込みます。
- セッションの終了を示す事前定義された 4 バイトを書き込みます。
- 各ビットは 3 回転送されるため、エラーが発生した場合、残りの 2 つ (ECC) によって正しいビットを推測できます。
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 にする必要があることです。1 秒あたり 44100 サンプルあるため、1 秒あたり約 441 ビットを書き込みます。
私のデータは 3 倍になったので、全体としては 20 バイト/秒未満です。
少なくとも 1KB/秒でデータを送信できる必要があります。
ビットレートを上げる方法についての提案は非常に役立ちます。
Naudio の The FastFourierTransform クラスを使用して、FSK (振幅は同じまま、周波数が変化する) でそれを行うことを考えましたが、その方法の方が高速になるとは思いません (エラーが発生しにくい可能性があります)。