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
|
/*
* Copyright (C) 2014 Andrew Comminos
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package se.lublin.humla.audio.encoder;
import com.googlecode.javacpp.IntPointer;
import com.googlecode.javacpp.Pointer;
import se.lublin.humla.audio.javacpp.CELT11;
import se.lublin.humla.exception.NativeAudioException;
import se.lublin.humla.net.PacketBuffer;
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;
/**
* Created by andrew on 08/12/14.
*/
public class CELT11Encoder implements IEncoder {
private final byte[][] mBuffer;
private final int mBufferSize;
private final int mFramesPerPacket;
private int mBufferedFrames;
private Pointer mState;
public CELT11Encoder(int sampleRate, int channels, int framesPerPacket) throws
NativeAudioException {
mFramesPerPacket = framesPerPacket;
mBufferSize = sampleRate / 800;
mBuffer = new byte[framesPerPacket][mBufferSize];
mBufferedFrames = 0;
IntPointer error = new IntPointer(1);
error.put(0);
mState = CELT11.celt_encoder_create(sampleRate, channels, error);
if(error.get() < 0) throw new NativeAudioException("CELT 0.11.0 encoder initialization " +
"failed with error: "+error.get());
}
@Override
public int encode(short[] input, int frameSize) throws NativeAudioException {
if (mBufferedFrames >= mFramesPerPacket) {
throw new BufferOverflowException();
}
int result = CELT11.celt_encode(mState, input, frameSize, mBuffer[mBufferedFrames],
mBufferSize);
if(result < 0) throw new NativeAudioException("CELT 0.11.0 encoding failed with error: "
+ result);
mBufferedFrames++;
return result;
}
@Override
public int getBufferedFrames() {
return mBufferedFrames;
}
@Override
public boolean isReady() {
return mBufferedFrames == mFramesPerPacket;
}
@Override
public void getEncodedData(PacketBuffer packetBuffer) throws BufferUnderflowException {
if (mBufferedFrames < mFramesPerPacket) {
throw new BufferUnderflowException();
}
for (int x = 0; x < mBufferedFrames; x++) {
byte[] frame = mBuffer[x];
int head = frame.length;
if(x < mBufferedFrames - 1)
head |= 0x80;
packetBuffer.append(head);
packetBuffer.append(frame, frame.length);
}
mBufferedFrames = 0;
}
@Override
public void terminate() throws NativeAudioException {
// TODO
}
@Override
public void destroy() {
CELT11.celt_encoder_destroy(mState);
}
}
|