Error: unsupported audio format while converting .wav to double[] - java

I'm trying to convert a file with a .wav extension to a double array but I am getting an error:
09-15 05:09:47.222 22358-22358/com.R1100.bluetooth D/R1100Err: unsupported audio format: '/storage/emulated/0/HeartSounds/a0002.wav'
The file really is a .wav but I have no idea why this happens.
Here is the method I used:
public static double[] read(String filename) {
byte[] data = readByte(filename);
int n = data.length;
double[] d = new double[n/2];
for (int i = 0; i < n/2; i++) {
d[i] = ((short) (((data[2*i+1] & 0xFF) << 8) + (data[2*i] & 0xFF))) / ((double) MAX_16_BIT);
}
return d;
}
// return data as a byte array
private static byte[] readByte(String filename) {
byte[] data = null;
AudioInputStream ais = null;
try {
// try to read from file
File file = new File(filename);
if (file.exists()) {
ais = AudioSystem.getAudioInputStream(file);
int bytesToRead = ais.available();
data = new byte[bytesToRead];
int bytesRead = ais.read(data);
if (bytesToRead != bytesRead)
throw new IllegalStateException("read only " + bytesRead + " of " + bytesToRead + " bytes");
}
// try to read from URL
else {
URL url = Wav.class.getResource(filename);
ais = AudioSystem.getAudioInputStream(url);
int bytesToRead = ais.available();
data = new byte[bytesToRead];
int bytesRead = ais.read(data);
if (bytesToRead != bytesRead)
throw new IllegalStateException("read only " + bytesRead + " of " + bytesToRead + " bytes");
}
}
catch (IOException e) {
throw new IllegalArgumentException("could not read '" + filename + "'", e);
}
catch (UnsupportedAudioFileException e) {
throw new IllegalArgumentException("unsupported audio format: '" + filename + "'", e);
}
return data;
}
Thanks.

Related

Split wav files based on Silence in Java

