Truyền dữ liệu qua âm thanh giữa 2 máy tính (khoảng cách rất gần)


12

Tôi đang viết một ví dụ về việc truyền dữ liệu qua âm thanh betwwen 2 máy tính. Một số yêu cầu:

  • Khoảng cách rất gần, tức là 2 máy tính về cơ bản liền kề nhau

  • Rất ít tiếng ồn (Tôi không nghĩ rằng giáo viên của tôi sẽ bật một bài hát rock như một nguồn tiếng ồn)

  • Lỗi có thể chấp nhận: Ví dụ: nếu tôi gửi "Liên lạc vô tuyến" thì nếu máy tính khác nhận được "RadiQ CommunEcation" thì cũng không sao.

  • Nếu có thể: Không có tiêu đề, cờ, tổng kiểm tra, .... vì tôi chỉ muốn một ví dụ rất cơ bản thể hiện những điều cơ bản của việc truyền dữ liệu qua âm thanh. Không cần phải cầu kỳ.

Tôi đã thử sử dụng Phím Shift Tần số Âm thanh theo liên kết này:

Lab 5 APRS (Hệ thống báo cáo gói tự động)

và đã nhận được một số kết quả: Trang Github của tôi

Nhưng nó không phải là đủ. Tôi không biết cách phục hồi đồng bộ hóa, đồng bộ hóa, ... (liên kết có Giai đoạn khóa vòng như cơ chế phục hồi thời gian, nhưng rõ ràng là không đủ).

Vì vậy, tôi nghĩ rằng tôi nên tìm một cách tiếp cận đơn giản hơn. Tìm thấy một liên kết ở đây:

Dữ liệu vào âm thanh và trở lại. Điều chế / giải điều chế với mã nguồn

nhưng OP đã không thực hiện phương pháp được đề xuất trong câu trả lời, vì vậy tôi e rằng nó có thể rất phức tạp. Ngoài ra tôi không hiểu rõ phương pháp giải mã được đề xuất trong câu trả lời:

Bộ giải mã phức tạp hơn một chút nhưng đây là một phác thảo:

Tùy chọn lọc băng thông, tín hiệu được lấy mẫu khoảng 11Khz. Điều này sẽ cải thiện hiệu suất trong một môi trường ồn ào. Bộ lọc FIR khá đơn giản và có một vài applet thiết kế trực tuyến sẽ tạo bộ lọc cho bạn.

Ngưỡng tín hiệu. Mỗi giá trị trên 1/2 biên độ tối đa là 1 mỗi giá trị dưới đây là 0. Điều này giả sử bạn đã lấy mẫu toàn bộ tín hiệu. Nếu đây là thời gian thực, bạn có thể chọn một ngưỡng cố định hoặc thực hiện một số loại điều khiển khuếch đại tự động trong đó bạn theo dõi mức tín hiệu tối đa trong một thời gian.

Quét để bắt đầu dấu chấm hoặc dấu gạch ngang. Bạn có thể muốn xem ít nhất một số 1 nhất định trong dấu chấm của mình để xem các mẫu là một dấu chấm. Sau đó tiếp tục quét để xem nếu đây là một dấu gạch ngang. Đừng mong đợi một tín hiệu hoàn hảo - bạn sẽ thấy một vài 0 ở giữa số 1 của bạn và một số 1 ở giữa số 0 của bạn. Nếu có ít tiếng ồn thì việc phân biệt các khoảng thời gian "bật" với các khoảng thời gian "tắt" sẽ khá dễ dàng.

Sau đó đảo ngược quá trình trên. Nếu bạn thấy dấu gạch ngang đẩy 1 bit vào bộ đệm của bạn, nếu một dấu chấm đẩy số không.

Tôi không hiểu có bao nhiêu 1 trước khi phân loại nó thành một dấu chấm, ... Vì vậy, có nhiều điều mà tôi không hiểu ngay bây giờ. Vui lòng gợi ý cho tôi một phương pháp đơn giản để truyền dữ liệu qua âm thanh để tôi có thể hiểu quy trình. Cảm ơn rât nhiều :)

CẬP NHẬT:

