2012-11-08 25 views
6

Tôi đặc biệt quan tâm đến các onaudioprocess của ScriptProcessorNode (cho đến thời gian gần đây được gọi là JavaScriptNode). Nó là một trình nghe sự kiện được gọi định kỳ để xử lý âm thanh. Nó có chạy trong một chủ đề riêng biệt không?Sự kiện API âm thanh web có chạy trong một chuỗi riêng biệt không?

Tôi muốn cấp dữ liệu vào bộ đệm tròn và xử lý nó bên ngoài cuộc gọi lại này để tôi không hog CPU. Tôi có thể sử dụng công nhân web cho việc xử lý async, nhưng AFAIK tôi cần một sự thực hiện khác nhau của bộ đệm vòng trong trường hợp các chủ đề khác nhau.

Có cách nào để kiểm tra điều này không?

+0

bạn cũng đang truyền phát âm thanh bằng cách sử dụng ổ cắm web chưa? Sao mà bạn vào được ? ... trên nút bên sẽ là tốt đẹp để khởi động Web âm thanh từ bên trong một chủ đề Web Worker! –

Trả lời

5

Tất cả JavaScript là một luồng, được thực thi đồng bộ. Bất kỳ công cụ không đồng bộ nào được thực hiện thông qua các sự kiện, sẽ thêm các trình xử lý của chúng vào hàng đợi nhiệm vụ - được thực thi khi tác vụ hiện tại kết thúc.

Để sử dụng các chuỗi riêng biệt, bạn sẽ cần một môi trường như WebWorkers - mỗi luồng có ngữ cảnh thực thi riêng (phạm vi toàn cục) và hàng đợi nhiệm vụ; giao tiếp giữa chúng được thực hiện thông qua các sự kiện.

Khi trình xử lý onaudioprocess có vẻ như nằm trong cùng phạm vi với DOM, rất khó có thể chạy trong chuỗi riêng của nó. Nếu bạn thực sự có một nhiệm vụ chuyên sâu tính toán mà làm cho trang web của bạn không phản hồi, bạn nên sử dụng một WebWorker vào mà bạn ăn các sự kiện âm thanh:

myScriptProcessorNode.onaudioprocess = myWebWorker.postMessage; 
+0

Tôi đã sử dụng nhân viên web trước đây. Nếu onaudioprocess đang được thực hiện trong thread chính, sau đó tôi đoán tôi sẽ không cần một bộ đệm vòng khóa, chỉ là một đồng bộ đơn giản, phải không? Tôi sẽ lặp lại câu hỏi của tôi một chút. – Davorin

+0

Có, với JavaScript bạn không bao giờ cần khóa - chỉ có một tác vụ được thực hiện tại một thời điểm. – Bergi

0

Với giải pháp Bergi, bạn sẽ chạy vào các vấn đề với structured clone algorithm không có thể sao chép các thông số chỉ đọc trong audioProcessingEvent. Những gì bạn cần làm là chia nhỏ các phần bạn cần từ sự kiện có tính chất cloneable và chuyển chúng cho nhân viên của bạn trong một cấu trúc dữ liệu khác như sau:

_onAudioProcess(audioProcessingEvent) { 
    const {inputBuffer, outputBuffer} = audioProcessingEvent; 
    // The output buffer contains the samples that will be modified and 
    // eventually played, so we need to keep a reference to it. 
    this._outputBuffer = outputBuffer; 
    const numChannels = inputBuffer.numberOfChannels; 

    const inputChannels = 
    Array.from({length: numChannels}, (i) => { 
     return inputBuffer.getChannelData(i); 
    }); 

    this._worker.postMessage({ 
    command: 'DO_STUFF', 
    inputChannels: inputChannels, 
    }); 
} 

Bạn cũng sẽ cần phải truy cập tham chiếu đến tệp outputBuffer của bạn trong setMessageHandler, để sao chép dữ liệu đã xử lý trở lại cuối cùng được người dùng phát.

Các vấn đề liên quan