私は、2台のコンピューター間でサウンドを介してデータを送信する例を作成しています。いくつかの要件:
距離が非常に近い。つまり、2台のコンピューターは基本的に互いに隣接している
ノイズが非常に少ない(先生がノイズソースとしてロックソングをオンにするとは思わない)
エラーは許容されます。たとえば、「無線通信」を送信した場合、他のコンピューターが「RadiQ通信」を受信した場合も同様に問題ありません。
可能であれば:ヘッダー、フラグ、チェックサムなどはありません。サウンドを介してデータを送信する基本を示す非常に基本的な例が必要なためです。派手になる必要はありません。
このリンクに従って、オーディオ周波数シフトキーイングを使用してみました。
そしていくつかの結果を得ました: 私のGithubページ
しかし、それだけでは十分ではありません。クロックリカバリ、同期の方法がわかりません...(リンクにはタイミングリカバリメカニズムとしてフェーズロックループがありますが、明らかに十分ではありませんでした)。
だから私はもっと簡単なアプローチを見つけるべきだと思う。ここにリンクを見つけました:
データを音声に変換して戻します。ソースコードによる変調/復調
しかし、OPは回答で提案されたメソッドを実装していなかったため、非常に複雑になる可能性があります。また、私は答えで提案されているデコード方法を明確に理解していません:
デコーダはもう少し複雑ですが、概要は次のとおりです。
必要に応じて、サンプリングされた信号を11Khz付近でバンドパスフィルターします。これにより、ノイズの多い環境でパフォーマンスが向上します。FIRフィルターは非常にシンプルで、フィルターを生成するオンラインデザインアプレットがいくつかあります。
信号をしきい値処理します。最大振幅の1/2を超える値はすべて1で、以下の値はすべて0です。これは、信号全体をサンプリングしたことを前提としています。これがリアルタイムの場合は、固定のしきい値を選択するか、一定の時間にわたって最大信号レベルを追跡する何らかの自動ゲイン制御を行います。
ドットまたはダッシュの開始をスキャンします。サンプルをドットと見なすために、ドット期間に少なくとも一定数の1を表示することをお勧めします。次に、スキャンを続けて、これがダッシュかどうかを確認します。完全な信号を期待しないでください。1の真ん中にいくつかの0が表示され、0の真ん中にいくつかの1が表示されます。ノイズがほとんどない場合、「オン」期間と「オフ」期間を区別するのはかなり簡単です。
次に、上記のプロセスを逆にします。ダッシュが1ビットをバッファにプッシュする場合、ドットが0をプッシュする場合。
ドットとして分類する前に1がいくつあるのかわかりません。そのため、今のところわからないことがたくさんあります。プロセスを理解できるように、音声でデータを送信する簡単な方法を提案してください。どうもありがとうございました :)
更新:
(ある程度)動作しているように見えるMatlabコードをいくつか作成しました。まず、振幅シフトキーイング(サンプリング周波数48000 Hz、F_on = 5000 Hz、ビットレート= 10ビット/秒)を使用して信号を変調し、次にヘッダーと終了シーケンスを追加します(もちろん変調もします)。ヘッダーと終了シーケンスはアドホックベースで選択されました(そう、ハックでした)。
header = [0 0 1 0 1 1 1 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 1 1 0 1 0 1];
end_seq = [1 1 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 0 0 1 0 0 0 1];
その後、音声でそれらを送信し、スマートフォンで録音しました。次に、録音したオーディオをコンピューターに送り返し、別のコードを使用してオーディオを読み取ります。次に、受信信号(まだ復調されていない)を変調されたヘッダーと終了シーケンスと相関させて、開始と終了を見つけます。その後、関連する信号のみを取得します(相関部分に見られるように、最初から最後まで)。次に、デジタルデータを見つけるために復調とサンプリングを行います。以下に3つのオーディオファイルを示します。
「DigitalCommunication_ask」:ここにリンクすると、テキスト「Digital communication」が送信されます。比較的ノイズはありませんが、最初と最後に背景ノイズが聞こえます。しかし、結果は「デジタル通信」のみを示しました
「HelloWorld_ask」:ここにリンクすると、「Hello world」というテキストが送信されます。「DigitalCommunication_ask」のようなノイズフリー。ただし、この結果は正しかった
「HelloWorld_noise_ask」:ここにリンクすると、「Hello world」というテキストが送信されます。しかし、私が作ったノイズがあります(送信中にランダムなものを "A、B、C、D、E、...."と言っただけです)。残念ながらこれは失敗しました
送信者のコード(sender.m)は次のとおりです。
clear
fs = 48000;
F_on = 5000;
bit_rate = 10;
% header = [0 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ];
% header = [0 0 1 0 1 1 1 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 ];
header = [0 0 1 0 1 1 1 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 1 1 0 1 0 1];
% end_seq = [1 0 0 1 0 1 0 0 1 0 1 1 0 0 0 1 0 0 0 0 1 0 0 1 1 0 0 0 1 0 0 1];
% end_seq = [1 0 0 1 0 1 0 0 1 0 1 1 0 0 0 1 0 0 0 0 1 0 0 1 1 0 0 0 1 0 0 1 0 1 0 0 1 1 0 0 1 1 0 1 1 0 0 1 ];
% end_seq = [0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0];
end_seq = [1 1 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 0 0 1 0 0 0 1];
num_of_samples_per_bit = round(fs / bit_rate);
modulated_header = ask_modulate(header, fs, F_on, bit_rate);
modulated_end_seq = ask_modulate(end_seq, fs, F_on, bit_rate);
% input_str = 'Ah';
input_str = 'Hello world';
ascii_list = double(input_str); % https://www.mathworks.com/matlabcentral/answers/298215-how-to-get-ascii-value-of-characters-stored-in-an-array
bit_stream = [];
for i = 1:numel(ascii_list)
bit = de2bi(ascii_list(i), 8, 'left-msb');
bit_stream = [bit_stream bit];
end
bit_stream = [header bit_stream end_seq];
num_of_bits = numel(bit_stream);
bandlimited_and_modulated_signal = ask_modulate(bit_stream, fs, F_on, bit_rate);
sound(bandlimited_and_modulated_signal, fs);
受信者(receiver.m)の場合:
clear
fs = 48000;
F_on = 5000;
bit_rate = 10;
% header = [0 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ];
% header = [0 0 1 0 1 1 1 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 ];
header = [0 0 1 0 1 1 1 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 1 1 0 1 0 1];
% end_seq = [1 0 0 1 0 1 0 0 1 0 1 1 0 0 0 1 0 0 0 0 1 0 0 1 1 0 0 0 1 0 0 1];
% end_seq = [1 0 0 1 0 1 0 0 1 0 1 1 0 0 0 1 0 0 0 0 1 0 0 1 1 0 0 0 1 0 0 1 0 1 0 0 1 1 0 0 1 1 0 1 1 0 0 1 ];
% end_seq = [0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 0];
end_seq = [1 1 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 0 0 1 0 0 0 1];
modulated_header = ask_modulate(header, fs, F_on, bit_rate);
modulated_end_seq = ask_modulate(end_seq, fs, F_on, bit_rate);
% recObj = audiorecorder(fs,8,1);
% time_to_record = 10; % In seconds
% recordblocking(recObj, time_to_record);
% received_signal = getaudiodata(recObj);
% [received_signal, fs] = audioread('SounddataTruong_Ask.m4a');
% [received_signal, fs] = audioread('HelloWorld_noise_ask.m4a');
% [received_signal, fs] = audioread('HelloWorld_ask.m4a');
[received_signal, fs] = audioread('DigitalCommunication_ask.m4a');
ereceived_signal = received_signal(:)';
num_of_samples_per_bit = round(fs / bit_rate);
modulated_header = ask_modulate(header, fs, F_on, bit_rate);
modulated_end_seq = ask_modulate(end_seq, fs, F_on, bit_rate);
y= xcorr(modulated_header, received_signal); % do cross correlation
[m,ind]=max(y); % location of largest correlation
headstart=length(received_signal)-ind+1;
z = xcorr(modulated_end_seq, received_signal);
[m,ind]=max(z); % location of largest correlation
end_index=length(received_signal)-ind+1;
relevant_signal = received_signal(headstart + num_of_samples_per_bit * numel(header) : end_index - 1);
% relevant_signal = received_signal(headstart + num_of_samples_per_bit * numel(header): end);
demodulated_signal = ask_demodulate(relevant_signal, fs, F_on, bit_rate);
sampled_points_in_demodulated_signal = demodulated_signal(round(num_of_samples_per_bit / 2) : num_of_samples_per_bit :end);
digital_output = (sampled_points_in_demodulated_signal > (max(sampled_points_in_demodulated_signal(:)) / 2));
% digital_output = (sampled_points_in_demodulated_signal > 0.05);
% Convert to characters
total_num_of_bits = numel(digital_output);
total_num_of_characters = total_num_of_bits / 8;
first_idx = 0;
last_idx = 0;
output_str = '';
for i = 1:total_num_of_characters
first_idx = last_idx + 1;
last_idx = first_idx + 7;
binary_repr = digital_output(first_idx:last_idx);
ascii_value = bi2de(binary_repr(:)', 'left-msb');
character = char(ascii_value);
output_str = [output_str character];
end
output_str
ASK変調コード(ask_modulate):
function [bandlimited_and_modulated_signal] = ask_modulate(bit_stream, fs, F_on, bit_rate)
% Amplitude shift keying: Modulation
% Dang Manh Truong (dangmanhtruong@gmail.com)
num_of_bits = numel(bit_stream);
num_of_samples_per_bit = round(fs / bit_rate);
alpha = 0;
d_alpha = 2 * pi * F_on / fs;
A = 3;
analog_signal = [];
for i = 1 : num_of_bits
bit = bit_stream(i);
switch bit
case 1
for j = 1 : num_of_samples_per_bit
analog_signal = [analog_signal A * cos(alpha)];
alpha = alpha + d_alpha;
end
case 0
for j = 1 : num_of_samples_per_bit
analog_signal = [analog_signal 0];
alpha = alpha + d_alpha;
end
end
end
filter_order = 15;
LP_filter = fir1(filter_order, (2*6000)/fs, 'low');
bandlimited_analog_signal = conv(analog_signal, LP_filter,'same');
% plot(abs(fft(bandlimited_analog_signal)))
% plot(bandlimited_analog_signal)
bandlimited_and_modulated_signal = bandlimited_analog_signal;
end
ASK復調(ask_demodulate.m)(基本的には単なるエンベロープ検出であり、ヒルベルト変換を使用しました)
function [demodulated_signal] = ask_demodulate(received_signal, fs, F_on, bit_rate)
% Amplitude shift keying: Demodulation
% Dang Manh Truong (dangmanhtruong@gmail.com)
demodulated_signal = abs(hilbert(received_signal));
end
なぜ機能しないのですか?どうもありがとうございました