Saya sedang menulis sebuah contoh tentang pengiriman data melalui suara antara 2 komputer. Beberapa persyaratan:
Jaraknya sangat dekat, yaitu 2 komputer pada dasarnya berdekatan satu sama lain
Sangat sedikit noise (saya pikir guru saya tidak akan menyalakan lagu rock sebagai sumber noise)
Kesalahan dapat diterima: Misalnya jika saya mengirim "Radio komunikasi" maka jika komputer lain menerima "RadiQ communEcation" juga tidak apa-apa.
Jika memungkinkan: Tanpa header, flag, checksum, .... karena saya hanya ingin contoh yang sangat mendasar yang menunjukkan dasar-dasar pengiriman data melalui suara. Tidak perlu mewah.
Saya mencoba menggunakan Audio Frequency Shift Keying sesuai dengan tautan ini:
Lab 5 APRS (Sistem Pelaporan Paket Otomatis)
dan mendapat beberapa hasil: Halaman Github saya
tapi itu tidak cukup. Saya tidak tahu bagaimana melakukan pemulihan jam, sinkronisasi, ... (tautannya memiliki Loop Terkunci Fase sebagai mekanisme pemulihan waktu, tetapi ternyata itu tidak cukup).
Jadi saya pikir saya harus menemukan pendekatan yang lebih sederhana. Temukan tautan di sini:
Data ke audio dan kembali. Modulasi / demodulasi dengan kode sumber
tetapi OP tidak menerapkan metode yang disarankan dalam jawaban, jadi saya khawatir itu mungkin sangat kompleks. Saya juga tidak mengerti metode decoding yang disarankan dalam jawaban:
Dekoder sedikit lebih rumit tapi inilah garis besarnya:
Opsional band-pass menyaring sinyal sampel sekitar 11KHz. Ini akan meningkatkan kinerja di lingkungan yang bising. Filter FIR cukup sederhana dan ada beberapa applet desain online yang akan menghasilkan filter untuk Anda.
Ambang sinyal. Setiap nilai di atas 1/2 amplitudo maksimum adalah 1 setiap nilai di bawah adalah 0. Ini mengasumsikan Anda telah mengambil sampel seluruh sinyal. Jika ini secara real time Anda memilih ambang batas tetap atau melakukan semacam kontrol penguatan otomatis tempat Anda melacak level sinyal maksimum selama beberapa waktu.
Pindai untuk mulai dari titik atau garis putus-putus. Anda mungkin ingin melihat setidaknya sejumlah 1 dalam periode titik Anda untuk mempertimbangkan sampel sebagai titik. Kemudian terus memindai untuk melihat apakah ini tanda hubung. Jangan mengharapkan sinyal yang sempurna - Anda akan melihat beberapa 0 di tengah 1 Anda dan beberapa 1 di tengah 0 Anda. Jika ada sedikit noise maka membedakan periode "on" dari periode "off" seharusnya cukup mudah.
Kemudian balikkan proses di atas. Jika Anda melihat tanda hubung dorong 1 bit ke buffer Anda, jika titik menekan angka nol.
Saya tidak mengerti berapa banyak 1 sebelum mengklasifikasikannya sebagai titik, ... Jadi ada banyak hal yang saya tidak mengerti sekarang. Tolong sarankan kepada saya metode sederhana untuk mengirimkan data melalui suara sehingga saya bisa memahami prosesnya. Terima kasih banyak :)
MEMPERBARUI:
Saya telah membuat beberapa kode Matlab yang tampaknya (agak) operasional. Saya pertama-tama memodulasi sinyal menggunakan kunci shift Amplitudo (frekuensi sampling 48000 Hz, F_on = 5000 Hz, bit rate = 10 bit / s), kemudian menambahkannya dengan header dan urutan akhir (tentu saja memodulasi mereka juga). Header dan urutan akhir dipilih berdasarkan ad-hoc (ya itu peretasan):
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];
Kemudian saya mengirimkannya melalui suara, dan merekamnya dengan smartphone saya. Kemudian saya mengirim rekaman audio kembali ke komputer saya, menggunakan kode lain untuk membaca audio. Kemudian saya mengkorelasikan sinyal yang diterima (belum didemodulasi) dengan header termodulasi dan urutan akhir untuk mengetahui awal dan akhir. Setelah itu saya hanya mengambil sinyal yang relevan (dari awal hingga akhir, seperti yang ditemukan di bagian korelasi). Kemudian saya mendemodulasi dan mencicipi untuk menemukan data digital. Berikut adalah 3 file audio:
"DigitalCommunication_ask": Tautan di sini mengirimkan teks "Komunikasi digital". Relatif bebas noise meskipun Anda dapat mendengar beberapa kebisingan latar belakang di awal dan di akhir. Namun hasilnya hanya menunjukkan "Digital Commincatio"
"HelloWorld_ask": Tautan di sini mengirimkan teks "Hello world". Bebas suara seperti "DigitalCommunication_ask". Namun hasilnya untuk yang ini benar
"HelloWorld_noise_ask": Tautan di sini mengirim teks "Hello world". Namun ada beberapa kebisingan yang saya buat (saya baru saja mengatakan beberapa hal acak "A, B, C, D, E, ...." selama transmisi). Sayangnya yang ini gagal
Berikut adalah kode untuk pengirim (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);
Untuk penerima (penerima.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
Kode modulasi ASK (ask_modulate):
function [bandlimited_and_modulated_signal] = ask_modulate(bit_stream, fs, F_on, bit_rate)
% Amplitude shift keying: Modulation
% Dang Manh Truong ([email protected])
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
Demodulation ASK (ask_demodulate.m) (Pada dasarnya itu hanya deteksi amplop, yang saya gunakan transformasi Hilbert)
function [demodulated_signal] = ask_demodulate(received_signal, fs, F_on, bit_rate)
% Amplitude shift keying: Demodulation
% Dang Manh Truong ([email protected])
demodulated_signal = abs(hilbert(received_signal));
end
Tolong beritahu saya mengapa itu tidak berhasil? Terima kasih banyak
sumber
Jawaban:
Seperti yang telah Anda sadari, bagian tersulit dalam melakukan komunikasi digital adalah sinkronisasi carrier, simbol dan frame, serta estimasi / penyamaan kanal.
Berita buruknya adalah Anda tidak bisa mengatasi masalah ini. Berita baiknya adalah penerapan ini tidak terlalu sulit, asalkan Anda membatasi diri Anda dengan mempersempit BPSK. Saya tahu, karena saya telah melakukan ini sendiri, dan begitu juga dengan mahasiswa (sarjana) saya (lihat http://ieeexplore.ieee.org/document/5739249/ )
Satu saran sederhana untuk mengatasi masalah sinkronisasi pembawa adalah menggunakan AM DSB-LC untuk meningkatkan sinyal baseband Anda. Kemudian, Anda dapat menggunakan detektor amplop tanpa sinkronisasi pembawa dan fase. Ini akan membebani Anda dalam efisiensi daya, tetapi itu bukan prioritas dalam kasus Anda.
Saran sederhana lainnya adalah melakukan "pemrosesan batch" alih-alih "pemrosesan waktu nyata"; artinya, simpan seluruh sinyal yang diterima dan proses setelah itu. Ini jauh lebih mudah diimplementasikan daripada stream atau pemrosesan real-time.
Saran saya yang lebih besar adalah membaca buku ini: Johnson, Sethares dan Klein, "desain penerima perangkat lunak", Cambridge. Ini menjelaskan dengan sangat jelas setiap bagian dari receiver, dan memiliki banyak contoh kode Matlab. Ada buku serupa oleh Steven Tretter, tentang penerapan sistem komunikasi pada DSP (saya tidak dapat mengingat judulnya sekarang).
Semoga berhasil; dan tolong ajukan pertanyaan baru yang lebih spesifik jika Anda memilikinya.
sumber
Pada akhirnya, saya menggunakan DTMF (Dual Tone Multi Frequency signaling). DTMF asli memiliki 16 sinyal masing-masing menggunakan kombinasi 2 frekuensi. Tapi di sini saya hanya menggunakan "1" (697 Hz dan 1209 Hz) dan "0" (941Hz dan 1336 Hz)
Garis besar cara kerja kode:
Sisi penerima pertama-tama menggunakan filter bandpass 2 ridiculously-memerintahkan-dan-ridiculously-sempit untuk mengekstrak masing-masing komponen frekuensi "0" dan "1":
filter_order = 1000;
Setelah ini selesai, kita akan menemukan awal dan akhir dari setiap sinyal "1" dan "0". Kode ini berasal dari https://github.com/codyaray/dtmf-signaling . Pada dasarnya ia menemukan periode diam yang setidaknya 10 ms dan periode nada lebih dari 100 ms):
(Dari atas ke bawah: sinyal Nol, sinyal setelah filter rata-rata bergerak, perbedaan sinyal setelah menghapus yang di bawah ambang batas, sinyal setelah ambang)
Kemudian kami merakit bit dan mengubahnya kembali menjadi teks :)
Demo video: https://www.youtube.com/watch?v=vwQVmNnWa4s , tempat saya mengirim teks "Xin chao" antara laptop saya dan PC saudara saya :)
P / S: Awalnya saya melakukan ini karena guru Komunikasi Digital saya mengatakan bahwa siapa pun yang melakukan ini akan mendapatkan nilai A tanpa harus melakukan ujian akhir, tetapi saya hanya bisa melakukan ini setelah ujian. Jadi, inilah semua usaha saya :(
P / S2: Saya mendapat C + :(
sumber
Jika Anda menginginkan pustaka sumber terbuka dengan sinkronisasi yang sangat baik, saya sarankan https://github.com/jgaeddert/liquid-dsp yang menggunakan mosedences untuk menyelaraskan, kemudian lakukan penyamaan dan demodulasi muatan. Saya membuat modem audio yang berjalan di atas dan itu bekerja dengan cukup baik, jadi jika tidak ada yang lain, metode cair seharusnya bisa membantu
sumber