UNPKG

paqad-ai

Version:

Spec-driven development framework — AI agents that think before they type

63 lines (57 loc) • 1.87 kB
const RATE = 8000; const NOTES: ReadonlyArray<{ hz: number; seconds: number }> = [ { hz: 880, seconds: 0.12 }, { hz: 1320, seconds: 0.22 }, ]; const ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; export function toBase64(bytes: Uint8Array): string { let out = ''; for (let i = 0; i < bytes.length; i += 3) { const a = bytes[i]!; const b = bytes[i + 1]; const c = bytes[i + 2]; const n = (a << 16) | ((b ?? 0) << 8) | (c ?? 0); out += ALPHABET[(n >> 18) & 63]! + ALPHABET[(n >> 12) & 63]!; out += b === undefined ? '=' : ALPHABET[(n >> 6) & 63]!; out += c === undefined ? '=' : ALPHABET[n & 63]!; } return out; } function samples(): Uint8Array { const out: number[] = []; for (const note of NOTES) { const count = Math.round(RATE * note.seconds); for (let i = 0; i < count; i += 1) { const fade = 1 - i / count; const wave = Math.sin((2 * Math.PI * note.hz * i) / RATE); out.push(Math.round(128 + 80 * fade * wave)); } } return Uint8Array.from(out); } export function chimeWav(): Uint8Array { const data = samples(); const bytes = new Uint8Array(44 + data.length); const view = new DataView(bytes.buffer); const text = (offset: number, value: string) => { for (let i = 0; i < value.length; i += 1) bytes[offset + i] = value.charCodeAt(i); }; text(0, 'RIFF'); view.setUint32(4, 36 + data.length, 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, true); view.setUint16(32, 1, true); view.setUint16(34, 8, true); text(36, 'data'); view.setUint32(40, data.length, true); bytes.set(data, 44); return bytes; } export function chimeBase64(): string { return toBase64(chimeWav()); }