Tôi đã thực hiện một số mã Matlab có vẻ như (phần nào) hoạt động. Trước tiên tôi điều chỉnh tín hiệu bằng cách sử dụng khóa dịch chuyển Biên độ (tần số lấy mẫu 48000 Hz, F_on = 5000 Hz, tốc độ bit = 10 bit / s), sau đó thêm nó bằng một tiêu đề và chuỗi kết thúc (tất nhiên cũng điều chỉnh chúng). Tiêu đề và chuỗi kết thúc đã được chọn trên cơ sở đặc biệt (vâng, đó là một vụ 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];

Sau đó, tôi truyền chúng qua âm thanh và ghi lại bằng điện thoại thông minh của mình. Sau đó, tôi gửi âm thanh được ghi lại vào máy tính của mình, sử dụng một đoạn mã khác để đọc âm thanh. Sau đó, tôi tương quan tín hiệu thu được (chưa được giải điều chế) với tiêu đề và chuỗi kết thúc được điều chế để tìm ra điểm bắt đầu và kết thúc. Sau đó tôi chỉ lấy tín hiệu liên quan (từ đầu đến cuối, như được tìm thấy trong phần tương quan). Sau đó tôi giải điều chế và lấy mẫu để tìm dữ liệu số. Dưới đây là 3 tệp âm thanh:

  • "DigitalC truyền thông_ask": Liên kết ở đây nó sẽ gửi văn bản "Giao tiếp kỹ thuật số". Tương đối không có tiếng ồn mặc dù bạn có thể nghe thấy một số tiếng ồn nền ở đầu và cuối. Tuy nhiên, kết quả chỉ cho thấy "Digital Commincatio"

  • "HelloWorld_ask": Liên kết tại đây, nó sẽ gửi văn bản "Hello world". Không có tiếng ồn như "DigitalC truyền thông_ask". Tuy nhiên, kết quả cho điều này là chính xác

  • "HelloWorld_noir_ask": Liên kết tại đây, nó sẽ gửi văn bản "Hello world". Tuy nhiên, có một số tiếng ồn mà tôi đã tạo ra (tôi chỉ nói một số nội dung ngẫu nhiên "A, B, C, D, E, ...." trong quá trình truyền tải). Thật không may, điều này đã thất bại

Đây là mã cho người gửi (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);

