Giới thiệu
Khi làm việc với âm thanh, cảm biến hoặc hệ thống truyền thông, hầu hết các tín hiệu bắt đầu dưới dạng analog - liên tục theo thời gian và biên độ. Tuy nhiên, máy tính cần tín hiệu số. Bài viết này sẽ trình bày cách mô phỏng quá trình lấy mẫu và lượng tử hóa trong MATLAB, cũng như cách chất lượng tín hiệu phụ thuộc vào những bước này.
1. Tín hiệu Analog
Chúng ta bắt đầu với một sóng sin đơn giản tại 100 Hz:
matlab
t = 0:0.0001:0.01; % Khung thời gian
f = 100; % Tần số
x_analog = sin(2*pi*f*t); % Tín hiệu analog
plot(t, x_analog, 'k', 'LineWidth', 1.5); % Vẽ tín hiệu
title('Tín hiệu Analog');
Đoạn mã trên đại diện cho một tín hiệu liên tục theo thời gian.
2. Lấy mẫu (Định lý Nyquist)
Định lý Nyquist nói rằng chúng ta cần lấy mẫu ít nhất 2 lần tần số để tránh hiện tượng aliasing. Đối với sóng sin 100 Hz, điều này có nghĩa là ≥ 200 Hz.
Chúng ta thử ba trường hợp:
- Dưới Nyquist: 150 Hz
- Tại Nyquist: 200 Hz
- Trên Nyquist: 1000 Hz
matlab
Fs_list = [150, 200, 1000]; % Tần số lấy mẫu
colors = {'r', 'g', 'b'}; % Màu sắc cho từng biểu đồ
for i = 1:length(Fs_list)
Fs = Fs_list(i); % Tần số
Ts = 1/Fs; % Thời gian giữa các mẫu
n = 0:Ts:0.01; % Tín hiệu đã lấy mẫu
x_sampled = sin(2*pi*f*n); % Tín hiệu đã lấy mẫu
subplot(3,1,i); % Chia biểu đồ thành 3 phần
stem(n, x_sampled, colors{i}, 'filled'); % Vẽ tín hiệu đã lấy mẫu
hold on;
plot(t, x_analog, 'k'); % Vẽ tín hiệu analog
title(['Lấy mẫu tại Fs = ' num2str(Fs) ' Hz']);
end
👉 Kết quả:
- Tại 150 Hz, hiện tượng aliasing xuất hiện (tín hiệu bị biến dạng).
- Tại 200 Hz, đủ để tránh aliasing.
- Tại 1000 Hz, tín hiệu đã lấy mẫu rất gần gũi với tín hiệu analog.
3. Lượng tử hóa
Sau khi lấy mẫu, biên độ tín hiệu vẫn liên tục. Lượng tử hóa ánh xạ chúng đến các mức rời rạc. Nhiều mức hơn = chất lượng tốt hơn, nhưng cần nhiều bit hơn.
Chúng ta thử với 8, 16 và 64 mức (3, 4, và 6 bit):
matlab
bits_list = [3, 4, 6]; % Số bit
Fs = 1000; % Lấy mẫu cao để tách biệt hiệu ứng lượng tử hóa
Ts = 1/Fs;
n = 0:Ts:0.01;
x_sampled = sin(2*pi*f*n); % Tín hiệu đã lấy mẫu
for j = 1:length(bits_list)
bits = bits_list(j); % Số bit cho từng mức
levels = 2^bits; % Số mức tương ứng
x_min = min(x_sampled); % Giá trị tối thiểu
x_max = max(x_sampled); % Giá trị tối đa
q_step = (x_max - x_min)/levels; % Bước lượng tử hóa
x_index = round((x_sampled - x_min)/q_step); % Chỉ số cho tín hiệu lượng tử hóa
x_quantized = x_index*q_step + x_min; % Tín hiệu lượng tử hóa
subplot(3,1,j); % Chia biểu đồ thành 3 phần
stem(n, x_quantized, 'filled'); % Vẽ tín hiệu lượng tử hóa
hold on;
plot(t, x_analog, 'k'); % Vẽ tín hiệu analog
title([num2str(levels) ' Mức (' num2str(bits) ' bits)']);
end
👉 Kết quả:
- Với 8 mức, tín hiệu trông bị khối.
- Với 16 mức, mượt mà hơn.
- Với 64 mức, gần như giống hệt tín hiệu analog.
4. Kết luận
Thí nghiệm nhỏ này cho thấy các đánh đổi trong xử lý tín hiệu số:
- Tần số lấy mẫu xác định xem có xảy ra aliasing hay không.
- Số mức lượng tử hóa kiểm soát độ phân giải và chất lượng.
- Nhiều mẫu và nhiều bit có nghĩa là độ chính xác cao hơn, nhưng cũng cần nhiều dung lượng lưu trữ và băng thông hơn.
👨💻 Thực hành và Tài nguyên
Hãy thử nghiệm với mã nguồn trên GitHub: Tài nguyên MATLAB. Thực hiện các thay đổi và xem ảnh hưởng của việc thay đổi tần số lấy mẫu và số mức lượng tử hóa đến tín hiệu của bạn.
Những lưu ý quan trọng
- Đảm bảo rằng bạn hiểu rõ định lý Nyquist để tránh hiện tượng aliasing.
- Lựa chọn số mức lượng tử hóa phù hợp để cân bằng giữa chất lượng tín hiệu và dung lượng lưu trữ.
Câu hỏi thường gặp (FAQ)
Q: Tại sao cần phải lấy mẫu tín hiệu?
A: Lấy mẫu tín hiệu là cần thiết để chuyển đổi tín hiệu analog sang dạng mà máy tính có thể xử lý.
Q: Lượng tử hóa có ảnh hưởng đến chất lượng tín hiệu không?
A: Có, số lượng mức lượng tử hóa càng cao, chất lượng tín hiệu càng tốt.
Q: Làm thế nào để tránh hiện tượng aliasing?
A: Bạn cần lấy mẫu với tần số ít nhất gấp đôi tần số cao nhất trong tín hiệu.