How can I convert a wav file in java
AudioFormat targetFormat = new AudioFormat(
sourceFormat.getEncoding(),
fTargetFrameRate,
16,
sourceFormat.getChannels(),
sourceFormat.getFrameSize(),
fTargetFrameRate,
false);
in result Exception :
java.lang.IllegalArgumentException: Unsupported conversion:
ULAW 8000.0 Hz, **16 bit**, mono, 1 bytes/frame, **from** ULAW 8000.0 Hz, **8 bit**, mono, 1 bytes/frame
it is possible in java?
I need get wav file 16 bit, from 8
Here is a method that will convert an 8-bit uLaw encoded binary file into a 16-bit WAV file using built-in Java methods.
public static void convertULawFileToWav(String filename) {
File file = new File(filename);
if (!file.exists())
return;
try {
long fileSize = file.length();
int frameSize = 160;
long numFrames = fileSize / frameSize;
AudioFormat audioFormat = new AudioFormat(Encoding.ULAW, 8000, 8, 1, frameSize, 50, true);
AudioInputStream audioInputStream = new AudioInputStream(new FileInputStream(file), audioFormat, numFrames);
AudioSystem.write(audioInputStream, Type.WAVE, new File("C:\\file.wav"));
} catch (IOException e) {
e.printStackTrace();
}
}
Look at this one: Conversion of Audio Format it is similar to your issue suggesting looking at http://docs.oracle.com/javase/6/docs/api/javax/sound/sampled/AudioSystem.html
You can always use FFMPEG, http://ffmpeg.org/, to do the conversion. Your Java program can call FFMPEG to do the conversion.
FFMPEG works on all OS.
Related
I've confirmed my program "works" with a variety of signed integer output formats. However, when I attempt to use 32-bit floating point, the output audio metadata indicates it to be 32-bit signed integer, and this results in broken playback.
Here's my audio format:
AudioFormat audioFormat = new AudioFormat(AudioFormat.Encoding.PCM_FLOAT,
48000, // Hz sample rate
32, // bits per sample
2, // channels
8, // bytes per frame
48000, // Hz frame rate
false), // not big-endian
This is sent to a processor function (which I've confirmed "works" using other output formats):
public void mixToFile(AudioFormat format,
String outputPath,
int totalFrames) throws Exception {
ByteBuffer outputBytes = byteBufferOf(mix()); // the big show
AudioInputStream ais = new AudioInputStream(
new ByteArrayInputStream(outputBytes.array()), outputFormat,
totalFrames
);
AudioSystem.write(ais, AudioFileFormat.Type.WAVE, new File(outputPath));
}
The result is failure; the file has metadata format 32-bit signed int, see:
Playing WAVE '/tmp/output.wav' : Signed 32 bit Little Endian, Rate 48000 Hz, Stereo
I'm looking for the equivalent of How to write wav file with 32-bit float data?
which I've dealt with before, manually setting the wFormat tag in the 'fmt' chunk to WAVE_FORMAT_IEEE_FLOAT (3) when writing a RIFF container.
Is it possible to achieve this using AudioSystem.write, AudioInputStream and AudioFormat?
Trying to get the frame size of an audio file I am getting instead -1. I tried to look for the interpretation of of this result in the JavaDoc but it does not mention anything big. Here's the source code :
import javazoom.spi.mpeg.sampled.file.MpegAudioFileReader;
/*....*/
File file = new File("/home/songs/audio.mp3");
MpegAudioFileReader mpegAudioFileReader = new MpegAudioFileReader();
AudioInputStream audioInputStream = mpegAudioFileReader.getAudioInputStream(file);
AudioFormat format = audioInputStream.getFormat();
long frameSize = format.getFrameSize();//frameSize = -1
float frameRate = format.getFrameRate();//frameRate = 38.28125
Inspecting he format object gives this : MPEG1L3 44100.0 Hz, unknown bits per sample, stereo, unknown frame size, 38.28125 frames/second,
I do not know why the frame size is unknown although it does appear on my audio file properties :
Any help is more than appreciated. Thanks.
getFormat() etc is implemented by the MPEG guys so it returns what they have - probably they left this blank or unable to extract;
If you put another .wav file you will probably get 2:
try {
audioInputStream=AudioSystem.getAudioInputStream(new File(".......wav"));
System.out.println(audioInputStream.getFormat().getFrameSize());
} catch (Exception e) {
e.printStackTrace();
}
Other notes: I dont see the Frame size in your display; it's rather the sample/bit rate so be sure to differentiate about that.
But for mp3 you have to live with that.
You can also create your own format if that helps - dont know your application
AudioFormat format = audioInputStream.getFormat();
newFormat=new AudioFormat(
AudioFormat.Encoding.PCM_SIGNED,
format.getSampleRate(),
16,
format.getChannels(),
format.getChannels() * 2,
format.getSampleRate(),
false);
I would like to extract byte array from a given mp3 file in order to apply fast fourier transform on the latter. The performed FFT will give me some features for my pet-project musical -- recommendation system.
I have written the following code to extract the bytes from a given mp3 file:
public class TrackSample {
private static byte[] readBytesInPredefinedFormat(TargetDataLine format, InputStream inStream) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = inStream.read(buffer)) > 0) {
int count = format.read(buffer, 0, buffer.length);
if (count > 0) {
byteArrayOutputStream.write(buffer, 0, count);
}
byteArrayOutputStream.write(buffer, 0, bytesRead);
}
byte[] bytes = byteArrayOutputStream.toByteArray();
byteArrayOutputStream.close();
inStream.close();
return bytes;
}
public static byte[] getTrackBytes(String pathToTrackSample) throws IOException, LineUnavailableException {
FileInputStream fileInputStream = new FileInputStream(pathToTrackSample);
final AudioFormat format = CurrentAudioFormat.getAudioFormat(); //Fill AudioFormat with the wanted settings
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
TargetDataLine line = (TargetDataLine) AudioSystem.getLine(info);
line.open(format);
line.start();
return readBytesInPredefinedFormat(line, fileInputStream);
}
}
And the specified audio format is
public class CurrentAudioFormat {
public static AudioFormat getAudioFormat(){
float sampleRate = 44100;
int sampleSizeInBits = 8;
int channels = 1; //mono
boolean signed = true;
boolean bigEndian = true;
return new AudioFormat(sampleRate, sampleSizeInBits, channels, signed, bigEndian);
}
}
I tried to test this code on the following mp3 file:
File type ID: MPG3
Num Tracks: 1
----
Data format: 2 ch, 44100 Hz, '.mp3' (0x00000000) 0 bits/channel, 0 bytes/packet, 1152 frames/packet, 0 bytes/frame
no channel layout.
estimated duration: 104.176325 sec
audio bytes: 4167053
audio packets: 3988
bit rate: 320000 bits per second
packet size upper bound: 1052
maximum packet size: 1045
audio data file offset: 3169
optimized
audio 4591692 valid frames + 576 priming + 1908 remainder = 4594176
The system characteristics are:
processor: Intel core i5, 1.4 GHz;
RAM: DDR3, 4Gb
OS: Mac OS X El Captain
It took roughly 5 minutes to extract the byte array from this mp3 file.
What are the possible bottlenecks and how can I improve them?
To read the bytes you just need
while ((bytesRead = inStream.read(buffer)) > -1) {
byteArrayOutputStream.write(buffer, 0, bytesRead);
}
I dont know why you are reading twice.
To make sure that what you got is right try to resave it to a new audio file.
--
The standard way to read the audio file is
AudioInputStream audioInputStream=null;
try {
audioInputStream=AudioSystem.getAudioInputStream(new File(file));
}
catch(UnsupportedAudioFileException auf) { auf.printStackTrace(); }
then you pass this audioInputStream to your reading method.
I am using JDK7 and trying to run a wav file - I tried the following test but got the error copied below:
Error:
line with format ULAW 8000.0 Hz, 8 bit, mono, 1 bytes/frame, not supported.
Sample Code:
import javax.sound.sampled.*;
try {
Clip clip = AudioSystem.getClip();
AudioInputStream inputStream = AudioSystem.getAudioInputStream(
new File("C://Users//xyz//Desktop//centerClosed.wav"));
clip.open(inputStream);
clip.start();
} catch (Exception e) {
System.err.println(e.getMessage());
}
Any ideas on how I go about handling this case? Thanks in advance
Your wav file seems to be in ULAW format, sampled at 8kHz, a format the clip apparently does not understand.
Try converting the audio to 44.1kHz PCM like this:
import javax.sound.sampled.*;
try {
Clip clip = AudioSystem.getClip();
AudioInputStream ulawIn = AudioSystem.getAudioInputStream(
new File("C://Users//xyz//Desktop//centerClosed.wav"));
// define a target AudioFormat that is likely to be supported by your audio hardware,
// i.e. 44.1kHz sampling rate and 16 bit samples.
AudioInputStream pcmIn = AudioSystem.getAudioInputStream(
new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100f, 16, 1, 2, 44100f, true)
ulawIn);
clip.open(pcmIn);
clip.start();
} catch (Exception e) {
System.err.println(e.getMessage());
}
i am using tritonous package for audio encoding in ogg-vorbis. I face a problem when i am giving the audio format.
Unsupported conversion: VORBIS 44100.0Hz, unknown bits per sample, mono, unknown frame size, from PCM_SIGNED 44100.0 Hz, 16 bit, mono, 2 bytes/frame, little-endian
This is my code where i am specifying the format
File outputFile = new File(userDir+"//San"+"_"+strFilename + ".spx");
// Using PCM 44.1 kHz, 16 bit signed,stereo.
if(osName.indexOf("win") >= 0){
System.out.println("windows");
audioFormat = getWindowsAudioFormat();
sampleRate = 44100.0F;
}else {
System.out.println("mac");
audioFormat = getMacAudioFormat();
sampleRate = 44100.0F;
}
AudioFormat vorbisFormat = new AudioFormat(VORBIS,
sampleRate,
AudioSystem.NOT_SPECIFIED,
1,
AudioSystem.NOT_SPECIFIED,
AudioSystem.NOT_SPECIFIED,
false);
DataLine.Info info = new DataLine.Info(TargetDataLine.class, audioFormat);
TargetDataLine targetDataLine = null;
AudioFileFormat.Type fileType = null;
File audioFile = null;
fileType = VORBIS;
try
{
targetDataLine = (TargetDataLine) AudioSystem.getLine(info);
targetDataLine.open(audioFormat);
}
catch (LineUnavailableException e)
{
System.out.println("unable to get a recording line");
e.printStackTrace();
System.exit(1);
}
AudioInputStream ais = new AudioInputStream(targetDataLine);
ais = AudioSystem.getAudioInputStream(vorbisFormat, ais);
final Recorder recorder = new Recorder(targetDataLine,ais,fileType,outputFile);
int number = 0;
System.out.println("Recording...");
recorder.start();
I wrote a utility class to encode OGG Vorbis audio files from Java, using the xiph Java ports of libogg and libvorbis.
https://github.com/xjmusic/java-vorbis-encoder/blob/master/VorbisEncoder.java