MATLAB, 1960 bps
Đây là nỗ lực cập nhật của tôi:
fs = 44100; %44.1kHz audio rate
fc = 2450; %2.45kHz carrier - nice fraction of fs!
fsym = fc/5; %symbol rate
tmax = 4; %about 4 seconds worth
preamblesyms = 6;
t = 1/fs:1/fs:(tmax+preamblesyms/fsym);
symbols = preamblesyms+fsym*tmax;
symbollength = length(t)/symbols;
bits = symbols*3;
bitstream = [zeros(1,preamblesyms*3),rand(1,bits-preamblesyms*3)>0.5]; %Add a little preamble of 18 bits
data = bin2dec(char(reshape(bitstream,3,symbols)'+'0'))';
greycode = [0 1 3 2 6 7 5 4];
%Encode the symbols using QAM8 - we use effectively grey code so that
%adjacent symbols in the constellation have only one bit difference
%(minimises error rate)
encoded = zeros(2,symbols);
encoded(1,data==1) = 1/sqrt(2);
encoded(1,data==3) = 1;
encoded(1,data==2) = 1/sqrt(2);
encoded(1,data==7) = -1/sqrt(2);
encoded(1,data==5) = -1;
encoded(1,data==4) = -1/sqrt(2);
encoded(2,data==0) = 1;
encoded(2,data==1) = 1/sqrt(2);
encoded(2,data==2) = -1/sqrt(2);
encoded(2,data==6) = -1;
encoded(2,data==7) = -1/sqrt(2);
encoded(2,data==4) = 1/sqrt(2);
%Modulate onto carrier
carrier = [sin(2*pi*fc*t);cos(2*pi*fc*t)];
signal = reshape(repmat(encoded(1,:)',1,symbollength)',1,[]);
signal(2,:) = reshape(repmat(encoded(2,:)',1,symbollength)',1,[]);
modulated = sum(signal.*carrier)';
%Write out an audio file
audiowrite('audio.wav',modulated,fs);
%Wait for the user to run through the POTS simulator
input('');
%Read in the filtered data
filtered=audioread('audio.pots-filtered.wav')';
%Recover the two carrier signals
preamblecos = filtered(symbollength+1:symbollength*2);
preamblesin = filtered(symbollength+1+round(symbollength*3/4):symbollength*2+round(symbollength*3/4));
%Replicated the recovered carriers for all symbols
carrierfiltered = [repmat(preamblesin,1,symbols);repmat(preamblecos,1,symbols)];
%Generate a demodulation filter (pass up to 0.66*fc, stop at 1.33*fc
%(really we just need to kill everything around 2*fc where the alias ends up)
d=fdesign.lowpass('Fp,Fst,Ap,Ast',0.05,0.1,0.5,60);
Hd = design(d,'equiripple');
%Demodulate the incoming stream
demodulated = carrierfiltered .* [filtered;filtered];
demodulated(1,:)=filtfilt(Hd.Numerator,1,demodulated(1,:));
demodulated(2,:)=filtfilt(Hd.Numerator,1,demodulated(2,:));
%Split signal up into bit periods
recovereddemodulated=[];
recovereddemodulated(1,:,:) = reshape(demodulated(1,:),symbollength,symbols);
recovereddemodulated(2,:,:) = reshape(demodulated(2,:),symbollength,symbols);
%Extract the average level for each bit period. Only look at the second
%half to account for slow rise times in the signal due to filtering
recoveredsignal=mean(recovereddemodulated(1,round(symbollength/2):symbollength,:));
recoveredsignal(2,:)=mean(recovereddemodulated(2,round(symbollength/2):symbollength,:));
%Convert the recovered signal into a complex number.
recoveredsignal=recoveredsignal(2,:) + 1j*recoveredsignal(1,:);
%Determine the magnitude and angle of the symbol. The phase is normalised
%to pi/4 as that is the angle between the symbols. Rounding this to the
%nearest integer will tell us which of the 8 phases it is closest to
recoveredphase = round(angle(recoveredsignal)/(pi/4));
recoveredphase = mod(recoveredphase+8,8)+1; %Remap to an index in the grey code vector.
%Determine the symbol in the QAM8 constellation
recoveredencoded=greycode(recoveredphase);
recoveredencoded(1:preamblesyms)=0; %Assume the preamble is correct for comparison
%Turn it back in to a bit stream
bitstreamRecovered = reshape(dec2bin(recoveredencoded)'-'0',1,[]);
%And check if they are all correct...
if(all(bitstream==bitstreamRecovered))
disp(['Woop, ' num2str(fsym*4) 'bps']);
else
error('Its corrupt Jim.');
end
Kể từ lần thử đầu tiên, tôi đã chơi xung quanh một chút. Bây giờ có một lời mở đầu nhỏ ở đầu (chu kỳ 18 bit, nhưng có thể ngắn hơn) chỉ chứa một sóng cosin. Tôi trích xuất cái này và sao chép nó để tạo ra các sóng mang sin và cosine chính xác để giải điều chế - vì nó là một đoạn đầu rất ngắn, tôi đã không tính nó theo tốc độ bit theo hướng dẫn của bạn.
Ngoài ra, kể từ lần thử đầu tiên, tôi hiện đang sử dụng chòm sao QAM8 để đạt được 3 bit cho mỗi ký hiệu thay vì 2. Điều này giúp tăng gấp đôi tốc độ truyền. Vì vậy, với sóng mang ~ 2,4kHz, giờ đây tôi đạt được 1960bps.
Tôi cũng đã cải thiện khả năng phát hiện biểu tượng để tính trung bình không bị ảnh hưởng bởi thời gian tăng chậm do quá trình lọc gây ra - về cơ bản chỉ nửa sau của mỗi giai đoạn bit được lấy trung bình để loại bỏ tác động của thời gian tăng.
Vẫn không có nơi nào gần băng thông kênh lý thuyết 40kbps từ lý thuyết Shannon-Hartley (giả sử SNR 30dB)
Chỉ dành cho những người thích âm thanh khủng khiếp , đây là mục mới:
Và trong trường hợp bất cứ ai quan tâm, đây là mục nhập 960bps trước đó