1 /* 2 * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.media.sound; 27 28 import java.nio.ByteBuffer; 29 import java.nio.ByteOrder; 30 import java.nio.DoubleBuffer; 31 import java.nio.FloatBuffer; 32 33 import javax.sound.sampled.AudioFormat; 34 import javax.sound.sampled.AudioFormat.Encoding; 35 36 /** 37 * This class is used to convert between 8,16,24,32,32+ bit signed/unsigned 38 * big/litle endian fixed/floating point byte buffers and float buffers. 39 * 40 * @author Karl Helgason 41 */ 42 public abstract class AudioFloatConverter { 43 44 /*************************************************************************** 45 * 46 * LSB Filter, used filter least significant byte in samples arrays. 47 * 48 * Is used filter out data in lsb byte when SampleSizeInBits is not 49 * dividable by 8. 50 * 51 **************************************************************************/ 52 53 private static class AudioFloatLSBFilter extends AudioFloatConverter { 54 55 private final AudioFloatConverter converter; 56 57 private final int offset; 58 59 private final int stepsize; 60 61 private final byte mask; 62 63 private byte[] mask_buffer; 64 AudioFloatLSBFilter(AudioFloatConverter converter, AudioFormat format)65 AudioFloatLSBFilter(AudioFloatConverter converter, AudioFormat format) { 66 int bits = format.getSampleSizeInBits(); 67 boolean bigEndian = format.isBigEndian(); 68 this.converter = converter; 69 stepsize = (bits + 7) / 8; 70 offset = bigEndian ? (stepsize - 1) : 0; 71 int lsb_bits = bits % 8; 72 if (lsb_bits == 0) 73 mask = (byte) 0x00; 74 else if (lsb_bits == 1) 75 mask = (byte) 0x80; 76 else if (lsb_bits == 2) 77 mask = (byte) 0xC0; 78 else if (lsb_bits == 3) 79 mask = (byte) 0xE0; 80 else if (lsb_bits == 4) 81 mask = (byte) 0xF0; 82 else if (lsb_bits == 5) 83 mask = (byte) 0xF8; 84 else if (lsb_bits == 6) 85 mask = (byte) 0xFC; 86 else if (lsb_bits == 7) 87 mask = (byte) 0xFE; 88 else 89 mask = (byte) 0xFF; 90 } 91 92 @Override toByteArray(float[] in_buff, int in_offset, int in_len, byte[] out_buff, int out_offset)93 public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, 94 byte[] out_buff, int out_offset) { 95 byte[] ret = converter.toByteArray(in_buff, in_offset, in_len, 96 out_buff, out_offset); 97 98 int out_offset_end = in_len * stepsize; 99 for (int i = out_offset + offset; i < out_offset_end; i += stepsize) { 100 out_buff[i] = (byte) (out_buff[i] & mask); 101 } 102 103 return ret; 104 } 105 106 @Override toFloatArray(byte[] in_buff, int in_offset, float[] out_buff, int out_offset, int out_len)107 public float[] toFloatArray(byte[] in_buff, int in_offset, 108 float[] out_buff, int out_offset, int out_len) { 109 if (mask_buffer == null || mask_buffer.length < in_buff.length) 110 mask_buffer = new byte[in_buff.length]; 111 System.arraycopy(in_buff, 0, mask_buffer, 0, in_buff.length); 112 int in_offset_end = out_len * stepsize; 113 for (int i = in_offset + offset; i < in_offset_end; i += stepsize) { 114 mask_buffer[i] = (byte) (mask_buffer[i] & mask); 115 } 116 float[] ret = converter.toFloatArray(mask_buffer, in_offset, 117 out_buff, out_offset, out_len); 118 return ret; 119 } 120 121 } 122 123 /*************************************************************************** 124 * 125 * 64 bit float, little/big-endian 126 * 127 **************************************************************************/ 128 129 // PCM 64 bit float, little-endian 130 private static class AudioFloatConversion64L extends AudioFloatConverter { 131 ByteBuffer bytebuffer = null; 132 133 DoubleBuffer floatbuffer = null; 134 135 double[] double_buff = null; 136 137 @Override toFloatArray(byte[] in_buff, int in_offset, float[] out_buff, int out_offset, int out_len)138 public float[] toFloatArray(byte[] in_buff, int in_offset, 139 float[] out_buff, int out_offset, int out_len) { 140 int in_len = out_len * 8; 141 if (bytebuffer == null || bytebuffer.capacity() < in_len) { 142 bytebuffer = ByteBuffer.allocate(in_len).order( 143 ByteOrder.LITTLE_ENDIAN); 144 floatbuffer = bytebuffer.asDoubleBuffer(); 145 } 146 bytebuffer.position(0); 147 floatbuffer.position(0); 148 bytebuffer.put(in_buff, in_offset, in_len); 149 if (double_buff == null 150 || double_buff.length < out_len + out_offset) 151 double_buff = new double[out_len + out_offset]; 152 floatbuffer.get(double_buff, out_offset, out_len); 153 int out_offset_end = out_offset + out_len; 154 for (int i = out_offset; i < out_offset_end; i++) { 155 out_buff[i] = (float) double_buff[i]; 156 } 157 return out_buff; 158 } 159 160 @Override toByteArray(float[] in_buff, int in_offset, int in_len, byte[] out_buff, int out_offset)161 public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, 162 byte[] out_buff, int out_offset) { 163 int out_len = in_len * 8; 164 if (bytebuffer == null || bytebuffer.capacity() < out_len) { 165 bytebuffer = ByteBuffer.allocate(out_len).order( 166 ByteOrder.LITTLE_ENDIAN); 167 floatbuffer = bytebuffer.asDoubleBuffer(); 168 } 169 floatbuffer.position(0); 170 bytebuffer.position(0); 171 if (double_buff == null || double_buff.length < in_offset + in_len) 172 double_buff = new double[in_offset + in_len]; 173 int in_offset_end = in_offset + in_len; 174 for (int i = in_offset; i < in_offset_end; i++) { 175 double_buff[i] = in_buff[i]; 176 } 177 floatbuffer.put(double_buff, in_offset, in_len); 178 bytebuffer.get(out_buff, out_offset, out_len); 179 return out_buff; 180 } 181 } 182 183 // PCM 64 bit float, big-endian 184 private static class AudioFloatConversion64B extends AudioFloatConverter { 185 ByteBuffer bytebuffer = null; 186 187 DoubleBuffer floatbuffer = null; 188 189 double[] double_buff = null; 190 191 @Override toFloatArray(byte[] in_buff, int in_offset, float[] out_buff, int out_offset, int out_len)192 public float[] toFloatArray(byte[] in_buff, int in_offset, 193 float[] out_buff, int out_offset, int out_len) { 194 int in_len = out_len * 8; 195 if (bytebuffer == null || bytebuffer.capacity() < in_len) { 196 bytebuffer = ByteBuffer.allocate(in_len).order( 197 ByteOrder.BIG_ENDIAN); 198 floatbuffer = bytebuffer.asDoubleBuffer(); 199 } 200 bytebuffer.position(0); 201 floatbuffer.position(0); 202 bytebuffer.put(in_buff, in_offset, in_len); 203 if (double_buff == null 204 || double_buff.length < out_len + out_offset) 205 double_buff = new double[out_len + out_offset]; 206 floatbuffer.get(double_buff, out_offset, out_len); 207 int out_offset_end = out_offset + out_len; 208 for (int i = out_offset; i < out_offset_end; i++) { 209 out_buff[i] = (float) double_buff[i]; 210 } 211 return out_buff; 212 } 213 214 @Override toByteArray(float[] in_buff, int in_offset, int in_len, byte[] out_buff, int out_offset)215 public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, 216 byte[] out_buff, int out_offset) { 217 int out_len = in_len * 8; 218 if (bytebuffer == null || bytebuffer.capacity() < out_len) { 219 bytebuffer = ByteBuffer.allocate(out_len).order( 220 ByteOrder.BIG_ENDIAN); 221 floatbuffer = bytebuffer.asDoubleBuffer(); 222 } 223 floatbuffer.position(0); 224 bytebuffer.position(0); 225 if (double_buff == null || double_buff.length < in_offset + in_len) 226 double_buff = new double[in_offset + in_len]; 227 int in_offset_end = in_offset + in_len; 228 for (int i = in_offset; i < in_offset_end; i++) { 229 double_buff[i] = in_buff[i]; 230 } 231 floatbuffer.put(double_buff, in_offset, in_len); 232 bytebuffer.get(out_buff, out_offset, out_len); 233 return out_buff; 234 } 235 } 236 237 /*************************************************************************** 238 * 239 * 32 bit float, little/big-endian 240 * 241 **************************************************************************/ 242 243 // PCM 32 bit float, little-endian 244 private static class AudioFloatConversion32L extends AudioFloatConverter { 245 ByteBuffer bytebuffer = null; 246 247 FloatBuffer floatbuffer = null; 248 249 @Override toFloatArray(byte[] in_buff, int in_offset, float[] out_buff, int out_offset, int out_len)250 public float[] toFloatArray(byte[] in_buff, int in_offset, 251 float[] out_buff, int out_offset, int out_len) { 252 int in_len = out_len * 4; 253 if (bytebuffer == null || bytebuffer.capacity() < in_len) { 254 bytebuffer = ByteBuffer.allocate(in_len).order( 255 ByteOrder.LITTLE_ENDIAN); 256 floatbuffer = bytebuffer.asFloatBuffer(); 257 } 258 bytebuffer.position(0); 259 floatbuffer.position(0); 260 bytebuffer.put(in_buff, in_offset, in_len); 261 floatbuffer.get(out_buff, out_offset, out_len); 262 return out_buff; 263 } 264 265 @Override toByteArray(float[] in_buff, int in_offset, int in_len, byte[] out_buff, int out_offset)266 public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, 267 byte[] out_buff, int out_offset) { 268 int out_len = in_len * 4; 269 if (bytebuffer == null || bytebuffer.capacity() < out_len) { 270 bytebuffer = ByteBuffer.allocate(out_len).order( 271 ByteOrder.LITTLE_ENDIAN); 272 floatbuffer = bytebuffer.asFloatBuffer(); 273 } 274 floatbuffer.position(0); 275 bytebuffer.position(0); 276 floatbuffer.put(in_buff, in_offset, in_len); 277 bytebuffer.get(out_buff, out_offset, out_len); 278 return out_buff; 279 } 280 } 281 282 // PCM 32 bit float, big-endian 283 private static class AudioFloatConversion32B extends AudioFloatConverter { 284 ByteBuffer bytebuffer = null; 285 286 FloatBuffer floatbuffer = null; 287 288 @Override toFloatArray(byte[] in_buff, int in_offset, float[] out_buff, int out_offset, int out_len)289 public float[] toFloatArray(byte[] in_buff, int in_offset, 290 float[] out_buff, int out_offset, int out_len) { 291 int in_len = out_len * 4; 292 if (bytebuffer == null || bytebuffer.capacity() < in_len) { 293 bytebuffer = ByteBuffer.allocate(in_len).order( 294 ByteOrder.BIG_ENDIAN); 295 floatbuffer = bytebuffer.asFloatBuffer(); 296 } 297 bytebuffer.position(0); 298 floatbuffer.position(0); 299 bytebuffer.put(in_buff, in_offset, in_len); 300 floatbuffer.get(out_buff, out_offset, out_len); 301 return out_buff; 302 } 303 304 @Override toByteArray(float[] in_buff, int in_offset, int in_len, byte[] out_buff, int out_offset)305 public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, 306 byte[] out_buff, int out_offset) { 307 int out_len = in_len * 4; 308 if (bytebuffer == null || bytebuffer.capacity() < out_len) { 309 bytebuffer = ByteBuffer.allocate(out_len).order( 310 ByteOrder.BIG_ENDIAN); 311 floatbuffer = bytebuffer.asFloatBuffer(); 312 } 313 floatbuffer.position(0); 314 bytebuffer.position(0); 315 floatbuffer.put(in_buff, in_offset, in_len); 316 bytebuffer.get(out_buff, out_offset, out_len); 317 return out_buff; 318 } 319 } 320 321 /*************************************************************************** 322 * 323 * 8 bit signed/unsigned 324 * 325 **************************************************************************/ 326 327 // PCM 8 bit, signed 328 private static class AudioFloatConversion8S extends AudioFloatConverter { 329 @Override toFloatArray(byte[] in_buff, int in_offset, float[] out_buff, int out_offset, int out_len)330 public float[] toFloatArray(byte[] in_buff, int in_offset, 331 float[] out_buff, int out_offset, int out_len) { 332 int ix = in_offset; 333 int ox = out_offset; 334 for (int i = 0; i < out_len; i++) { 335 byte x = in_buff[ix++]; 336 out_buff[ox++] = x > 0 ? x / 127.0f : x / 128.0f; 337 } 338 return out_buff; 339 } 340 341 @Override toByteArray(float[] in_buff, int in_offset, int in_len, byte[] out_buff, int out_offset)342 public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, 343 byte[] out_buff, int out_offset) { 344 int ix = in_offset; 345 int ox = out_offset; 346 for (int i = 0; i < in_len; i++) { 347 final float x = in_buff[ix++]; 348 out_buff[ox++] = (byte) (x > 0 ? x * 127 : x * 128); 349 } 350 return out_buff; 351 } 352 } 353 354 // PCM 8 bit, unsigned 355 private static class AudioFloatConversion8U extends AudioFloatConverter { 356 @Override toFloatArray(byte[] in_buff, int in_offset, float[] out_buff, int out_offset, int out_len)357 public float[] toFloatArray(byte[] in_buff, int in_offset, 358 float[] out_buff, int out_offset, int out_len) { 359 int ix = in_offset; 360 int ox = out_offset; 361 for (int i = 0; i < out_len; i++) { 362 byte x = (byte) (in_buff[ix++] - 128); 363 out_buff[ox++] = x > 0 ? x / 127.0f : x / 128.0f; 364 } 365 return out_buff; 366 } 367 368 @Override toByteArray(float[] in_buff, int in_offset, int in_len, byte[] out_buff, int out_offset)369 public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, 370 byte[] out_buff, int out_offset) { 371 int ix = in_offset; 372 int ox = out_offset; 373 for (int i = 0; i < in_len; i++) { 374 float x = in_buff[ix++]; 375 out_buff[ox++] = (byte) (128 + (x > 0 ? x * 127 : x * 128)); 376 } 377 return out_buff; 378 } 379 } 380 381 /*************************************************************************** 382 * 383 * 16 bit signed/unsigned, little/big-endian 384 * 385 **************************************************************************/ 386 387 // PCM 16 bit, signed, little-endian 388 private static class AudioFloatConversion16SL extends AudioFloatConverter { 389 @Override toFloatArray(byte[] in_buff, int in_offset, float[] out_buff, int out_offset, int out_len)390 public float[] toFloatArray(byte[] in_buff, int in_offset, 391 float[] out_buff, int out_offset, int out_len) { 392 int ix = in_offset; 393 int len = out_offset + out_len; 394 for (int ox = out_offset; ox < len; ox++) { 395 short x = (short) (in_buff[ix++] & 0xFF | (in_buff[ix++] << 8)); 396 out_buff[ox] = x > 0 ? x / 32767.0f : x / 32768.0f; 397 } 398 return out_buff; 399 } 400 401 @Override toByteArray(float[] in_buff, int in_offset, int in_len, byte[] out_buff, int out_offset)402 public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, 403 byte[] out_buff, int out_offset) { 404 int ox = out_offset; 405 int len = in_offset + in_len; 406 for (int ix = in_offset; ix < len; ix++) { 407 float f = in_buff[ix]; 408 short x = (short) (f > 0 ? f * 32767 : f * 32768); 409 out_buff[ox++] = (byte) x; 410 out_buff[ox++] = (byte) (x >>> 8); 411 } 412 return out_buff; 413 } 414 } 415 416 // PCM 16 bit, signed, big-endian 417 private static class AudioFloatConversion16SB extends AudioFloatConverter { 418 @Override toFloatArray(byte[] in_buff, int in_offset, float[] out_buff, int out_offset, int out_len)419 public float[] toFloatArray(byte[] in_buff, int in_offset, 420 float[] out_buff, int out_offset, int out_len) { 421 int ix = in_offset; 422 int ox = out_offset; 423 for (int i = 0; i < out_len; i++) { 424 short x = (short) ((in_buff[ix++] << 8) | (in_buff[ix++] & 0xFF)); 425 out_buff[ox++] = x > 0 ? x / 32767.0f : x / 32768.0f; 426 } 427 return out_buff; 428 } 429 430 @Override toByteArray(float[] in_buff, int in_offset, int in_len, byte[] out_buff, int out_offset)431 public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, 432 byte[] out_buff, int out_offset) { 433 int ix = in_offset; 434 int ox = out_offset; 435 for (int i = 0; i < in_len; i++) { 436 float f = in_buff[ix++]; 437 short x = (short) (f > 0 ? f * 32767.0f : f * 32768.0f); 438 out_buff[ox++] = (byte) (x >>> 8); 439 out_buff[ox++] = (byte) x; 440 } 441 return out_buff; 442 } 443 } 444 445 // PCM 16 bit, unsigned, little-endian 446 private static class AudioFloatConversion16UL extends AudioFloatConverter { 447 @Override toFloatArray(byte[] in_buff, int in_offset, float[] out_buff, int out_offset, int out_len)448 public float[] toFloatArray(byte[] in_buff, int in_offset, 449 float[] out_buff, int out_offset, int out_len) { 450 int ix = in_offset; 451 int ox = out_offset; 452 for (int i = 0; i < out_len; i++) { 453 int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8); 454 x -= 32768; 455 out_buff[ox++] = x > 0 ? x / 32767.0f : x / 32768.0f; 456 } 457 return out_buff; 458 } 459 460 @Override toByteArray(float[] in_buff, int in_offset, int in_len, byte[] out_buff, int out_offset)461 public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, 462 byte[] out_buff, int out_offset) { 463 int ix = in_offset; 464 int ox = out_offset; 465 for (int i = 0; i < in_len; i++) { 466 float f = in_buff[ix++]; 467 int x = 32768 + (int) (f > 0 ? f * 32767 : f * 32768); 468 out_buff[ox++] = (byte) x; 469 out_buff[ox++] = (byte) (x >>> 8); 470 } 471 return out_buff; 472 } 473 } 474 475 // PCM 16 bit, unsigned, big-endian 476 private static class AudioFloatConversion16UB extends AudioFloatConverter { 477 @Override toFloatArray(byte[] in_buff, int in_offset, float[] out_buff, int out_offset, int out_len)478 public float[] toFloatArray(byte[] in_buff, int in_offset, 479 float[] out_buff, int out_offset, int out_len) { 480 int ix = in_offset; 481 int ox = out_offset; 482 for (int i = 0; i < out_len; i++) { 483 int x = ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF); 484 x -= 32768; 485 out_buff[ox++] = x > 0 ? x / 32767.0f : x / 32768.0f; 486 } 487 return out_buff; 488 } 489 490 @Override toByteArray(float[] in_buff, int in_offset, int in_len, byte[] out_buff, int out_offset)491 public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, 492 byte[] out_buff, int out_offset) { 493 int ix = in_offset; 494 int ox = out_offset; 495 for (int i = 0; i < in_len; i++) { 496 float f = in_buff[ix++]; 497 int x = 32768 + (int) (f > 0 ? f * 32767 : f * 32768); 498 out_buff[ox++] = (byte) (x >>> 8); 499 out_buff[ox++] = (byte) x; 500 } 501 return out_buff; 502 } 503 } 504 505 /*************************************************************************** 506 * 507 * 24 bit signed/unsigned, little/big-endian 508 * 509 **************************************************************************/ 510 511 // PCM 24 bit, signed, little-endian 512 private static class AudioFloatConversion24SL extends AudioFloatConverter { 513 @Override toFloatArray(byte[] in_buff, int in_offset, float[] out_buff, int out_offset, int out_len)514 public float[] toFloatArray(byte[] in_buff, int in_offset, 515 float[] out_buff, int out_offset, int out_len) { 516 int ix = in_offset; 517 int ox = out_offset; 518 for (int i = 0; i < out_len; i++) { 519 int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8) 520 | ((in_buff[ix++] & 0xFF) << 16); 521 if (x > 0x7FFFFF) 522 x -= 0x1000000; 523 out_buff[ox++] = x > 0 ? x / 8388607.0f : x / 8388608.0f; 524 } 525 return out_buff; 526 } 527 528 @Override toByteArray(float[] in_buff, int in_offset, int in_len, byte[] out_buff, int out_offset)529 public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, 530 byte[] out_buff, int out_offset) { 531 int ix = in_offset; 532 int ox = out_offset; 533 for (int i = 0; i < in_len; i++) { 534 float f = in_buff[ix++]; 535 int x = (int) (f > 0 ? f * 8388607.0f : f * 8388608.0f); 536 if (x < 0) 537 x += 0x1000000; 538 out_buff[ox++] = (byte) x; 539 out_buff[ox++] = (byte) (x >>> 8); 540 out_buff[ox++] = (byte) (x >>> 16); 541 } 542 return out_buff; 543 } 544 } 545 546 // PCM 24 bit, signed, big-endian 547 private static class AudioFloatConversion24SB extends AudioFloatConverter { 548 @Override toFloatArray(byte[] in_buff, int in_offset, float[] out_buff, int out_offset, int out_len)549 public float[] toFloatArray(byte[] in_buff, int in_offset, 550 float[] out_buff, int out_offset, int out_len) { 551 int ix = in_offset; 552 int ox = out_offset; 553 for (int i = 0; i < out_len; i++) { 554 int x = ((in_buff[ix++] & 0xFF) << 16) 555 | ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF); 556 if (x > 0x7FFFFF) 557 x -= 0x1000000; 558 out_buff[ox++] = x > 0 ? x / 8388607.0f : x / 8388608.0f; 559 } 560 return out_buff; 561 } 562 563 @Override toByteArray(float[] in_buff, int in_offset, int in_len, byte[] out_buff, int out_offset)564 public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, 565 byte[] out_buff, int out_offset) { 566 int ix = in_offset; 567 int ox = out_offset; 568 for (int i = 0; i < in_len; i++) { 569 float f = in_buff[ix++]; 570 int x = (int) (f > 0 ? f * 8388607.0f : f * 8388608.0f); 571 if (x < 0) 572 x += 0x1000000; 573 out_buff[ox++] = (byte) (x >>> 16); 574 out_buff[ox++] = (byte) (x >>> 8); 575 out_buff[ox++] = (byte) x; 576 } 577 return out_buff; 578 } 579 } 580 581 // PCM 24 bit, unsigned, little-endian 582 private static class AudioFloatConversion24UL extends AudioFloatConverter { 583 @Override toFloatArray(byte[] in_buff, int in_offset, float[] out_buff, int out_offset, int out_len)584 public float[] toFloatArray(byte[] in_buff, int in_offset, 585 float[] out_buff, int out_offset, int out_len) { 586 int ix = in_offset; 587 int ox = out_offset; 588 for (int i = 0; i < out_len; i++) { 589 int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8) 590 | ((in_buff[ix++] & 0xFF) << 16); 591 x -= 0x800000; 592 out_buff[ox++] = x > 0 ? x / 8388607.0f : x / 8388608.0f; 593 } 594 return out_buff; 595 } 596 597 @Override toByteArray(float[] in_buff, int in_offset, int in_len, byte[] out_buff, int out_offset)598 public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, 599 byte[] out_buff, int out_offset) { 600 int ix = in_offset; 601 int ox = out_offset; 602 for (int i = 0; i < in_len; i++) { 603 float f = in_buff[ix++]; 604 int x = (int) (f > 0 ? f * 8388607.0f : f * 8388608.0f); 605 x += 0x800000; 606 out_buff[ox++] = (byte) x; 607 out_buff[ox++] = (byte) (x >>> 8); 608 out_buff[ox++] = (byte) (x >>> 16); 609 } 610 return out_buff; 611 } 612 } 613 614 // PCM 24 bit, unsigned, big-endian 615 private static class AudioFloatConversion24UB extends AudioFloatConverter { 616 @Override toFloatArray(byte[] in_buff, int in_offset, float[] out_buff, int out_offset, int out_len)617 public float[] toFloatArray(byte[] in_buff, int in_offset, 618 float[] out_buff, int out_offset, int out_len) { 619 int ix = in_offset; 620 int ox = out_offset; 621 for (int i = 0; i < out_len; i++) { 622 int x = ((in_buff[ix++] & 0xFF) << 16) 623 | ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF); 624 x -= 0x800000; 625 out_buff[ox++] = x > 0 ? x / 8388607.0f : x / 8388608.0f; 626 } 627 return out_buff; 628 } 629 630 @Override toByteArray(float[] in_buff, int in_offset, int in_len, byte[] out_buff, int out_offset)631 public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, 632 byte[] out_buff, int out_offset) { 633 int ix = in_offset; 634 int ox = out_offset; 635 for (int i = 0; i < in_len; i++) { 636 float f = in_buff[ix++]; 637 int x = (int) (f > 0 ? f * 8388607.0f : f * 8388608.0f); 638 x += 8388608; 639 out_buff[ox++] = (byte) (x >>> 16); 640 out_buff[ox++] = (byte) (x >>> 8); 641 out_buff[ox++] = (byte) x; 642 } 643 return out_buff; 644 } 645 } 646 647 /*************************************************************************** 648 * 649 * 32 bit signed/unsigned, little/big-endian 650 * 651 **************************************************************************/ 652 653 // PCM 32 bit, signed, little-endian 654 private static class AudioFloatConversion32SL extends AudioFloatConverter { 655 @Override toFloatArray(byte[] in_buff, int in_offset, float[] out_buff, int out_offset, int out_len)656 public float[] toFloatArray(byte[] in_buff, int in_offset, 657 float[] out_buff, int out_offset, int out_len) { 658 int ix = in_offset; 659 int ox = out_offset; 660 for (int i = 0; i < out_len; i++) { 661 int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8) | 662 ((in_buff[ix++] & 0xFF) << 16) | 663 ((in_buff[ix++] & 0xFF) << 24); 664 out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF); 665 } 666 return out_buff; 667 } 668 669 @Override toByteArray(float[] in_buff, int in_offset, int in_len, byte[] out_buff, int out_offset)670 public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, 671 byte[] out_buff, int out_offset) { 672 int ix = in_offset; 673 int ox = out_offset; 674 for (int i = 0; i < in_len; i++) { 675 int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF); 676 out_buff[ox++] = (byte) x; 677 out_buff[ox++] = (byte) (x >>> 8); 678 out_buff[ox++] = (byte) (x >>> 16); 679 out_buff[ox++] = (byte) (x >>> 24); 680 } 681 return out_buff; 682 } 683 } 684 685 // PCM 32 bit, signed, big-endian 686 private static class AudioFloatConversion32SB extends AudioFloatConverter { 687 @Override toFloatArray(byte[] in_buff, int in_offset, float[] out_buff, int out_offset, int out_len)688 public float[] toFloatArray(byte[] in_buff, int in_offset, 689 float[] out_buff, int out_offset, int out_len) { 690 int ix = in_offset; 691 int ox = out_offset; 692 for (int i = 0; i < out_len; i++) { 693 int x = ((in_buff[ix++] & 0xFF) << 24) | 694 ((in_buff[ix++] & 0xFF) << 16) | 695 ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF); 696 out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF); 697 } 698 return out_buff; 699 } 700 701 @Override toByteArray(float[] in_buff, int in_offset, int in_len, byte[] out_buff, int out_offset)702 public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, 703 byte[] out_buff, int out_offset) { 704 int ix = in_offset; 705 int ox = out_offset; 706 for (int i = 0; i < in_len; i++) { 707 int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF); 708 out_buff[ox++] = (byte) (x >>> 24); 709 out_buff[ox++] = (byte) (x >>> 16); 710 out_buff[ox++] = (byte) (x >>> 8); 711 out_buff[ox++] = (byte) x; 712 } 713 return out_buff; 714 } 715 } 716 717 // PCM 32 bit, unsigned, little-endian 718 private static class AudioFloatConversion32UL extends AudioFloatConverter { 719 @Override toFloatArray(byte[] in_buff, int in_offset, float[] out_buff, int out_offset, int out_len)720 public float[] toFloatArray(byte[] in_buff, int in_offset, 721 float[] out_buff, int out_offset, int out_len) { 722 int ix = in_offset; 723 int ox = out_offset; 724 for (int i = 0; i < out_len; i++) { 725 int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8) | 726 ((in_buff[ix++] & 0xFF) << 16) | 727 ((in_buff[ix++] & 0xFF) << 24); 728 x -= 0x80000000; 729 out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF); 730 } 731 return out_buff; 732 } 733 734 @Override toByteArray(float[] in_buff, int in_offset, int in_len, byte[] out_buff, int out_offset)735 public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, 736 byte[] out_buff, int out_offset) { 737 int ix = in_offset; 738 int ox = out_offset; 739 for (int i = 0; i < in_len; i++) { 740 int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF); 741 x += 0x80000000; 742 out_buff[ox++] = (byte) x; 743 out_buff[ox++] = (byte) (x >>> 8); 744 out_buff[ox++] = (byte) (x >>> 16); 745 out_buff[ox++] = (byte) (x >>> 24); 746 } 747 return out_buff; 748 } 749 } 750 751 // PCM 32 bit, unsigned, big-endian 752 private static class AudioFloatConversion32UB extends AudioFloatConverter { 753 754 @Override toFloatArray(byte[] in_buff, int in_offset, float[] out_buff, int out_offset, int out_len)755 public float[] toFloatArray(byte[] in_buff, int in_offset, 756 float[] out_buff, int out_offset, int out_len) { 757 int ix = in_offset; 758 int ox = out_offset; 759 for (int i = 0; i < out_len; i++) { 760 int x = ((in_buff[ix++] & 0xFF) << 24) | 761 ((in_buff[ix++] & 0xFF) << 16) | 762 ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF); 763 x -= 0x80000000; 764 out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF); 765 } 766 return out_buff; 767 } 768 769 @Override toByteArray(float[] in_buff, int in_offset, int in_len, byte[] out_buff, int out_offset)770 public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, 771 byte[] out_buff, int out_offset) { 772 int ix = in_offset; 773 int ox = out_offset; 774 for (int i = 0; i < in_len; i++) { 775 int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF); 776 x += 0x80000000; 777 out_buff[ox++] = (byte) (x >>> 24); 778 out_buff[ox++] = (byte) (x >>> 16); 779 out_buff[ox++] = (byte) (x >>> 8); 780 out_buff[ox++] = (byte) x; 781 } 782 return out_buff; 783 } 784 } 785 786 /*************************************************************************** 787 * 788 * 32+ bit signed/unsigned, little/big-endian 789 * 790 **************************************************************************/ 791 792 // PCM 32+ bit, signed, little-endian 793 private static class AudioFloatConversion32xSL extends AudioFloatConverter { 794 795 private final int xbytes; 796 AudioFloatConversion32xSL(int xbytes)797 AudioFloatConversion32xSL(int xbytes) { 798 this.xbytes = xbytes; 799 } 800 801 @Override toFloatArray(byte[] in_buff, int in_offset, float[] out_buff, int out_offset, int out_len)802 public float[] toFloatArray(byte[] in_buff, int in_offset, 803 float[] out_buff, int out_offset, int out_len) { 804 int ix = in_offset; 805 int ox = out_offset; 806 for (int i = 0; i < out_len; i++) { 807 ix += xbytes; 808 int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8) 809 | ((in_buff[ix++] & 0xFF) << 16) 810 | ((in_buff[ix++] & 0xFF) << 24); 811 out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF); 812 } 813 return out_buff; 814 } 815 816 @Override toByteArray(float[] in_buff, int in_offset, int in_len, byte[] out_buff, int out_offset)817 public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, 818 byte[] out_buff, int out_offset) { 819 int ix = in_offset; 820 int ox = out_offset; 821 for (int i = 0; i < in_len; i++) { 822 int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF); 823 for (int j = 0; j < xbytes; j++) { 824 out_buff[ox++] = 0; 825 } 826 out_buff[ox++] = (byte) x; 827 out_buff[ox++] = (byte) (x >>> 8); 828 out_buff[ox++] = (byte) (x >>> 16); 829 out_buff[ox++] = (byte) (x >>> 24); 830 } 831 return out_buff; 832 } 833 } 834 835 // PCM 32+ bit, signed, big-endian 836 private static class AudioFloatConversion32xSB extends AudioFloatConverter { 837 838 private final int xbytes; 839 AudioFloatConversion32xSB(int xbytes)840 AudioFloatConversion32xSB(int xbytes) { 841 this.xbytes = xbytes; 842 } 843 844 @Override toFloatArray(byte[] in_buff, int in_offset, float[] out_buff, int out_offset, int out_len)845 public float[] toFloatArray(byte[] in_buff, int in_offset, 846 float[] out_buff, int out_offset, int out_len) { 847 int ix = in_offset; 848 int ox = out_offset; 849 for (int i = 0; i < out_len; i++) { 850 int x = ((in_buff[ix++] & 0xFF) << 24) 851 | ((in_buff[ix++] & 0xFF) << 16) 852 | ((in_buff[ix++] & 0xFF) << 8) 853 | (in_buff[ix++] & 0xFF); 854 ix += xbytes; 855 out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF); 856 } 857 return out_buff; 858 } 859 860 @Override toByteArray(float[] in_buff, int in_offset, int in_len, byte[] out_buff, int out_offset)861 public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, 862 byte[] out_buff, int out_offset) { 863 int ix = in_offset; 864 int ox = out_offset; 865 for (int i = 0; i < in_len; i++) { 866 int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF); 867 out_buff[ox++] = (byte) (x >>> 24); 868 out_buff[ox++] = (byte) (x >>> 16); 869 out_buff[ox++] = (byte) (x >>> 8); 870 out_buff[ox++] = (byte) x; 871 for (int j = 0; j < xbytes; j++) { 872 out_buff[ox++] = 0; 873 } 874 } 875 return out_buff; 876 } 877 } 878 879 // PCM 32+ bit, unsigned, little-endian 880 private static class AudioFloatConversion32xUL extends AudioFloatConverter { 881 882 private final int xbytes; 883 AudioFloatConversion32xUL(int xbytes)884 AudioFloatConversion32xUL(int xbytes) { 885 this.xbytes = xbytes; 886 } 887 888 @Override toFloatArray(byte[] in_buff, int in_offset, float[] out_buff, int out_offset, int out_len)889 public float[] toFloatArray(byte[] in_buff, int in_offset, 890 float[] out_buff, int out_offset, int out_len) { 891 int ix = in_offset; 892 int ox = out_offset; 893 for (int i = 0; i < out_len; i++) { 894 ix += xbytes; 895 int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8) 896 | ((in_buff[ix++] & 0xFF) << 16) 897 | ((in_buff[ix++] & 0xFF) << 24); 898 x -= 0x80000000; 899 out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF); 900 } 901 return out_buff; 902 } 903 904 @Override toByteArray(float[] in_buff, int in_offset, int in_len, byte[] out_buff, int out_offset)905 public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, 906 byte[] out_buff, int out_offset) { 907 int ix = in_offset; 908 int ox = out_offset; 909 for (int i = 0; i < in_len; i++) { 910 int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF); 911 x += 0x80000000; 912 for (int j = 0; j < xbytes; j++) { 913 out_buff[ox++] = 0; 914 } 915 out_buff[ox++] = (byte) x; 916 out_buff[ox++] = (byte) (x >>> 8); 917 out_buff[ox++] = (byte) (x >>> 16); 918 out_buff[ox++] = (byte) (x >>> 24); 919 } 920 return out_buff; 921 } 922 } 923 924 // PCM 32+ bit, unsigned, big-endian 925 private static class AudioFloatConversion32xUB extends AudioFloatConverter { 926 927 private final int xbytes; 928 AudioFloatConversion32xUB(int xbytes)929 AudioFloatConversion32xUB(int xbytes) { 930 this.xbytes = xbytes; 931 } 932 933 @Override toFloatArray(byte[] in_buff, int in_offset, float[] out_buff, int out_offset, int out_len)934 public float[] toFloatArray(byte[] in_buff, int in_offset, 935 float[] out_buff, int out_offset, int out_len) { 936 int ix = in_offset; 937 int ox = out_offset; 938 for (int i = 0; i < out_len; i++) { 939 int x = ((in_buff[ix++] & 0xFF) << 24) | 940 ((in_buff[ix++] & 0xFF) << 16) | 941 ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF); 942 ix += xbytes; 943 x -= 0x80000000; 944 out_buff[ox++] = x * (1.0f / 2147483647.0f); 945 } 946 return out_buff; 947 } 948 949 @Override toByteArray(float[] in_buff, int in_offset, int in_len, byte[] out_buff, int out_offset)950 public byte[] toByteArray(float[] in_buff, int in_offset, int in_len, 951 byte[] out_buff, int out_offset) { 952 int ix = in_offset; 953 int ox = out_offset; 954 for (int i = 0; i < in_len; i++) { 955 int x = (int) (in_buff[ix++] * 2147483647.0f); 956 x += 0x80000000; 957 out_buff[ox++] = (byte) (x >>> 24); 958 out_buff[ox++] = (byte) (x >>> 16); 959 out_buff[ox++] = (byte) (x >>> 8); 960 out_buff[ox++] = (byte) x; 961 for (int j = 0; j < xbytes; j++) { 962 out_buff[ox++] = 0; 963 } 964 } 965 return out_buff; 966 } 967 } 968 getConverter(AudioFormat format)969 public static AudioFloatConverter getConverter(AudioFormat format) { 970 AudioFloatConverter conv = null; 971 if (format.getFrameSize() == 0) 972 return null; 973 if (format.getFrameSize() != 974 ((format.getSampleSizeInBits() + 7) / 8) * format.getChannels()) { 975 return null; 976 } 977 if (format.getEncoding().equals(Encoding.PCM_SIGNED)) { 978 if (format.isBigEndian()) { 979 if (format.getSampleSizeInBits() <= 8) { 980 conv = new AudioFloatConversion8S(); 981 } else if (format.getSampleSizeInBits() > 8 && 982 format.getSampleSizeInBits() <= 16) { 983 conv = new AudioFloatConversion16SB(); 984 } else if (format.getSampleSizeInBits() > 16 && 985 format.getSampleSizeInBits() <= 24) { 986 conv = new AudioFloatConversion24SB(); 987 } else if (format.getSampleSizeInBits() > 24 && 988 format.getSampleSizeInBits() <= 32) { 989 conv = new AudioFloatConversion32SB(); 990 } else if (format.getSampleSizeInBits() > 32) { 991 conv = new AudioFloatConversion32xSB(((format 992 .getSampleSizeInBits() + 7) / 8) - 4); 993 } 994 } else { 995 if (format.getSampleSizeInBits() <= 8) { 996 conv = new AudioFloatConversion8S(); 997 } else if (format.getSampleSizeInBits() > 8 && 998 format.getSampleSizeInBits() <= 16) { 999 conv = new AudioFloatConversion16SL(); 1000 } else if (format.getSampleSizeInBits() > 16 && 1001 format.getSampleSizeInBits() <= 24) { 1002 conv = new AudioFloatConversion24SL(); 1003 } else if (format.getSampleSizeInBits() > 24 && 1004 format.getSampleSizeInBits() <= 32) { 1005 conv = new AudioFloatConversion32SL(); 1006 } else if (format.getSampleSizeInBits() > 32) { 1007 conv = new AudioFloatConversion32xSL(((format 1008 .getSampleSizeInBits() + 7) / 8) - 4); 1009 } 1010 } 1011 } else if (format.getEncoding().equals(Encoding.PCM_UNSIGNED)) { 1012 if (format.isBigEndian()) { 1013 if (format.getSampleSizeInBits() <= 8) { 1014 conv = new AudioFloatConversion8U(); 1015 } else if (format.getSampleSizeInBits() > 8 && 1016 format.getSampleSizeInBits() <= 16) { 1017 conv = new AudioFloatConversion16UB(); 1018 } else if (format.getSampleSizeInBits() > 16 && 1019 format.getSampleSizeInBits() <= 24) { 1020 conv = new AudioFloatConversion24UB(); 1021 } else if (format.getSampleSizeInBits() > 24 && 1022 format.getSampleSizeInBits() <= 32) { 1023 conv = new AudioFloatConversion32UB(); 1024 } else if (format.getSampleSizeInBits() > 32) { 1025 conv = new AudioFloatConversion32xUB((( 1026 format.getSampleSizeInBits() + 7) / 8) - 4); 1027 } 1028 } else { 1029 if (format.getSampleSizeInBits() <= 8) { 1030 conv = new AudioFloatConversion8U(); 1031 } else if (format.getSampleSizeInBits() > 8 && 1032 format.getSampleSizeInBits() <= 16) { 1033 conv = new AudioFloatConversion16UL(); 1034 } else if (format.getSampleSizeInBits() > 16 && 1035 format.getSampleSizeInBits() <= 24) { 1036 conv = new AudioFloatConversion24UL(); 1037 } else if (format.getSampleSizeInBits() > 24 && 1038 format.getSampleSizeInBits() <= 32) { 1039 conv = new AudioFloatConversion32UL(); 1040 } else if (format.getSampleSizeInBits() > 32) { 1041 conv = new AudioFloatConversion32xUL((( 1042 format.getSampleSizeInBits() + 7) / 8) - 4); 1043 } 1044 } 1045 } else if (format.getEncoding().equals(Encoding.PCM_FLOAT)) { 1046 if (format.getSampleSizeInBits() == 32) { 1047 if (format.isBigEndian()) 1048 conv = new AudioFloatConversion32B(); 1049 else 1050 conv = new AudioFloatConversion32L(); 1051 } else if (format.getSampleSizeInBits() == 64) { 1052 if (format.isBigEndian()) 1053 conv = new AudioFloatConversion64B(); 1054 else 1055 conv = new AudioFloatConversion64L(); 1056 } 1057 1058 } 1059 1060 if ((format.getEncoding().equals(Encoding.PCM_SIGNED) || 1061 format.getEncoding().equals(Encoding.PCM_UNSIGNED)) && 1062 (format.getSampleSizeInBits() % 8 != 0)) { 1063 conv = new AudioFloatLSBFilter(conv, format); 1064 } 1065 1066 if (conv != null) 1067 conv.format = format; 1068 return conv; 1069 } 1070 1071 private AudioFormat format; 1072 getFormat()1073 public final AudioFormat getFormat() { 1074 return format; 1075 } 1076 toFloatArray(byte[] in_buff, int in_offset, float[] out_buff, int out_offset, int out_len)1077 public abstract float[] toFloatArray(byte[] in_buff, int in_offset, 1078 float[] out_buff, int out_offset, int out_len); 1079 toFloatArray(byte[] in_buff, float[] out_buff, int out_offset, int out_len)1080 public final float[] toFloatArray(byte[] in_buff, float[] out_buff, 1081 int out_offset, int out_len) { 1082 return toFloatArray(in_buff, 0, out_buff, out_offset, out_len); 1083 } 1084 toFloatArray(byte[] in_buff, int in_offset, float[] out_buff, int out_len)1085 public final float[] toFloatArray(byte[] in_buff, int in_offset, 1086 float[] out_buff, int out_len) { 1087 return toFloatArray(in_buff, in_offset, out_buff, 0, out_len); 1088 } 1089 toFloatArray(byte[] in_buff, float[] out_buff, int out_len)1090 public final float[] toFloatArray(byte[] in_buff, float[] out_buff, 1091 int out_len) { 1092 return toFloatArray(in_buff, 0, out_buff, 0, out_len); 1093 } 1094 toFloatArray(byte[] in_buff, float[] out_buff)1095 public final float[] toFloatArray(byte[] in_buff, float[] out_buff) { 1096 return toFloatArray(in_buff, 0, out_buff, 0, out_buff.length); 1097 } 1098 toByteArray(float[] in_buff, int in_offset, int in_len, byte[] out_buff, int out_offset)1099 public abstract byte[] toByteArray(float[] in_buff, int in_offset, 1100 int in_len, byte[] out_buff, int out_offset); 1101 toByteArray(float[] in_buff, int in_len, byte[] out_buff, int out_offset)1102 public final byte[] toByteArray(float[] in_buff, int in_len, 1103 byte[] out_buff, int out_offset) { 1104 return toByteArray(in_buff, 0, in_len, out_buff, out_offset); 1105 } 1106 toByteArray(float[] in_buff, int in_offset, int in_len, byte[] out_buff)1107 public final byte[] toByteArray(float[] in_buff, int in_offset, int in_len, 1108 byte[] out_buff) { 1109 return toByteArray(in_buff, in_offset, in_len, out_buff, 0); 1110 } 1111 toByteArray(float[] in_buff, int in_len, byte[] out_buff)1112 public final byte[] toByteArray(float[] in_buff, int in_len, 1113 byte[] out_buff) { 1114 return toByteArray(in_buff, 0, in_len, out_buff, 0); 1115 } 1116 toByteArray(float[] in_buff, byte[] out_buff)1117 public final byte[] toByteArray(float[] in_buff, byte[] out_buff) { 1118 return toByteArray(in_buff, 0, in_buff.length, out_buff, 0); 1119 } 1120 } 1121