I need to transfer files using only the sound card.
my algorithm so far is based on amplitude shift keying (ASK).
Transmitter:
The program writes to a WAV file the modulated data.
Simply write "noise" (create wave) when the bit is 1, and write "silence" (0 amplitude) otherwise.
The number of samples for silence and noise is pre-defined and equal in both cases.
Receiver:
The program starts recording and wait for a sample that is above the pre-defined noise threshold.
Once it detected noise, it demodulates the recorded samples to WAV file until it detects the "Ending signal".
protocol:
- The first byte is 255 and is not part of the data (notify the receiver on a new file).
- Then write the data (file content).
- Write 4 pre-defined bytes that indicates end of session.
- Each bit is transferred 3 times, so in case of an error, it could guess the correct bit by the other two (ECC).
I am using NAudio C# library to handle with the WAV files (record, play, write, read).
For better understanding i added some of my code below, but in my opinion you can save yourself the trouble, i only want to know the defects in the algorithm and how can i improve it.
Transmitter:
//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);
}
}
After i have this file, it is played once:
System.Media.SoundPlayer player = new System.Media.SoundPlayer(tempFile);
player.Play();
Receiver:
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...
}
I didn't write all of it but basically the receiver seeks 8 * SamplesPerBit
noise samples.
(it determines whether a sample is noisy or not by comparing it to the noise-threshold).
Then save all other data until it detects the end-signal.
Finally it saves the content to a file.
the problem is that for this to work properly, i need SamplesPerBit to be at least 100. Since there are 44100 samples per second, It writes about 441 bits per seconds.
And since my data it tripled, all in all it is less than 20 Bytes/Sec.
I need to be able to transmit the data in at least 1KB/sec.
Any suggestions on how i could increase the bitrate will be very helpfull.
I thought to do it with FSK (amplitude stays the same, frequency changes), with The FastFourierTransform class in Naudio, but i don't think it would be faster that way (maybe less error prone).