Welcome to mirror list, hosted at ThFree Co, Russian Federation.

CELT11Encoder.java « encoder « audio « humla « lublin « se « java « main « src - gitlab.com/quite/humla.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 9dcb7a8ffba17597e50ff9b058fbdbfbace66282 (plain)
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);
    }
}