Sto scrivendo un esempio sulla trasmissione di dati attraverso l'audio tra computer 2. Alcuni requisiti:
La distanza è molto vicina, ovvero i 2 computer sono sostanzialmente adiacenti l'uno all'altro
Molto poco rumore (non credo che il mio insegnante avrebbe attivato una canzone rock come fonte di rumore)
L'errore è accettabile: ad esempio se invio "Comunicazione radio", anche se l'altro computer riceve "RadiQ communEcation", va bene lo stesso.
Se possibile: nessuna intestazione, flag, checksum, .... poiché voglio solo un esempio molto semplice che dimostri le basi della trasmissione dei dati attraverso il suono. Non c'è bisogno di essere fantasiosi.
Ho provato a utilizzare la codifica di spostamento della frequenza audio in base a questo link:
Lab 5 APRS (sistema di reportistica automatica dei pacchetti)
e ho ottenuto alcuni risultati: La mia pagina Github
Ma non è abbastanza. Non so come fare il recupero del clock, la sincronizzazione, ... (il collegamento ha un Phase Locked Loop come meccanismo di recupero del timing, ma apparentemente non era abbastanza).
Quindi penso che dovrei trovare un approccio più semplice. Ho trovato un link qui:
Dati in audio e ritorno. Modulazione / demodulazione con codice sorgente
ma l'OP non ha implementato il metodo suggerito nella risposta, quindi temo che potrebbe essere molto complesso. Inoltre non capisco chiaramente il metodo di decodifica suggerito nella risposta:
Il decoder è un po 'più complicato ma ecco uno schema:
Facoltativamente, il filtro passa-banda filtra il segnale campionato intorno a 11Khz. Ciò migliorerà le prestazioni in un ambiente rumoroso. I filtri FIR sono piuttosto semplici e ci sono alcune applet di design online che genereranno il filtro per te.
Soglia il segnale. Ogni valore superiore a 1/2 dell'ampiezza massima è 1 ogni valore inferiore è 0. Ciò presuppone che sia stato campionato l'intero segnale. Se questo è in tempo reale, scegli una soglia fissa o esegui una sorta di controllo automatico del guadagno in cui segui il livello massimo del segnale nel tempo.
Cerca l'inizio del punto o del trattino. Probabilmente vuoi vedere almeno un certo numero di 1 nel tuo punto periodo per considerare i campioni come un punto. Quindi continua la scansione per vedere se si tratta di un trattino. Non aspettarti un segnale perfetto: vedrai alcuni 0 nel mezzo dei tuoi 1 e alcuni 1 nel mezzo dei tuoi 0. Se c'è poco rumore, differenziare i periodi "on" dai periodi "off" dovrebbe essere abbastanza semplice.
Quindi invertire il processo sopra descritto. Se vedi trattino spingere un bit per il tuo buffer, se un punto spinge uno zero.
Non capisco quanti 1 sono prima di classificarlo come punto, ... Quindi ci sono molte cose che non capisco in questo momento. Per favore, suggeriscimi un metodo semplice per trasmettere dati attraverso il suono in modo che io possa capire il processo. Grazie mille :)
AGGIORNARE:
Ho creato un codice Matlab che sembra essere (in qualche modo) operativo. Per prima cosa modulo il segnale usando il key shift di ampiezza (frequenza di campionamento 48000 Hz, F_on = 5000 Hz, bit rate = 10 bit / s), quindi lo aggiungo con un'intestazione e una sequenza finale (ovviamente modulandoli anche). L'intestazione e la sequenza finale sono state scelte su una base ad hoc (sì, era un trucco):
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];
Quindi le trasmetto attraverso il suono e le ho registrate con il mio smartphone. Quindi rispedisco l'audio registrato al mio computer, uso un altro codice per leggere l'audio. Quindi correlo il segnale ricevuto (non ancora demodulato) con l'intestazione modulata e la sequenza finale per scoprire l'inizio e la fine. Successivamente prendo solo il segnale rilevante (dall'inizio alla fine, come si trova nella parte di correlazione). Quindi demodulo e campiono per trovare i dati digitali. Ecco 3 file audio:
"DigitalCommunication_ask": Link qui invia il testo "Comunicazione digitale". Relativamente privo di rumore sebbene si possa sentire un po 'di rumore di fondo all'inizio e alla fine. Tuttavia, il risultato ha mostrato solo "Digital Commincatio"
"HelloWorld_ask": Link qui invia il testo "Hello world". Senza rumore come "DigitalCommunication_ask". Tuttavia, il risultato per questo è stato corretto
"HelloWorld_noise_ask": Link qui invia il testo "Hello world". Tuttavia c'è un po 'di rumore che ho fatto (ho appena detto alcune cose a caso "A, B, C, D, E, ..." durante la trasmissione). Purtroppo questo ha fallito
Ecco il codice per il mittente (mittente.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);
Per il ricevitore (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
Chiedere il codice di modulazione (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
CHIEDERE la demodulazione (ask_demodulate.m) (Fondamentalmente si tratta solo del rilevamento dell'inviluppo, per il quale ho usato la trasformazione di 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
Per favore, dimmi perché non funziona? Grazie mille