Ripping sound from closed applications to files with reasonably good names

The idea

Some applications that play sound do not allow the user to save those sounds for later listening. However, it is possible to tap into the audio playing through the sound card and record it to file (see here and here). This is one way to do what generally is called “ripping”.

Sometimes it is OK that everything ends up in the same file. The user then can separate the audio to individual files manually, but I thought that it would be nice if this was done automatically. Since most programs display the title of the playing song or sound, it is quite easy.

A prototype

I have written a small prototype in Java that runs on Windows (it uses the native functions EnumWindows and GetWindowText to find windows and get their titles). The concept could be extended to other languages (C# would be a good alternative in Windows, I imagine) and other platforms of course.

Implementation

One part of the code registers (the prefix of) the window title it is interested in and then sits listening for title change events from the code interfacing with Windows. Whenever it is notified it determines if the program is playing a song or not from the title. If it is playing it starts recording to a new wav file with the title extracted from the window title. If it was previously recording to another file, it closes that file. If the program is paused it closes any current recordings too.

The program takes some options to specify how to find the specific application and how to extract the title. Please see the source code for details.

I’m using an evaluation version of the commercial lib J/Invoke to access the Windows functions. Several open source libraries that do more or less the same thing exist (JNA, NativeCall, etc).

Some drawbacks with this implementation:

  • Sound quality. The sound quality isn’t optimal. This is partly due to the method of recording from the soundcard and partly due to that we have to reencode the decoded audio in order to get compressed files. This is hard to improve, since the assumption is that we do not have access to the original sound stream/file. I find the resulting quality OK, anyway.
  • Performance. I am polling the whole window list and getting each window´s title every 300 ms. this is clearly not good. Some small modifications would poll the list only when we call addWindowTitleListener and then get the titles of the registerered windows every 300 ms (or whatever time period would be best). If there is some event model in the chosen window system, that would be even better, of course.
  • User experience. This is not a nice GUI and the user has to manually adjust the volume of the output to get a good amplitude level in the resulting file. Additionally, the prototype records to a wav file. The user has to encode MP3s (or similar) using another program, for example Lame. This could of course be automated too. And it can be hard to find the correct sound mixer to record from. There is a link to Audacity in the source that can help with this though.
  • Commercial library dependency. J/Invoke (which seems to be very good) should be replaced if continued use is desired.

Source code

Source code of example ripper in Java: rip.zip
J/Invoke is not included but can be downloaded from the J/Invoke site.
EDIT: Browse the individual files:
TitledRipper.java
Recorder.java
JInvokeTitlePoller.java
WindowTitleListener.java
WindowTitleWatcher.java

Finally

I will not be developing this ripper any further. It was fun to make, though!

Leave a Reply

Your email address will not be published. Required fields are marked *