MATLAB, 1960 bps
นี่คือความพยายามที่อัปเดตของฉัน:
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
ตั้งแต่ครั้งแรกที่ฉันเล่นไปรอบ ๆ ตอนนี้มีคำนำเล็ก ๆ ที่จุดเริ่มต้น (ช่วงเวลา 18 บิต แต่อาจสั้นกว่า) ซึ่งมีเพียงแค่คลื่นโคไซน์ ฉันแยกมันออกมาและทำซ้ำเพื่อสร้าง phased sine และ cosine carrier เพื่อ demodulation อย่างถูกต้อง - เนื่องจากเป็นการเริ่มนำที่สั้นมากฉันไม่ได้นับในอัตราบิตตามคำแนะนำของคุณ
นอกจากนี้ตั้งแต่ครั้งแรกที่ฉันใช้กลุ่ม QAM8 เพื่อให้ได้ 3 บิตต่อสัญญลักษณ์แทน 2 สิ่งนี้ทำให้อัตราการถ่ายโอนเป็นสองเท่าได้อย่างมีประสิทธิภาพ ด้วยผู้ให้บริการ ~ 2.4kHz ตอนนี้ฉันได้รับ 1960bps
ฉันได้ปรับปรุงการตรวจจับสัญลักษณ์เพื่อให้ค่าเฉลี่ยไม่ได้รับผลกระทบจากเวลาที่เพิ่มขึ้นอย่างช้า ๆ ซึ่งเกิดจากการกรองโดยทั่วไปแล้วเพียงช่วงครึ่งหลังของแต่ละช่วงเวลาบิตจะถูกนำมาเฉลี่ยเพื่อขจัดผลกระทบของเวลาที่เพิ่มขึ้น
ยังคงอยู่ใกล้กับแบนด์วิดท์ช่องทฤษฎี 40kbps จากทฤษฎีShannon-Hartley (สมมติว่า 30dB SNR)
สำหรับผู้ที่ชอบเสียงที่น่ากลัวนี่เป็นรายการใหม่:
และในกรณีที่ใครสนใจรายการนี้เป็น 960bps ก่อนหน้า