{"record":{"id":"5e2e135665c3847e","repo":"MathewSachin/Captura","slug":"wav-file-too-large","errorCode":null,"errorMessage":"WAV file too large","messagePattern":"WAV file too large","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Screna/AudioFileWriter.cs","lineNumber":85,"sourceCode":"        public AudioFileWriter(string FileName, WaveFormat Format, bool Riff = true)\n            : this(new FileStream(FileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read), Format, Riff) { }\n        \n        bool HasFactChunk => _format.Encoding != WaveFormatEncoding.Pcm && _format.BitsPerSample != 0;\n        \n        /// <summary>\n        /// Number of bytes of audio in the data chunk\n        /// </summary>\n        public long Length { get; private set; }\n\n        /// <summary>\n        /// Writes to file.\n        /// </summary>\n        public void Write(byte[] Data, int Offset, int Count)\n        {\n            lock (_syncLock)\n            {\n                if (_riff && _writer.BaseStream.Length + Count > uint.MaxValue)\n                    throw new ArgumentException(\"WAV file too large\", nameof(Count));\n                \n                _writer.Write(Data, Offset, Count);\n                Length += Count;\n            }\n        }\n\n        /// <summary>\n        /// Writes all buffered data to file.\n        /// </summary>\n        public void Flush()\n        {\n            lock (_syncLock)\n            {\n                _writer.Flush();\n                \n                if (!_riff)\n                    return;\n","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/MathewSachin/Captura/blob/3fdf41529bf4d50cd7a85aedd856f30e34279a47/src/Screna/AudioFileWriter.cs#L67-L103","documentation":"Thrown by AudioFileWriter.Write when the running output would exceed the RIFF/WAV container's hard 4 GiB ceiling (uint.MaxValue = 4,294,967,295 bytes). WAV headers store chunk and data sizes as unsigned 32-bit integers, so a single RIFF file physically cannot describe more data; the writer guards against producing a corrupt file by aborting the write instead. It only triggers when the writer was constructed with Riff = true (the default), which writes a canonical RIFF/WAVE header. Passing Riff = false disables the guard because the data is emitted as a raw/non-RIFF stream with no size field to overflow.","triggerScenarios":"Any call to AudioFileWriter.Write(byte[] Data, int Offset, int Count) where _writer.BaseStream.Length + Count > uint.MaxValue while _riff is true. In practice this is the Nth write of a long-running capture once cumulative bytes cross ~4 GiB; the failing call is the one whose Count pushes the total over the limit, even if that single Count is small. Constructing the writer via the (string FileName, WaveFormat, bool Riff = true) overload or the Stream overload without specifying Riff leaves _riff = true and thus enables the guard.","commonSituations":"Recording audio for many hours at PCM rates that exceed the 4 GiB data-chunk limit (e.g. 44100 Hz / 16-bit / stereo = ~176 KB/s hits the cap in ~6.8 h; 96000 Hz / 24-bit / stereo = ~864 KB/s in ~1.4 h; multichannel 7.1 at 192 kHz hits it in minutes). Continuous 24/7 capture daemons, conference/recording sessions left running, or high-bitrate lossless PCM where the developer assumed WAV had no practical size cap. Switching from a compressed format to PCM without raising the limit, or writing to one ever-growing file instead of rotating segments.","solutions":["Construct the writer with Riff = false to emit a non-RIFF (e.g. RF64-style raw) stream, bypassing the 32-bit size guard entirely: new AudioFileWriter(path, format, Riff: false).","Rotate output into segments smaller than 4 GiB (time- or size-based chunking), opening a fresh AudioFileWriter per segment before the cumulative total reaches uint.MaxValue.","Lower the data rate of the WaveFormat so the same wall-clock duration stays under the cap: reduce sample rate, bit depth, or channel count, or use a compressed WaveFormatEncoding so fewer bytes are written per second.","If you must keep RIFF and one file, switch to a container without a 32-bit data-size limit (e.g. W64 or a real RF64 writer) rather than relying on this writer."],"exampleFix":"// before\nusing (var writer = new AudioFileWriter(path, waveFormat))\n{\n    while (capturing)\n        writer.Write(buffer, 0, read); // throws once total > 4 GiB\n}\n\n// after (option A: disable RIFF size guard)\nusing (var writer = new AudioFileWriter(path, waveFormat, Riff: false))\n{\n    while (capturing)\n        writer.Write(buffer, 0, read);\n}\n\n// after (option B: rotate segments before the 4 GiB ceiling)\nconst long SegmentCap = 3L * 1024 * 1024 * 1024; // 3 GiB headroom\nvar writer = new AudioFileWriter(path, waveFormat);\ntry\n{\n    while (capturing)\n    {\n        if (writer.Length + read > SegmentCap)\n        {\n            writer.Dispose();\n            writer = new AudioFileWriter(NextSegmentPath(), waveFormat);\n        }\n        writer.Write(buffer, 0, read);\n    }\n}\nfinally { writer.Dispose(); }","handlingStrategy":"validation","validationCode":"// Validate before each Write that the RIFF file still has room for the chunk.\n// Call this immediately before AudioFileWriter.Write to prevent the throw.\nstatic bool CanWriteRiffWav(AudioFileWriter writer, int count, bool isRiff)\n{\n    if (!isRiff) return true;            // Riff=false has no 32-bit cap\n    // writer.Length tracks bytes of audio in the data chunk\n    return writer.Length + count <= uint.MaxValue;\n}\n\n// Usage:\n// if (!CanWriteRiffWav(writer, count, isRiff)) RotateWriter();","typeGuard":"// Not a type-narrowing error; the guard is a numeric precondition.\nstatic bool HasRiffRoom(AudioFileWriter writer, int count, bool isRiff)\n    => !isRiff || (writer.Length + count) <= uint.MaxValue;","tryCatchPattern":"// Prefer prevention; catch only to rotate/stop gracefully if a write slips through.\ntry\n{\n    writer.Write(buffer, offset, count);\n}\ncatch (ArgumentException ex) when (ex.ParamName == nameof(count)\n                                   && ex.Message.Contains(\"WAV file too large\"))\n{\n    writer.Dispose();\n    writer = new AudioFileWriter(NextSegmentPath(), waveFormat); // rotate\n    writer.Write(buffer, offset, count);\n}","preventionTips":["Compute the expected file size up front: durationSeconds * bytesPerSecond, where bytesPerSecond = sampleRate * bitsPerSample/8 * channels; if it approaches 4 GiB, disable RIFF or rotate.","Default to new AudioFileWriter(path, format, Riff: false) for any capture whose duration is open-ended or unknown at start time.","Track AudioFileWriter.Length and rotate to a new file when it crosses a safe threshold (e.g. 3 GiB) instead of waiting for the exception.","For long PCM captures, prefer a compressed WaveFormatEncoding or a non-RIFF container so the per-second byte rate keeps total size under the cap."],"tags":["audio","wav","riff","container-limit","file-size","captura"],"backgroundTag":null,"analyzedSha":"3fdf41529bf4d50cd7a85aedd856f30e34279a47","analyzedAt":"2026-08-13T19:35:27.486Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}