少年修仙传客户端代码仓库
hch
2023-06-14 f23c81d21c9cc4c9f06e8bed3ebb7ddbe7e15ac3
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityOpus;
 
public static class OpusNative
{
#if UNITY_ANDROID || UNITY_EDITOR || UNITY_STANDALONE
    const int frameSize = 160;
    static readonly byte[] encodeBuffer = new byte[frameSize * 4];
    static readonly List<short> sampleList = new List<short>();
    static readonly List<byte> encodedByteList = new List<byte>();
 
    static readonly short[] decodedBuffer = new short[Decoder.maximumPacketDuration];
    static readonly List<byte> bytesToDecode = new List<byte>();
    static readonly List<short> decodeFloatList = new List<short>();
#endif
 
    public static byte[] opus_encode_native(float[] pcm)
    {
#if UNITY_ANDROID || UNITY_EDITOR || UNITY_STANDALONE
        var encoder = new Encoder(
            SamplingFrequency.Frequency_16000,
            NumChannels.Mono,
            OpusApplication.VoIP
        )
        {
            Bitrate = 20000,
            Complexity = 10,
            Signal = OpusSignal.Music
        };
        var shorts = VoiceConvert.SamplesToShorts(pcm);
        sampleList.Clear();
        sampleList.AddRange(shorts);
 
        encodedByteList.Clear();
        int totalsize = 0;
 
        while (sampleList.Count > frameSize)
        {
            var encodedLength = encoder.Encode(sampleList.GetRange(0, frameSize).ToArray(), encodeBuffer);
            sampleList.RemoveRange(0, frameSize);
            encodedByteList.Add((byte)encodedLength);
            var bytes = new byte[encodedLength];
            Array.Copy(encodeBuffer, bytes, encodedLength);
            encodedByteList.AddRange(bytes);
            totalsize += (encodedLength + 1);
        }
        UnityEngine.Debug.Log(totalsize);
        encoder.Dispose();
        return encodedByteList.ToArray();
      
#elif UNITY_IOS
        var shorts = VoiceConvert.SamplesToShorts(pcm);        
        byte[] opus = new byte[VoiceSettings.frequency * VoiceSettings.length];
        int length = native_opus_encode(shorts, shorts.Length, opus);
        System.IO.MemoryStream stream=new System.IO.MemoryStream();  
        stream.Write(opus, 0, length );  
        stream.Close(); 
 
        return stream.ToArray();
        //return opus;
#endif
    }
 
    public static float[] opus_decode_native(byte[] opus)
    {
#if UNITY_ANDROID || UNITY_EDITOR || UNITY_STANDALONE
        var decoder = new Decoder(
            SamplingFrequency.Frequency_16000,
            NumChannels.Mono
        );
        
        decodeFloatList.Clear();
        bytesToDecode.Clear();
        bytesToDecode.AddRange(opus);
 
        short[] audioClipData = null;
        while (bytesToDecode.Count > 0)
        {
            var bytesLength = bytesToDecode[0];
            bytesToDecode.RemoveAt(0);
            var sampleLength = decoder.Decode(bytesToDecode.GetRange(0, bytesLength).ToArray(), bytesLength, decodedBuffer);
 
            if (audioClipData == null || audioClipData.Length != sampleLength)
            {
                audioClipData = new short[sampleLength];
            }
 
            Array.Copy(decodedBuffer, audioClipData, sampleLength);
            decodeFloatList.AddRange(audioClipData);
            bytesToDecode.RemoveRange(0, bytesLength);
        }
        decoder.Dispose();
        //return decodeFloatList.ToArray();
        var floats = VoiceConvert.ShortsToSamples(decodeFloatList.ToArray());
        return floats;
 
#elif UNITY_IOS
        short[] pcm = new short[VoiceSettings.frequency * VoiceSettings.length];        
        native_opus_decode(opus, opus.Length, pcm);
        var floats = VoiceConvert.ShortsToSamples(pcm);
        return floats;
#endif
    }
 
#if UNITY_IOS
    [DllImport("__Internal")]
    public static extern int native_opus_encode(short[] pcm, int len, byte[] opus);
 
    [DllImport("__Internal")]
    public static extern int native_opus_decode(byte[] opus, int len, short[] pcm);
 
#endif
 
 
}