Mengirimkan data melalui suara antara 2 komputer (jarak sangat dekat)


12

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 (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

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 (dangmanhtruong@gmail.com)

demodulated_signal = abs(hilbert(received_signal));

end

Tolong beritahu saya mengapa itu tidak berhasil? Terima kasih banyak


Secara teori (dalam lingkungan yang bebas noise), ini mungkin sepele untuk diterapkan tetapi dalam praktiknya ini jauh lebih sulit. Namun, itu tergantung pada jenis informasi yang Anda coba kirim. Teks akan sangat sulit untuk ditransmisikan secara andal karena bahkan noise terkecil akan membuat teks tidak dapat dikenali.
dsp_user

@dsp_user Saya mencoba mengirim teks. Saya dapat hidup dengan beberapa kesalahan (seperti "Audio" -> "Apdio") :) Juga saya tidak begitu mengerti bahwa, untuk Amplitude Shift Keying misalnya, ketika Anda memiliki 1 maka Anda mengirim gelombang sinus, 0 maka tidak ada yang lain selain bagaimana Anda tahu 0 pertama? Maksud saya di lingkungan yang bebas noise, tetapi sebelum 1 pertama akan ada banyak 0 kan? Lalu bagaimana Anda tahu itu?
Dang Manh Truong

Saya sarankan Anda melihat sesuatu seperti modem 14,4 kuno untuk ide.

@StanleyPawlukiewicz Saya telah membuat beberapa kemajuan. Silakan periksa pembaruan. Terima kasih banyak.
Dang Manh Truong

Ada banyak komentar. Anda mungkin ingin melihat urutan Barker untuk mukadimah Anda, mengingat bahwa Anda menggunakan mukadimah

Jawaban:


8

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.


Saya sudah membaca makalah Anda. Pertahankan kerja bagus! Satu pertanyaan: Di koran, Anda berbicara tentang beberapa metode yang digunakan oleh siswa untuk menemukan respons saluran (menggunakan impuls, gelombang sinus, ..). Apakah saya perlu menemukan respons saluran juga? :)
Dang Manh Truong

1
Terima kasih atas kata-kata baik Anda :) Masalahnya adalah Anda ingin memastikan bahwa Anda mentransmisikan melalui pita frekuensi di mana respons salurannya datar; jika tidak, Anda akan membutuhkan equalizer di receiver. Jika Anda tidak ingin memperkirakan respons saluran, yang dapat Anda lakukan adalah menggunakan kecepatan data yang sangat rendah (katakanlah, 100 b / dtk) pada frekuensi yang membuat nyaman semua peralatan audio (katakanlah, 5000 Hz).
MBaz

1
@DangManhTruong Satu hal lagi: pastikan untuk menggunakan pulsa-bandwidth terbatas seperti cosine yang ditinggikan oleh root-square, bukan pulsa-pulsa persegi yang memiliki bandwidth besar dan kemungkinan besar akan mengalami distorsi.
MBaz

Saya telah membaca desain penerima Software buku seperti yang Anda sarankan (sebenarnya saya membaca sekilas sebagian besar dan berkonsentrasi pada Bab 8: Bits to Symbols to Signals). Jadi saya punya beberapa pertanyaan. Anda mengatakan sesuatu tentang pulsa, tetapi dalam contoh buku itu mereka menggunakan jendela Hamming sebagai denyut nadi, apakah tidak apa-apa jika saya melakukannya? Dan apakah saya mengerti benar: Pertama Anda memodulasi sinyal menggunakan, katakanlah, BERTANYA, kemudian Anda menggunakan pembentukan pulsa. Kemudian pada penerima, Anda pertama kali berkorelasi dengan sinyal pulsa untuk menerima sinyal termodulasi. Kemudian Anda mendemodulasi. Apakah itu benar?
Dang Manh Truong

Dan jika saya ingin mengirim data dalam bentuk paket, dengan header di awal dan akhir, katakan 1 1 1 1 1 1 1 1, jadi saya harus menambahkannya dengan data, kemudian memodulasi, lalu membentuknya. Pada penerima, saya akan mengkorelasikan sinyal yang diterima dengan bentuk pulsa (kuadrat akar yang dinaikkan, ..) maka saya harus mendemodulasi sinyal, setelah itu berkorelasi dengan header. Apakah pemahaman saya benar?
Dang Manh Truong

4

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:

  • Pengirim mengubah teks menjadi biner, kemudian mengirimkan sinyal DTMF "0" / "1" (di sini waktunya adalah 0,3 detik untuk durasi nada, dan 0,1 detik untuk periode diam antara nada). Kode transmisi diambil dari: https://sites.google.com/a/nd.edu/adsp-nik-kleber/home/advanced-digital-signal-processing/project-3-touch-tone . Rupanya penulis menggunakan filter IIR yang sedikit stabil untuk mengimplementasikan osilator digital.
  • 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;

    one_band = [[((2696)/Fs) ((2698)/Fs)] [((21208)/Fs) ((21210)/Fs)]];
    
    one_dtmf_filter = fir1(filter_order, one_band);
    
    zero_band = [[((2940)/Fs) ((2942)/Fs)] [((21335)/Fs) ((21337)/Fs)]];
    
    zero_dtmf_filter = fir1(filter_order, zero_band);
    

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):

masukkan deskripsi gambar di sini

(Dari atas ke bawah: sinyal Nol, sinyal setelah filter rata-rata bergerak, perbedaan sinyal setelah menghapus yang di bawah ambang batas, sinyal setelah ambang)

  • Pertama hasil dari langkah sebelumnya dinormalisasi kemudian pergi melalui filter rata-rata bergerak (dengan ukuran filter sama dengan 10ms * Fs). Jika kita memplot hasilnya, kita akan melihat bahwa bentuk "0" dan "1" dapat terlihat dengan jelas. Jadi saya pikir ini berfungsi sebagai detektor amplop dalam kasus ini.
  • Kemudian semua sinyal di bawah ambang tertentu terputus (saya memilih 0,1).
  • Akhirnya menemukan semua interval di atas ambang batas yang memiliki interval waktu lebih dari 100 ms (perhatikan bahwa gambar tidak dapat direproduksi dari kode, Anda harus menggali sekitar untuk membuatnya)

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 + :(


0

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

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.