internal unsafe PcmEncodingTranscoder(PipeReader input, PcmAudioCodec codec) { const int Application = 2049; // OPUS_APPLICATION_AUDIO Debug.Assert( typeof(T) == typeof(short) || typeof(T) == typeof(float)); Debug.Assert(codec.ChannelCount == 2); Debug.Assert(codec.SamplingRate == 48000); _codec = codec; int status; _encoder = opus_encoder_create(codec.SamplingRate, codec.ChannelCount, Application, &status); if (status < 0) { ThrowExternalException("Could not create Opus Encoder", status); } _input = input; _pipe = new Pipe(); }
static unsafe int WriteInternal(OpusEncoder *encoder, int channelCount, ReadOnlySpan <byte> frame, PipeWriter writer) { var block = writer.GetSpan(); int frameSize = frame.Length / sizeof(T) / channelCount; int encoded = default; fixed(byte *sampleData = frame) fixed(byte *outputBlock = block.Slice(2)) if (typeof(T) == typeof(short)) { encoded = opus_encode(encoder, (short *)sampleData, frameSize, outputBlock, block.Length); } else if (typeof(T) == typeof(float)) { encoded = opus_encode_float(encoder, (float *)sampleData, frameSize, outputBlock, block.Length); } return(encoded > 0 && !BinaryPrimitives.TryWriteInt16LittleEndian(block, (short)encoded) ? -1 : encoded); }
public static extern int opus_encoder_ctl([NativeTypeName("OpusEncoder *")] OpusEncoder *st, int request);
public static extern void opus_encoder_destroy([NativeTypeName("OpusEncoder *")] OpusEncoder *st);
public static extern int opus_encode_float([NativeTypeName("OpusEncoder *")] OpusEncoder *st, [NativeTypeName("const float *")] float *pcm, int frame_size, [NativeTypeName("unsigned char *")] byte *data, [NativeTypeName("opus_int32")] int max_data_bytes);
public static extern int opus_encoder_init([NativeTypeName("OpusEncoder *")] OpusEncoder *st, [NativeTypeName("opus_int32")] int Fs, int channels, int application);