Các bản cập nhật cho âm thanh trên web trong Chrome 49

Chris Wilson
Chris Wilson

Chrome đã liên tục và âm thầm cải thiện khả năng hỗ trợ cho Web Audio API. Trong Chrome 49 (Phiên bản Beta từ tháng 2 năm 2016 và dự kiến sẽ có bản chính thức vào tháng 3 năm 2016), chúng tôi đã cập nhật một số tính năng để theo dõi quy cách, đồng thời thêm một nút mới.

codeAudioData() hiện trả về một lời hứa

Phương thức decodeAudioData() trên AudioContext hiện trả về một Promise, cho phép xử lý mẫu không đồng bộ dựa trên Promise. Phương thức decodeAudioData() luôn lấy các hàm callback thành công và lỗi làm tham số:

context.decodeAudioData( arraybufferData, onSuccess, onError);

Tuy nhiên, giờ đây, bạn có thể sử dụng phương thức Promise tiêu chuẩn để xử lý bản chất không đồng bộ của việc giải mã dữ liệu âm thanh:

context.decodeAudioData( arraybufferData ).then(
        (buffer) => { /* store the buffer */ },
        (reason) => { console.log("decode failed! " + reason) });

Mặc dù trong một ví dụ duy nhất, việc này có vẻ chi tiết hơn, nhưng Promise giúp việc lập trình không đồng bộ trở nên dễ dàng và nhất quán hơn. Để tương thích, hàm callback Thành công và Lỗi vẫn được hỗ trợ, theo thông số kỹ thuật.

ngoại tuyếnAudioContext hiện đã hỗ trợ tạm ngưng() và tiếp tục()

Thoạt nhìn, bạn có thể thấy lạ khi thấy việc tạm ngưng() trên một OfflineAudioContext. Xét cho cùng, suspend() đã được thêm vào AudioContext để cho phép đưa phần cứng âm thanh vào chế độ chờ. Điều này dường như vô nghĩa trong các trường hợp khi bạn kết xuất vào vùng đệm (tất nhiên là đối với OfflineAudioContext). Tuy nhiên, điểm mấu chốt của tính năng này là có thể chỉ tạo một phần của "điểm số" tại một thời điểm để giảm thiểu mức sử dụng bộ nhớ. Bạn có thể tạo thêm nút trong khi bị tạm ngưng ở giữa quá trình hiển thị.

Một ví dụ, bản Sonata Ánh trăng của Beethoven chứa khoảng 6.500 nốt. Mỗi "ghi chú" có thể huỷ cấu trúc cho ít nhất một vài nút biểu đồ âm thanh (ví dụ: AudioBuffer và nút Gain). Nếu muốn kết xuất toàn bộ 7,5 phút vào vùng đệm bằng OfflineAudioContext, thì có thể bạn không muốn tạo tất cả các nút đó cùng một lúc. Thay vào đó, bạn có thể tạo chúng trong những đoạn thời gian:

var context = new OfflineAudioContext(2, length, sampleRate);
scheduleNextBlock();
context.startRendering().then( (buffer) => { /* store the buffer */ } );

function scheduleNextBlock() {
    // create any notes for the next blockSize number of seconds here
    // ...

    // make sure to tell the context to suspend again after this block;
    context.suspend(context.currentTime + blockSize).then( scheduleNextBlock );

    context.resume();
}

Điều này sẽ cho phép bạn giảm thiểu số lượng nút cần được tạo trước khi bắt đầu quá trình kết xuất và giảm nhu cầu về bộ nhớ.

IIRFilterNode

Thông số kỹ thuật này đã thêm một nút cho những người đam mê âm thanh và muốn tạo phản hồi vô hạn-impulse của riêng họ: IIRFilterNode. Bộ lọc này bổ sung cho BiquadFilterNode nhưng cho phép thông số kỹ thuật đầy đủ về các tham số phản hồi bộ lọc (thay vì AudioParams dễ sử dụng của BiquadFilterNode cho loại, tần suất, Q và các tham số tương tự). IIRFilterNode cho phép tạo thông số kỹ thuật chính xác về các bộ lọc trước đây không thể được tạo, chẳng hạn như bộ lọc đơn đặt hàng. Tuy nhiên, việc sử dụng IIRFilterNode đòi hỏi một số kiến thức chuyên sâu về cách hoạt động của các bộ lọc IIR và các bộ lọc này cũng không được lập lịch như BiquadFilterNodes.

Các thay đổi trước đó

Tôi cũng muốn đề cập đến một vài điểm cải tiến đã được tiến hành trước đó: trong Chrome 48, tính năng tự động hoá nút BiquadFilter bắt đầu chạy ở tốc độ âm thanh. API này hoàn toàn không thay đổi, nhưng điều này có nghĩa là quá trình quét bộ lọc của bạn sẽ cho âm thanh mượt mà hơn. Cũng trong Chrome 48, chúng tôi đã thêm tính năng tạo chuỗi vào phương thức AudioNode.connect() bằng cách trả về nút mà chúng tôi đang kết nối. Điều này giúp việc tạo chuỗi nút trở nên đơn giản hơn, như trong ví dụ sau:

sourceNode.connect(gainNode).connect(filterNode).connect(context.destination);

Đó là tất cả tin tức hiện tại và hãy tiếp tục thưởng thức!