// META: global=window // META: script=/webcodecs/utils.js function make_audio_frame(timestamp, channels, sampleRate, length) { let buffer = new AudioBuffer({ length: length, numberOfChannels: channels, sampleRate: sampleRate }); for (var channel = 0; channel < buffer.numberOfChannels; channel++) { // This gives us the actual array that contains the data var array = buffer.getChannelData(channel); let hz = 100 + channel * 50; // sound frequency for (var i = 0; i < array.length; i++) { let t = (i / sampleRate) * hz * (Math.PI * 2); array[i] = Math.sin(t); } } return new AudioFrame({ timestamp: timestamp, buffer: buffer }); } promise_test(async t => { let sample_rate = 48000; let total_duration_s = 2; let frame_count = 20; let outputs = []; let init = { error: e => { assert_unreached("error: " + e); }, output: chunk => { outputs.push(chunk); } }; let encoder = new AudioEncoder(init); assert_equals(encoder.state, "unconfigured"); let config = { codec: 'opus', sampleRate: sample_rate, numberOfChannels: 2, bitrate: 256000 //256kbit }; encoder.configure(config); let timestamp_us = 0; for (let i = 0; i < frame_count; i++) { let frame_duration_s = total_duration_s / frame_count; let length = frame_duration_s * config.sampleRate; let frame = make_audio_frame(timestamp_us, config.numberOfChannels, config.sampleRate, length); encoder.encode(frame); timestamp_us += frame_duration_s * 1_000_000; } await encoder.flush(); encoder.close(); assert_greater_than_equal(outputs.length, frame_count); assert_equals(outputs[0].timestamp, 0, "first chunk timestamp"); for (chunk of outputs) { assert_greater_than(chunk.data.byteLength, 0); assert_greater_than(timestamp_us, chunk.timestamp); } }, 'Simple audio encoding');