22 February, 2020

#28: Âm nhạc, lập trình và toán học

#28: Âm nhạc, lập trình và toán học
Available in:
 Vietnamese
Reading time: 5 min.
Table of content

    Đối với những bạn thường xuyên theo dõi blog của mình, chắc các bạn đều có ấn tượng mình là một người học giỏi tin, và suy ra cũng sẽ học giỏi toán. Nhưng thực tế mình luôn chậm chạp trong môn toán, và bế tắc ở việc làm thế nào áp dụng nó vào thực tế.

    Đổi lại, mình lại được trời phú cho khả năng cảm âm cũng kha khá, so với bạn bè xung quanh mình (mình có thể nghe và dịch được hợp âm của một bài hát bất kỳ). Vậy nên một ngày đẹp trời, mình mới nghĩ, liệu có những giao điểm nào, mà ở đó “hội tụ” cả âm nhạc, cả toán học và tin học không?

    Câu trả lời thực tế là có, và có rất nhiều. Nhưng ở nội dung bài này, mình sẽ giới hạn ở 1 chủ đề mà đi cả 3 hướng nhạc-toán-tin đều căn bản: Chuyển giọng một bài hát

    Trong bài này, mình sẽ giải quyết vấn đề theo hướng nhẹ nhàng tình cảm:
    1. Chuyển giọng (hay dịch giọng) là gì? Vì sao cần nó?
    2. Liên hệ về mặt toán học
    3. Áp dụng vào code (có source code tham khảo)

    Disclaimer: Có thể có 1 vài thông tin trong bài không chính xác lắm. Rất mong các bạn thông cảm và đóng góp dưới phần comment. Mình xin cảm ơn!

    1. Chuyển giọng là gì?

    Khi người ta viết ra một bài hát (có lời), thì lời hát sẽ có những nốt thấp và nốt cao. Lấy ví dụ như Quốc ca Việt Nam (Tiến Quân Ca), nốt thấp nhất sẽ nằm ở:

    “Bước chân dồn vang trên đường gập ** ghềnh** xa”

    và nốt cao nhất nằm ở:

    “Tiến lên, cùng **tiến** lên”

    Như vậy nếu chơi bài Tiến Quân Ca ở giọng Đô Trưởng, ta sẽ thấy 2 nốt này tạo nên 2 giới hạn trên – dưới của các phím đàn. Ở đây chính xác là nốt Mi 2 (E2) và nốt La 3 (A3) như dưới hình:

    Tất cả các từ khác được hát trong bài chỉ nằm giữa khoảng này thôi, và như vậy bạn có thể hiểu nôm na rằng cái giới hạn này là quãng giọng của bài bát

    Giờ giả sử có một vấn đề như sau: bạn chỉ có thể hát được các nốt từ C2 đến F3, trong khi bài hát lại cần cả nốt G3 và A3 nữa (nhìn hình dưới). Như vậy bạn sẽ phải dịch giọng bài hát xuống, để vừa vào khoảng bạn hát được

    Vậy làm thế nào để biết bạn cần dịch bao nhiêu? Hãy đếm số nốt từ F3 đến A3 nhé, bạn sẽ thấy có 2 phím đàn màu đen và 2 phím đàn màu trắng. Như vậy tổng cộng bạn phải dịch lên 2+2=4 nửa cung (semitones), còn gọi là 2 cung.

    Việc chuyển giọng sẽ làm chuyển tất cả các nốt trong bài hát, ví dụ nốt C3 sẽ chuyển thành E3 (đi thêm 4 phím đàn, tính cả phím đen và phím trắng). Và phần này hơi nâng cao chút, nói cho vui thôi, rằng 7 nốt trong bài: Đồ, Rê, Mi, Pha, Son, La, Si, sau khi chuyển nó sẽ thành Rê, Mi, Pha thăng, Son, La, Si, Đố thăng

    2. Liên hệ toán học

    Mỗi nốt nhạc đều có một tần số riêng của nó, nhưng thật ra tất cả đều dựa trên nốt La chuẩn quốc tế, là 440Hz (nhưng thi thoảng mình cũng chỉnh đàn của mình về La 432Hz, nghe nó khá lạ tai và hơi buồn chút)

    Như vậy biết nốt La (ký hiệu A) là 440Hz, làm đế nào để tính được tần số nốt “La thăng” (ký hiệu A#)?

    A# và A cách nhau 1 nửa cung, nên công thức chuẩn để tính nốt A# sẽ = nốt A nhân 2 mũ (1/12). Và do nốt Si (ký hiệu B) cũng trên A# nửa cung, nên nó sẽ có thể được tính dựa vào A# hoặc A. Nói loằng ngoằng thế chứ nhìn hình này là hiểu ngay:

    Vậy ngắn gọn, tức là nếu muốn nâng giọng bài hát lên 1 nửa cung, chúng ta chỉ cần nâng tất cả các tần số của bài hát lên 2 mũ (1/12) lần. Nhưng làm thế nào để “tách” được tần số ra, sau đó lại “trộn” lại thành bài hát mới?

    Đây là lúc một công cụ khá “khó hiểu” trong toán học giúp chúng ta: Phép biến đổi Fourier. Cái này nôm na là giúp biến “tín hiệu âm thanh” thành “các tần số”. Sau đó ta sẽ làm việc với các tần số này, và dùng Phép biến đổi Fourier ngược để đưa nó về thành “tín hiệu âm thanh mới”

    3. Áp dụng vào code

    Như vậy, kế hoạch sẽ là:

    Đọc file âm thanh, ở đây mình dùng file WAV đơn kênh (mono) để dễ thực hiện. Ví dụ mình dùng bài “Hà Nội mùa vắng những cơn mưa” của Trang (nghe bản gốc trên soundcloud)

    1. Tách bài hát thành các khoảng (gọi là frame), mỗi frame bằng 1/20 giây. Việc tách này để tránh bị tiếng vọng.
    2. Đối với mỗi frame nhỏ, áp dụng quy trình: Biến đổi Fourier => Sửa tần số => Biến trở lại thành âm thanh => Lưu vào file mới
    3. Đóng file, kết thúc chương trình

    Trong bài này mình đã thử nâng lên 1 nửa cung. Kết quả cho chất lượng khá kém. Điều này là hoàn toàn dễ hiểu, vì khi nâng tần số lên thì có những tần số sẽ bị bỏ đi => bài hát thiếu một vài âm sắc, vỡ tiếng… Nhưng dù sao cũng là làm chơi, nó chạy là tốt rồi!

    Và kết quả sau khi chạy code:

    Cảm ơn các bạn đã theo dõi!

    Want to receive latest articles from my blog?