-
Notifications
You must be signed in to change notification settings - Fork 239
/
CUOpusCoder.h
87 lines (65 loc) · 2.54 KB
/
CUOpusCoder.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// Copyright 2019-current Getnamo. All Rights Reserved
#pragma once
#include "CoreMinimal.h"
#define WITH_OPUS (PLATFORM_WINDOWS || PLATFORM_UNIX || PLATFORM_ANDROID)
#if WITH_OPUS
#include "ThirdParty/libOpus/opus-1.1/include/opus.h"
//#include "ogg/ogg.h"
#endif
//Bare minimum struct for transferring opus bytes.
struct FCUOpusMinimalStream
{
TArray<int16> PacketSizes; // Maximum packet size is 32768 (much larger than typical packet)
TArray<uint8> CompressedBytes;
};
/**
Symmetric coder for e.g. voip written from raw libopus due to how hidden the opus
coder is in the engine (this one doesn't require an online subsystem)
*/
class FCUOpusCoder
{
public:
FCUOpusCoder();
~FCUOpusCoder();
/** Set Encoder and Decoder Samples per sec */
void SetSampleRate(int32 InSampleRate);
void SetChannels(int32 Channels);
void SetBitrate(int32 Bitrate);
void SetFrameSizeMs(int32 FrameSizeInMs);
/** Expects raw PCM data, outputs compressed raw opus data along with compressed frame sizes*/
bool EncodeStream(const TArray<uint8>& InPCMBytes, FCUOpusMinimalStream& OutStream);
bool DecodeStream(const FCUOpusMinimalStream& InStream, TArray<uint8>& OutPCMFrame);
//Format: PacketCount, PacketSizes, CompressedOpusBytes. Expects settings set in a different stream
bool SerializeMinimal(const FCUOpusMinimalStream& InStream, TArray<uint8>& OutSerializedBytes);
bool DeserializeMinimal(const TArray<uint8>& InSerializedMinimalBytes, FCUOpusMinimalStream& OutStream);
//Handle a single frame
int32 EncodeFrame(const TArray<uint8>& InPCMFrame, TArray<uint8>& OutCompressed);
int32 DecodeFrame(const TArray<uint8>& InCompressedFrame, TArray<uint8>& OutPCMFrame);
//Todo: add ogg file format wrapper for raw opus bytes
//Intended to be Read-only
int32 Channels;
int32 SampleRate;
//Whether we should reset the coder per stream to keep byte size small. Costs ~0.01ms
bool bResetBetweenEncoding;
bool bApplicationVoip;
bool bLowestPossibleLatency; //trade-off is compression size; ~3ms/sec of audio if on, ~10ms/sec if off. For ~ 33% more bytes.
void ResetCoderIfInitialized();
protected:
//Call this if some settings need to be reflected (all setters all this)
bool InitEncoderIfNeeded();
bool InitDecoderIfNeeded();
private:
#if WITH_OPUS
OpusEncoder* Encoder;
OpusDecoder* Decoder;
#endif
int32 BitRate;
int32 MaxPacketSize;
int32 FrameSizeMs;
int32 FrameSize;
int32 MaxFrameSize;
//Debug utilities
void DebugLogEncoder();
void DebugLogDecoder();
void DebugLogFrame(const uint8* PacketData, uint32 PacketLength, uint32 SampleRate, bool bEncode);
};