Posts Tagged ‘ruby’

lossfully: a music library transcoder

I’ll just explain my situation, but say “you” instead of “I” because I’ll assume it applies to you, too. If it doesn’t, you won’t have much use for this library anyway.

You have a large collection of music. After several misguided attempts at ripping all your CDs to mp3s or something, it’s finally mostly ripped (“for the last time”) to a lossless format like FLAC. But you still have a bunch of other lossy formats thrown in because…well, just because.

Now you want to take some of that music, shrink it in size, and put it on a portable device. You fire up some GUI program, drag the folders you want onto it, and ask it to give you back some Oggs. Or mp3s. Or whatever.

Ah yes, but now you’ve incurred the wrath of the information theory gods, for while you succeeded in shrinking your pristine FLACs, you have also indiscriminately transcoded your lossy files into a different lossy format. Depending on how smart the program was, you maybe even encoded a file into the same lossy format but using a higher bitrate. Scandalous!

Plus, you don’t just have one portable device. You have a phone, your wife has a tablet, there are three or four mp3 players floating around the house that belong to different people, and you want some music on your work laptop. But some of those have more memory than others, plus you only want some of your massive library on any one of them.

Lossfully isn’t your usual, “drag a bunch of music files on me and press go” music converter. You write a small script to describe what actions to take on all or a subset of your music library. Something along the lines of, “convert all of my lossless files to vorbis, and go ahead and convert all the lossy stuff too as long as it has a bitrate over 192 kbps.” You would do that by writing

require 'lossfully'
 
Lossfully.generate '~/share/music' => '~/share/music_lossy' do
  threads 2
  clobber true
 
  encode :lossless => ['.ogg', 6]
  encode [:lossy, 192] => ['.ogg', 4]
end

It might be easy enough for someone who doesn’t even know ruby, as long as they have some examples they can stare at and modify. Check out the documentation on RubyGems.org for more examples and to learn how to write your own. Code is on GitHub.

It uses sox to do the actual conversion, so you have to, you know, have that. And you might need to recompile it if your distribution has LAME support turned off. Might work on Windows, or it might not. And it definitely will throw nasty errors at you if you call it the wrong way, for now anyway.

, ,

1 Comment


Relisp 1.1.0

For all three of you who will read this (though there has been about 1000 downloads–that’s exciting) there’s a new version of Relisp. Check out the changelog, or look at the new examples in the gem. I promise that there’s documentation, even if rubygems.org isn’t currently showing it.

https://rubygems.org/gems/relisp

, ,

No Comments


Relisp: Rubyfied Emacs Lisp

Okay, look. If you use Emacs extensively and have never wished you could use something, anything, to customize it besides Lisp…well, then, 100 hacker points for you. But not this project. This project is not for you.

This purpose of Relisp is to:

  • call Ruby from Emacs
  • call Elisp from Ruby
  • manipulate Emacs without using Elisp to some extent (Ruby wrappers around some Elisp functions and objects)
  • reduce the number of blog entries titled “Is Ruby an acceptable Lisp?” and flame wars under the title “ruby vs. lisp vs. scheme vs. haskell vs. …”

How about some examples?

Call Ruby from Emacs

(relisp-start-slave)
(ruby-eval "1 + 2 + 3")
;    => 6
(ruby-eval "'ruby string'.reverse")
;    => "gnirts ybur"

Emacs starts a ruby process and they both pass questions and answers back and forth. Simple enough. But it’s more than just handing each other strings:

(type-of (ruby-eval "{:first => 'john', :last => 'doe'}"))
;    => hash-table
(setq list '(3 5 2 6 4 1))
(ruby-eval (concat (relisp-to-ruby list) ".class"))
;    => Relisp::Cons
(ruby-eval (concat (relisp-to-ruby list) ".to_list.class"))
;    => Relisp::List [a subclass of Array]
(ruby-eval (concat (relisp-to-ruby list) ".to_list.sort"))
;    => (1 2 3 4 5 6)
(type-of (ruby-eval (concat (relisp-to-ruby list) ".to_list.sort")))
;    => cons

Whenever objects are passed from Elisp to Ruby or back again they’re translated to the appropriate analogous type/class in the other language. An Elisp integer becomes a Ruby Fixnum, a vector becomes an Array, things like that.

Call Elisp from Ruby

I’ll admit it—I initially added this functionality just so I could run Relisp’s unit tests from the Ruby side. But if you ever want to use some Lisp in your Ruby programs, you can do that now.

require 'relisp'
 
emacs = Relisp::ElispSlave.new
emacs.elisp_eval( "(+ 1 2)" )
#    => 3
emacs.elisp_eval( '(concat "two " "words")' )
#    => "two words"

Looks sort of like the Lisp version, right? Using the typical method_missing magic, unknown ElispSlave methods are translated into calls to Lisp functions:

emacs.*(5, 2)
#    => 10 [calls (* 5 2)]
emacs.create_file_buffer( "blah.txt" )
#    =>  #<Relisp::Buffer:0x7f3839cf8168 ...> [calls (create-file-buffer "blah.txt")]

The result to that last example sort of gives away the grand finale. Wouldn’t it be nice to have a Ruby interface to things like buffers, windows and frames? Yes. Yes it would:

new_buffer = Relisp::Buffer.new("name_of_new_buffer")
new_buffer.switch_to
Relisp::Frame.new({:width => 80, :height => 20, :name => "ruby frame"})

Installation

For all of the glorious details, see the documentation at http://relisp.rubyforge.org/. To get the gem, just pull up the terminal:

[sudo] gem install relisp

There’s one little extra step after installing the gem that involves putting the relisp.el file in your ~/.elisp directory. The instructions will come up when you install the gem.

, ,

2 Comments



SetPageWidth