My goal
I want to do the following in Java: record some sound made by Java itself, and then save it as a wav file.
I've searched for a lot of these kind of programs online, and I've found some good ones, but I get the same problem again and again (the current version can be found here). The problem is always something like this:
In the public class, the function start begins with
AudioFormat format = getAudioFormat();
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
if (!AudioSystem.isLineSupported(info)) {
System.out.println("Line not supported");
System.exit(0);
}
, where getAudioFormat() returns AudioFormat(16000,8,2,true,true). If I run the file, it prints Line not supported, but why?
What I've tried:
I've searched for loads of different formats online, and tried each of them.
I've taken an existing wav file which Java can play, taken the format of that one, and used it as the format for the file I try to create.
Some more information:
System.out.println(AudioSystem.getTargetLineInfo(info));
System.out.println(AudioSystem.getAudioFileTypes());
System.out.println(AudioSystem.getMixerInfo());
System.out.println(AudioSystem.getSourceDataLine(format));
where format is the format of the existing wav file, and info is defined as in the first code snippet, prints:
[Ljavax.sound.sampled.Line$Info;#4eec7777
[Ljavax.sound.sampled.AudioFileFormat$Type;#41629346
[Ljavax.sound.sampled.Mixer$Info;#6d311334
com.sun.media.sound.DirectAudioDevice$DirectSDL#448139f0
I use Windows 7, 64 bits.
I'd like to add that if there's a better, entirely different way to achieve my goal, that's fine too.
Related
My app encodes a PCM file to a m4a file using MediaMuxer, MediaFormat, and MediaCodec.
I read some code that sets things like this:
MediaFormat outputFormat = MediaFormat.createAudioFormat("audio/mp4a-latm", SampleRate, 1);
outputFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
outputFormat.setInteger(MediaFormat.KEY_BIT_RATE, 96000);
outputFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 16384);
I searched for MediaFormat.KEY_MAX_INPUT_SIZE, but it is not clear to me why it is necessary to be set. I've read that some Samsung devices crash without this, but I don't know if this is true.
Is it necessary/good/advisable to set this? If so, to which value(s)?
I'm writing a generalized utility for converting audio files to WAV. Works ok for WAV to WAV (I'm also changing some of the attributes), but I can't convert MP3 files. I have mp3spi in my classpath, so it seems to be able to read the MP3, but the WAV file that gets written doesn't seem to work.
In this example, I'm not trying to change any properties. Just reading the MP3 and writing to a WAV file
My code looks something like this
File inputFileObj = new File(input);
AudioInputStream audioInputStream = null;
try {
audioInputStream = AudioSystem.getAudioInputStream(inputFileObj);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Input file format:");
System.out.println(AudioSystem.getAudioFileFormat(inputFileObj));
try {
AudioSystem.write(audioInputStream, outputType, new File(output));
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Output file format:");
System.out.println(AudioSystem.getAudioFileFormat(new File(output)));
Here's the output. As you can see, it appears to write the output file, but when I try to retrieve the format of the output file, it can't handle it. And if I try to play the output file, the player doesn't recognize it.
Input file: c:\testfiles\sample-b-converted.mp3
Output file: c:\testfiles\foo.wav
Output type: wav
Input file format:
MP3 (.mp3) file, byte length: 13227300, data format: MPEG2L3 16000.0 Hz, unknown bits per sample, mono, unknown frame size, 27.777779 frames/second, , frame length: 122475
Bytes written: 13227344
Output file format:
Exception in thread "main" javax.sound.sampled.UnsupportedAudioFileException: file is not a supported file type
at javax.sound.sampled.AudioSystem.getAudioFileFormat(AudioSystem.java:1078)
at org.torchai.AudioFileConvert01.main(AudioFileConvert01.java:60)
Is there something else I need to get this working?
Someone posted a comment referring me to mp3 to wav conversion in java. I had seen this issue, but didn't quite see the main aspect of the answer, since it wasn't really explained well.
An MP3 file apparently needs to go through a 2-step conversion. I don't fully understand why, but it seems you must first convert it to PCM_SIGNED with a sample size of 16 and a framesize of 2*# of channels. At that point, you can convert it again to the final format that you want.
Would still love to have a better explanation, but this at least gets me past my issue.
I'm thinking about coding a Java applet that would take in the top 100 or so songs, find their samples (music that appears within the songs) off WhoSampled.com and then playing those samples off of YouTube.
My problem is the playing part, let's say I have the URL. What's the best way to deal with that in Java, do you think ripping the audio off and playing the audio from there would be best, or should I try to control a sentient YouTube player.
I'm leaning towards extracting the audio, and this: thread mentions a way to extract that audio, however the code:
wget http://www.youtube.com/get_video.php?video_id=...
ffmpeg -i - audio.mp3
Is not written in Java. How do I, if possible convert this to run in a Java program? Or does anyone know a good way in Java
Thank you for your suggestions.
You can use an FFMPEG Java wrapper like this one https://github.com/bramp/ffmpeg-cli-wrapper/
An example can be found in Readme. Converting MP4 to mp3 should be like this:
FFmpeg ffmpeg = new FFmpeg("/path/to/ffmpeg");
FFprobe ffprobe = new FFprobe("/path/to/ffprobe");
FFmpegBuilder builder = new FFmpegBuilder()
.setInput("input.mp4") // Filename, or a FFmpegProbeResult
.overrideOutputFiles(true) // Override the output if it exists
.addOutput("output.mp3") // Filename for the destination
.setFormat("mp3") // Format is inferred from filename, or can be set
.setAudioCodec("aac") // using the aac codec
.setAudioSampleRate(48_000) // at 48KHz
.setAudioBitRate(32768) // at 32 kbit/s
.done();
FFmpegExecutor executor = new FFmpegExecutor(ffmpeg, ffprobe);
// Run a one-pass encode
executor.createJob(builder).run();
I have a simple JUnit test which checks two files have the same content. It works perfectly fine in my Unix laptop.
Here it is the test:
boolean response = false;
try {
File got = File.createTempFile("got-", ".csv");
String outputPath = got.getAbsolutePath();
testedObject.createCsvFile(outputPath);
got = new File(outputPath);
String expectedFilePath = getClass().getClassLoader().getResource("expected.csv").getFile();
File expected = new File(expectedFilePath);
response = FileUtils.contentEquals(got, expected); // Here it is the key
} catch (IOException e) {
// Nothing to do Yay!
}
Assert.assertTrue(response);
It works because if I compare both files manually, example via diff command, are exactly the same. Now.
My teem-mate codes with a Windows laptop, when he ran the test it brokes down! and we started debugging.
Visually, both files are the same; I mean in a human revision you cannot realize any difference. But If in a Cwin terminal we executed:
diff expected.csv got.csv and windows thought each line was different
And the test falls.
What is the problem, is the operative system? If that is true, Is there any way to compare file content not dependent on operative system
My guess is that this is most likely this is due to the \n value, which in unix like software is \r\n.
Anyway, the correct way to see if two files have the same content, is to hash both of them (ie via sha1) and check if the hashes matches!
This behaviour can be attributed to the Line Feed being different on both operating systems.
If you want it to be platform independent , you should pick up the value from the runtime using
System.getProperty("line.separator");
Also you might want to have a look at the char encoding for both the files
This answer can help you: Java Apache FileUtils readFileToString and writeStringToFile problems. The question's author is talking about PDF file, but this answer makes sense for your question.
I'm working on a microcontroller and I'm trying to write some data from some sensors into a .txt file on the SDcard and later on place the sd card in a card reader and read the data on the PC.
Does anyone know how to write a .txt file from scratch for a FAT32 file system? I don't have any predefined code/methods/functions to call, I'll need to create the code from nothin.
It's not a question for a specific programming language, that is why I tagged more than one. I can later on convert the code from C or Java to my programming language of choice. But I can't seem to find such low level methods/functions in any type of language :)
Any ideas?
FatFs is quite good, and highly portable. It has support for FAT12, FAT16 and FAT32, long filenames, seeking, reading and writing (most of these things can be switched on and off to change the memory footprint).
If you're really tight on memory there's also Petit FatFs, but it doesn't have write support by default and adding it would take some work.
After mounting the drive you'd simply open a file to create it. For example:
FATFS fatFs;
FIL newFile;
// The drive number may differ
if (f_mount(0, &fatFs) != FR_OK) {
// Something went wrong
}
if (f_open(&newFile, "/test.txt", FA_WRITE | FA_OPEN_ALWAYS) != FR_OK) {
// Something went wrong
}
If you really need to create the file using only your own code you'll have to traverse the FAT, looking for empty space and then creating new LFN entries (where you store the filename) and DIRENTs (which specify the clusters on the disk that will hold the file data).I can't see any reason for doing this except if this is some kind of homework / lab exercise. In any case you should do some reading about the FAT structure first and return with some more specific questions once you've got started.
In JAVA you can do like this
Writer output = null;
String text = "This is test message";
File file = new File("write.txt");
output = new BufferedWriter(new FileWriter(file));
output.write(text);
output.close();
System.out.println("Your file has been written");