Detecting Audio File Bit Rate - Processing / Java - java

Trying to build a little app for sorting through audio files based on some of their properties. Have managed to grab the Sample Rate and Bit Depth using Minim but can't find anything anywhere for getting the Bit Rate?
Happy to look at taking the program to Javascript if needed but just desperate to find a method for detecting bit rate of a given file.
EDIT: Attempted to try and form an equation based off file size but cannot find a method for detecting MP3 file size either.

You can use jaudiotagger
You will need to download the jar, I managed to get it from maven central
Go to Sketch -> Add File... and select the downloaded jar, it should be added in a folder named code within your sketch folder.
Assuming you have placed an mp3 file in your data folder named audio.mp3 the following code should work, printing out the bit rate in the terminal.
import org.jaudiotagger.audio.mp3.*;
import org.jaudiotagger.audio.AudioFileIO;
void setup() {
File f = new File(dataPath("audio.mp3"));
try {
MP3File mp3 = (MP3File) AudioFileIO.read(f);
MP3AudioHeader audioHeader = mp3.getMP3AudioHeader();
println("" + audioHeader.getBitRate());
}
catch(Exception e) {
e.printStackTrace();
}
}
JAudiotagger supports a variety of file formats and you can use the relevant classes and methods for each one of these.
I suggest you take a look at the javadoc. Be careful of the examples though, the one I used in order to answer your question seems to be faulty, as you can see I had to swap getAudioHeader with getMP3AudioHeader.

Related

Implementing Microsoft.CognitiveServices.Speech recognition for several files

I have gotten the coding example from here to work.
I can run a .wav file through and get the transcript, however in the example the program never ends until I hit a key:
System.out.println("Press any key to stop");
new Scanner(System.in).nextLine();
That seems to artificially pause everything while the service is being queried.
If I remove those that line, the program jumps through to fast and concludes without waiting for the service to respond.
Question: How do I resume/continue the program with the full transcription without needing to hit a key?
I would like to run this for multiple .wav files transcribing each one after the other. But so far it runs the first one then waits.
I have been scouring the documentation and I have tried multiple things including using recognizer.close(); which I would expect to end the SpeechRecognizer but which seems to do nothing.
Or using result = recognizer.recognizeOnceAsync().get(); which does not transcribe the full file.
Does anyone know of an example of this running multiple files or how to implement that?
Thanks.
You can create a function that will read and return the list of files in your directory:
private static String[] GetFiles(String directory)
{
String[] files = (new File(directory)).list(File::isFile);
return files;
}
Then loop through them to process them, and then transcribe them.
String[] files = GetFiles(args[0]);
for (String file : files)
{
//Your code goes here.
System.out.printf("File %1$s processed" + "\r\n",file);//print out which file has been successfully processed.
}
You could also try using the Batch Transcription feature!
Batch transcription is ideal if you have large amounts of audio in
storage.

Platform independent way to open arbitrary files in the default text editor

I am trying to figure out if there is any platform independent way to open a text file with the default text editor even if the file doesn't end in .txt. I tried following code but it throws exception for files not having .txt extension. Works perfectly fine for .txt files.
Desktop dt = Desktop.getDesktop();
try
{
dt.open(fileName);
}
catch(Exception e){
// Catch exception here
}
Untested, never the less:
create a symbolic link via nio
with the right extension
in a temp dir
Call Desktop.open() on the symbolic link
This works for me locally:
public static void main(String... args) throws IOException {
Path source = FileSystems.getDefault().getPath(args[0]);
Path symLink = Files.createTempFile(source.getFileName().toString(), ".txt");
Files.delete(symLink);
Files.createSymbolicLink(symLink, source);
Desktop.getDesktop().open(symLink.toFile());
}
Disclaimer: I have not done any research beyond the above smoke test.
I am trying to figure out if there is any platform independent way to open a text file with the default text editor whatever it is.
Do you see the conflict above?
All the platforms have their own ways to manage default text editors and there's no way for Java to find the default editor.
Since your files are not .txt, you cannot use the nice methods from AWT.
However, you could
use File.renameTo() and add the .txt extension
open the directory containing the file
I'm aware that both methods (especially the first one) have their drawbacks.
The first method actually moves the file and even a copy doesn't solve the problem effectively.
However, the second approach might work.
I'm afraid you can't do more if you want to stay platform independent.

Can I make a Netbeans "empty file" part of compiled jar file?