I want to split wav files in to number of waves files, each of them
is split
by silence between words, I tried to code a bit. I managed to split the files
But things got complex when trying to dedect silence.. any help?
Thanks
Splits WAV-files in multiple parts. This class splits a big WAV-file in
multiple WAV-file, each with a fixed length (SPLIT_FILE_LENGTH_MS). It
takes
it input file from an embedded resource, and writes a series of out*.wav files.
heres my code so far:
public class WaveSplitter {
public static int SPLIT_FILE_LENGTH_MS = 0;
public static final String INPUT_FILE_LOCATION = "resources/AUD-20171027-WA0001.wav";
public static void main(String[] args) {
try {
// Get the wave file from the embedded resources
URL defaultImage =
WaveSplitter.class.getResource(INPUT_FILE_LOCATION);
// GSpeechDuplex duplex = new
// GSpeechDuplex("AIzaSyDHQsnCHDk71x-Dpp05IIK3tYNOEP84z1s");
// duplex.setLanguage("heb");
File audioFile = new File(defaultImage.toURI());
File soundFile = new File(defaultImage.toURI());
FileInputStream fileInputStream = null;
long duration = 0;
try {
fileInputStream = new FileInputStream(soundFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
duration =
Objects.requireNonNull(fileInputStream).getChannel().size() / 128;
} catch (IOException e) {
}
AudioInputStream stream;
WavFile wavFile = WavFile.openWavFile(new File(defaultImage.toURI()));
AudioInputStream audioInputStream =
AudioSystem.getAudioInputStream(soundFile);
AudioFormat format = audioInputStream.getFormat();
long frames = audioInputStream.getFrameLength();
double durationInSeconds = (frames + 0.0) / format.getFrameRate();
System.out.println("Duration " + durationInSeconds + " seconds \n");
durationInSeconds = durationInSeconds * 1000;
SPLIT_FILE_LENGTH_MS = (int) durationInSeconds;
// wavFile.display();
// Get the number of audio channels in the wav file
int numberChannels = wavFile.getNumChannels();
System.out.println("number channels is " + numberChannels);
System.out.println("SPLIT_FILE_LENGTH_MS is " + SPLIT_FILE_LENGTH_MS);
int framesRead;
double min = Double.MAX_VALUE;
double max = Double.MIN_VALUE;
byte[] bytes = FileUtils.readFileToByteArray(soundFile);
// String encoded = Base64.encodeToString(bytes, 0);
// playSoundFile(soundFile);
WavFile inputWavFile = WavFile.openWavFile(soundFile);
// File audioFile = new File("AUD-20171027-WA0001.wav");
// sendToGoogleViaOnvegoServer(myByteData);
/// System.out.println("Seneteces:\n " + bytes);
// Get the number of audio channels in the wav file
int numChannels = inputWavFile.getNumChannels();
// set the maximum number of frames for a target file,
// based on the number of milliseconds assigned for each file
int maxFramesPerFile = (int) inputWavFile.getSampleRate() *
SPLIT_FILE_LENGTH_MS / 1000;
System.out.println("maxFramesPerFile is " + maxFramesPerFile + "\n");
// Create a buffer of maxFramesPerFile frames
double[] buffer = new double[maxFramesPerFile * numChannels];
// sendToGoogleViaOnvegoServer(myByteData);
framesRead = inputWavFile.readFrames(buffer, maxFramesPerFile);
// System.out.print(buffer.length);
int fileCount = 0;
int s = 0;
int j = 0;
int timercount = 0;
int audiorecord = 0;
int count = 0;
// SPLIT_FILE_LENGTH_MS = 0;
double maxlengh = framesRead * numChannels;
System.out.print("Audio Duration " + maxFramesPerFile + "\n");
int arraylengh = framesRead * numChannels;
System.out.print("frame*channels " + framesRead * numChannels);
///loop to find silent places
do {
// Read frames into buffer
framesRead = inputWavFile.readFrames(buffer, maxFramesPerFile);
// System.out.print(framesRead);
for (s = 0; s < arraylengh; s++) {
if (buffer[s] == 0) {
// System.out.print(s + ", " + buffer[s] + "\n");
count++;
timercount++;
}
else {
for (j = s; j < arraylengh; j++) {
if (buffer[j] != 0)
{
} else {
SPLIT_FILE_LENGTH_MS = 1500;
maxFramesPerFile = (int)
inputWavFile.getSampleRate() * SPLIT_FILE_LENGTH_MS /
1000;
framesRead = inputWavFile.readFrames(buffer,
maxFramesPerFile);
// framesRead = inputWavFile.readFrames(buffer,
maxFramesPerFile);
WavFile outputWavFile = WavFile.newWavFile(new
File("out" + (fileCount + 1) + ".wav"),
inputWavFile.getNumChannels(), framesRead,
inputWavFile.getValidBits(),
inputWavFile.getSampleRate());
// Write the buffer
outputWavFile.writeFrames(buffer, framesRead);
outputWavFile.close();
return;
}
}
}
// System.out.print(maxFramesPerFile);
}
// SPLIT_FILE_LENGTH_MS=1000;
maxFramesPerFile = (int) inputWavFile.getSampleRate() *
SPLIT_FILE_LENGTH_MS / 1000;
framesRead = inputWavFile.readFrames(buffer, maxFramesPerFile);
WavFile outputWavFile = WavFile.newWavFile(new File("out" + (
fileCount + 1) + ".wav"),
inputWavFile.getNumChannels(), framesRead,
inputWavFile.getValidBits(),
inputWavFile.getSampleRate());
// Write the buffer
outputWavFile.writeFrames(buffer, framesRead);
outputWavFile.close();
fileCount++;
// System.out.print(fileCount);
} while (framesRead != 0);
System.out.print(count + "\n");
System.out.print(fileCount);
//catch error
} catch (Exception e) {
System.err.println(e);
}
}
// Play sound function
public static void playSoundFile(File soundFile)
throws UnsupportedAudioFileException, IOException, LineUnavailableException {
try {
final Clip clip = (Clip) AudioSystem.getLine(new Info(Clip.class));
clip.removeLineListener(new LineListener() {
#Override
public void update(LineEvent event) {
if (event.getType() == LineEvent.Type.STOP)
clip.close();
}
});
clip.open(AudioSystem.getAudioInputStream(soundFile));
clip.start();
} catch (Exception exc) {
exc.printStackTrace(System.out);
}
}
}

Strange behavior in GZIPOutputStream/GZIPInputStream

