ZX Spectrum: Khám phá kỹ thuật tạo âm thanh 1-bit trên sóng điện từ
Bài viết là một hành trình kỹ thuật chi tiết của tác giả khi thử nghiệm tạo âm thanh đa kênh (hợp âm) từ chiếc loa 1-bit huyền thoại của ZX Spectrum. Từ việc tái hiện các kỹ thuật PCM và phần nào đó là PWM, tác giả đã đi sâu vào phân tích cách sử dụng bộ xử lý Z80 với độ trễ chu kỳ chính xác để tạo ra âm thanh phức tạp, đồng thời ghi nhận những thất bại và thành công trong quá trình thử nghiệm. Bài viết mang đến cái nhìn sâu sắc về giới hạn phần cứng và sự khéo léo của lập trình viên thời kỳ đầu.

Loa 1-bit của ZX Spectrum: Nghệ thuật chơi hợp âm từ một chiếc loa beep
Trong hành trình khám phá phần cứng của ZX Spectrum, chúng ta sẽ đi sâu vào thử nghiệm táo bạo: tạo ra âm thanh đa kênh và hợp âm từ chiếc loa chỉ có hai trạng thái bật/tắt. Tác giả không ngần ngại chia sẻ cả những thành công lẫn thất bại khi áp dụng các kỹ thuật như PCM, PWM và trộn kênh bằng phần mềm, hé lộ ranh giới mong manh giữa lý thuyết tín hiệu và hiện thực phần cứng.
Bối cảnh và thử thách của âm thanh 1-bit
Khác với các hệ máy hiện đại, ZX Spectrum (cụ thể là bản 48K với CPU Z80 chạy ở xung 3.5 MHz) chỉ có một chiếc loa với hai trạng thái: bật hoặc tắt. Điều này tạo ra thách thức lớn cho việc tái tạo âm thanh chất lượng cao. Người chơi và lập trình viên thời đó đã phải vận dụng mọi kiến thức về lập trình hợp ngữ và điện tử để "ép" chiếc loa này tạo ra những giai điệu phức tạp, thậm chí là hợp âm.
Kỹ thuật phổ biến nhất là Điều chế xung mã (Pulse Code Modulation - PCM). Về cơ bản, âm thanh được lấy mẫu thành các giá trị số. Tuy nhiên, với loa 1-bit, mỗi mẫu chỉ có thể là 0 hoặc 1. Điều này dẫn đến độ méo tiếng rất lớn, giống như tiếng loa bị "nổ" do khuếch đại quá mức. Một kỹ thuật khác là Điều chế độ rộng xung (Pulse Width Modulation - PWM), điều khiển thời gian xung ở mức cao trong mỗi chu kỳ để mô phỏng cường độ âm thanh, giúp âm thanh mượt hơn nhờ vào quán tính vật lý của màng loa.
Xử lý độ trễ chu kỳ trên CPU Z80
Để tạo ra các tín hiệu chính xác, việc kiểm soát thời gian ở cấp độ chu kỳ máy (T-State) là tối quan trọng. Khác với CPU 6502, Z80 có số lượng T-State đa dạng và phức tạp hơn. Tác giả đã đưa ra một số quy tắc ngón tay cái cho việc tạo độ trễ:
- Lệnh
NOPmất 4 chu kỳ. - Lệnh
INC HLhoặc các lệnh 16-bit tương tự tốn 6 chu kỳ, hữu ích cho việc "bo" 2 chu kỳ dư thừa. - Lệnh
LD A, ntốn 7 chu kỳ. - Lệnh
JPmất 10 chu kỳ kể cả khi có điều kiện (conditional), thích hợp hơnJRhayDJNZtrong các vòng lặp cần thời gian chính xác.
Một cấu trúc vòng lặp trễ phổ biến được sử dụng là LD B,n; LBL: DJNZ LBL. Vòng lặp này tốn 13n+2 chu kỳ, là lựa chọn tối ưu cho các khoảng thời gian chờ dài.
Phát lại PCM: Thành công về mặt kỹ thuật, thất bại về chất lượng
Tác giả đã xây dựng một quy trình phát PCM 1-bit với tốc độ lấy mẫu 16kHz. Ý tưởng là nén 8 mẫu vào một byte. Với tốc độ CPU 3.5MHz, mỗi mẫu cần cách nhau 219 chu kỳ. Mã nguồn được viết rất tỉ mỉ, sử dụng các macro của assembler Sjasm để nhân bản code, giải quyết vấn đề thiếu hụt thanh ghi.
Kết quả là quy trình phát nhạc hoạt động hoàn hảo về mặt logic, nhưng chất lượng âm thanh thực tế rất tệ. Dù đã thử tiền xử lý để làm sạch nhiễu, âm thanh vẫn bị méo nghiêm trọng. Tác giả kết luận rằng đây là một công cụ hữu ích để "bỏ túi" nhưng không hứa hẹn về chất lượng âm nhạc.
Chơi hợp âm: Thành công với hai phương pháp khác biệt
Mục tiêu chính của tuần làm việc là tạo ra hợp âm, tức là nhiều nốt nhạc vang lên cùng lúc. Tác giả đã thử nghiệm và so sánh hai phương pháp chính.
Rải nốt (Arpeggiation)
Kỹ thuật này không thực sự chơi các nốt cùng nhau mà chuyển đổi tần số rất nhanh giữa các nốt trong một vòng lặp. Với đoạn code sử dụng các lời gọi hàm sound trong một vòng lặp DJNZ, kết quả tạo ra hiệu ứng nghe giống một hợp âm, nhưng có "tiếng rè" đặc trưng. Tuy nhiên, nếu thời gian chuyển nốt quá ngắn, hợp âm bị lệch tông (detune), do các xung âm thanh không được tạo ra trọn vẹn.
Trộn kênh bằng phần mềm (Software Mixing)
Đây là phương pháp tiên tiến hơn, mô phỏng cách trộn tín hiệu của các bộ tổng hợp đa âm. Thay vì chuyển đổi nhanh, phương pháp này duy trì ba bộ đếm tần số và cộng dồn các bit cao nhất của từng bộ đếm sau mỗi chu kỳ. Kết quả là một tổng giá trị từ 0 đến 3. Loa sẽ được bật nếu tổng này nằm ở nửa trên của dải giá trị.
Điểm mấu chốt là mỗi vòng lặp xử lý cả ba kênh đều có thời gian thực thi cố định là 91 chu kỳ, đảm bảo tín hiệu được tạo ra một cách đều đặn. Mặc dù phức tạp hơn về mặt mã và yêu cầu bộ nhớ để lưu trạng thái các bộ đếm, kết quả âm thanh của phương pháp này vượt trội hơn hẳn so với arpeggiation. Âm thanh nghe dày và phong phú hơn, không còn cảm giác "1-bit" nữa, khiến tác giả rất ấn tượng.
Khám phá các hướng đi thất bại: PWM và trộn mẫu
PWM và "tiếng rít" khó chịu
Kỹ thuật PWM trên ZX Spectrum không dễ dàng như trên PC IBM (nơi có bộ định thời phần cứng). Trên Spectrum, mọi thứ phải được kiểm soát bằng đếm chu kỳ CPU. Dù đã xây dựng được logic điều khiển xung, thử nghiệm cho ra âm thanh chủ yếu là một tiếng rít the thé (tần số lấy mẫu (sample rate) tạo ra tín hiệu phụ) đến mức gần như không nghe thấy nội dung gốc. Điều này cho thấy giới hạn của việc mô phỏng vật lý loa bằng phần mềm.
Trộn mẫu: Một biến thể của Arpeggiation
Tác giả cũng thử một cách tiếp cận lấy cảm hứng từ Apple IIGS. Thay vì xen kẽ các xung sóng (pulse) hoàn chỉnh, ông trộn các mẫu (sample) dữ liệu PCM của từng kênh lại với nhau. Kết quả tốt hơn hẳn các phương pháp arpeggiation khác nhưng vẫn kém hơn phương pháp cộng dồn (software mixing) do có nhiều sự chuyển đổi trạng thái loa hơn, tạo cảm giác âm thanh "nhám" hơn.
Tổng kết
Trải qua nhiều thử nghiệm, tác giả đã đạt được một số thành công quan trọng với các kỹ thuật chơi hợp âm trên loa 1-bit, đặc biệt là phương pháp trộn kênh. Tuy nhiên, ông cũng nhận ra rằng để tiến xa hơn trong lĩnh vực PWM, cần phải nghiên cứu kỹ hơn các driver âm thanh của các lập trình viên huyền thoại như anh em nhà Follin, đồng thời cần kiểm chứng trên phần cứng thực (real hardware) thay vì chỉ giả lập. Mọi thứ đều được đóng góp vào kho mã nguồn GitHub của tác giả. Cuộc hành trình chứng minh rằng sự khéo léo của lập trình viên có thể tạo ra những điều kỳ diệu, ngay cả khi bị giới hạn bởi phần cứng tối giản nhất.