const { test, expect } = require('@playwright/test'); const { openClassic } = require('./helpers/classic-fixture'); test('Basic Pitch is lazy and transcribes a short synthetic WAV', async ({ page }) => { test.setTimeout(120000); page.on('requestfailed', (req) => console.log('Engine request failed:', req.url(), req.failure()?.errorText), ); const requests = []; page.on('request', (req) => { if (/esm\.sh|jsdelivr.*basic-pitch/.test(req.url())) requests.push(req.url()); }); await openClassic(page); expect(requests).toEqual([]); const result = await page.evaluate(async () => { const rate = 22050, samples = rate * 2, buffer = new ArrayBuffer(44 + samples * 2), view = new DataView(buffer); const text = (offset, value) => { [...value].forEach((c, i) => view.setUint8(offset + i, c.charCodeAt(0))); }; text(0, 'RIFF'); view.setUint32(4, 36 + samples * 2, true); text(8, 'WAVE'); text(12, 'fmt '); view.setUint32(16, 16, true); view.setUint16(20, 1, true); view.setUint16(22, 1, true); view.setUint32(24, rate, true); view.setUint32(28, rate * 2, true); view.setUint16(32, 2, true); view.setUint16(34, 16, true); text(36, 'data'); view.setUint32(40, samples * 2, true); for (let i = 0; i < samples; i++) view.setInt16(44 + i * 2, Math.sin((2 * Math.PI * 440 * i) / rate) * 16000, true); const engine = await import('/piano-engine.mjs'); const result = await engine.transcribe(buffer.slice(0), () => {}); const tf = await import('https://esm.sh/@tensorflow/tfjs@4.22.0'); const before = tf.memory().numTensors; const second = await engine.transcribe(buffer.slice(0), () => {}); return { engine: result.engine, notes: PianoCore.fromBasicPitch(result.notes), secondNotes: second.notes.length, before, after: tf.memory().numTensors, }; }); expect(result.engine).toMatch(/basic-pitch-1.0.1\/(webgpu|webgl|cpu)/); expect(requests.length).toBeGreaterThan(0); expect(result.notes.length).toBeGreaterThan(0); expect(result.notes.some((n) => n.pitch === 69)).toBe(true); expect(result.secondNotes).toBeGreaterThan(0); expect(result.after).toBe(result.before); });