I capture song in real-time with TargetDataLine:
line.read(buffer, 0, buffer.length);
But this buffer have to be byte array. I need capture to buffer which is long array or float array. I try to convert from byte to long or float but these data are not correct.
How Can I capture with another type or covert byte to float/long in correct way?
You could try this approach:
byte[] buffer = new byte[2048];
float[] fBuffer = new float[buffer.length >> 2];
ByteBuffer bb = ByteBuffer.wrap(buffer);
FloatBuffer fb = bb.asFloatBuffer();
fb.get(fBuffer, 0, fBuffer.length);
This does the conversion for you.
Related
Why do we read into a byte array when downloading a file from a URL? In the below code a byte array ('data') is created which is allocated a number of "1024" and is passed as a parameter in the below piece of code
while ((x = in.read(data, 0, 1024)) >= 0)
Can you please explain what "reading" into a byte array means? Also, why were "0" and "1024" passed in as well?
This code was taken from Java getting download progress
URL url = new URL("http://downloads.sourceforge.net/project/bitcoin/Bitcoin/blockchain/bitcoin_blockchain_170000.zip");
HttpURLConnection httpConnection = (HttpURLConnection) (url.openConnection());
long completeFileSize = httpConnection.getContentLength();
java.io.BufferedInputStream in = new java.io.BufferedInputStream(httpConnection.getInputStream());
java.io.FileOutputStream fos = new java.io.FileOutputStream(
"package.zip");
java.io.BufferedOutputStream bout = new BufferedOutputStream(
fos, 1024);
byte[] data = new byte[1024];
long downloadedFileSize = 0;
int x = 0;
while ((x = in.read(data, 0, 1024)) >= 0) {
downloadedFileSize += x;
Can you please explain what "reading" into a byte array means?
When we read data into a byte array, we mean that we store the data from an input stream into an array for later use. We read the data into a byte array instead of a char array or an int array because it is binary data. It might be text or a picture or a video. At the end of the day, these are all binary data that we store in bytes.
Also, why were "0" and "1024" passed in as well?
The documentation for read() says it takes 3 arguments:
b - destination buffer.
off - offset at which to start storing bytes.
len - maximum number of bytes to read.
So the 0 is the "offset" where the read operation will start storing bytes. The 1024 is the number of bytes to read. These can be any sensible numbers as long as you don't try to read into a location past the end of the array.
My task is convert short[] array to byte[] array, because need send bytes via socket. This is bytes for AudioTrack (Android)
For converting use this post, specifically this and this
This method gives only white noise, when try to convert short to byte array:
val sampleBuffer = decoder.decodeFrame(frameHeader, bitstream) as SampleBuffer
val pcm = sampleBuffer.buffer //pcm is short[] array
byteBuf = ByteBuffer.allocate(pcm.size * 2) // because 1 short = 2 bytes
while (pcm.size > i) {
byteBuf.putShort(pcm[i])
i++
}
auddioTrack.write(byteBuf.array(), 0, byteBuf.limit());
But this convert works fine:
var i = 0
val byteBuf = ByteBuffer.allocate(pcm.size * 2)
val buff = ByteBuffer.allocate(2)
//pcm size equals 2304
while (pcm.size > i) {
// byteBuf.putShort(pcm[i])
byteBuf.put(byteArrayOf((pcm[i].toInt() and 0x00FF).toByte(), ((pcm[i].toInt() and 0xFF00) shr (8)).toByte()))
i++
}
auddioTrack.write(byteBuf.array(), 0, byteBuf.limit());
Why has it happened?
byteBuf.array().size will return the size of the buffer (pcm.size * 2) regardless of whether that many bytes were written into the buffer. You probably want byteBuf.limit() instead.
Here is the code
byte data[] = new byte[1024];
fout = new FileOutputStream(fileLocation);
ByteBuffer bb = ByteBuffer.allocate(i+i); // i is size of download
ReadableByteChannel rbc = Channels.newChannel(url.openStream());
while( (dat = rbc.read(bb)) != -1 )
{
bb.get(data);
fout.write(data, 0, 1024); // write the data to the file
speed.setText(String.valueOf(dat));
}
In this code I try to download a file from a given URL, but the file doesn't complete all it's way.
I don't know what error happened, is it the ReadableByteChannel's fault? Or I didn't put my bytes from the ByteBuffer into the Byte[] properly.
When you read into a ByteBuffer, the offset of the buffer is changed. Which means, after the read, you need to rewind the ByteBuffer:
while ((dat = rbc.read(bb)) != -1) {
fout.write(bb.array(), 0, bb.position());
bb.rewind(); // prepare the byte buffer for another read
}
But in your case, you don't really need a ByteBuffer anyway, just using a plain byte array is enough -- and it is shorter:
final InputStream in = url.openStream();
final byte[] buf = new byte[16384];
while ((dat = in.read(buf)) != -1)
fout.write(buf, 0, dat);
Note that in Java 1.7, you can use that:
Files.copy(url.openStream(), Paths.get(fileLocation));
I've been searching for a way to convert a FloatBuffer array to a byte array. I have found a way to convert a FloatBuffer object to byte[]:
convert from floatbuffer to byte[]
But after searching the Internet for several hours I haven't been able to find something equivalent to convert from FloatBuffer[].
And to do the inverse, to convert from byte[] to FloatBuffer[], I've only found this:
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(floatBufferObject);
byte [] descriptorsBytes = bos.toByteArray();
But it seems a little strange there is not a simpler way to do this.
Maybe I'm missing something very obvious, maybe I should convert the FloatBuffer array to other type that is simpler to convert to a byte array?
Do you want one FloatBuffer, or multiple?
To convert from a FloatBuffer to a byte[], you could do something like
FloatBuffer input;
byte[] output = new byte[input.capacity() * 4];
ByteBuffer.wrap(output).asFloatBuffer().put(input);
The other direction would just be
ByteBuffer.wrap(byteArray).asFloatBuffer()
You already had the answer on how to convert one FloatBuffer into a byte array, so simply extend that to convert an array of them:
final FloatBuffer[] floatBuffers = new FloatBuffer[] {...};
final ByteBuffer byteBuffer = ByteBuffer.allocate(sumOfFloatBufferCapacities) * 4);
final FloatBuffer floatBufView = byteBuffer.asFloatBuffer();
for (final FloatBuffer fBuf : floatBuffers) {
floatBufView.put(fBuf);
}
byte[] data = byteBuffer.array();
The above is pseudocode, you can adapt it to your needs.
Convert FloatBuffer[] to byte[]:
FloatBuffer[] buffers = ...
ByteArrayOutputStream bos = new ByteArrayOutputStream();
for (FloatBuffer fb : buffers) {
ByteBuffer byteBuffer = ByteBuffer.allocate(fb.capacity() * 4);
byteBuffer.asFloatBuffer().put(fb);
bos.write(byteBuffer.array());
}
byte[] ba = bos.toByteArray();
Is this the recommended way to get the bytes from the ByteBuffer
ByteBuffer bb =..
byte[] b = new byte[bb.remaining()]
bb.get(b, 0, b.length);
Depends what you want to do.
If what you want is to retrieve the bytes that are remaining (between position and limit), then what you have will work. You could also just do:
ByteBuffer bb =..
byte[] b = new byte[bb.remaining()];
bb.get(b);
which is equivalent as per the ByteBuffer javadocs.
Note that the bb.array() doesn't honor the byte-buffers position, and might be even worse if the bytebuffer you are working on is a slice of some other buffer.
I.e.
byte[] test = "Hello World".getBytes("Latin1");
ByteBuffer b1 = ByteBuffer.wrap(test);
byte[] hello = new byte[6];
b1.get(hello); // "Hello "
ByteBuffer b2 = b1.slice(); // position = 0, string = "World"
byte[] tooLong = b2.array(); // Will NOT be "World", but will be "Hello World".
byte[] world = new byte[5];
b2.get(world); // world = "World"
Which might not be what you intend to do.
If you really do not want to copy the byte-array, a work-around could be to use the byte-buffer's arrayOffset() + remaining(), but this only works if the application supports index+length of the byte-buffers it needs.
As simple as that
private static byte[] getByteArrayFromByteBuffer(ByteBuffer byteBuffer) {
byte[] bytesArray = new byte[byteBuffer.remaining()];
byteBuffer.get(bytesArray, 0, bytesArray.length);
return bytesArray;
}
final ByteBuffer buffer;
if (buffer.hasArray()) {
final byte[] array = buffer.array();
final int arrayOffset = buffer.arrayOffset();
return Arrays.copyOfRange(array, arrayOffset + buffer.position(),
arrayOffset + buffer.limit());
}
// do something else
If one does not know anything about the internal state of the given (Direct)ByteBuffer and wants to retrieve the whole content of the buffer, this can be used:
ByteBuffer byteBuffer = ...;
byte[] data = new byte[byteBuffer.capacity()];
((ByteBuffer) byteBuffer.duplicate().clear()).get(data);
This is a simple way to get a byte[], but part of the point of using a ByteBuffer is avoiding having to create a byte[]. Perhaps you can get whatever you wanted to get from the byte[] directly from the ByteBuffer.