I have reduced the strange issue in this code to the minimum. This program writes 128,000 times the bytes for (int)90000 into a file and then tries to read it back in.
set zipped=false and everything works like a charm
set zipped=true and everything works like a charm until the 496th chunk of 1024 bytes. At that point a single byte is lost and everything is shifted to the left by one byte (see output)
...
0 1 95 -112- which is byte code for int 90,000
Counters: 496 126937
1 95 -112 0- which is byte code for int 23,040,000
...
this is the code i came up with. I just can't figure out why it suddenly breaks in the middle of doing the same thing over and over. Any help/insights/explainers much appreciated.
public class TestApp7 {
static final boolean zipped = true;
static File theFile = null;
private static void writeZipData() throws Exception {
FileOutputStream fos = new FileOutputStream(theFile);
BufferedOutputStream bos = null;
if (zipped) {
GZIPOutputStream gzout = new GZIPOutputStream(fos);
bos = new BufferedOutputStream(gzout);
} else
bos = new BufferedOutputStream(fos);
byte[] bs9 = RHUtilities.toByteArray((int)90000);
for (int i=0; i<128000; i++)
bos.write(bs9);
bos.flush();
bos.close();
}
private static void readZipData() throws Exception {
byte[] buf = new byte[1024];
int chunkCounter = 0;
int intCounter = 0;
FileInputStream fin = new FileInputStream(theFile);
int rdLen = 0;
if (zipped) {
GZIPInputStream gin = new GZIPInputStream(fin);
while ((rdLen = gin.read(buf)) != -1) {
System.out.println("Counters: " + chunkCounter + " " + intCounter);
for (int i=0; i<rdLen/4; i++) {
byte[] bs = Arrays.copyOfRange(buf,(i*4),((i+1)*4));
intCounter++;
System.out.print(bs[0] + " " + bs[1] + " " + bs[2] + " " + bs[3]);
}
chunkCounter++;
}
gin.close();
} else {
while ((rdLen = fin.read(buf)) != -1) {
System.out.println("Counters: " + chunkCounter + " " + intCounter);
for (int i=0; i<rdLen/4; i++) {
byte[] bs = Arrays.copyOfRange(buf,(i*4),((i+1)*4));
intCounter++;
System.out.print(bs[0] + " " + bs[1] + " " + bs[2] + " " + bs[3]);
}
chunkCounter++;
}
}
fin.close();
}
public static void main(String args[]) {
try {
if (zipped)
theFile = new File("Test.gz");
else
theFile = new File("Test.dat");
writeZipData();
readZipData();
} catch (Throwable e) { e.printStackTrace(); }
}
}
So based on Jon's wonderful comments ... you cannot rely on .read(buffer) filling the buffer even when there are more bytes in the stream - it stops at the boundary where the BufferedOutputStream-wrapped GZIPOutputStream saved a chunk of data. just add another read to go beyond the boundary and complete the chunk
while ((rdLen = gin.read(buf)) != -1) {
if (rdLen<chunksize) {
byte[] missBytes = new byte[chunksize-rdLen];
int rdLine_miss = 0;
if ((rdLine_miss = gin.read(missBytes)) > 0)
System.arraycopy(missBytes,0,buf,rdLen,rdLine_miss);
rdLen += rdLine_miss;
}
for (int i=0; i<rdLen/4; i++) {
byte[] bs = Arrays.copyOfRange(buf,(i*4),((i+1)*4));
intCounter++;
System.out.println(bs[0] + " " + bs[1] + " " + bs[2] + " " + bs[3] + " ");
}
chunkCounter++;
}

How to export all files and folders in resources folder in java

How in java code do i copy everything from src/main/resources directory inside of the jar file into the same directory of the jar file?
This is what i found from org.bukkit.plugin.java.JavaPlugin and it seems to work
public void saveResource(String resourcePath, boolean replace) {
if (resourcePath == null || resourcePath.equals("")) {
throw new IllegalArgumentException("ResourcePath cannot be null or empty");
}
resourcePath = resourcePath.replace('\\', '/');
InputStream in = getResource(resourcePath);
if (in == null) {
throw new IllegalArgumentException("The embedded resource '" + resourcePath + "' cannot be found");
}
File outFile = new File(dataFolder, resourcePath);
int lastIndex = resourcePath.lastIndexOf('/');
File outDir = new File(dataFolder, resourcePath.substring(0, lastIndex >= 0 ? lastIndex : 0));
if (!outDir.exists()) {
outDir.mkdirs();
}
try {
if (!outFile.exists() || replace) {
OutputStream out = new FileOutputStream(outFile);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
out.close();
in.close();
} else {
logger.log(Level.WARNING, "Could not save " + outFile.getName() + " to " + outFile + " because "
+ outFile.getName() + " already exists.");
}
} catch (IOException ex) {
logger.log(Level.SEVERE, "Could not save " + outFile.getName() + " to " + outFile, ex);
}
}

