J'écris un exemple sur la transmission de données via le son entre deux ordinateurs. Quelques exigences:
La distance est très proche, c'est-à-dire que les 2 ordinateurs sont fondamentalement adjacents l'un à l'autre
Très peu de bruit (je ne pense pas que mon professeur allumerait une chanson rock comme source de bruit)
L'erreur est acceptable: par exemple, si j'envoie "Communication radio", si l'autre ordinateur reçoit "RadiQ communEcation", ça va aussi.
Si possible: pas d'en-tête, indicateur, somme de contrôle, .... car je veux juste un exemple très basique démontrant les bases de la transmission de données par le son. Pas besoin d'être chic.
J'ai essayé d'utiliser la modulation de fréquence audio selon ce lien:
Lab 5 APRS (Automatic Package Reporting System)
et obtenu quelques résultats: Ma page Github
Mais ce n'est pas assez. Je ne sais pas comment faire la récupération d'horloge, la synchronisation, ... (le lien a une boucle à verrouillage de phase comme mécanisme de récupération de synchronisation, mais ce n'était apparemment pas suffisant).
Je pense donc que je devrais trouver une approche plus simple. Trouvé un lien ici:
Données audio et retour. Modulation / démodulation avec code source
mais l'OP n'a pas mis en œuvre la méthode suggérée dans la réponse, donc je crains que cela ne soit très complexe. De plus, je ne comprends pas clairement la méthode de décodage suggérée dans la réponse:
Le décodeur est un peu plus compliqué mais voici un aperçu:
Optionnellement, filtre passe-bande du signal échantillonné autour de 11 kHz. Cela améliorera les performances dans un environnement bruyant. Les filtres FIR sont assez simples et il existe quelques applets de conception en ligne qui généreront le filtre pour vous.
Seuil le signal. Chaque valeur au-dessus de 1/2 amplitude maximale est 1 chaque valeur au-dessous est 0. Cela suppose que vous avez échantillonné la totalité du signal. Si c'est en temps réel, vous choisissez un seuil fixe ou effectuez une sorte de contrôle automatique du gain où vous suivez le niveau de signal maximum sur une certaine période.
Recherchez le début du point ou du tiret. Vous voulez probablement voir au moins un certain nombre de 1 dans votre période de points pour considérer les échantillons comme un point. Continuez ensuite à scanner pour voir s'il s'agit d'un tiret. Ne vous attendez pas à un signal parfait - vous verrez quelques 0 au milieu de vos 1 et quelques 1 au milieu de vos 0. S'il y a peu de bruit, différencier les périodes "marche" des périodes "arrêt" devrait être assez facile.
Inversez ensuite le processus ci-dessus. Si vous voyez un tiret, poussez 1 bit vers votre tampon, si un point pousse un zéro.
Je ne comprends pas combien de 1 avant de le classer comme un point, ... Il y a donc beaucoup de choses que je ne comprends pas en ce moment. Veuillez me suggérer une méthode simple pour transmettre des données par le son afin que je puisse comprendre le processus. Merci beaucoup :)
MISE À JOUR:
J'ai créé du code Matlab qui semble être (quelque peu) opérationnel. Je module d'abord le signal en utilisant la modulation par décalage d'amplitude (fréquence d'échantillonnage 48000 Hz, F_on = 5000 Hz, débit binaire = 10 bits / s), puis je l'ajoute avec un en-tête et une séquence de fin (bien sûr, modulez-les également). L'en-tête et la séquence de fin ont été choisis sur une base ad hoc (ouais c'était un hack):
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];
Je les transmets ensuite par le son et je les enregistre avec mon smartphone. Ensuite, j'envoie l'audio enregistré à mon ordinateur, utilise un autre morceau de code pour lire l'audio. Ensuite, je corrèle le signal reçu (pas encore démodulé) avec l'en-tête modulé et la séquence de fin pour connaître le début et la fin. Après cela, je ne prends que le signal pertinent (du début à la fin, comme on le trouve dans la partie corrélation). Ensuite, je démodule et échantillonne pour trouver les données numériques. Voici 3 fichiers audio:
"DigitalCommunication_ask": Le lien ici envoie le texte "Communication numérique". Relativement sans bruit, bien que vous puissiez entendre un bruit de fond au début et à la fin. Cependant, le résultat n'a montré que "Digital Commincatio"
"HelloWorld_ask": Le lien ici envoie le texte "Hello world". Sans bruit comme "DigitalCommunication_ask". Cependant le résultat pour celui-ci était correct
"HelloWorld_noise_ask": Le lien ici envoie le texte "Hello world". Cependant il y a du bruit que j'ai fait (je viens de dire quelques trucs aléatoires "A, B, C, D, E, ...." pendant la transmission). Malheureusement celui-ci a échoué
Voici le code de l'expéditeur (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);
Pour le récepteur (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
Code de modulation 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
Démodulation ASK (ask_demodulate.m) (Fondamentalement, ce n'est que la détection d'enveloppe, pour laquelle j'ai utilisé la transformée de Hilbert)
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
Veuillez me dire pourquoi cela ne fonctionne pas? Merci beaucoup