I have 80,000 words for a crossword (among others) puzzle word pattern matcher. (User inputs "ba??" and gets, among other things, "ball, baby, bank, ..." or enters "ba*" and gets the aforementioned as well as "bat, basket, babboon...".)
I stuck the words in a Netbeans "empty file" and named it "dictionary". The file's contents are just (80,000) words, one per line. This code works like a charm to read the dictionary (code that filters is omitted):
static void showMatches(String pattern, String legal, String w) throws IOException
{
Path p = Paths.get("C:\\Users\\Dov\\Documents\\NetBeansProjects\\Masterwords\\src\\masterwords\\dictionary");
String word;
Scanner sc = new Scanner(p).useDelimiter("\r");
while(sc.hasNext()){
word = sc.next().substring(1);
gui.appendOutput(word);
}
sc.reset();
}
Is there a way to make the file (named "dictionary") become part of the compiled jar file so that I only need to "ship" one file to new, (largely helpless) users?
In another matter of curiosity...
Is it possible to make the argument to Paths.get(...) something like "masterwords/src/dictionary" to make the connection for the Scanner object to be able read it? I'm wondering if this might relate to an answer my first question. (If there's a way, I can't stumble onto it. Whatever similar string I use, I get no error, no output, no "build successful"--gotta click Run > Stop build/run.)
I'm not certain, based on your description, that my solution addresses your issue, but let me restate the problem as I understand it: You have a .jar file that relies on a dictionary resource. That resource is subject to change, and you'd like to be able to update it without having to ship out a whole new .jar containing a new dictionary.
If I'm reading you correctly, you want something like:
private File getInstallPath()
{
return new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().getPath());
}
This will return the install directory of your .jar file, which is where you can put your dictionary resource so that the .jar knows where to find it. Of course, now you have a bit of a training issue, because users can move, delete or misplace your dictionary file.
Part II:
Now that you've clarified your question, let me again restate: You want to be able to read an arbitrary file included in your .jar file. Fine. You're probably trying to open the file as a file, but once the file is in your .jar, you need to treat it as a resource.
Try using:
Class myClass = Class.forName("MyClass");
ClassLoader myLoader = myclass.getClassLoader();
InputStream myStream = myLoader.getResourceAsStream(myFile);
Do you really need me to explain what "myClass," "myLoader," etc. refer to? Hint: "myClass" is whatever your class is that needs to read the file.
After leaving this thread in frustration for a couple of weeks, yesterday I found a similar question at this forum, which led me to Google "java resource files" and visit ((this URL)).
Between the two I figured out how to read a file named 'dictionary' that was created as a Netbeans "empty Java file", which was located in Source Packages ... [default package] (as shown in Netbeans Projects window) and stored as C:\Users\Dov\!Docs\Documents\NetBeansProjects\WordPatternHelp\src\dictionary:
File file = new File("src/dictionary");
...
p = file.toPath();
sc = new Scanner(p).useDelimiter("\r");
Success. Hooray.
But after compiling and executing the .jar file from a DOS command line, 'dictionary' couldn't be found. So the above only works from within Netbeans IDE.
After mostly erroneous attempts caused by the above 'success', I finally got success using #Mars' second suggestion like so:
package masterwords;
public class Masterwords
...
InputStream myStream = Class.forName("masterwords.Masterwords").
getClassLoader().getResourceAsStream("dictionary");
sc = new Scanner(myStream).useDelimiter("\r"); // NULL PTR EXCEPTION HERE
So, for whatever it might be worth, a very belated thanks (and another apology) to #Mars. It was as straightforward as he indicated. Wish I'd tried it 2 weeks ago, but I'd never seen any of the methods and didn't want to take the time to learn how they work back then with other more pressing issues at hand. So I had no idea Mars had actually written the exact code I needed (except for the string arguments). Boy, do I know how the methods work now.

Checking for write access in a directory before creating files inside it

