opus-wrapper's People
opus-wrapper's Issues
FEC Support?
Hello,
I'm just wondering if this wrapper has FEC support?
Thank you
Stream Encoding and Decoding
Hello!
I modified your example to keep running in a loop. I cleaned up the code and reduced the lag of the audio to less than half a second. But I get little breaks in the audio. I don't know if the issue is in the usage of the library, or somewhere in the code:
import com.sun.jna.ptr.PointerByReference;
import net.tomp2p.opuswrapper.Opus;
import javax.sound.sampled.*;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
import java.util.ArrayList;
import java.util.List;
public class Main {
private static final int SAMPLE_RATE = 48000;
private static final int FRAME_SIZE = 480;
public static void main(String[] args) throws LineUnavailableException {
AudioFormat format = new AudioFormat(SAMPLE_RATE, 16, 1, true, true);
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
if (!AudioSystem.isLineSupported(info)) {
throw new LineUnavailableException("not supported");
}
TargetDataLine microphone = AudioSystem.getTargetDataLine(format);
// Obtain and open the line.
microphone.open(format);
// Begin audio capture.
microphone.start();
SourceDataLine speaker = AudioSystem.getSourceDataLine(format);
speaker.open(format);
speaker.start();
IntBuffer error = IntBuffer.allocate(4);
PointerByReference opusDecoder = Opus.INSTANCE.opus_decoder_create(SAMPLE_RATE, 1, error);
PointerByReference opusEncoder = Opus.INSTANCE.opus_encoder_create(SAMPLE_RATE, 1, Opus.OPUS_APPLICATION_RESTRICTED_LOWDELAY, error);
while (true) {
ShortBuffer dataFromMic = recordFromMicrophone(microphone);
long start = System.nanoTime();
List<ByteBuffer> packets = encode(opusEncoder, dataFromMic);
// packets go over network
ShortBuffer decodedFromNetwork = decode(opusDecoder, packets);
long stop = System.nanoTime();
System.out.println((stop - start) / 1000000D + "ms");
playBack(speaker, decodedFromNetwork);
}
// Opus.INSTANCE.opus_decoder_destroy(opusDecoder);
// Opus.INSTANCE.opus_encoder_destroy(opusEncoder);
}
private static ShortBuffer decode(PointerByReference opusDecoder, List<ByteBuffer> packets) {
ShortBuffer shortBuffer = ShortBuffer.allocate(packets.size() * FRAME_SIZE);
for (ByteBuffer dataBuffer : packets) {
byte[] transferedBytes = new byte[dataBuffer.remaining()];
dataBuffer.get(transferedBytes);
int decoded = Opus.INSTANCE.opus_decode(opusDecoder, transferedBytes, transferedBytes.length, shortBuffer, FRAME_SIZE, 0);
shortBuffer.position(shortBuffer.position() + decoded);
}
shortBuffer.flip();
return shortBuffer;
}
private static List<ByteBuffer> encode(PointerByReference opusEncoder, ShortBuffer shortBuffer) {
int read = 0;
List<ByteBuffer> list = new ArrayList<>();
while (shortBuffer.hasRemaining()) {
ByteBuffer dataBuffer = ByteBuffer.allocate(8192);
int toRead = Math.min(shortBuffer.remaining(), dataBuffer.remaining());
read = Opus.INSTANCE.opus_encode(opusEncoder, shortBuffer, FRAME_SIZE, dataBuffer, toRead);
dataBuffer.position(dataBuffer.position() + read);
dataBuffer.flip();
list.add(dataBuffer);
shortBuffer.position(shortBuffer.position() + FRAME_SIZE);
}
// used for debugging
shortBuffer.flip();
return list;
}
private static void playBack(SourceDataLine speaker, ShortBuffer shortBuffer) throws LineUnavailableException {
short[] shortAudioBuffer = new short[shortBuffer.remaining()];
shortBuffer.get(shortAudioBuffer);
byte[] audio = ShortToByte_Twiddle_Method(shortAudioBuffer);
speaker.write(audio, 0, audio.length);
}
private static ShortBuffer recordFromMicrophone(TargetDataLine microphone) throws LineUnavailableException {
// Assume that the TargetDataLine, line, has already been obtained and
// opened.
byte[] data = new byte[microphone.getBufferSize() / 10];
// probably way too big
// Here, stopped is a global boolean set by another thread.
int numBytesRead;
numBytesRead = microphone.read(data, 0, data.length);
ShortBuffer shortBuffer = ShortBuffer.allocate(numBytesRead * 2);
shortBuffer.put(ByteBuffer.wrap(data).asShortBuffer());
shortBuffer.flip();
return shortBuffer;
}
private static byte[] ShortToByte_Twiddle_Method(final short[] input) {
final int len = input.length;
final byte[] buffer = new byte[len * 2];
for (int i = 0; i < len; i++) {
buffer[(i * 2) + 1] = (byte) (input[i]);
buffer[(i * 2)] = (byte) (input[i] >> 8);
}
return buffer;
}
}
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. ๐๐๐
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google โค๏ธ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.