{"record":{"id":"eb5afe9ddfbed17b","repo":"Hmbown/CodeWhale","slug":"invalid-pet-pcm-range-native","errorCode":null,"errorMessage":"Invalid pet PCM range.","messagePattern":"Invalid pet PCM range\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"pet/ios/Resources/pet-native.js","lineNumber":1624,"sourceCode":"                if (frame.needs === 'call' && window % 10 === 0)\n                    add(`call:${window}`, pet_sim_js_1.CHANNELS[11].freq * 1.5, .38, .03);\n            }\n        }\n        return out;\n    }\n}\nexports.PetScore = PetScore;\n/** Sample-addressed noise: no global RNG, identical samples when chunked/seeking. */\nfunction noise(seed, sample) {\n    let x = (seed + Math.imul(sample, 0x6D2B79F5)) >>> 0;\n    x = Math.imul(x ^ x >>> 15, x | 1);\n    x ^= x + Math.imul(x ^ x >>> 7, x | 61);\n    return ((x ^ x >>> 14) >>> 0) / 2147483648 - 1;\n}\nfunction renderPetPCM(voices, startSample, length, sampleRate = 48_000) {\n    if (!Number.isInteger(sampleRate) || sampleRate < 8000 || sampleRate > 96000\n        || !Number.isSafeInteger(startSample) || startSample < 0 || !Number.isInteger(length) || length < 0 || length > sampleRate * 120)\n        throw new Error('Invalid pet PCM range.');\n    const left = new Float32Array(length), right = new Float32Array(length);\n    for (const v of voices) {\n        if (![v.start, v.duration, v.frequency, v.gain, v.pan].every(Number.isFinite)\n            || v.start < 0 || v.duration <= 0 || v.duration > 10 || v.frequency <= 0 || v.frequency > sampleRate / 2\n            || v.gain < 0 || v.gain > 1 || Math.abs(v.pan) > 1 || !['tone', 'noise'].includes(v.kind))\n            throw new Error('Invalid pet voice.');\n        const first = Math.max(startSample, Math.ceil(v.start * sampleRate));\n        const last = Math.min(startSample + length, Math.ceil((v.start + v.duration) * sampleRate));\n        const pan = (v.pan + 1) * Math.PI / 4, seed = (0xC0FFEE ^ (0, model_js_1.stableHash)(v.id)) >>> 0;\n        for (let absolute = first; absolute < last; absolute++) {\n            const age = absolute / sampleRate - v.start;\n            const envelope = Math.min(1, age / .015, (v.duration - age) / .045);\n            const sample = v.kind === 'noise' ? noise(seed, absolute) * Math.exp(-age * 14)\n                : Math.sin(2 * Math.PI * v.frequency * age) * .88 + Math.sin(4 * Math.PI * v.frequency * age) * .12;\n            const value = sample * Math.max(0, envelope) * v.gain, at = absolute - startSample;\n            left[at] += value * Math.cos(pan);\n            right[at] += value * Math.sin(pan);\n        }","sourceCodeStart":1606,"sourceCodeEnd":1642,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/pet/ios/Resources/pet-native.js#L1606-L1642","documentation":"renderPetPCM validates the output request: sampleRate must be an integer in [8000, 96000], startSample a safe nonnegative integer, and length a nonnegative integer no greater than sampleRate * 120 (2 minutes of audio). Requests outside these bounds would allocate absurd buffers or produce invalid audio, so they throw before any rendering.","triggerScenarios":"Calling renderPetPCM with a length above sampleRate*120, a startSample that is negative or fractional, sampleRate outside 8k–96k, or arguments arriving as strings/undefined from upstream code.","commonSituations":"Requesting a whole long trace's audio in one shot instead of streaming windows, computing length from a float duration times sampleRate, or a misconfigured sample rate constant.","solutions":["Clamp length to sampleRate * 120 and render in multiple windows, advancing startSample between calls.","Ensure length and startSample are integers: Math.max(0, Math.floor(length)), Math.floor(startSample).","Use a supported sample rate between 8000 and 96000 Hz (default 48000).","Coerce arguments with Number() and validate Number.isSafeInteger before calling."],"exampleFix":"// before\nrenderPetPCM(voices, 0, durationSec * 48000 * 10); // > 2 minutes\n// after\nconst len = Math.min(durationSec * 48000, 48000 * 120);\nrenderPetPCM(voices, 0, Math.floor(len));","handlingStrategy":"validation","validationCode":"const len = Math.min(Math.floor(length), sampleRate * 120);\nif (!(sampleRate >= 8000 && sampleRate <= 96000) || !Number.isSafeInteger(startSample) || startSample < 0 || len < 0)\n  throw new TypeError('invalid PCM request');","typeGuard":null,"tryCatchPattern":"try { renderPetPCM(voices, s, l) } catch (err) { if (err.message.includes('PCM range')) return renderPetPCM(voices, s, Math.min(l, 48000 * 120)); throw err; }","preventionTips":["Stream long audio in <=120s windows instead of one call","Floor derived lengths so they are integers","Keep the sample-rate constant within 8k–96k"],"tags":["audio","limits","parameters"],"backgroundTag":"argument-out-of-range","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-22T16:17:23.217Z"}