Handle specific byte from socket in Java

I'm using the code below to read a Unix socket:
Boolean flag = false;
while (!flag) {
try {
File socketFile = new File("./RISP");
AFUNIXSocket sock = AFUNIXSocket.newInstance();
sock.connect(new AFUNIXSocketAddress(socketFile));
System.out.println("!!!!!!!!!!CONNECTED!!!!!!!!!");
flag = true;
BufferedReader input = new BufferedReader(new InputStreamReader(sock.getInputStream()));
String line = null;
while ((line = input.readLine())!=null) {
System.out.println(line);
}
} catch (IOException e) {
System.out.println("NOT CONNECTED....." + e);
}
try {
Thread.sleep(2000);
} catch (InterruptedException inter) {
System.out.println(inter);
}
}
I need to read the first 4 bytes of each pack and convert them from binary to integer.
I've read many posts but I'm still looking for the best solution to my problem.
Reader and Writer are designed for reading text.
For binary, you should try InputStream and OutputStream, in this case, you want DataInputStream, possibly buffered.
DataInputStream in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
int len = in.readInt(); // read big-endian.
if (LITTLE_ENDIAN)
len = Integer.reverseBytes(len);
byte[] bytes = new byte[len];
in.readFully(bytes);
seems it works
DataInputStream in = new DataInputStream(new BufferedInputStream(sock.getInputStream()));
int len = -1;
while ((len = in.readInt()) != -1) {
len = Integer.reverseBytes(len);
byte[] bytes = new byte[len];
in.readFully(bytes);
if (bytes.length > 4) {
System.out.println(" BYTE0: " + bytes[0] +
" BYTE1: " + bytes[1] +
" BYTE2: " + bytes[2] +
" BYTE2: " + bytes[3] +
" LENGHT: " + bytes.length);
}
}
please let me know is i miss something.
thanks a lot to you guys.

Stream closed showing up in play framework 1.2.5

i have an application that want to write a file using fileoutputstream
here's the code, method patch
public static Response patch() {
try {
System.out.println("PATCH");
System.out.println(request.contentType);
String file = params.get("filename");
System.out.println("patch file: " + file);
Map<String, Header> MapOffset = request.headers;
for (Entry<String, Header> entry : MapOffset.entrySet()) {
System.out.println("Header['" + entry.getKey() + "]: "
+ entry.getValue().value());
}
Header offsetParam = MapOffset.get("offset");
Long offset = 0L;
if (offsetParam != null) {
offset = Long.parseLong(offsetParam.value());
}
InputStream input = request.body;
File f = new File(UPLOAD_DIR + System.getProperty("file.separator")
+ file);
System.out.println("address: " + f.getAbsolutePath());
System.out.println("offset: " + offset);
System.out.println("length: " + f.length());
fileBasicUpload(f, offset, input);
Response respon = new Response();
respon.status = OK;
return respon;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
and this is where i write a file
private static void fileBasicUpload(File f, Long offset, InputStream input)
throws IOException {
FileOutputStream output = null;
try {
int c = -1;
byte[] b = new byte[1024];
try {
output = new FileOutputStream(f, true);
while ((c = input.read(b)) != -1) {
output.write(b, 0, c);
}
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
} finally {
output.close();
}
}
but when my application called, then stream closed error is show up at while ((c = input.read(b)) != -1) that line.
i don't know how that error is called. sorry for my poor english and thanks
i found the answer. in my application i found like this
public static Response upload(File file){
System.out.println("Appliaction.upload");
response = ResumableUpload.post();
return response;
// render(response);
}
the parameter file, it must be delete, then it work!

Categories

Resources