JSpeex Decoding not working - java

I'm using the JSpeex library for audio encoding.
The encoding seems to work fine. But decoding doesn't.(i.e. I get all zeros as decoded data.)
// encoding ///
SpeexEncoder enc = new SpeexEncoder();
// if i use channel as 1 instead of 2 even encoding doesn't work
enc.init(mode, quality, 44100, 2);
enc.processData(b, 0, b.length); // b is byte array i'm trying to encode & then decode
enc.getProcessedData(temp, 0); // save encoded data to temp // temp is byte array
////Decoding /////////
SpeexDecoder dec = new SpeexDecoder();
dec.init(mode,44100,2,true);
dec.processData(temp, 0, temp.length);
dec.getProcessedData(decoded, 0); //decoded is the output byte array which comes only zeros
If anyone has any info on this please reply.
Thanks

I realize this post is a bit old, but ran into a similar problem with Speex.js (a javascript port).
Not sure if the issue is the same for you, but I found that there was an implicit conversion from Float32Array to Int16Array that didn't actually convert the data. This meant that all of the (-1.0,1.0) float data was essentially integer zeros, and was converted as such.
Just needed to do the conversion to Int16Array before passing in the data (so it wouldn't need to do any data conversion within the library) and the output sprang to life :)
Hope that helps. cheers!

Related

Decoding String (from header) encoded by Base64 and RFC2047 in Java

I'm working on a function to decode a string (from a header) that is encoded in both Base64 and RFC2047 in Java.
Given this header:
SGVhZGVyOiBoZWFkZXJ2YWx1ZQ0KQmFkOiBOYW1lOiBiYWRuYW1ldmFsdWUNClVuaWNvZGU6ID0/VVRGLTg/Qj81YmV4NXF5eTU2dUw2SUNNNTZ1TDVMcTY3N3lNNWJleDVxeXk2WUdVNklDTTZZR1U/PSA9P1VURi04P0I/NUxxNjc3eU01YmV4NW9tQTVMaU41cXl5Nzd5TTVZdS81cGE5NXBhODVMcTY0NENDPz0NCg0K
My expected output is:
Header: headervalue Bad: Name: badnamevalue Unicode:
己欲立而立人,己欲達而達人,己所不欲,勿施於人。
The only relevant function that I have found and tried was Base64.decodeBase64(headers), which produces this when printed out:
Header: headervalue Bad: Name: badnamevalue Unicode:
=?UTF-8?B?5bex5qyy56uL6ICM56uL5Lq677yM5bex5qyy6YGU6ICM6YGU?= =?UTF-8?B?5Lq677yM5bex5omA5LiN5qyy77yM5Yu/5pa95pa85Lq644CC?=
To solve this, I've been trying MimeUtility.decode() by converting the byte array returned from Base64.decodeBase64(headers) to InputStream, but the result was identical as above.
InputStream headerStream = new ByteArrayInputStream(Base64.decodeBase64(headers));
InputStream result = MimeUtility.decode(headerStream, "quoted-printable");
Have been searching around the internet but have yet found a solution, wondering if anyone knows ways to decode MIME headers from resulted byte arrays?
Any help is appreciated! It's also my first stack overflow post, apologies if I'm missing anything but please let me know if there's more information that I can provide!
The base64 you have there actually is what you pasted. Including the bizarre =?UTF-8?B? weirdness.
The stuff that follows is again base64.
There's base64-encoded data inside your base-64 encoded data. As Xzibit would say: I put some Base64 in your base64 so you can base64 while you base64. Why do I feel old all of a sudden?
In other words, the base64 input you get is a crazy, extremely inefficient format invented by a crazy person.
My advice is that you tell them to come up with something less insane.
Failing that:
Search the resulting string for the regex pattern and then again apply base64 decode to the stuff in the middle.
Also, you're using some third party base64 decoder, probably apache. Apache libraries tend to suck. Base64 is baked into java, there is no reason to use worse libraries here. I've fixed that; the Base64 in this snippet is java.util.Base64. Its API is slightly different.
String sourceB64 = "SGV..."; // that input base64 you have.
byte[] sourceBytes = Base64.decodeBase64(sourceB64);
String source = new String(sourceBytes, StandardCharsets.UTF_8);
Pattern p = Pattern.compile("=\\?UTF-8\\?B\\?(.*?)\\?=");
Matcher m = p.matcher(source);
StringBuilder out = new StringBuilder();
int curPos = 0;
while (m.find()) {
out.append(source.substring(curPos, m.start()));
curPos = m.end();
String content = new String(Base64.getDecoder().decode(m.group(1)), StandardCharsets.UTF_8);
out.append(content);
}
out.append(source.substring(curPos));
System.out.println(out.toString());
If I run that, I get:
Header: headervalue
Bad: Name: badnamevalue
Unicode: 己欲立而立人,己欲達而達 人,己所不欲,勿施於人。
Which looks exactly like what you want.
Explanation of that code:
It first base64-decodes the input, and turns that into a string. (Your idea of using InputStream is a red herring. That doesn't help at all here. You just want to turn bytes into a string, you do it as per line 3 of that snippet. Pass the byte array and the encoding those bytes are in, that's all you need to do).
It then goes on the hunt for =?UTF-8?B?--base64here--?= inside your base64. The base64-in-the-base64.
It then decoder that base64, turns it into a string in the same fashion, and replaces it.
It just adds everything besides those =?UTF-8?B?...?= segments verbatim.

Java Multipart file to blob then back to Image has loads of random characters

I am recieveing an image from a jsp, converting into a byte, then blob and saving it in my Database, on a different page I am then retriving it, and when I retrieve the image I get the following String.
'x*??{[?Y?>YE *?????_/???????~%?+y?`??uH????#??\t?????|B??k?-??Z4V?U7?F???m+(?? ? I??pq^?Q???????18?R???-???>0~?sXxCI?;[;t???9?fBX?Bp?A??^M?k? ??G?S?u???????r?U&‚w*??8????`??> Y?2?????1?j$??\??DR[??t0? pps?_Ex? ???_o?*?? xV)?6D8?$??!?9??~???N?`???}W?s?gNUf?Mn>?s?3?r?3M???X???Q????N!pr~?W????Mjq5??????2m???8????x??V?????????[???"??*,I?/#s?V?d?B?/?Vb?&R?n|?>??2????)?r??1??%7?Q??^f?R?C?????mvm??%6?K?p??;O?Z?&?????u?????\???R"ZOex???VkE???????_??????K?M#=??o?Z[?[hb?H?V????
I have cut this down manually on here.
This is the tag that I have done.
<img src="data:image/jpeg;base64,${img}" width="100" height="100"></img>
I'm not quite sure what has gone wrong here, here is where I have taken the file and made it into a byte[] then a blob.
byte[] byteData = file.getBytes();
Blob blobs = new SerialBlob(byteData);
and how then I've converted it into a base64 string.
String base64DataString = new String(byteData , "UTF-8");
System.out.println(base64DataString);
model.addAttribute("img", base64DataString);
If anyone has any idea how I can turn this string into a normal base64 string which can be used to reproduce an image, that would be very helpful.
Jim
String base64DataString = Base64.getEncoder().encodeToString(byteData);
Binary data should never be converted to String, which contains Unicode, mostly as UTF-16 chars, where every byte costs 2 bytes (one char), and the conversion takes time and probably goes wrong.

How to get rid of incorrect symbols during Java NIO decoding?

I need to read a text from file and, for instance, print it in console. The file is in UTF-8. It seems that I'm doing something wrong because some russian symbols are printed incorrectly. What's wrong with my code?
StringBuilder content = new StringBuilder();
try (FileChannel fChan = (FileChannel) Files.newByteChannel(Paths.get("D:/test.txt")) ) {
ByteBuffer byteBuf = ByteBuffer.allocate(16);
Charset charset = Charset.forName("UTF-8");
while(fChan.read(byteBuf) != -1) {
byteBuf.flip();
content.append(new String(byteBuf.array(), charset));
byteBuf.clear();
}
System.out.println(content);
}
The result:
Здравствуйте, как поживае��е?
Это п��имер текста на русском яз��ке.ом яз�
The actual text:
Здравствуйте, как поживаете?
Это пример текста на русском языке.
UTF-8 uses a variable number of bytes per character. This gives you a boundary error: You have mixed buffer-based code with byte-array based code and you can't do that here; it is possible for you to read enough bytes to be stuck halfway into a character, you then turn your input into a byte array, and convert it, which will fail, because you can't convert half a character.
What you really want is either to first read ALL the data and then convert the entire input, or, to keep any half-characters in the bytebuffer when you flip back, or better yet, ditch all this stuff and use code that is written to read actual characters. In general, using the channel API complicates matters a ton; it's flexible, but complicated - that's how it goes.
Unless you can explain why you need it, don't use it. Do this instead:
Path target = Paths.get("D:/test.txt");
try (var reader = Files.newBufferedReader(target)) {
// read a line at a time here. Yes, it will be UTF-8 decoded.
}
or better yet, as you apparently want to read the whole thing in one go:
Path target = Paths.get("D:/test.txt");
var content = Files.readString(target);
NB: Unlike most java methods that convert bytes to chars or vice versa, the Files API defaults to UTF-8 (instead of the useless and dangerous, untestable-bug-causing 'platform default encoding' that most java API does). That's why this last incredibly simple code is nevertheless correct.

Trailing zeros in byte array from RawBsonDocument.getByteBuffer().array() in org.Bson

I am trying to encode an org.Json JSONObject into a BSON format byte[].
I have noticed, however, that the resulting byte[] has trailing zeros. While these zeros do not pose a problem when deserializing the byte[] to JSON again, they do however take up a lot of space.
My code is the following:
#deserializing incoming message
RawBsonDocument bson = new RawBsonDocument((byte[])incomingBson);
json = new JSONObject(bson.toJson());
#serializing response to **bson format**
RawBsonDocument bsonDoc = RawBsonDocument.parse(json.toString());
responseBson = bsonDoc.getByteBuffer().array();
Simply trimming the byte[] from all trailing zeroes is not an option, since the byte[] can very well have valid zeros at the end, that where not added by the serialization.
Edit 1
I solved the issue with the following code:
RawBsonDocument bsonDoc = RawBsonDocument.parse(json.toString());
responseBson = Arrays.copyOfRange(bsonDoc.getByteBuffer().array(), 0, bsonDoc.getByteBuffer().limit());
I feel as tough the must be a more elegant answer
I also encountered this problem in a similar class and solved it by making a truncated copy of the internal buffer.
Since getByteBuffer returns the internal buffer which the document object holds, the ending unused spaces are filled with zeros, which caused the problem.
Here is my solution:
return Arrays.copyOf(writeBuffer.getInternalBuffer(), writeBuffer.getSize());
where writeBuffer is a BasicOutputBuffer instance which implements org.bson's OutputBuffer interface. So this should also work in your situation.

Ruby base 64 decoding for Java base 64 encoding

I having a string that is encoded in java using
data = new String(Base64.getEncoder().encode(encVal), StandardCharsets.UTF_8);
I am receiving this encoded data as an API response. I want to base64 decode this in ruby. I am using
Base64.strict_decode64(data)
for this. but this is not working. Can anyone help me with this?
Your Java code is correct:
byte[] encVal = "Hello World".getBytes();
String data = new String(Base64.getEncoder().encode(encVal), StandardCharsets.UTF_8);
System.out.println(data); // SGVsbG8gV29ybGQ=
The SGVsbG8gV29ybGQ= decodes correctly using multiple tools, e.g. https://www.base64decode.org/.
You are observing garbage characters decoding your value most likely due to an error in creating byte[]. Possibly you have to specify the correct encoding when creating byte[].

Categories