下面列出了怎么用java.nio.ShortBuffer的API类实例代码及写法,或者点击链接到github查看源代码。
private ShortBuffer readVorbis(String resource, int bufferSize, STBVorbisInfo info) throws Exception {
try (MemoryStack stack = MemoryStack.stackPush()) {
vorbis = Utils.ioResourceToByteBuffer(resource, bufferSize);
IntBuffer error = stack.mallocInt(1);
long decoder = stb_vorbis_open_memory(vorbis, error, null);
if (decoder == NULL) {
throw new RuntimeException("Failed to open Ogg Vorbis file. Error: " + error.get(0));
}
stb_vorbis_get_info(decoder, info);
int channels = info.channels();
int lengthSamples = stb_vorbis_stream_length_in_samples(decoder);
pcm = MemoryUtil.memAllocShort(lengthSamples);
pcm.limit(stb_vorbis_get_samples_short_interleaved(decoder, channels, pcm) * channels);
stb_vorbis_close(decoder);
return pcm;
}
}
/**
* Creates a new ShortBuffer with the same contents as the given
* ShortBuffer. The new ShortBuffer is separate from the old one and changes
* are not reflected across. If you want to reflect changes, consider using
* Buffer.duplicate().
*
* @param buf
* the ShortBuffer to copy
* @return the copy
*/
public static ShortBuffer clone(ShortBuffer buf) {
if (buf == null) {
return null;
}
buf.rewind();
ShortBuffer copy;
if (isDirect(buf)) {
copy = createShortBuffer(buf.limit());
} else {
copy = ShortBuffer.allocate(buf.limit());
}
copy.put(buf);
return copy;
}
public final void fillCoverIndices(ShortBuffer buffer, int lod, int border_set, int start_x, int start_y, int end_x, int end_y) {
border_set = adjustBorderSet(lod, border_set);
int num_quads_exp = getNumQuadsExp(lod);
int quad_size_exp = patch_exp - num_quads_exp;
int quad_size = 1 << quad_size_exp;
int start_quad_x = start_x>>quad_size_exp;
int start_quad_y = start_y>>quad_size_exp;
int end_quad_x = end_x>>quad_size_exp;
int end_quad_y = end_y>>quad_size_exp;
LandscapeTileTriangle[][] quads = quad_to_planes[lod];
for (int x = start_quad_x; x <= end_quad_x; x++)
for (int y = start_quad_y; y <= end_quad_y; y++) {
LandscapeTileTriangle[] quad = quads[getQuadIndex(num_quads_exp, x, y)];
LandscapeTileTriangle north = quad[LandscapeTileTriangle.NORTH_EXP];
LandscapeTileTriangle south = quad[LandscapeTileTriangle.SOUTH_EXP];
LandscapeTileTriangle east = quad[LandscapeTileTriangle.EAST_EXP];
LandscapeTileTriangle west = quad[LandscapeTileTriangle.WEST_EXP];
north.addIndices(buffer, border_set);
south.addIndices(buffer, border_set);
if (east != north && east != south) {
east.addIndices(buffer, border_set);
west.addIndices(buffer, border_set);
}
}
}
/**
* Encode the input buffer to output.
* @param directInput Input sample buffer
* @param frameSize Number of samples per channel
* @param directOutput Output byte buffer
* @return Number of bytes written to the output
*/
public int encode(ShortBuffer directInput, int frameSize, ByteBuffer directOutput) {
checkNotReleased();
if (!directInput.isDirect() || !directOutput.isDirect()) {
throw new IllegalArgumentException("Arguments must be direct buffers.");
}
directOutput.clear();
int result = library.encode(instance, directInput, frameSize, directOutput, directOutput.capacity());
if (result < 0) {
throw new IllegalStateException("Encoding failed with error " + result);
}
directOutput.position(result);
directOutput.flip();
return result;
}
private long drainOverflow(final ShortBuffer outBuff) {
final ShortBuffer overflowBuff = mOverflowBuffer.data;
final int overflowLimit = overflowBuff.limit();
final int overflowSize = overflowBuff.remaining();
final long beginPresentationTimeUs = mOverflowBuffer.presentationTimeUs + sampleCountToDurationUs(overflowBuff.position(), mInputSampleRate,
mOutputChannelCount);
outBuff.clear();
// Limit overflowBuff to outBuff's capacity
overflowBuff.limit(outBuff.capacity());
// Load overflowBuff onto outBuff
outBuff.put(overflowBuff);
if (overflowSize >= outBuff.capacity()) {
// Overflow fully consumed - Reset
overflowBuff.clear().limit(0);
} else {
// Only partially consumed - Keep position & restore previous limit
overflowBuff.limit(overflowLimit);
}
return beginPresentationTimeUs;
}
@Test
public void createData()
{
IOpenGL opengl = opengl();
OpenGLRenderingEngine renderingEngine = new OpenGLRenderingEngine(opengl);
renderingEngine.init();
IMesh mesh = renderingEngine.createMesh();
mesh.update(vertexData());
verify(opengl, times(1)).generateVertexArray();
verify(opengl, times(2)).generateBuffer();
verify(opengl, times(1)).uploadBufferData((FloatBuffer) any());
verify(opengl, times(1)).uploadBufferData((ShortBuffer) any());
}
private static boolean isDirect(Buffer buf) {
if (buf instanceof FloatBuffer) {
return ((FloatBuffer) buf).isDirect();
}
if (buf instanceof IntBuffer) {
return ((IntBuffer) buf).isDirect();
}
if (buf instanceof ShortBuffer) {
return ((ShortBuffer) buf).isDirect();
}
if (buf instanceof ByteBuffer) {
return ((ByteBuffer) buf).isDirect();
}
if (buf instanceof DoubleBuffer) {
return ((DoubleBuffer) buf).isDirect();
}
if (buf instanceof LongBuffer) {
return ((LongBuffer) buf).isDirect();
}
throw new UnsupportedOperationException(" BufferUtils.isDirect was called on " + buf.getClass().getName());
}
public static byte[] toByteArray(short[] data, boolean bigEndian) {
ByteBuffer byteBuffer = ByteBuffer.allocate(data.length * 2);
if (bigEndian) {
byteBuffer.order(ByteOrder.BIG_ENDIAN);
} else {
byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
}
ShortBuffer shortBuffer = byteBuffer.asShortBuffer();
shortBuffer.put(data);
byte[] array = byteBuffer.array();
return array;
}
/**
* ByteChannelからshort配列を読み込む
* @param channel
* @return
* @throws IOException
*/
public static short[] readShortArray(@NonNull final ByteChannel channel)
throws IOException {
final int n = readInt(channel);
final ByteBuffer buf = ByteBuffer.allocate(n * 2).order(ByteOrder.BIG_ENDIAN);
final int readBytes = channel.read(buf);
if (readBytes != n * 2) throw new IOException();
buf.clear();
final ShortBuffer result = buf.asShortBuffer();
if (result.hasArray()) {
return result.array();
} else {
final short[] b = new short[n];
result.get(b);
return b;
}
}
private ShortBuffer getElementBuffer(float radius, short rings, short sectors) {
float R = 1f / (float) (rings - 1);
float S = 1f / (float) (sectors - 1);
short r, s;
float x, y, z;
ShortBuffer elementBuffer = GLBuffers.newDirectShortBuffer(rings * sectors * 6);
for (r = 0; r < rings - 1; r++) {
for (s = 0; s < sectors - 1; s++) {
elementBuffer.put((short) (r * sectors + s));
elementBuffer.put((short) (r * sectors + (s + 1)));
elementBuffer.put((short) ((r + 1) * sectors + (s + 1)));
elementBuffer.put((short) ((r + 1) * sectors + (s + 1)));
elementBuffer.put((short) (r * sectors + s));
// elementBuffer.put((short) (r * sectors + (s + 1)));
elementBuffer.put((short) ((r + 1) * sectors + s));
}
}
elementBuffer.position(0);
return elementBuffer;
}
private boolean initBuffer(GL4 gl4) {
ShortBuffer elementBuffer = GLBuffers.newDirectShortBuffer(elementData);
FloatBuffer vertexBuffer = GLBuffers.newDirectFloatBuffer(vertexData);
gl4.glGenBuffers(Buffer.MAX, bufferName);
gl4.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferName.get(Buffer.ELEMENT));
gl4.glBufferData(GL_ELEMENT_ARRAY_BUFFER, elementSize, elementBuffer, GL_STATIC_DRAW);
gl4.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
gl4.glBindBuffer(GL_ARRAY_BUFFER, bufferName.get(Buffer.VERTEX));
gl4.glBufferData(GL_ARRAY_BUFFER, vertexSize, vertexBuffer, GL_STATIC_DRAW);
gl4.glBindBuffer(GL_ARRAY_BUFFER, 0);
BufferUtils.destroyDirectBuffer(elementBuffer);
BufferUtils.destroyDirectBuffer(vertexBuffer);
return checkError(gl4, "initBuffer");
}
public ShortBuffer getIndexBuffer() {
short[] iarray = new short[sides * 3];
ByteBuffer ibb = ByteBuffer.allocateDirect(sides * 3 * 2);
ibb.order(ByteOrder.nativeOrder());
ShortBuffer mIndexBuffer = ibb.asShortBuffer();
for (int i = 0; i < sides; i++) {
short index1 = 0;
short index2 = (short) (i + 1);
short index3 = (short) (i + 2);
if (index3 == sides + 1) {
index3 = 1;
}
mIndexBuffer.put(index1);
mIndexBuffer.put(index2);
mIndexBuffer.put(index3);
iarray[i * 3 + 0] = index1;
iarray[i * 3 + 1] = index2;
iarray[i * 3 + 2] = index3;
}
//this.printShortArray(iarray, "index array");
return mIndexBuffer;
}
public static void convertToList(Mesh mesh){
IndexBuffer inBuf = mesh.getIndicesAsList();
IndexBuffer outBuf = IndexBuffer.createIndexBuffer(mesh.getVertexCount(),
inBuf.size());
for (int i = 0; i < inBuf.size(); i++){
outBuf.put(i, inBuf.get(i));
}
mesh.clearBuffer(Type.Index);
switch (mesh.getMode()){
case LineLoop:
case LineStrip:
mesh.setMode(Mode.Lines);
break;
case TriangleStrip:
case TriangleFan:
mesh.setMode(Mode.Triangles);
break;
default:
break;
}
if (outBuf instanceof IndexIntBuffer){
mesh.setBuffer(Type.Index, 3, (IntBuffer)outBuf.getBuffer());
}else{
mesh.setBuffer(Type.Index, 3, (ShortBuffer)outBuf.getBuffer());
}
}
public void write(ShortBuffer value, String name, ShortBuffer defVal) throws IOException {
if (value == null) {
return;
}
if (value.equals(defVal)) {
return;
}
Element el = appendElement(name);
el.setAttribute("size", String.valueOf(value.limit()));
StringBuilder buf = new StringBuilder();
int pos = value.position();
value.rewind();
int ctr = 0;
while (value.hasRemaining()) {
ctr++;
buf.append(value.get());
buf.append(" ");
}
if (ctr != value.limit())
throw new IOException("'" + name
+ "' buffer contention resulted in write data consistency. "
+ ctr + " values written when should have written "
+ value.limit());
buf.setLength(buf.length() - 1);
value.position(pos);
el.setAttribute(dataAttributeName, buf.toString());
currentElement = (Element) el.getParentNode();
}
/**
* Encode raw audio data into Opus format then call OpusWriter to write the Ogg packet
*
* @param rawAudio
* @return
* @throws IOException
*/
public int encodeAndWrite(byte[] rawAudio) throws IOException {
int uploadedAudioSize = 0;
ByteArrayInputStream ios = new ByteArrayInputStream(rawAudio);
byte[] data = new byte[SpeechConfiguration.FRAME_SIZE*2];
int bufferSize, read;
while((read = ios.read(data)) > 0){
bufferSize = read;
byte[] pcmBuffer = new byte[read];
System.arraycopy(data, 0, pcmBuffer, 0, read);
ShortBuffer shortBuffer = ShortBuffer.allocate(bufferSize);
for (int i = 0; i < read; i += 2) {
int b1 = pcmBuffer[i] & 0xff;
int b2 = pcmBuffer[i+1] << 8;
shortBuffer.put((short) (b1 | b2));
}
shortBuffer.flip();
ByteBuffer opusBuffer = ByteBuffer.allocate(bufferSize);
int opus_encoded = JNAOpus.INSTANCE.opus_encode(this.opusEncoder, shortBuffer, SpeechConfiguration.FRAME_SIZE, opusBuffer, bufferSize);
opusBuffer.position(opus_encoded);
opusBuffer.flip();
byte[] opusData = new byte[opusBuffer.remaining()];
opusBuffer.get(opusData, 0, opusData.length);
if (opus_encoded > 0) {
uploadedAudioSize += opusData.length;
writer.writePacket(opusData, 0, opusData.length);
}
}
ios.close();
return uploadedAudioSize;
}
private void processMonoToStereo(ShortBuffer buffer) throws InterruptedException {
while (buffer.hasRemaining()) {
short sample = buffer.get();
outputBuffer.put(sample);
outputBuffer.put(sample);
if (!outputBuffer.hasRemaining()) {
outputBuffer.flip();
downstream.process(outputBuffer);
outputBuffer.clear();
}
}
}
protected void initAllNames(int requestedID, HashSet<String> names) {
byte[] name = new byte[256];
ByteBuffer buffer = getTableBuffer(nameTag);
if (buffer != null) {
ShortBuffer sbuffer = buffer.asShortBuffer();
sbuffer.get(); // format - not needed.
short numRecords = sbuffer.get();
/* The name table uses unsigned shorts. Many of these
* are known small values that fit in a short.
* The values that are sizes or offsets into the table could be
* greater than 32767, so read and store those as ints
*/
int stringPtr = ((int) sbuffer.get()) & 0xffff;
for (int i=0; i<numRecords; i++) {
short platformID = sbuffer.get();
if (platformID != MS_PLATFORM_ID) {
sbuffer.position(sbuffer.position()+5);
continue; // skip over this record.
}
short encodingID = sbuffer.get();
short langID = sbuffer.get();
short nameID = sbuffer.get();
int nameLen = ((int) sbuffer.get()) & 0xffff;
int namePtr = (((int) sbuffer.get()) & 0xffff) + stringPtr;
if (nameID == requestedID) {
buffer.position(namePtr);
buffer.get(name, 0, nameLen);
names.add(makeString(name, nameLen, platformID, encodingID));
}
}
}
}
protected void initAllNames(int requestedID, HashSet names) {
byte[] name = new byte[256];
ByteBuffer buffer = getTableBuffer(nameTag);
if (buffer != null) {
ShortBuffer sbuffer = buffer.asShortBuffer();
sbuffer.get(); // format - not needed.
short numRecords = sbuffer.get();
/* The name table uses unsigned shorts. Many of these
* are known small values that fit in a short.
* The values that are sizes or offsets into the table could be
* greater than 32767, so read and store those as ints
*/
int stringPtr = ((int) sbuffer.get()) & 0xffff;
for (int i=0; i<numRecords; i++) {
short platformID = sbuffer.get();
if (platformID != MS_PLATFORM_ID) {
sbuffer.position(sbuffer.position()+5);
continue; // skip over this record.
}
short encodingID = sbuffer.get();
short langID = sbuffer.get();
short nameID = sbuffer.get();
int nameLen = ((int) sbuffer.get()) & 0xffff;
int namePtr = (((int) sbuffer.get()) & 0xffff) + stringPtr;
if (nameID == requestedID) {
buffer.position(namePtr);
buffer.get(name, 0, nameLen);
names.add(makeString(name, nameLen, encodingID));
}
}
}
}
public ShortBuffer getData() {
ShortBuffer data = ShortBuffer.allocate(image.getWidth() * image.getHeight());
for (int y = 0; y < image.getHeight(); y++) {
for (int x = 0; x < image.getWidth(); x++) {
Color color = new Color(image.getRGB(x, y));
data.put(color.toShortColor(1));
}
}
data.rewind();
return data;
}
public SoundBuffer(String file) throws Exception {
this.bufferId = alGenBuffers();
try (STBVorbisInfo info = STBVorbisInfo.malloc()) {
ShortBuffer pcm = readVorbis(file, 32 * 1024, info);
// Copy to buffer
alBufferData(bufferId, info.channels() == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, pcm, info.sample_rate());
}
}
/**
* @return sum of elements added
*/
public int compile(ShortBuffer sbuf) {
if (cur == null)
return 0;
cur.used = used;
int size = 0;
for (Chunk it = head(); it != null; it = it.next) {
size += it.used;
sbuf.put(it.vertices, 0, it.used);
}
dispose();
return size;
}
private static GuardedInvocation linkSetElement(final Object self) {
MethodHandle method = null;
MethodHandle guard = null;
if (self instanceof ByteBuffer) {
method = BYTEBUFFER_PUT;
guard = IS_BYTEBUFFER;
} else if (self instanceof CharBuffer) {
method = CHARBUFFER_PUT;
guard = IS_CHARBUFFER;
} else if (self instanceof ShortBuffer) {
method = SHORTBUFFER_PUT;
guard = IS_SHORTBUFFER;
} else if (self instanceof IntBuffer) {
method = INTBUFFER_PUT;
guard = IS_INTBUFFER;
} else if (self instanceof LongBuffer) {
method = LONGBUFFER_PUT;
guard = IS_LONGBUFFER;
} else if (self instanceof FloatBuffer) {
method = FLOATBUFFER_PUT;
guard = IS_FLOATBUFFER;
} else if (self instanceof DoubleBuffer) {
method = DOUBLEBUFFER_PUT;
guard = IS_DOUBLEBUFFER;
}
return method != null? new GuardedInvocation(method, guard) : null;
}
public final void putIndices(int lod, int border_set, ShortBuffer indices) {
//System.out.println("lod = " + lod + " | Integer.toHexString(border_set) = " + Integer.toHexString(border_set) + " | Integer.toHexString(border_direction) = " + Integer.toHexString(border_direction));
if (lod > 0 || (lod == 0 && containsBorder(border_set))) {
t0.putIndices(lod - 1, border_set, indices);
t1.putIndices(lod - 1, border_set, indices);
} else {
indices.put(i0);
indices.put(i1);
indices.put(i2);
}
}
protected void initAllNames(int requestedID, HashSet names) {
byte[] name = new byte[256];
ByteBuffer buffer = getTableBuffer(nameTag);
if (buffer != null) {
ShortBuffer sbuffer = buffer.asShortBuffer();
sbuffer.get(); // format - not needed.
short numRecords = sbuffer.get();
/* The name table uses unsigned shorts. Many of these
* are known small values that fit in a short.
* The values that are sizes or offsets into the table could be
* greater than 32767, so read and store those as ints
*/
int stringPtr = ((int) sbuffer.get()) & 0xffff;
for (int i=0; i<numRecords; i++) {
short platformID = sbuffer.get();
if (platformID != MS_PLATFORM_ID) {
sbuffer.position(sbuffer.position()+5);
continue; // skip over this record.
}
short encodingID = sbuffer.get();
short langID = sbuffer.get();
short nameID = sbuffer.get();
int nameLen = ((int) sbuffer.get()) & 0xffff;
int namePtr = (((int) sbuffer.get()) & 0xffff) + stringPtr;
if (nameID == requestedID) {
buffer.position(namePtr);
buffer.get(name, 0, nameLen);
names.add(makeString(name, nameLen, encodingID));
}
}
}
}
protected void initAllNames(int requestedID, HashSet names) {
byte[] name = new byte[256];
ByteBuffer buffer = getTableBuffer(nameTag);
if (buffer != null) {
ShortBuffer sbuffer = buffer.asShortBuffer();
sbuffer.get(); // format - not needed.
short numRecords = sbuffer.get();
/* The name table uses unsigned shorts. Many of these
* are known small values that fit in a short.
* The values that are sizes or offsets into the table could be
* greater than 32767, so read and store those as ints
*/
int stringPtr = ((int) sbuffer.get()) & 0xffff;
for (int i=0; i<numRecords; i++) {
short platformID = sbuffer.get();
if (platformID != MS_PLATFORM_ID) {
sbuffer.position(sbuffer.position()+5);
continue; // skip over this record.
}
short encodingID = sbuffer.get();
short langID = sbuffer.get();
short nameID = sbuffer.get();
int nameLen = ((int) sbuffer.get()) & 0xffff;
int namePtr = (((int) sbuffer.get()) & 0xffff) + stringPtr;
if (nameID == requestedID) {
buffer.position(namePtr);
buffer.get(name, 0, nameLen);
names.add(makeString(name, nameLen, encodingID));
}
}
}
}
private void setStrikethroughMetrics(ByteBuffer os_2Table, int upem) {
if (os_2Table == null || os_2Table.capacity() < 30 || upem < 0) {
stSize = .05f;
stPos = -.4f;
return;
}
ShortBuffer sb = os_2Table.asShortBuffer();
stSize = sb.get(13) / (float)upem;
stPos = -sb.get(14) / (float)upem;
}
private void setStrikethroughMetrics(ByteBuffer os_2Table, int upem) {
if (os_2Table == null || os_2Table.capacity() < 30 || upem < 0) {
stSize = .05f;
stPos = -.4f;
return;
}
ShortBuffer sb = os_2Table.asShortBuffer();
stSize = sb.get(13) / (float)upem;
stPos = -sb.get(14) / (float)upem;
}
/**
* creates buffers for Quad shape object
* @param pos
* @param widths
*/
public void createBuffers( float[] pos, float[] widths) {
createVertexData(pos, widths);
final FloatBuffer heightMapVertexDataBuffer = ByteBuffer
.allocateDirect(aQuadVertexData.length * BYTES_PER_FLOAT).order(ByteOrder.nativeOrder())
.asFloatBuffer();
heightMapVertexDataBuffer.put(aQuadVertexData).position(0);
final ShortBuffer heightMapIndexDataBuffer = ByteBuffer
.allocateDirect(aQuadIndexData.length * BYTES_PER_SHORT).order(ByteOrder.nativeOrder())
.asShortBuffer();
heightMapIndexDataBuffer.put(aQuadIndexData).position(0);
if (qvbo[0] > 0 && qibo[0] > 0) {
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, qvbo[0]);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, heightMapVertexDataBuffer.capacity() * BYTES_PER_FLOAT,
heightMapVertexDataBuffer, GLES20.GL_STATIC_DRAW);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, qibo[0]);
GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER, heightMapIndexDataBuffer.capacity()
* BYTES_PER_SHORT, heightMapIndexDataBuffer, GLES20.GL_STATIC_DRAW);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
} else {
GlUtil.checkGlError("glGenBuffers");
}
}
@Override
public void getStyleMetrics(float pointSize, float[] metrics, int offset) {
if (ulSize == 0f && ulPos == 0f) {
ByteBuffer head_Table = getTableBuffer(headTag);
int upem = -1;
if (head_Table != null && head_Table.capacity() >= 18) {
ShortBuffer sb = head_Table.asShortBuffer();
upem = sb.get(9) & 0xffff;
if (upem < 16 || upem > 16384) {
upem = 2048;
}
}
ByteBuffer os2_Table = getTableBuffer(os_2Tag);
setStrikethroughMetrics(os2_Table, upem);
ByteBuffer post_Table = getTableBuffer(postTag);
setUnderlineMetrics(post_Table, upem);
}
metrics[offset] = stPos * pointSize;
metrics[offset+1] = stSize * pointSize;
metrics[offset+2] = ulPos * pointSize;
metrics[offset+3] = ulSize * pointSize;
}
private static final ShortBuffer asShortBuffer(TypedArrayObject typedArray) {
ByteBuffer data = byteBuffer(typedArray);
int byteOffset = byteOffset(typedArray);
int byteLength = byteLength(typedArray);
data.limit(byteOffset + byteLength).position(byteOffset);
ShortBuffer view = data.asShortBuffer();
data.clear();
return view;
}