Đối với người nhận (người nhận.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

Mã điều chế ASK (ask_modulation):

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

Giải điều chế ASK (ask_demodulation.m) (Về cơ bản nó chỉ là phát hiện đường bao, mà tôi đã sử dụng biến đổi 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

Xin vui lòng cho tôi biết tại sao nó không hoạt động? Cảm ơn rât nhiều


Về lý thuyết (trong môi trường không có tiếng ồn), điều này sẽ không quan trọng để thực hiện nhưng trong thực tế, điều này khó khăn hơn nhiều. Tuy nhiên, nó phụ thuộc vào loại thông tin bạn đang cố gắng gửi. Văn bản sẽ cực kỳ khó truyền tải đáng tin cậy vì ngay cả tiếng ồn nhỏ nhất cũng sẽ khiến văn bản không thể nhận ra.
dsp_user

@dsp_user Tôi đang cố gắng gửi văn bản. Tôi có thể sống với một số lỗi (như "Âm thanh" -> "Apdio") :) Ngoài ra, tôi không thực sự hiểu rằng, ví dụ, đối với Khóa dịch chuyển biên độ, khi bạn có 1 thì bạn gửi sóng hình sin, 0 rồi không có gì ngoài cách Bạn có biết 0 đầu tiên không? Ý tôi là trong một môi trường không có tiếng ồn, nhưng trước 1 đầu tiên sẽ có rất nhiều phải không? Sau đó, làm thế nào để bạn biết nó?
Đặng Mạnh Trường

Tôi đề nghị bạn nên xem xét một cái gì đó giống như một modem 14.4 lỗi thời để tìm ý tưởng.

@StanleyPawlukiewicz Tôi đã đạt được một số tiến bộ. Vui lòng kiểm tra cập nhật. Cảm ơn rât nhiều.
Đặng Mạnh Trường

Có rất nhiều để nhận xét về. Bạn có thể muốn xem các chuỗi Barker cho phần mở đầu của mình, với điều kiện là bạn đang sử dụng phần mở đầu

Câu trả lời:


8

Như bạn đã nhận ra, phần khó của việc thực hiện truyền thông kỹ thuật số là vận chuyển, đồng bộ hóa biểu tượng và khung và ước tính / cân bằng kênh.

Tin xấu là bạn không thể giải quyết những vấn đề này. Tin tốt là việc thực hiện những điều này không khó, miễn là bạn giới hạn bản thân trong BPSK băng thông hẹp. Tôi biết, vì tôi đã tự làm việc này và các sinh viên (sinh viên) của tôi cũng vậy (xem http://ieeexplore.ieee.org/document/5739249/ )

Một gợi ý đơn giản để giải quyết vấn đề đồng bộ hóa mạng di động là sử dụng AM DSB-LC để chuyển đổi tín hiệu băng cơ sở của bạn. Sau đó, bạn có thể sử dụng một máy dò phong bì mà không cần đồng bộ hóa sóng mang và pha. Điều này sẽ khiến bạn mất chi phí điện năng, nhưng đó không phải là ưu tiên trong trường hợp của bạn.

Một đề nghị đơn giản khác là thực hiện "xử lý hàng loạt" thay vì "xử lý thời gian thực"; điều đó có nghĩa là gì, lưu trữ toàn bộ tín hiệu nhận được và xử lý nó sau đó. Điều này dễ thực hiện hơn nhiều so với xử lý luồng hoặc thời gian thực.

Đề nghị quan trọng hơn của tôi là đọc cuốn sách này: Johnson, Sethares và Klein, "Thiết kế bộ thu phần mềm", Cambridge. Nó giải thích một cách rất rõ ràng từng phần của người nhận và có rất nhiều mã Matlab ví dụ. Có một cuốn sách tương tự của Steven Tretter, về việc triển khai một hệ thống truyền thông trên DSP (tôi không thể nhớ lại tiêu đề chính xác ngay bây giờ).

Chúc may mắn; và xin hỏi những câu hỏi mới, cụ thể hơn nếu bạn có chúng.


Tôi đã đọc bài viết của bạn. Hãy tiếp tục phát huy! Một câu hỏi: Trong bài báo, bạn đã nói về một số phương pháp được sử dụng bởi các sinh viên để tìm phản ứng kênh (sử dụng xung, sóng hình sin, ..). Tôi có cần tìm phản hồi kênh không? :)
Đặng Mạnh Trường

1
Cảm ơn những lời tốt đẹp của bạn :) Điều bạn muốn chắc chắn là bạn truyền qua một dải tần nơi đáp ứng kênh là phẳng; nếu không, bạn sẽ cần một bộ cân bằng trong máy thu. Nếu bạn không muốn ước tính phản hồi kênh, điều bạn có thể làm là sử dụng tốc độ dữ liệu rất thấp (giả sử 100 b / s) trên tần số mà tất cả các thiết bị âm thanh phải thoải mái (giả sử, 5000 Hz).
MBaz

1
@DangManhTruong Một điều nữa: hãy chắc chắn sử dụng các xung giới hạn băng thông như cosin tăng căn bậc hai, không phải các xung vuông có băng thông lớn và rất có thể sẽ bị biến dạng.
MBaz

Tôi đã đọc cuốn sách Thiết kế phần mềm nhận như bạn đề xuất (thực ra tôi đã đọc lướt qua phần lớn và tập trung vào Chương 8: Bits to Symbols to Signals). Vì vậy, tôi có một số câu hỏi. Bạn đã nói điều gì đó về các xung, nhưng trong ví dụ của cuốn sách họ đã sử dụng cửa sổ Hamming như một xung, liệu tôi có ổn không? Và tôi hiểu đúng: Đầu tiên bạn điều chỉnh tín hiệu bằng cách sử dụng ASK, sau đó bạn sử dụng định dạng xung. Sau đó, trên máy thu, trước tiên bạn tương quan với tín hiệu xung để nhận tín hiệu điều chế. Sau đó, bạn giải điều chế. Nó có đúng không?
Đặng Mạnh Trường

Và nếu tôi muốn gửi dữ liệu ở dạng gói, với tiêu đề ở đầu và cuối, hãy nói 1 1 1 1 1 1 1 1, vì vậy tôi nên nối nó với dữ liệu, sau đó điều chỉnh nó, sau đó điều chỉnh xung. Trên máy thu, tôi sẽ tương quan tín hiệu thu được với hình dạng xung (cosin tăng căn bậc hai, ..) sau đó tôi phải giải điều chế tín hiệu, sau đó tương quan với tiêu đề. Tôi hiểu có đúng không?
Đặng Mạnh Trường

