audio to real numbers - java

I am able to convert my audio into byte values.
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException;
public class Audio_to_bytes {
public static void main(String args[]) throws IOException {
File WAV_FILE = new File("/home/cybersecurity/Desktop/scream2.wav");
ByteArrayOutputStream out = new ByteArrayOutputStream();
AudioInputStream in = null;
try {
in = AudioSystem.getAudioInputStream(WAV_FILE);
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
int read, i;
byte[] buff = new byte[1024];
while ((read = in.read(buff)) > 0) {
out.write(buff, 0, read);
}
out.flush();
byte[] audioBytes = out.toByteArray();
}
}
I want to identify audios which contains scream in them.For that i need to convert my audio into real numbers so that i can apply fft on it.Can anyone help me how this can be done

I came up with this code snippet and tested it. I hope it helps. I am allocating 4 floats (as bytes) I previously created and converted to bytes. Then I use the NIO FloatBuffer View of a ByteBuffer so NIO automatically returns 4 bytes as a float number without further treatment.
ByteBuffer bb = ByteBuffer.allocate(4*4);
bb.put(new byte[]{64,-112,0,0,66,-10, 22,-68, 66,9, 73, -43, 63,-114, 56, -38});
bb.rewind();
FloatBuffer floatBuffer = bb.asFloatBuffer();
for(int i = 0; i < 4;i++){
System.out.println(floatBuffer.get());
}

Related

It duplicates content when transferring it via java socket

I have written a client-socket "system" that is supposed to upload a file.
Although, when I attempt to upload, content duplicates.
I'm pretty sure that it is because the program doesn't recognise the eof.
I've found something like "Object stream", but I don't fancy importing new classes. I reckon that I don't really require that. But I wanna know how what the problem precisely is and how to hanle it.
package client;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
private Socket socket;
private DataInputStream in;
private DataOutputStream out;
public static void main(String[] args) {
new Client();
}
public Client()
{
try {
socket = new Socket("127.0.0.1", 5010);
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
this.sendFile("./some.txt");
in.close();
out.close();
socket.close();
}
catch(UnknownHostException ex)
{
System.out.println("unknown host");
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void sendFile(String path)
{
int bytes = 0;
File file = new File(path);
FileInputStream input;
try {
input = new FileInputStream(file);
long size = file.length();
//long size = file.getTotalSpace();
System.out.println(size);
// send a file's size
out.writeLong(size);
byte[] buffer = new byte[1024];
int i = 0, r=0;
//while((bytes = input.read(buffer,0,buffer.length))!=-1)
while(size > 0 && (bytes = input.read(buffer,0,(int)Math.min(buffer.length, size)))!=-1)
{
System.out.println("\n -------------"+(++i));
for (byte b : buffer)
try
{
if ((char)b == '\n' || r == 0)
System.out.print("\n" + (++r));
System.out.print((char)b);
}
catch(NullPointerException ex)
{
}
out.write(buffer, 0, bytes);
out.flush();
size -= bytes;
}
input.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package server;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
private ServerSocket ss;
private Socket cs;
private DataInputStream in;
private DataOutputStream out;
public static void main(String[] args) {
new Server();
}
public Server()
{
try {
ss = new ServerSocket(5010);
cs = ss.accept();
in = new DataInputStream(cs.getInputStream());
out = new DataOutputStream(cs.getOutputStream());
this.receiveFile("./uploaded.txt");
in.close();
out.close();
cs.close();
ss.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
private void receiveFile(String path)
{
int bytes = 0;
try {
File file = new File(path);
file.createNewFile();
FileOutputStream output = new FileOutputStream(file);
long size = in.readLong();
byte[] buffer = new byte[1024];
int i = 0;
while(size>0 && (bytes = in.read(buffer, 0, (int)Math.min(buffer.length, size))) != -1)
{
System.out.println("\n -------------"+(++i));
for (byte b : buffer)
try
{
System.out.print((char)b);
}
catch(NullPointerException ex)
{
}
output.write(buffer, 0, bytes);
size -= bytes;
}
output.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
The problem was that I didn't check if the size were 0 on the client side.
That try catch should NOT be in the for loop !!!! It only needs single code use by wrapping. Also use counting metering conventionally the number of bytes with a conventional numeric "for" loop, Not for(byte b : buffer). Note: byte is not strictly numeric, it will only reach to 255 in the for counter! It depends the quantity bytes required iterated over and should be as many as are packaged to it over the connection.
In the read you need to obtain the number of bytes sent andmark that into the write length to take from the array, so it would be better to instantiate the array based on the number of bytes or maximum bytes the the client sender has sent or negotiated as the maximum allowed (see the api docs for the stream.
NB ObjectStream does not apply , it's for RMI)
Of counting into the byte[] buffer array, you should remove it from the method and put it as a global. In the method , instantiate a new "buffer" array on the global variable each iteration of the loop according to the number of bytes read as it's new length.
The code does not appear to be particularly safe or debugable. You might try carefully constructing it starting again from scratch.

Is it possible to randomly access specific index value in serialized array stored in a file in Java?

I am trying to access an array index position in a serialized array object file. I do not want to deserialize the whole array object and then access the array. I have been able to do it in C++ using seekg, but have not been successful in Java.
I have tried using the RandomAccessFile [please see the following code], but I am not able to access the specific location in array and convert it to the actual value [see code comment- //Random Access Reading (Read specific position)].
Let me know the solution for this problem.
Code-
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.RandomAccessFile;
import java.io.Serializable;
import java.util.Arrays;
class Bitmaps implements Serializable
{
int bitmapArray[] = new int[5];
#Override
public String toString() {
return "Bitmaps [bitmapArray=" + Arrays.toString(bitmapArray) + "]";
}
}
public class RandomAccess2 {
public static void main(String[] args) {
try {
Bitmaps bitmaps = new Bitmaps();
String filename = "blocksinfo.txt";
String workingDirectory = System.getProperty("user.dir");
String FILEPATH = workingDirectory + "\\" + filename; //C:\\Users\ashis\workspace\hackerrank1\src\hackerrank1\blocksinfo.txt';
//Initialize array with 100....104
int cnt=100;
for(int i=0;i<5;i++)
bitmaps.bitmapArray[i]=cnt++;
//Serialize array and store in a file
serializeObject(bitmaps, FILEPATH);
int objLength = sizeof(bitmaps); //function to calculate size of serialized array
System.out.println("Length in bytes after serialization=>"+objLength);
//System.out.println(new String(readFromFile(FILEPATH, 0, ewahBitmap1.sizeInBytes())));
try {
//Random Access Reading (Read all contents)
byte[] byteArray = readFromFile(FILEPATH, 0, objLength);
ByteArrayInputStream in = new ByteArrayInputStream(byteArray);
ObjectInputStream is = new ObjectInputStream(in);
Bitmaps bitmaps2 = (Bitmaps) is.readObject();
System.out.println("Full Random Access Reading=>"+bitmaps2);
//Random Access Reading (Read specific position)
byte[] byteArray1 = readFromFile(FILEPATH, 98, 2);
ByteArrayInputStream in1 = new ByteArrayInputStream(byteArray1);
ObjectInputStream is1 = new ObjectInputStream(in1);
int val = (int) is1.readObject();
System.out.println("Partial Random Access Reading=>"+val);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//writeToFile(FILEPATH, ewahBitmap1.toString(), 0);
} catch (IOException e) {
e.printStackTrace();
}
}
private static byte[] readFromFile(String filePath, int position, int size)
throws IOException {
RandomAccessFile file = new RandomAccessFile(filePath, "r");
file.seek(position);
byte[] bytes = new byte[size];
file.read(bytes);
file.close();
return bytes;
}
public static void serializeObject(Object bitmap, String fileName) throws IOException
{
FileOutputStream fos = new FileOutputStream(fileName);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(bitmap);
oos.close();
}
public static int sizeof(Object obj) throws IOException {
ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteOutputStream);
objectOutputStream.writeObject(obj);
objectOutputStream.flush();
objectOutputStream.close();
return byteOutputStream.toByteArray().length;
}
}
No, it isn't possible. It's not a random-access format. You have to deserialize the array and then in index it in memory.

Writing image in to a file [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 7 years ago.
I am trying to write an buffered image into a file that appends the next buffered image bytes.I have the following code for which some runtime exception is thrown. when i run this code i get the following exception. Why and what has to be changed?
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import javax.imageio.ImageIO;
public class FileT
{
public static void main(String[] args)
{
try {
BufferedImage originalImage = ImageIO.read(new File("ani.jpg"));
int i=0,c=0;
// convert BufferedImage to byte array
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(originalImage, "jpg", baos);
baos.flush();
byte[] imageInByte = baos.toByteArray();
byte[] copybuf = new byte[1024];
baos.close();
while(i<imageInByte.length)
{
copybuf[c]=imageInByte[i];
c++;
if(i%1023==0)
{
// convert byte array back to BufferedImage
InputStream in = new ByteArrayInputStream(copybuf);
BufferedImage bImageFromConvert = ImageIO.read(in);
ImageIO.write(bImageFromConvert, "jpg", new FileOutputStream(new File("ani1.jpg"),true));
}
copybuf = new byte[1024];
i++;
}
}
catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
Exception in thread "main" java.lang.IllegalArgumentException: image == null!
at javax.imageio.ImageTypeSpecifier.createFromRenderedImage(ImageTypeSpecifier.java:925)
at javax.imageio.ImageIO.getWriter(ImageIO.java:1592)
at javax.imageio.ImageIO.write(ImageIO.java:1578)
at FileT.main(FileT.java:45)
if(i%1023==0){
// convert byte array back to BufferedImage
InputStream in = new ByteArrayInputStream(copybuf);
BufferedImage bImageFromConvert = ImageIO.read(in);
ImageIO.write(bImageFromConvert, "jpg", new FileOutputStream(new File("ani1.jpg"),true));
}
copybuf = new byte[1024];
i++;
In this code you might want to change new FileOutputStream(new File()) to be casted to ImageOutputStream
It is very hard to determine from your question what you need, but I think this will fix it. If it doesn't just leave a comment and Ill try to fix it

Unable to change the encoding of a Shift_JIS to UTF-8 using java.nio

I am trying to read a file that is encoded using Shift_JIS and then convert it into UTF-8. When i use java.nio CharsetDecoder.decode it throws the following error. I am not able to pinpoint the actual cause of this issue.
java.nio.charset.UnmappableCharacterException: Input length = 2
java.nio.charset.UnmappableCharacterException: Input length = 2
at java.nio.charset.CoderResult.throwException(CoderResult.java:278)
at java.nio.charset.CharsetDecoder.decode(CharsetDecoder.java:798)
at CharacterSetConversionUtility.getString(CharacterSetConversionUtility.java:23)
at CharacterSetConversionUtility.convertBetweenEncodings(CharacterSetConversionUtility.java:39)
at CharacterSetConversionUtility.main(CharacterSetConversionUtility.java:94
Below is the code snippet
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.charset.CharsetDecoder;
import org.mozilla.universalchardet.UniversalDetector;
public class CharacterSetConversionUtility
{
public static String getString(String charSet, byte[] bytes) throws CharacterCodingException
{
ByteBuffer buffer = ByteBuffer.wrap(bytes);
Charset charset = Charset.forName(charSet);
CharsetDecoder decoder = charset.newDecoder();
CharBuffer output = decoder.decode(buffer);
return output.toString();
}
public static byte[] convertToEncoding(String charSet, String input) throws CharacterCodingException
{
CharBuffer buffer = CharBuffer.wrap(input);
Charset charset = Charset.forName(charSet);
CharsetEncoder encoder = charset.newEncoder();
ByteBuffer output = encoder.encode(buffer);
return output.array();
}
public static byte[] convertBetweenEncodings(byte[] originalBytes, String sourceCharSet, String destCharSet)
throws CharacterCodingException
{
String unicodeString = getString(sourceCharSet, originalBytes);
byte[] output = convertToEncoding(destCharSet, unicodeString);
return output;
}
/** Utility Method to detect character encoding in a byte stream **/
public static String getCharacterEncoding(String fileName){
byte[] buf = new byte[4096];
String encoding = null;
try {
java.io.FileInputStream fis = new java.io.FileInputStream(fileName);
// (1)
UniversalDetector detector = new UniversalDetector(null);
// (2)
int nread;
while ((nread = fis.read(buf)) > 0 && !detector.isDone()) {
detector.handleData(buf, 0, nread);
}
// (3)
detector.dataEnd();
// (4)
encoding = detector.getDetectedCharset();
if (encoding != null) {
System.out.println("Detected encoding = " + encoding);
} else {
System.out.println("No encoding detected.");
}
// (5)
detector.reset();
//
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return encoding;
}
public static void main(String[] args) {
Path path = Paths.get("E:/Encoding Issue/SJISFile");
try {
byte[] inputdata = Files.readAllBytes(path);
//Detect the character encoding of the input data
String inputCharEncoding = getCharacterEncoding("E:/Encoding Issue/SJISFile");
//Perform a character set conversion
byte[] outputdata =convertBetweenEncodings(inputdata,inputCharEncoding,"UTF-8");
FileOutputStream fos = new FileOutputStream("E:/Encoding Issue/convertedutf8.txt");
fos.write(outputdata);
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
So, I don't have a definitive answer to the cause of the failure you experienced, although I suspect it lies somewhere in the conversion between String/char[]/byte[].
That said, I'd like to offer a more simple and compact working solution to the problem at hand, which uses this method instead, i.e. the conversion functionality offered by the String class itself as opposed to using en/decoders.
This will work for the Shift_JIS charset or any other one. Also, nothing wrong with the use of UniversalDetector, but I omitted it for simplicity's sake and hard-coded the source character set instead. Finally this version is JavaSE 1.6 compatible.
Hope it helps :)
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
public class JapaneseCharsetTest {
public static final int CHAR_LENGTH_TO_READ = 8192;
public static void main(String[] args) {
JapaneseCharsetTest test = new JapaneseCharsetTest();
test.doIt();
}
public void doIt() {
InputStreamReader reader = null;
FileOutputStream fos = null;
try {
FileInputStream stream = new FileInputStream(new File("C:/Path/To/My/ShiftJISFile.txt"));
reader = new InputStreamReader(stream, Charset.forName("Shift_JIS"));
fos = new FileOutputStream("C:/Path/To/My/UTF8TargetFile.txt");
char[] inputdata = new char[CHAR_LENGTH_TO_READ];
int len = 0;
while ((len = reader.read(inputdata)) != -1) {
convert(len, inputdata, fos);
}
}
catch (IOException e) {
e.printStackTrace();
}
finally {
try {if (reader != null) reader.close();} catch (IOException ignored) {}
try {if (fos != null) fos.close();} catch (IOException ignored){}
}
}
private void convert(int len, char[] inputData, FileOutputStream fos) throws IOException {
char[] charsToWrite = inputData;
if (len < CHAR_LENGTH_TO_READ) {
// Last chunk of data - cut it to size
charsToWrite = new char[len];
CharBuffer.wrap(inputData).get(charsToWrite, 0, len);
}
// Convert initial charset (here Shift_JIS) to target (here UTF-8)
byte[] utf8 = new String(charsToWrite).getBytes("UTF-8");
fos.write(utf8);
}
}

Read mp3 binary data for visualization

In my previous post, I had a little trouble trying to read a mp3 file. Now I am able to do that and I want to be able to render the data from the mp3 with java swing. And it would be nice to play the mp3 and visualize at the same time.
I have the binary data (which I piped to the outputstream) but I don't know how to interpret the data.
Essentially, at around LINE57, what do I need to do with the byte array so I can interpret the data as db values?
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
public class MainSound {
public static void main(final String [] args) throws Exception {
System.out.println("Running");
System.out.println(System.getProperty("java.version"));
final AudioFileFormat.Type [] types = AudioSystem.getAudioFileTypes();
for (final AudioFileFormat.Type t : types) {
System.out.println("Returning Type : " + t);
} // End of the for //
final String PATH = "C:\\Users\\bbrown\\Downloads\\swing-hacks-examples-20060109\\Ch10-Audio\\75\\soundcloud2.mp3";
final File file = new File(PATH);
final AudioInputStream in = AudioSystem.getAudioInputStream(new BufferedInputStream(new FileInputStream(file)));
AudioInputStream din = null;
final AudioFormat baseFormat = in.getFormat();
final AudioFormat decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
baseFormat.getSampleRate(),
16,
baseFormat.getChannels(),
baseFormat.getChannels() * 2,
baseFormat.getSampleRate(),
false);
System.out.println("Channels : " + baseFormat.getChannels());
din = AudioSystem.getAudioInputStream(decodedFormat, in);
rawplay(decodedFormat, din);
in.close();
System.out.println("Done");
}
private static synchronized void rawplay(final AudioFormat targetFormat, final AudioInputStream din) throws IOException, LineUnavailableException {
final byte[] data = new byte[4096];
final SourceDataLine line = getLine(targetFormat);
if (line != null) {
System.out.println("Entering ...");
// Start
line.start();
int nBytesRead = 0, nBytesWritten = 0;
while (nBytesRead != -1) {
nBytesRead = din.read(data, 0, data.length);
if (nBytesRead != -1) {
// LINE57, HOW CAN INTERPRET this data for VISUALIZATION.
nBytesWritten = line.write(data, 0, nBytesRead);
System.out.println("... -->" + data[0] + " bytesWritten:" + nBytesWritten);
}
} // End of while //
System.out.println("Done ...");
// Stop
line.drain();
line.stop();
line.close();
din.close();
} // End of the if //
}
private static synchronized SourceDataLine getLine(AudioFormat audioFormat) throws LineUnavailableException {
SourceDataLine res = null;
final DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
res = (SourceDataLine) AudioSystem.getLine(info);
res.open(audioFormat);
return res;
}
} // End of the class //
Have a look at Extreme Media Player source code which is a cross Platform Media Player that supports visualizations, and of course written in Java.
A study of the code should help you understand how to read the decibels of the byte data being played. (I loved the question as I haven't seen this asked before).
As seen here:
UPDATE:
Its a pity Java does not natively support MP3 format, but have a look at this link showing us JMF (Java Media Framework) which is a plugin for j2SE which enables MP3 support, with help of extra MP3 Plugin for JMF.

Categories

Resources