{"record":{"id":"8493f729f26fabe2","repo":"stride3d/stride","slug":"failed-to-create-celt-encoder","errorCode":null,"errorMessage":"Failed to create Celt encoder.","messagePattern":"Failed to create Celt encoder\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Audio/Native/Celt.AVFoundation.cs","lineNumber":57,"sourceCode":"        public Celt(int sampleRate, int bufferSize, int channels, bool decoderOnly)\n        {\n            SampleRate = sampleRate;\n            BufferSize = bufferSize;\n            Channels = channels;\n\n            mode = opus_custom_mode_create(sampleRate, bufferSize, IntPtr.Zero);\n            if (mode == IntPtr.Zero)\n                throw new Exception(\"Failed to create Celt custom mode.\");\n\n            decoder = opus_custom_decoder_create(mode, channels, IntPtr.Zero);\n            if (decoder == IntPtr.Zero)\n                throw new Exception(\"Failed to create Celt decoder.\");\n\n            if (!decoderOnly)\n            {\n                encoder = opus_custom_encoder_create(mode, channels, IntPtr.Zero);\n                if (encoder == IntPtr.Zero)\n                    throw new Exception(\"Failed to create Celt encoder.\");\n            }\n        }\n\n        public void Dispose()\n        {\n            if (encoder != IntPtr.Zero) { opus_custom_encoder_destroy(encoder); encoder = IntPtr.Zero; }\n            if (decoder != IntPtr.Zero) { opus_custom_decoder_destroy(decoder); decoder = IntPtr.Zero; }\n            if (mode != IntPtr.Zero) { opus_custom_mode_destroy(mode); mode = IntPtr.Zero; }\n        }\n\n        public unsafe int Decode(byte[] inputBuffer, int inputBufferSize, short[] outputSamples)\n        {\n            Debug.Assert((uint)inputBufferSize <= (uint)inputBuffer.Length);\n            fixed (short* samplesPtr = outputSamples)\n            fixed (byte* bufferPtr = inputBuffer)\n            {\n                return opus_custom_decode(decoder, bufferPtr, inputBufferSize, samplesPtr, outputSamples.Length / Channels);\n            }","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Audio/Native/Celt.AVFoundation.cs#L39-L75","documentation":"Thrown from the Celt constructor when opus_custom_encoder_create returns NULL, i.e. the native codec could not create an encoder for the given mode and channels. Only thrown when decoderOnly is false, i.e. the caller requested encoding capability.","triggerScenarios":"Constructing Celt with decoderOnly:false and an unsupported channel count, or native encoder allocation failing (memory, incompatible native lib) on the AVFoundation path.","commonSituations":"Requesting an encoder on devices with tight memory; mismatched native opus/celt binaries; passing channel counts outside codec limits during microphone capture setup.","solutions":["If only playback is needed, construct Celt with decoderOnly:true to skip encoder creation.","Verify the channel count is supported by the Celt encoder (typically 1 or 2).","Ensure the correct native celt/opus library version is bundled for the target platform.","Reduce concurrent codec instances or free memory if native allocation fails."],"exampleFix":"// before\nvar celt = new Celt(48000, 256, channels, decoderOnly:false);\n// after\nvar celt = new Celt(48000, 256, Math.Min(channels, 2), decoderOnly:false); // or true if playback-only","handlingStrategy":"try-catch","validationCode":"public static bool IsSupportedChannelCount(int channels) => channels is 1 or 2;\npublic static bool EncoderNeeded(bool playbackOnly) => !playbackOnly;","typeGuard":null,"tryCatchPattern":"try\n{\n    var celt = new Celt(48000, bufferSize, channels, decoderOnly: false);\n}\ncatch (Exception ex) when (ex.Message.Contains(\"Failed to create Celt encoder\"))\n{\n    logger.Error(\"Celt encoder creation failed; disabling microphone capture.\");\n    celt = new Celt(48000, bufferSize, channels, decoderOnly: true);\n}","preventionTips":["Pass decoderOnly:true whenever you only play back compressed audio.","Clamp channel counts to codec-supported values (1-2).","Keep native celt/opus binaries matched to the managed library version.","Degrade gracefully: fall back to decoder-only mode or uncompressed audio if encoding fails."],"tags":["audio","celt","native","codec","encoder"],"backgroundTag":"module-init-failed","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}