My small utility application asks the user for an output directory via a GUI file selector.
Then it creates a lot of files in this output directory after some processing.
I need to check if the application has write access so that it informs the user and does
not continue with the processing (which might take a long time)
My first attempt was the canWrite() method of java.io.File. But this does not work
since it deals with the directory entry itself and not its contents. I have seen at least
one instance of a Windows XP folder that can be renamed or deleted but no files may be created
in it (because of permissions). This is actually my testcase.
I finally settled with the following solution
//User places the input file in a directory and selects it from the GUI
//All output files will be created in the directory that contains the input file
File fileBrowse = chooser.getSelectedFile(); //chooser is a JFileChooser
File sample = new File(fileBrowse.getParent(),"empty.txt");
try
{
/*
* Create and delete a dummy file in order to check file permissions. Maybe
* there is a safer way for this check.
*/
sample.createNewFile();
sample.delete();
}
catch(IOException e)
{
//Error message shown to user. Operation is aborted
}
However this does not feel elegant to me since it just tries to actually create a file and checks if the operation succeeds.
I suspect that there must be a better way for this but all solutions I have found so far
with Security Managers and stuff deal with Java Applets and not standalone applications.
Am I missing something?
What is the recommended way of checking for file access inside a directory before
actually writing the files?
I am using Java 5.
You could check the file permissions, make sure the directory exists, and do a lot of checking or find a library that does all that checking for you BUT (!) isn't the best way of checking to try ? If you check for permissions and the filesystem changes... you will have to change your code. But trying to write a file will ALWAYS tell you if you can write a file.
Your solution doesn't have to be the most elegant one. It's not a cheap hard coded patch or something ugly. It's just normal code. And it will always work. But if you don't like to see that check in the code just separate it by putting it in class which only goal is to check for the possibly of writing. In fact, you should put it in a utility class wheter you like the elegance or not.
The other solution would be to place your whole writing-to-the-hard-drive code, in the try. And if you can't write, the whole part will be skipped and you give feedback to the user with a message in the catch part.
it doesn't works even if you invoke canWrite on the final path?
File sample = new File(fileBrowse.getParent(),"empty.txt");
if (sample.canWrite()) {
doSomethingUseful(sample);
} else {
notifyUser();
}
you can use FilePermission to get the details .
I find one way where you need to implement SecurityManager the code is here and here
Using Java 1.8 I was able to use the following.
Set<PosixFilePermission> permissions = Files.getPosixFilePermissions(Paths.get(destDir), LinkOption.NOFOLLOW_LINKS);
Assert.assertTrue("User did not have read permission.", permissions.contains(PosixFilePermission.OWNER_READ));
Assert.assertTrue("User did not have execute permission.", permissions.contains(PosixFilePermission.OWNER_EXECUTE));
Assert.assertTrue("User did not have write permission.", permissions.contains(PosixFilePermission.OWNER_WRITE));
Assert.assertFalse("Group did have read permission.", permissions.contains(PosixFilePermission.GROUP_READ));
Assert.assertFalse("Group did have execute permission.", permissions.contains(PosixFilePermission.GROUP_EXECUTE));
Assert.assertFalse("Group did have write permission.", permissions.contains(PosixFilePermission.GROUP_WRITE));
Assert.assertFalse("Others did have read permission.", permissions.contains(PosixFilePermission.OTHERS_READ));
Assert.assertFalse("Others did have execute permission.", permissions.contains(PosixFilePermission.OTHERS_EXECUTE));
Assert.assertFalse("Others did have write permission.", permissions.contains(PosixFilePermission.OTHERS_WRITE));

How to use ImageIO to save multiple BufferedImages to a file

I tried both of the following options:
1.
BufferedImage Buffered_Image;
MemoryCacheImageOutputStream MemoryCache_OutputStream =
new MemoryCacheImageOutputStream(new FileOutputStream("C:/Test.mov",false));
while (notFinished) // Main recording loop.
{
Buffered_Image=robot.createScreenCapture(); // Capture Screen image.
try { ImageIO.write(Buffered_Image,"png",MemoryCache_OutputStream); }
catch (Exception e) { e.printStackTrace(); }
}
2.
BufferedImage Buffered_Image;
ImageWriter writer;
try
{
ImageOutputStream ios=ImageIO.createImageOutputStream(new File("C:/Test.mov"));
Iterator writers=ImageIO.getImageWritersByFormatName("png");
while (writers.hasNext())
{
writer=(ImageWriter)writers.next();
writer.setOutput(ios);
Out(writer.toString()+" canInsertImage : "+writer.canInsertImage(0));
// Got this: com.sun.imageio.plugins.png.PNGImageWriter#19fcc69
// canInsertImage : false
}
}
catch (Exception e) { }
cntPics=0;
while (notFinished) // Main recording loop.
{
Buffered_Image=robot.createScreenCapture(); // Capture Screen image.
writer.write(null,new IIOImage(Buffered_Image,null,null),null);
if (writer.canInsertImage(-1)) {
// Append image at highest index
writer.writeInsert(-1,new IIOImage(Buffered_Image,null,null),null);
} else Out("Writer can’t append image Id : "+cntPics);
cntPics++;
}
Neither of them worked, what's the correct way to save multiple PNG images to a file?
Edit:
You are right, I found a java program called Krut that can record screen sessions, but it uses JPEGImageEncoder, the image quality isn't as good as I want, so I wonder if I can use ImageIO to encode the sequence.
If ImageIO can't do it, my next question would be is there a stand alone open source PNGImageEncoder that I can use to encode it? I know there are open source PNGImageEncoders, but they tend to be tangled in projects and hard to get all the supporting files out of it, any ideas? Thanks!
It looks like you're trying to create a video (MOV) file by writing multiple PNG files in a row. This isn't going to work. You'll probably have to find a third-party library for encoding your images into a video file (which is itself may be a good SO question).
EDIT: I should also note that you may actually be able to get video by writing multiple JPG images in a row to get a form of MJPEG (Motion JPEG) but for other formats such as MOV you're going to need an actual encoder.
What are you trying to do? Re-inventing MNG? Even if you can write multiple PNG images in the same file, it makes a compound file understood by no program (except those you might write).
If, as suggested by Marc, you want to make a movie, you might want to look at QuickTime for Java (QTJava). It is the solution used by Processing to make movies out of animations/frames. It has several quality/formats, from the worst (but small files) to the highest quality (high file sizes as result).

Categories

Resources