4

Cuối cùng, tôi đã sử dụng DTMF (Tín hiệu đa tần số giai điệu kép). DTMF ban đầu có 16 tín hiệu, mỗi tín hiệu sử dụng kết hợp 2 tần số. Nhưng ở đây tôi chỉ sử dụng "1" (697 Hz và 1209 Hz) và "0" (941Hz và 1336 Hz)

Một phác thảo về cách thức hoạt động của mã:

  • Người gửi chuyển đổi văn bản thành nhị phân, sau đó truyền tín hiệu DTMF "0" / "1" (ở đây thời gian là 0,3 giây cho thời lượng âm và 0,1 giây cho khoảng thời gian im lặng giữa các âm). Mã truyền được lấy từ: https://sites.google.com/a/nd.edu/adsp-nik-kleber/home/advified-digital-signal- Processing / project-3-touch-tone . Rõ ràng tác giả đã sử dụng bộ lọc IIR ổn định biên để thực hiện bộ tạo dao động kỹ thuật số.
  • Trước tiên, phía người nhận sử dụng 2 bộ lọc băng thông hẹp có thứ tự cao và cực kỳ hẹp để trích xuất các thành phần tần số "0" và "1", tương ứng:

    bộ lọc_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);
    

Sau khi hoàn thành, chúng ta sẽ tìm thấy điểm bắt đầu và kết thúc của mỗi tín hiệu "1" và "0". Mã này được lấy từ https://github.com/codyaray/dtmf-signaling . Về cơ bản, nó tìm thấy khoảng thời gian im lặng ít nhất là 10 ms và bất kỳ giai điệu nào hơn 100ms):

nhập mô tả hình ảnh ở đây

(Từ trên xuống dưới: Tín hiệu bằng không, tín hiệu sau khi di chuyển bộ lọc trung bình, chênh lệch tín hiệu sau khi loại bỏ các mức dưới ngưỡng, tín hiệu sau khi ngưỡng)

  • Đầu tiên, kết quả từ bước trước được chuẩn hóa sau đó chuyển qua bộ lọc trung bình di động (với kích thước bộ lọc bằng 10ms * Fs). Nếu chúng ta vẽ kết quả, chúng ta sẽ thấy rằng hình dạng của "0" và "1" có thể được nhìn thấy rõ ràng. Vì vậy, tôi nghĩ rằng nó hoạt động như một máy dò phong bì trong trường hợp này.
  • Sau đó, tất cả tín hiệu dưới một ngưỡng nhất định sẽ bị cắt (tôi chọn 0,1).
  • Cuối cùng tìm thấy tất cả các khoảng trên ngưỡng có khoảng thời gian lớn hơn 100ms (lưu ý rằng hình ảnh không thể tái tạo từ mã, bạn sẽ phải đào xung quanh để tạo ra nó)

Sau đó, chúng tôi lắp ráp các bit và chuyển đổi trở lại thành văn bản :)

Bản demo video: https://www.youtube.com/watch?v=vwQVmNnWa4s , nơi tôi gửi văn bản "Xin chao" giữa máy tính xách tay của tôi và PC của anh tôi :)

P / S: Ban đầu tôi đã làm điều này bởi vì giáo viên Truyền thông Kỹ thuật số của tôi nói rằng bất cứ ai làm điều này sẽ có điểm A mà không phải làm bài kiểm tra cuối cùng, nhưng tôi chỉ có thể làm điều này sau kỳ thi. Vì vậy, đây là tất cả những nỗ lực của tôi :(

P / S2: Tôi có C + :(


0

Nếu bạn muốn một thư viện mã nguồn mở có khả năng đồng bộ hóa rất tốt, tôi khuyên bạn nên https://github.com/jgaeddert/l Liquid-dsp sử dụng các kết quả để căn chỉnh, sau đó thực hiện cân bằng và giải điều chế tải trọng. Tôi đã tạo ra một modem âm thanh chạy trên đầu và nó hoạt động khá tốt, vì vậy nếu không có gì khác, các phương pháp của chất lỏng sẽ có ích

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.